From 54c92b3996a6708700105da60b42347c4eac59ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Rafael=20Siqueira?= Date: Tue, 14 Oct 2025 23:38:39 -0300 Subject: [PATCH] fix --- enrollments-events/app/enrollment.py | 2 +- .../app/events/schedule_reminders.py | 8 ++++--- .../stopgap/set_subscription_covered.py | 2 +- enrollments-events/app/schemas.py | 2 +- enrollments-events/template.yaml | 2 ++ konviva-events/app/config.py | 1 + konviva-events/app/enrollment.py | 23 ++++++++++++------- konviva-events/template.yaml | 6 +++++ konviva-events/tests/conftest.py | 1 + konviva-events/tests/seeds.jsonl | 7 +++--- konviva-events/tests/test_app.py | 2 +- 11 files changed, 38 insertions(+), 18 deletions(-) diff --git a/enrollments-events/app/enrollment.py b/enrollments-events/app/enrollment.py index 842fe07..7c450a2 100644 --- a/enrollments-events/app/enrollment.py +++ b/enrollments-events/app/enrollment.py @@ -2,7 +2,7 @@ from abc import ABC from dataclasses import dataclass from datetime import timedelta from enum import Enum -from typing import NotRequired, Self, TypedDict +from typing import NotRequired, TypedDict from layercake.dateutils import now, ttl from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair diff --git a/enrollments-events/app/events/schedule_reminders.py b/enrollments-events/app/events/schedule_reminders.py index c17cd2c..cd6d619 100644 --- a/enrollments-events/app/events/schedule_reminders.py +++ b/enrollments-events/app/events/schedule_reminders.py @@ -9,11 +9,13 @@ from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey from boto3clients import dynamodb_client from config import ( + COURSE_TABLE, ENROLLMENT_TABLE, ) logger = Logger(__name__) -dyn = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client) +enrollment_layer = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client) +course_layer = DynamoDBPersistenceLayer(COURSE_TABLE, dynamodb_client) @event_source(data_class=EventBridgeEvent) @@ -28,7 +30,7 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: # Post-migration: after removing the stopgap file `patch_course_metadata.py`, # use `access_expires_at` from `new_image` access_period = int( - dyn.collection.get_item( + course_layer.collection.get_item( KeyPair( pk=new_image['course']['id'], sk=SortKey('0', path_spec='access_period'), @@ -36,7 +38,7 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: ) ) - with dyn.transact_writer() as transact: + with enrollment_layer.transact_writer() as transact: transact.put( item={ 'id': enrollment_id, diff --git a/enrollments-events/app/events/stopgap/set_subscription_covered.py b/enrollments-events/app/events/stopgap/set_subscription_covered.py index 54f84e7..788c393 100644 --- a/enrollments-events/app/events/stopgap/set_subscription_covered.py +++ b/enrollments-events/app/events/stopgap/set_subscription_covered.py @@ -26,7 +26,7 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: terms = user_layer.get_item( # Post-migration (users): uncomment the following line # KeyPair(new_image['org_id'], 'METADATA#BILLING_TERMS'), - KeyPair(new_image['tenant_id'], 'metadata#billing_policy'), + KeyPair(new_image['org_id'], 'metadata#billing_policy'), ) if not terms: diff --git a/enrollments-events/app/schemas.py b/enrollments-events/app/schemas.py index 38e64a0..7ab893e 100644 --- a/enrollments-events/app/schemas.py +++ b/enrollments-events/app/schemas.py @@ -48,7 +48,7 @@ class Enrollment(BaseModel): return super().model_dump( exclude={ 'user': {'email_verified'}, - 'course': {'cert', 'access_period'}, + 'course': {'cert'}, }, *args, **kwargs, diff --git a/enrollments-events/template.yaml b/enrollments-events/template.yaml index 4a86f5e..09d6ebf 100644 --- a/enrollments-events/template.yaml +++ b/enrollments-events/template.yaml @@ -252,6 +252,8 @@ Resources: Policies: - DynamoDBCrudPolicy: TableName: !Ref EnrollmentTable + - DynamoDBReadPolicy: + TableName: !Ref CourseTable Events: DynamoDBEvent: Type: EventBridgeRule diff --git a/konviva-events/app/config.py b/konviva-events/app/config.py index 76e917b..e54b04f 100644 --- a/konviva-events/app/config.py +++ b/konviva-events/app/config.py @@ -1,6 +1,7 @@ import os USER_TABLE: str = os.getenv('USER_TABLE') # type: ignore +COURSE_TABLE: str = os.getenv('COURSE_TABLE') # type: ignore ENROLLMENT_TABLE: str = os.getenv('ENROLLMENT_TABLE') # type: ignore KONVIVA_API_URL: str = os.getenv('KONVIVA_API_URL') # type: ignore diff --git a/konviva-events/app/enrollment.py b/konviva-events/app/enrollment.py index e7cb6f0..9804f7c 100644 --- a/konviva-events/app/enrollment.py +++ b/konviva-events/app/enrollment.py @@ -10,6 +10,12 @@ from layercake.dateutils import now, ttl from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey, TransactKey from layercake.strutils import md5_hash +from boto3clients import dynamodb_client +from config import COURSE_TABLE + +# @TODO Find a better way +course_layer = DynamoDBPersistenceLayer(COURSE_TABLE, dynamodb_client) + def update_progress( id: str, @@ -106,11 +112,6 @@ def set_score( enrollment = dynamodb_persistence_layer.collection.get_items( TransactKey(id) + SortKey('0') - + SortKey( - sk='METADATA#COURSE', - # Prevent conflicts with `course` - rename_key='metadata__course', - ) + SortKey( sk='METADATA#DEDUPLICATION_WINDOW', path_spec='offset_days', @@ -119,6 +120,14 @@ def set_score( ) user_id = enrollment['user']['id'] course_id = glom(enrollment, 'course.id') + exp_interval = course_layer.collection.get_item( + KeyPair( + pk=course_id, + sk=SortKey('0', path_spec='cert.exp_interval'), + ), + raise_on_error=False, + default=0, + ) try: if score >= 70: @@ -129,9 +138,7 @@ def set_score( progress=progress, user_id=user_id, course_id=course_id, - cert_exp_interval=int( - glom(enrollment, 'metadata__course.cert.exp_interval', default=0) - ), + cert_exp_interval=int(exp_interval), dedup_window_offset_days=int(enrollment['dedup_window_offset_days']), dynamodb_persistence_layer=dynamodb_persistence_layer, ) diff --git a/konviva-events/template.yaml b/konviva-events/template.yaml index 0c7e4d6..5a4a49e 100644 --- a/konviva-events/template.yaml +++ b/konviva-events/template.yaml @@ -8,6 +8,9 @@ Parameters: EnrollmentTable: Type: String Default: betaeducacao-prod-enrollments + CourseTable: + Type: String + Default: saladeaula_courses Globals: Function: @@ -27,6 +30,7 @@ Globals: POWERTOOLS_LOGGER_LOG_EVENT: true USER_TABLE: !Ref UserTable ENROLLMENT_TABLE: !Ref EnrollmentTable + COURSE_TABLE: !Ref CourseTable KONVIVA_API_URL: https://lms.saladeaula.digital KONVIVA_SECRET_KEY: "{{resolve:ssm:/betaeducacao/konviva/secret_key/str}}" @@ -58,6 +62,8 @@ Resources: Policies: - DynamoDBCrudPolicy: TableName: !Ref EnrollmentTable + - DynamoDBReadPolicy: + TableName: !Ref CourseTable Events: Post: Type: HttpApi diff --git a/konviva-events/tests/conftest.py b/konviva-events/tests/conftest.py index 1d1ded1..f4359c2 100644 --- a/konviva-events/tests/conftest.py +++ b/konviva-events/tests/conftest.py @@ -18,6 +18,7 @@ def pytest_configure(): os.environ['DYNAMODB_PARTITION_KEY'] = PK os.environ['DYNAMODB_SORT_KEY'] = SK os.environ['USER_TABLE'] = PYTEST_TABLE_NAME + os.environ['COURSE_TABLE'] = PYTEST_TABLE_NAME os.environ['ENROLLMENT_TABLE'] = PYTEST_TABLE_NAME os.environ['KONVIVA_API_URL'] = 'https://lms.saladeaula.digital' diff --git a/konviva-events/tests/seeds.jsonl b/konviva-events/tests/seeds.jsonl index 091d31c..8995efd 100644 --- a/konviva-events/tests/seeds.jsonl +++ b/konviva-events/tests/seeds.jsonl @@ -1,6 +1,10 @@ // Users {"id": "123", "sk": "0"} +// Courses +{"id": "432", "sk": "0", "access_period": 360, "cert": {"exp_interval": 365}, "created_at": "2025-04-06T11:07:32.762178-03:00"} + + // Enrollments {"id": "197991aa-52e2-4e0c-b2a4-a7c53bcfee02", "sk": "0", "progress": 10, "status": "IN_PROGRESS"} @@ -11,18 +15,15 @@ {"id": "d9da85f2-e09f-472d-9515-3d91d70f1e8a", "sk": "SCHEDULE#REMINDER_NO_ACCESS_AFTER_3_DAYS"} {"id": "6c7e3d9b-f5d1-4da4-9e55-0825bb6ff2b8", "sk": "0", "progress": 80, "status": "IN_PROGRESS", "user": {"id": "123", "name": "Myles Kennedy"}, "course": {"id": "432", "name": "pytest"}, "created_at": "2022-04-06T11:07:32.762178-03:00"} -{"id": "6c7e3d9b-f5d1-4da4-9e55-0825bb6ff2b8", "sk": "METADATA#COURSE", "access_period": 360, "cert": {"exp_interval": 365}, "created_at": "2025-04-06T11:07:32.762178-03:00"} {"id": "6c7e3d9b-f5d1-4da4-9e55-0825bb6ff2b8", "sk": "METADATA#DEDUPLICATION_WINDOW", "offset_days": 90, "created_at": "2025-04-06T11:07:32.762178-03:00"} {"id": "6c7e3d9b-f5d1-4da4-9e55-0825bb6ff2b8", "sk": "SCHEDULE#REMINDER_ACCESS_PERIOD_BEFORE_30_DAYS"} {"id": "6c7e3d9b-f5d1-4da4-9e55-0825bb6ff2b8", "sk": "SCHEDULE#SET_ACCESS_EXPIRED"} {"id": "cc2c3bce-c34a-4e82-aa6c-1a19e70ec5ae", "sk": "0", "progress": 109, "status": "COMPLETED", "user": {"id": "321", "name": "Chester Bennington"}, "course": {"id": "432", "name": "pytest"}, "created_at": "2022-04-06T11:07:32.762178-03:00"} -{"id": "cc2c3bce-c34a-4e82-aa6c-1a19e70ec5ae", "sk": "METADATA#COURSE", "access_period": 360, "cert": {"exp_interval": 365}, "created_at": "2025-04-06T11:07:32.762178-03:00"} {"id": "cc2c3bce-c34a-4e82-aa6c-1a19e70ec5ae", "sk": "METADATA#DEDUPLICATION_WINDOW", "offset_days": 90, "created_at": "2025-04-06T11:07:32.762178-03:00"} {"id": "cc2c3bce-c34a-4e82-aa6c-1a19e70ec5ae", "sk": "SCHEDULE#SET_AS_ARCHIVED"} {"id": "5db53b35-0bae-4907-afda-a213cb5bf651", "sk": "0", "progress": 0, "status": "PENDING", "user": {"id": "1234", "name": "Michael Jackinson"}, "course": {"id": "432", "name": "pytest"}, "created_at": "2022-04-06T11:07:32.762178-03:00"} -{"id": "5db53b35-0bae-4907-afda-a213cb5bf651", "sk": "METADATA#COURSE", "access_period": 360, "cert": {"exp_interval": 365}, "created_at": "2025-04-06T11:07:32.762178-03:00"} // To relate with the enrollment {"id": "konviva", "sk": "123", "enrollment_id": "d9da85f2-e09f-472d-9515-3d91d70f1e8a"} diff --git a/konviva-events/tests/test_app.py b/konviva-events/tests/test_app.py index 2ca3064..805ce7c 100644 --- a/konviva-events/tests/test_app.py +++ b/konviva-events/tests/test_app.py @@ -113,7 +113,7 @@ def test_set_as_completed( docx = next((x for x in r['items'] if x['sk'] == '0'), {}) assert 'completed_at' in docx - assert len(r['items']) == 7 + assert len(r['items']) == 6 assert any(item.get('sk') == 'LOCK' for item in r['items']) assert any( item.get('sk') == 'SCHEDULE#REMINDER_CERT_EXPIRATION_BEFORE_30_DAYS'