From edecbce3567abf2cd7772e73d493c32ae2bcdf76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Rafael=20Siqueira?= Date: Wed, 23 Jul 2025 01:05:21 -0300 Subject: [PATCH] add user id to order --- order-events/app/events/assign_tenant_cnpj.py | 69 ------------------- .../app/events/remove_slots_if_canceled.py | 15 ++-- order-events/template.yaml | 33 ++++++++- order-events/tests/conftest.py | 3 +- .../tests/events/test_assign_tenant_cnpj.py | 27 -------- .../events/test_remove_slots_if_canceled.py | 6 +- order-events/tests/seeds.jsonl | 1 + 7 files changed, 41 insertions(+), 113 deletions(-) delete mode 100644 order-events/app/events/assign_tenant_cnpj.py delete mode 100644 order-events/tests/events/test_assign_tenant_cnpj.py diff --git a/order-events/app/events/assign_tenant_cnpj.py b/order-events/app/events/assign_tenant_cnpj.py deleted file mode 100644 index 29ac53b..0000000 --- a/order-events/app/events/assign_tenant_cnpj.py +++ /dev/null @@ -1,69 +0,0 @@ -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 layercake.dateutils import now -from layercake.dynamodb import ( - DynamoDBPersistenceLayer, - KeyPair, - SortKey, -) - -from boto3clients import dynamodb_client -from config import ORDER_TABLE, USER_TABLE - -logger = Logger(__name__) -user_layer = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client) -order_layer = DynamoDBPersistenceLayer(ORDER_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() - ids = user_layer.collection.get_items( - KeyPair( - pk='cnpj', - sk=SortKey(new_image['cnpj'], path_spec='user_id'), - rename_key='org_id', - ) - + KeyPair( - pk='email', - sk=SortKey(new_image['email'], path_spec='user_id'), - rename_key='user_id', - ), - flatten_top=False, - ) - - # Sometimes the function executes before the user insertion completes, - # so an exception is raised to trigger a retry. - if len(ids) < 2: - raise ValueError('IDs not found.') - - logger.info('IDs found', ids=ids) - - with order_layer.transact_writer() as transact: - transact.update( - key=KeyPair(new_image['id'], '0'), - update_expr='SET tenant_id = :tenant_id, updated_at = :updated_at', - expr_attr_values={ - ':tenant_id': ids['org_id'], - ':updated_at': now_, - }, - ) - - transact.update( - key=KeyPair(new_image['id'], 'author'), - update_expr='SET user_id = :user_id, updated_at = :updated_at', - expr_attr_values={ - ':user_id': ids['user_id'], - ':updated_at': now_, - }, - ) - - logger.info('IDs updated') - - return True diff --git a/order-events/app/events/remove_slots_if_canceled.py b/order-events/app/events/remove_slots_if_canceled.py index 36738af..7e5e0b5 100644 --- a/order-events/app/events/remove_slots_if_canceled.py +++ b/order-events/app/events/remove_slots_if_canceled.py @@ -17,23 +17,18 @@ enrollment_layer = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client) order_layer = DynamoDBPersistenceLayer(ORDER_TABLE, dynamodb_client) -class TenantDoesNotExistError(Exception): - def __init__(self, *args): - super().__init__('Tenant does not exist') - - @event_source(data_class=EventBridgeEvent) @logger.inject_lambda_context def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: new_image = event.detail['new_image'] order_id = new_image['id'] - tenant_id = new_image['tenant'] + org_id = new_image['tenant_id'] result = enrollment_layer.collection.query( KeyPair( # Post-migration: Uncomment the following line - # f'slots#org#{tenant_id}', - f'vacancies#{tenant_id}', + # f'SLOT#ORG#{org_id}', + f'vacancies#{org_id}', order_id, ) ) @@ -45,8 +40,8 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: batch.delete_item( Key={ # Post-migration: Uncomment the following line - # 'id': {'S': f'slots#org#{tenant_id}'}, - 'id': {'S': f'vacancies#{tenant_id}'}, + # 'id': {'S': f'SLOT#ORG#{org_id}'}, + 'id': {'S': f'vacancies#{org_id}'}, 'sk': {'S': pair['sk']}, } ) diff --git a/order-events/template.yaml b/order-events/template.yaml index 398b0d0..b5ad265 100644 --- a/order-events/template.yaml +++ b/order-events/template.yaml @@ -42,10 +42,10 @@ Resources: Properties: RetentionInDays: 90 - EventAssignTenantCnpjFunction: + EventAssignOrgIdFunction: Type: AWS::Serverless::Function Properties: - Handler: events.assign_tenant_cnpj.lambda_handler + Handler: events.assign_org_id.lambda_handler LoggingConfig: LogGroup: !Ref EventLog Policies: @@ -65,7 +65,34 @@ Resources: sk: ["0"] cnpj: - exists: true - metadata__tenant_id: + # Post-migration: rename `tenant_id` to `org_id` + tenant_id: + - exists: false + + EventAssignUserIdFunction: + Type: AWS::Serverless::Function + Properties: + Handler: events.assign_user_id.lambda_handler + LoggingConfig: + LogGroup: !Ref EventLog + Policies: + - DynamoDBCrudPolicy: + TableName: !Ref UserTable + - DynamoDBCrudPolicy: + TableName: !Ref OrderTable + Events: + Event: + Type: EventBridgeRule + Properties: + Pattern: + resources: [!Ref OrderTable] + detail-type: [INSERT] + detail: + new_image: + sk: ["0"] + cpf: + - exists: true + user_id: - exists: false EventRemoveSlotsIfCanceledFunction: diff --git a/order-events/tests/conftest.py b/order-events/tests/conftest.py index 6773b21..91e68bc 100644 --- a/order-events/tests/conftest.py +++ b/order-events/tests/conftest.py @@ -1,10 +1,11 @@ import os from dataclasses import dataclass +from uuid import uuid4 import jsonlines import pytest -PYTEST_TABLE_NAME = 'pytest' +PYTEST_TABLE_NAME = f'pytest-{uuid4()}' PK = 'id' SK = 'sk' diff --git a/order-events/tests/events/test_assign_tenant_cnpj.py b/order-events/tests/events/test_assign_tenant_cnpj.py deleted file mode 100644 index 290c213..0000000 --- a/order-events/tests/events/test_assign_tenant_cnpj.py +++ /dev/null @@ -1,27 +0,0 @@ -from aws_lambda_powertools.utilities.typing import LambdaContext -from layercake.dynamodb import DynamoDBPersistenceLayer, PartitionKey - -import events.assign_tenant_cnpj as app - - -def test_assign_tenant_cnpj( - dynamodb_seeds, - dynamodb_persistence_layer: DynamoDBPersistenceLayer, - lambda_context: LambdaContext, -): - event = { - 'detail': { - 'new_image': { - 'id': '9omWNKymwU5U4aeun6mWzZ', - 'cnpj': '15608435000190', - 'email': 'sergio@somosbeta.com.br', - } - } - } - - assert app.lambda_handler(event, lambda_context) # type: ignore - - r = dynamodb_persistence_layer.collection.query( - PartitionKey('9omWNKymwU5U4aeun6mWzZ') - ) - assert 2 == len(r['items']) diff --git a/order-events/tests/events/test_remove_slots_if_canceled.py b/order-events/tests/events/test_remove_slots_if_canceled.py index 85cd540..12f2857 100644 --- a/order-events/tests/events/test_remove_slots_if_canceled.py +++ b/order-events/tests/events/test_remove_slots_if_canceled.py @@ -14,15 +14,15 @@ def test_remove_slots_if_canceled( 'new_image': { 'id': '9omWNKymwU5U4aeun6mWzZ', 'status': 'CANCELED', - 'tenant': 'cJtK9SsnJhKPyxESe7g3DG', + 'tenant_id': 'cJtK9SsnJhKPyxESe7g3DG', } } } assert app.lambda_handler(event, lambda_context) # type: ignore - result = dynamodb_persistence_layer.collection.query( + r = dynamodb_persistence_layer.collection.query( PartitionKey('vacancies#cJtK9SsnJhKPyxESe7g3DG') ) - assert len(result['items']) == 0 + assert len(r['items']) == 0 diff --git a/order-events/tests/seeds.jsonl b/order-events/tests/seeds.jsonl index b7f6b14..597ad70 100644 --- a/order-events/tests/seeds.jsonl +++ b/order-events/tests/seeds.jsonl @@ -2,6 +2,7 @@ {"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "metadata#billing_policy"}, "billing_day": {"N": "1"}, "payment_method": {"S": "PIX"}} {"id": {"S": "9omWNKymwU5U4aeun6mWzZ"}, "sk": {"S": "0"}, "total": {"N": "398"}, "status": {"S": "PENDING"}, "payment_method": {"S": "MANUAL"}, "tenant_id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}} {"id": {"S": "cnpj"}, "sk": {"S": "15608435000190"}, "user_id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}} +{"id": {"S": "cpf"}, "sk": {"S": "07879819908"}, "user_id": {"S": "5OxmMjL-ujoR5IMGegQz"}} {"id": {"S": "email"}, "sk": {"S": "sergio@somosbeta.com.br"}, "user_id": {"S": "5OxmMjL-ujoR5IMGegQz"}} {"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "sk": {"S": "0"}, "name": {"S": "Sérgio R Siqueira"}} {"id": {"S": "vacancies#cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "9omWNKymwU5U4aeun6mWzZ#1"}}