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.') with order_layer.transact_writer() as transact: transact.update( key=KeyPair(new_image['id'], '0'), update_expr='SET metadata__tenant_id = :tenant_id, \ metadata__related_ids = :related_ids, \ update_date = :update_date', expr_attr_values={ ':tenant_id': ids['org_id'], ':related_ids': set(ids.values()), ':update_date': now_, }, ) transact.put( item={ 'id': new_image['id'], 'sk': 'metadata#tenant', 'tenant_id': f'ORG#{ids["org_id"]}', 'create_date': now_, } ) for k, v in ids.items(): kind = k.removesuffix('_id') transact.put( item={ 'id': new_image['id'], 'sk': f'related_ids#{kind}', # e.g. related_ids#user 'create_date': now_, k: v, } ) return True