diff --git a/order-events/app/events/assign_org_id.py b/order-events/app/events/assign_org_id.py new file mode 100644 index 0000000..c8d5626 --- /dev/null +++ b/order-events/app/events/assign_org_id.py @@ -0,0 +1,69 @@ +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() + data = 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(data) < 2: + raise ValueError('IDs not found') + + logger.info('IDs found', data=data) + + with order_layer.transact_writer() as transact: + transact.update( + key=KeyPair(new_image['id'], '0'), + update_expr='SET tenant_id = :org_id, updated_at = :updated_at', + expr_attr_values={ + ':org_id': data['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': data['user_id'], + ':updated_at': now_, + }, + ) + + logger.info('IDs updated') + + return True diff --git a/order-events/app/events/assign_user_id.py b/order-events/app/events/assign_user_id.py new file mode 100644 index 0000000..8db912e --- /dev/null +++ b/order-events/app/events/assign_user_id.py @@ -0,0 +1,55 @@ +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() + data = user_layer.collection.get_items( + KeyPair( + pk='cpf', + sk=SortKey(new_image['cpf'], path_spec='user_id'), + rename_key='user_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 not data: + raise ValueError('User ID not found') + + order_layer.update_item( + key=KeyPair(new_image['id'], '0'), + update_expr='SET user_id = :user_id, updated_at = :updated_at', + expr_attr_values={ + ':user_id': data['user_id'], + ':updated_at': now_, + }, + ) + + return True diff --git a/order-events/tests/events/test_assign_org_id.py b/order-events/tests/events/test_assign_org_id.py new file mode 100644 index 0000000..27d1051 --- /dev/null +++ b/order-events/tests/events/test_assign_org_id.py @@ -0,0 +1,27 @@ +from aws_lambda_powertools.utilities.typing import LambdaContext +from layercake.dynamodb import DynamoDBPersistenceLayer, PartitionKey + +import events.assign_org_id as app + + +def test_assign_org_id( + 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_assign_user_id.py b/order-events/tests/events/test_assign_user_id.py new file mode 100644 index 0000000..abab5e6 --- /dev/null +++ b/order-events/tests/events/test_assign_user_id.py @@ -0,0 +1,27 @@ +from aws_lambda_powertools.utilities.typing import LambdaContext +from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair + +import events.assign_user_id as app + + +def test_assign_user_id( + dynamodb_seeds, + dynamodb_persistence_layer: DynamoDBPersistenceLayer, + lambda_context: LambdaContext, +): + event = { + 'detail': { + 'new_image': { + 'id': '9omWNKymwU5U4aeun6mWzZ', + 'cpf': '07879819908', + 'email': 'sergio@somosbeta.com.br', + } + } + } + + assert app.lambda_handler(event, lambda_context) # type: ignore + + r = dynamodb_persistence_layer.collection.get_item( + KeyPair('9omWNKymwU5U4aeun6mWzZ', '0') + ) + assert 'user_id' in r