fix issued cert
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
"""
|
||||||
|
If a certificate exists, remind the user that the certificate expired.
|
||||||
|
"""
|
||||||
|
|
||||||
|
SUBJECT = 'Seu certificado {course} expirou!'
|
||||||
|
MESSAGE = """
|
||||||
|
Oi {first_name}, tudo bem?<br/><br/>
|
||||||
|
|
||||||
|
O certificado do curso <b>{course}</b> expirou.<br/>
|
||||||
|
Para manter sua certificação válida, é necessário refazer o curso.<br/><br/>
|
||||||
|
|
||||||
|
<a href="https://saladeaula.digital">👉 Acesse o curso e renove sua certificação</a>
|
||||||
|
"""
|
||||||
@@ -15,7 +15,7 @@ from boto3clients import dynamodb_client, s3_client
|
|||||||
from config import BUCKET_NAME, ENROLLMENT_TABLE, PAPERFORGE_API
|
from config import BUCKET_NAME, ENROLLMENT_TABLE, PAPERFORGE_API
|
||||||
|
|
||||||
logger = Logger(__name__)
|
logger = Logger(__name__)
|
||||||
enrollment_layer = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
|
dyn = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
|
||||||
|
|
||||||
|
|
||||||
@event_source(data_class=EventBridgeEvent)
|
@event_source(data_class=EventBridgeEvent)
|
||||||
@@ -24,24 +24,23 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
|
|||||||
new_image = event.detail['new_image']
|
new_image = event.detail['new_image']
|
||||||
now_ = now()
|
now_ = now()
|
||||||
enrollment_id = new_image['id']
|
enrollment_id = new_image['id']
|
||||||
course = enrollment_layer.collection.get_items(
|
cert = dyn.collection.get_item(
|
||||||
TransactKey(new_image['id'])
|
KeyPair(
|
||||||
+ SortKey('METADATA#COURSE', path_spec='cert', rename_key='cert')
|
pk=new_image['id'],
|
||||||
# Post-migration: remove the following lines
|
sk=SortKey('METADATA#COURSE', path_spec='cert', rename_key='cert'),
|
||||||
+ SortKey('STARTED', path_spec='started_at', rename_key='started_at')
|
),
|
||||||
+ SortKey('COMPLETED', path_spec='completed_at', rename_key='completed_at'),
|
raise_on_error=False,
|
||||||
flatten_top=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
if 'cert' not in course:
|
if not cert:
|
||||||
logger.debug('Certificate not found')
|
logger.debug('Certificate not found')
|
||||||
# There is no certificate to issue from metadata
|
# There is no certificate to issue from metadata
|
||||||
return False
|
return False
|
||||||
|
|
||||||
cert = course['cert']
|
started_at: datetime = fromisoformat(new_image['started_at']) # type: ignore
|
||||||
started_at: datetime = fromisoformat(course['started_at']) # type: ignore
|
completed_at: datetime = fromisoformat(new_image['completed_at']) # type: ignore
|
||||||
completed_at: datetime = fromisoformat(course['completed_at']) # type: ignore
|
cert_expires_at = completed_at + timedelta(days=int(cert['exp_interval']))
|
||||||
cert_expires_at = now_ + timedelta(days=int(cert['exp_interval']))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Send template URI and data to Paperforge API to generate a PDF
|
# Send template URI and data to Paperforge API to generate a PDF
|
||||||
@@ -83,13 +82,14 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
|
|||||||
logger.exception(exc)
|
logger.exception(exc)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
return enrollment_layer.update_item(
|
return dyn.update_item(
|
||||||
key=KeyPair(
|
key=KeyPair(
|
||||||
pk=enrollment_id,
|
pk=enrollment_id,
|
||||||
sk='0',
|
sk='0',
|
||||||
),
|
),
|
||||||
update_expr='SET issued_cert = :issued_cert',
|
update_expr='SET issued_cert = :issued_cert, uploaded_at = :now',
|
||||||
expr_attr_values={
|
expr_attr_values={
|
||||||
|
':now': now_,
|
||||||
':issued_cert': {
|
':issued_cert': {
|
||||||
'issued_at': now_,
|
'issued_at': now_,
|
||||||
'expires_at': cert_expires_at,
|
'expires_at': cert_expires_at,
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ def test_issue_cert(
|
|||||||
'detail': {
|
'detail': {
|
||||||
'new_image': {
|
'new_image': {
|
||||||
'id': enrollment_id,
|
'id': enrollment_id,
|
||||||
|
'completed_at': '2025-09-21T14:20:36.276467-03:00',
|
||||||
|
'started_at': '2025-09-19T14:34:54.704548-03:00',
|
||||||
'user': {
|
'user': {
|
||||||
'name': 'Jimi Hendrix',
|
'name': 'Jimi Hendrix',
|
||||||
'cpf': '74630003037',
|
'cpf': '74630003037',
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ def get_enrollment(id: str):
|
|||||||
record = enrollment_layer.collection.get_items(
|
record = enrollment_layer.collection.get_items(
|
||||||
TransactKey(id)
|
TransactKey(id)
|
||||||
+ SortKey('0')
|
+ SortKey('0')
|
||||||
+ SortKey('STARTED', rename_key='started_at', path_spec='started_at')
|
# + SortKey('STARTED', rename_key='started_at', path_spec='started_at')
|
||||||
+ SortKey('COMPLETED', rename_key='completed_at', path_spec='completed_at')
|
# + SortKey('COMPLETED', rename_key='completed_at', path_spec='completed_at')
|
||||||
+ SortKey('FAILED', rename_key='failed_at', path_spec='failed_at')
|
+ SortKey('FAILED', rename_key='failed_at', path_spec='failed_at')
|
||||||
+ SortKey('CANCELED', rename_key='canceled')
|
+ SortKey('CANCELED', rename_key='canceled')
|
||||||
+ SortKey('ARCHIVED', rename_key='archived_at', path_spec='archived_at')
|
+ SortKey('ARCHIVED', rename_key='archived_at', path_spec='archived_at')
|
||||||
|
|||||||
@@ -201,7 +201,10 @@ def set_status_as_canceled(
|
|||||||
with persistence_layer.transact_writer() as transact:
|
with persistence_layer.transact_writer() as transact:
|
||||||
transact.update(
|
transact.update(
|
||||||
key=KeyPair(id, '0'),
|
key=KeyPair(id, '0'),
|
||||||
update_expr='SET #status = :canceled, updated_at = :updated_at',
|
update_expr='SET #status = :canceled, \
|
||||||
|
access_expired = :true, \
|
||||||
|
canceled_at = :now, \
|
||||||
|
updated_at = :now',
|
||||||
cond_expr='#status = :pending',
|
cond_expr='#status = :pending',
|
||||||
expr_attr_names={
|
expr_attr_names={
|
||||||
'#status': 'status',
|
'#status': 'status',
|
||||||
@@ -209,7 +212,8 @@ def set_status_as_canceled(
|
|||||||
expr_attr_values={
|
expr_attr_values={
|
||||||
':canceled': 'CANCELED',
|
':canceled': 'CANCELED',
|
||||||
':pending': 'PENDING',
|
':pending': 'PENDING',
|
||||||
':updated_at': now_,
|
':true': True,
|
||||||
|
':now': now_,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
transact.put(
|
transact.put(
|
||||||
@@ -217,7 +221,7 @@ def set_status_as_canceled(
|
|||||||
'id': id,
|
'id': id,
|
||||||
'sk': 'CANCELED',
|
'sk': 'CANCELED',
|
||||||
'canceled_by': created_by,
|
'canceled_by': created_by,
|
||||||
'canceled_at': now_,
|
'created_at': now_,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
transact.delete(
|
transact.delete(
|
||||||
@@ -256,7 +260,7 @@ def set_status_as_canceled(
|
|||||||
transact.delete(
|
transact.delete(
|
||||||
key=KeyPair(
|
key=KeyPair(
|
||||||
pk=id,
|
pk=id,
|
||||||
sk='SCHEDULE#SET_AS_EXPIRED',
|
sk='SCHEDULE#SET_ACCESS_EXPIRED',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
transact.delete(
|
transact.delete(
|
||||||
|
|||||||
Reference in New Issue
Block a user