add patch

This commit is contained in:
2025-07-17 23:50:28 -03:00
parent 6eafb0f541
commit 5df126c605
5 changed files with 142 additions and 1 deletions

View File

@@ -68,8 +68,10 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
}, },
} }
) )
logger.info('Email sent')
except Exception as exc: except Exception as exc:
logger.exception(exc) logger.exception(exc)
enrollment_layer.put_item( enrollment_layer.put_item(
item={ item={
'id': old_image['id'], 'id': old_image['id'],

View File

@@ -0,0 +1,87 @@
import json
import sqlite3
from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.data_classes import (
EventBridgeEvent,
event_source,
)
from aws_lambda_powertools.utilities.typing import LambdaContext
from glom import glom
from layercake.dateutils import now
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey
from sqlite_utils import Database
from boto3clients import dynamodb_client
from config import (
COURSE_TABLE,
ENROLLMENT_TABLE,
SQLITE_DATABASE,
SQLITE_TABLE,
USER_TABLE,
)
sqlite3.register_converter('json', json.loads)
logger = Logger(__name__)
enrollment_layer = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
@event_source(data_class=EventBridgeEvent)
@logger.inject_lambda_context
def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
new_image = event.detail['new_image']
now_ = now()
course_id = glom(new_image, 'course.id')
data = enrollment_layer.collection.get_items(
KeyPair(
pk=glom(new_image, 'user.id'),
sk=SortKey('konviva', path_spec='konvivaId'),
rename_key='user_id',
table_name=USER_TABLE,
)
+ KeyPair(
pk=course_id,
sk=SortKey('0', path_spec='metadata__konviva_class_id'),
table_name=COURSE_TABLE,
rename_key='class_id',
),
flatten_top=False,
)
if 'class_id' not in data:
data['class_id'] = _get_class_id(course_id)
logger.info('IDs found', ids=data)
return enrollment_layer.put_item(
item={
'id': new_image['id'],
'sk': 'konviva',
'user_id': data['user_id'],
'class_id': data['class_id'],
'created_at': now_,
},
cond_expr='attribute_not_exists(sk)',
)
class CourseNotFoundError(Exception):
def __init__(self, *args):
super().__init__('Course not found')
def _get_class_id(course_id: str) -> int:
with sqlite3.connect(
database=SQLITE_DATABASE, detect_types=sqlite3.PARSE_DECLTYPES
) as conn:
db = Database(conn)
rows = db[SQLITE_TABLE].rows_where(
"json->>'$.metadata__betaeducacao_id' = ?", [course_id]
)
for row in rows:
return int(row['json']['metadata__konviva_id'])
raise CourseNotFoundError

View File

@@ -62,6 +62,30 @@ Resources:
new_image: new_image:
sk: ["0"] sk: ["0"]
EventPatchKonvivaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: events.stopgap.patch_konviva.lambda_handler
LoggingConfig:
LogGroup: !Ref EventLog
Policies:
- DynamoDBWritePolicy:
TableName: !Ref EnrollmentTable
- DynamoDBReadPolicy:
TableName: !Ref UserTable
- DynamoDBReadPolicy:
TableName: !Ref CourseTable
Events:
DynamoDBEvent:
Type: EventBridgeRule
Properties:
Pattern:
resources: [!Ref EnrollmentTable]
detail-type: [INSERT]
detail:
new_image:
sk: ["0"]
EventAllocateSlotsFunction: EventAllocateSlotsFunction:
Type: AWS::Serverless::Function Type: AWS::Serverless::Function
Properties: Properties:

View File

@@ -0,0 +1,27 @@
from aws_lambda_powertools.utilities.typing import LambdaContext
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
import events.stopgap.patch_konviva as app
def test_patch_konviva(
dynamodb_seeds,
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
lambda_context: LambdaContext,
):
event = {
'detail': {
'new_image': {
'id': 'f321f0aa-66a3-4419-b41f-cb6b961e7e4f',
'user': {'id': '5OxmMjL-ujoR5IMGegQz'},
'course': {'id': '123'},
},
}
}
assert app.lambda_handler(event, lambda_context)
r = dynamodb_persistence_layer.collection.get_item(
KeyPair('f321f0aa-66a3-4419-b41f-cb6b961e7e4f', 'konviva')
)
assert 'user_id' in r

View File

@@ -5,4 +5,5 @@
{"id": {"S": "JeCybf6oiv6CF3PchhBqdG"}, "sk": {"S": "items"},"items": {"L": [{"M": {"id": {"S": "a955518e-ebcb-4441-b914-ddc9ecef84f0"},"name": {"S": "NR-11 Operador de Munck"},"quantity": {"N": "3"},"unit_price": {"N": "99"}}}, {"M": {"id": {"S": "123"},"name": {"S": "pytest"},"quantity": {"N": "1"},"unit_price": {"N": "99"}}},{"M": {"id": {"S": "23020"},"name": {"S": "Desconto 100%"},"quantity": {"N": "1"},"unit_price": {"N": "-297"}}}]},"updated_at": {"S": "2025-07-16T15:54:27.154404-03:00"}} {"id": {"S": "JeCybf6oiv6CF3PchhBqdG"}, "sk": {"S": "items"},"items": {"L": [{"M": {"id": {"S": "a955518e-ebcb-4441-b914-ddc9ecef84f0"},"name": {"S": "NR-11 Operador de Munck"},"quantity": {"N": "3"},"unit_price": {"N": "99"}}}, {"M": {"id": {"S": "123"},"name": {"S": "pytest"},"quantity": {"N": "1"},"unit_price": {"N": "99"}}},{"M": {"id": {"S": "23020"},"name": {"S": "Desconto 100%"},"quantity": {"N": "1"},"unit_price": {"N": "-297"}}}]},"updated_at": {"S": "2025-07-16T15:54:27.154404-03:00"}}
{"id": {"S": "JeCybf6oiv6CF3PchhBqdG"},"sk": {"S": "generated_items"},"create_date": {"S": "2025-07-16T15:54:30.160729-03:00"},"scope": {"S": "MULTI_USER"},"status": {"S": "SUCCESS"},"update_date": {"S": "2025-07-16T15:54:33.674670-03:00"}} {"id": {"S": "JeCybf6oiv6CF3PchhBqdG"},"sk": {"S": "generated_items"},"create_date": {"S": "2025-07-16T15:54:30.160729-03:00"},"scope": {"S": "MULTI_USER"},"status": {"S": "SUCCESS"},"update_date": {"S": "2025-07-16T15:54:33.674670-03:00"}}
{"id": {"S": "a955518e-ebcb-4441-b914-ddc9ecef84f0"},"sk": {"S": "0"},"access_period": {"N": "360"},"cert": {"M": {"exp_interval": {"N": "360"}}},"created_at": {"S": "2025-07-14T15:09:18.559528-03:00"},"metadata__konviva_class_id": {"N": "281"},"name": {"S": "NR-11 Operador de Munck"},"tenant_id": {"S": "*"}} {"id": {"S": "a955518e-ebcb-4441-b914-ddc9ecef84f0"},"sk": {"S": "0"},"access_period": {"N": "360"},"cert": {"M": {"exp_interval": {"N": "360"}}},"created_at": {"S": "2025-07-14T15:09:18.559528-03:00"},"metadata__konviva_class_id": {"N": "281"},"name": {"S": "NR-11 Operador de Munck"},"tenant_id": {"S": "*"}}
{"id": {"S": "123"},"sk": {"S": "0"},"access_period": {"N": "360"},"cert": {"M": {"exp_interval": {"N": "360"}}},"created_at": {"S": "2025-07-14T15:09:18.559528-03:00"},"metadata__konviva_class_id": {"N": "281"},"name": {"S": "pytest"},"tenant_id": {"S": "*"}} {"id": {"S": "123"},"sk": {"S": "0"},"access_period": {"N": "360"},"cert": {"M": {"exp_interval": {"N": "360"}}},"created_at": {"S": "2025-07-14T15:09:18.559528-03:00"},"metadata__konviva_class_id": {"N": "281"},"name": {"S": "pytest"},"tenant_id": {"S": "*"}}
{"id": {"S": "5OxmMjL-ujoR5IMGegQz"},"sk": {"S": "konviva"},"created_at": {"S": "2025-07-11T13:52:35.521154-03:00"},"konvivaId": {"N": "26943"}}