remove archived and expired
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
from datetime import datetime, timedelta
|
||||
from decimal import Decimal
|
||||
|
||||
from aws_lambda_powertools.event_handler.exceptions import (
|
||||
@@ -7,7 +6,7 @@ from aws_lambda_powertools.event_handler.exceptions import (
|
||||
)
|
||||
from botocore.args import logger
|
||||
from glom import glom
|
||||
from layercake.dateutils import fromisoformat, now, ttl
|
||||
from layercake.dateutils import now, ttl
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey, TransactKey
|
||||
from layercake.strutils import md5_hash
|
||||
|
||||
@@ -124,56 +123,34 @@ def set_score(
|
||||
rename_key='dedup_window_offset_days',
|
||||
),
|
||||
)
|
||||
now_ = now()
|
||||
user_id = enrollment['user']['id']
|
||||
course_id = glom(enrollment, 'course.id')
|
||||
created_at: datetime = fromisoformat(enrollment['created_at']) # type: ignore
|
||||
access_period = created_at + timedelta(
|
||||
days=int(glom(enrollment, 'metadata__course.access_period'))
|
||||
)
|
||||
|
||||
try:
|
||||
match score >= 70, now_ > access_period:
|
||||
case True, True:
|
||||
# Got a score of 70 or higher, but the access period has expired
|
||||
return _set_status_as_archived(
|
||||
id,
|
||||
dynamodb_persistence_layer=dynamodb_persistence_layer,
|
||||
)
|
||||
case True, False:
|
||||
# Got a score of 70 or higher, and still within the access period
|
||||
return _set_status_as_completed(
|
||||
id,
|
||||
score,
|
||||
progress=progress,
|
||||
user_id=user_id,
|
||||
course_id=course_id,
|
||||
cert_exp_interval=int(
|
||||
glom(
|
||||
enrollment, 'metadata__course.cert.exp_interval', default=0
|
||||
)
|
||||
),
|
||||
dedup_window_offset_days=int(
|
||||
enrollment['dedup_window_offset_days']
|
||||
),
|
||||
dynamodb_persistence_layer=dynamodb_persistence_layer,
|
||||
)
|
||||
case False, True:
|
||||
# Got a score below 70, and the access period has expired
|
||||
return _set_status_as_expired(
|
||||
id,
|
||||
dynamodb_persistence_layer=dynamodb_persistence_layer,
|
||||
)
|
||||
case _:
|
||||
# Got a score below 70, and still within the access period
|
||||
return _set_status_as_failed(
|
||||
id,
|
||||
score,
|
||||
progress=progress,
|
||||
user_id=user_id,
|
||||
course_id=course_id,
|
||||
dynamodb_persistence_layer=dynamodb_persistence_layer,
|
||||
)
|
||||
if score >= 70:
|
||||
# Got a score of 70 or higher
|
||||
return _set_status_as_completed(
|
||||
id,
|
||||
score,
|
||||
progress=progress,
|
||||
user_id=user_id,
|
||||
course_id=course_id,
|
||||
cert_exp_interval=int(
|
||||
glom(enrollment, 'metadata__course.cert.exp_interval', default=0)
|
||||
),
|
||||
dedup_window_offset_days=int(enrollment['dedup_window_offset_days']),
|
||||
dynamodb_persistence_layer=dynamodb_persistence_layer,
|
||||
)
|
||||
|
||||
# Got a score below 70
|
||||
return _set_status_as_failed(
|
||||
id,
|
||||
score,
|
||||
progress=progress,
|
||||
user_id=user_id,
|
||||
course_id=course_id,
|
||||
dynamodb_persistence_layer=dynamodb_persistence_layer,
|
||||
)
|
||||
except EnrollmentConflictError as err:
|
||||
logger.exception(err)
|
||||
raise
|
||||
@@ -193,15 +170,15 @@ def _set_status_as_completed(
|
||||
) -> bool:
|
||||
now_ = now()
|
||||
lock_hash = md5_hash(f'{user_id}{course_id}')
|
||||
archive_ttl = ttl(
|
||||
cert_exp_ttl = ttl(
|
||||
start_dt=now_,
|
||||
days=cert_exp_interval,
|
||||
)
|
||||
cert_expiration_reminder_ttl = ttl(
|
||||
cert_exp_reminder_ttl = ttl(
|
||||
start_dt=now_,
|
||||
days=cert_exp_interval - 30,
|
||||
)
|
||||
deduplication_lock_ttl = ttl(
|
||||
dedup_lock_ttl = ttl(
|
||||
start_dt=now_,
|
||||
days=cert_exp_interval - dedup_window_offset_days,
|
||||
)
|
||||
@@ -209,8 +186,10 @@ def _set_status_as_completed(
|
||||
with dynamodb_persistence_layer.transact_writer() as transact:
|
||||
transact.update(
|
||||
key=KeyPair(pk=id, sk='0'),
|
||||
update_expr='SET #status = :completed, progress = :progress, \
|
||||
score = :score, updated_at = :updated_at',
|
||||
update_expr='SET #status = :completed, \
|
||||
progress = :progress, \
|
||||
score = :score, \
|
||||
updated_at = :updated_at',
|
||||
cond_expr='#status = :in_progress',
|
||||
expr_attr_names={'#status': 'status'},
|
||||
expr_attr_values={
|
||||
@@ -236,15 +215,15 @@ def _set_status_as_completed(
|
||||
item={
|
||||
'id': id,
|
||||
'sk': 'SCHEDULE#REMINDER_CERT_EXPIRATION_BEFORE_30_DAYS',
|
||||
'ttl': cert_expiration_reminder_ttl,
|
||||
'ttl': cert_exp_ttl,
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': id,
|
||||
'sk': 'SCHEDULE#SET_AS_ARCHIVED',
|
||||
'ttl': archive_ttl,
|
||||
'sk': 'SCHEDULE#SET_CERT_EXPIRED',
|
||||
'ttl': cert_exp_reminder_ttl,
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
@@ -252,7 +231,7 @@ def _set_status_as_completed(
|
||||
item={
|
||||
'id': id,
|
||||
'sk': 'LOCK',
|
||||
'ttl': deduplication_lock_ttl,
|
||||
'ttl': dedup_lock_ttl,
|
||||
'hash': lock_hash,
|
||||
'created_at': now_,
|
||||
}
|
||||
@@ -262,7 +241,7 @@ def _set_status_as_completed(
|
||||
'id': 'LOCK',
|
||||
'sk': lock_hash,
|
||||
'enrollment_id': id,
|
||||
'ttl': deduplication_lock_ttl,
|
||||
'ttl': dedup_lock_ttl,
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
@@ -274,12 +253,6 @@ def _set_status_as_completed(
|
||||
sk='CANCEL_POLICY',
|
||||
)
|
||||
)
|
||||
transact.delete(
|
||||
key=KeyPair(
|
||||
pk=id,
|
||||
sk='SCHEDULE#SET_AS_EXPIRED',
|
||||
)
|
||||
)
|
||||
transact.delete(
|
||||
key=KeyPair(
|
||||
pk=id,
|
||||
@@ -312,8 +285,11 @@ def _set_status_as_failed(
|
||||
with dynamodb_persistence_layer.transact_writer() as transact:
|
||||
transact.update(
|
||||
key=KeyPair(pk=id, sk='0'),
|
||||
update_expr='SET #status = :failed, progress = :progress, \
|
||||
score = :score, updated_at = :updated_at',
|
||||
update_expr='SET #status = :failed, \
|
||||
progress = :progress, \
|
||||
score = :score, \
|
||||
access_expired = :access_expired, \
|
||||
updated_at = :updated_at',
|
||||
cond_expr='#status = :in_progress',
|
||||
expr_attr_names={'#status': 'status'},
|
||||
expr_attr_values={
|
||||
@@ -321,6 +297,7 @@ def _set_status_as_failed(
|
||||
':in_progress': 'IN_PROGRESS',
|
||||
':score': score,
|
||||
':progress': progress,
|
||||
':access_expired': True,
|
||||
':updated_at': now_,
|
||||
},
|
||||
exc_cls=EnrollmentConflictError,
|
||||
@@ -343,7 +320,7 @@ def _set_status_as_failed(
|
||||
transact.delete(
|
||||
key=KeyPair(
|
||||
pk=id,
|
||||
sk='SCHEDULE#SET_AS_EXPIRED',
|
||||
sk='SCHEDULE#SET_ACCESS_EXPIRED',
|
||||
)
|
||||
)
|
||||
transact.delete(
|
||||
@@ -369,90 +346,6 @@ def _set_status_as_failed(
|
||||
return True
|
||||
|
||||
|
||||
def _set_status_as_archived(
|
||||
id: str,
|
||||
*,
|
||||
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
||||
):
|
||||
now_ = now()
|
||||
with dynamodb_persistence_layer.transact_writer() as transact:
|
||||
transact.update(
|
||||
key=KeyPair(pk=id, sk='0'),
|
||||
update_expr='SET #status = :archived, updated_at = :updated_at',
|
||||
cond_expr='#status = :completed',
|
||||
expr_attr_names={'#status': 'status'},
|
||||
expr_attr_values={
|
||||
':archived': 'ARCHIVED',
|
||||
':completed': 'COMPLETED',
|
||||
':updated_at': now_,
|
||||
},
|
||||
exc_cls=EnrollmentConflictError,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': id,
|
||||
'sk': 'ARCHIVED',
|
||||
'archived_at': now_,
|
||||
},
|
||||
cond_expr='attribute_not_exists(sk)',
|
||||
)
|
||||
# Remove events that no longer apply
|
||||
transact.delete(
|
||||
key=KeyPair(
|
||||
pk=id,
|
||||
sk='SCHEDULE#SET_AS_ARCHIVED',
|
||||
)
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _set_status_as_expired(
|
||||
id: str,
|
||||
*,
|
||||
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
||||
):
|
||||
now_ = now()
|
||||
|
||||
with dynamodb_persistence_layer.transact_writer() as transact:
|
||||
transact.update(
|
||||
key=KeyPair(pk=id, sk='0'),
|
||||
update_expr='SET #status = :expired, updated_at = :updated_at',
|
||||
cond_expr='#status = :in_progress OR #status = :pending',
|
||||
expr_attr_names={
|
||||
'#status': 'status',
|
||||
},
|
||||
expr_attr_values={
|
||||
':pending': 'PENDING',
|
||||
':in_progress': 'IN_PROGRESS',
|
||||
':expired': 'EXPIRED',
|
||||
':updated_at': now_,
|
||||
},
|
||||
exc_cls=EnrollmentConflictError,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': id,
|
||||
'sk': 'EXPIRED',
|
||||
'expired_at': now_,
|
||||
},
|
||||
cond_expr='attribute_not_exists(sk)',
|
||||
)
|
||||
# Remove events and policies that no longer apply
|
||||
transact.delete(
|
||||
key=KeyPair(
|
||||
pk=id,
|
||||
sk='CANCEL_POLICY',
|
||||
),
|
||||
)
|
||||
transact.delete(
|
||||
key=KeyPair(
|
||||
pk=id,
|
||||
sk='SCHEDULE#SET_AS_EXPIRED',
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class EnrollmentNotFoundError(NotFoundError):
|
||||
def __init__(self, *_):
|
||||
super().__init__('Enrollment not found')
|
||||
|
||||
Reference in New Issue
Block a user