diff --git a/order-management/README.md b/order-management/README.md new file mode 100644 index 0000000..c5cbe54 --- /dev/null +++ b/order-management/README.md @@ -0,0 +1,12 @@ +### Relacionamentos + +Toda compra feita é relacionada com a empresa responsável, que é definida como o `tenant` do registro. Essa relação é estabelecida com base no CNPJ presente na compra. + +O gestor responsável pela ação também é relacionado à compra. + +```json +{"id": "10", "sk": "0", "metadata__tenant_id": "100", "metadata__related_ids": ["100", "123"]} +{"id": "10", "sk": "metadata#tenant", "tenant_id": "100"} +{"id": "10", "sk": "related_ids#org", "org_id": "100"} +{"id": "10", "sk": "related_ids#user", "user_id": "123"} +``` diff --git a/order-management/app/events/assign_tenant_cnpj.py b/order-management/app/events/assign_tenant_cnpj.py index 1a99949..91a31b7 100644 --- a/order-management/app/events/assign_tenant_cnpj.py +++ b/order-management/app/events/assign_tenant_cnpj.py @@ -47,9 +47,11 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: transact = TransactItems(order_layer.table_name) transact.update( key=KeyPair(new_image['id'], '0'), - update_expr='SET metadata__tenant_id = :org_id, update_date = :update_date', + update_expr='SET metadata__tenant_id = :tenant_id, \ + metadata__related_ids = :related_ids, update_date = :update_date', expr_attr_values={ - ':org_id': {ids['org_id']}, + ':tenant_id': ids['org_id'], + ':related_ids': set(ids.values()), ':update_date': now_, }, ) @@ -57,7 +59,7 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: item={ 'id': new_image['id'], 'sk': 'metadata#tenant', - 'org_id': ids['org_id'], + 'tenant_id': f'ORG#{ids["org_id"]}', 'create_date': now_, } ) @@ -66,7 +68,7 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool: transact.put( item={ 'id': new_image['id'], - 'sk': 'rel#%s' % k.removesuffix('_id').upper(), + 'sk': 'related_ids#%s' % k.removesuffix('_id'), 'create_date': now_, k: v, } diff --git a/order-management/app/events/assign_tenant_cpf.py b/order-management/app/events/assign_tenant_cpf.py new file mode 100644 index 0000000..dbce635 --- /dev/null +++ b/order-management/app/events/assign_tenant_cpf.py @@ -0,0 +1,23 @@ +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.dynamodb import ( + DynamoDBPersistenceLayer, +) + +from boto3clients import dynamodb_client +from conf 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'] + return True diff --git a/order-management/app/events/stopgap/__init__.py b/order-management/app/events/stopgap/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/order-management/app/events/stopgap/set_as_paid.py b/order-management/app/events/stopgap/set_as_paid.py new file mode 100644 index 0000000..a0cde76 --- /dev/null +++ b/order-management/app/events/stopgap/set_as_paid.py @@ -0,0 +1,36 @@ +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, +) + +from boto3clients import dynamodb_client +from conf import ORDER_TABLE + +logger = Logger(__name__) +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'] + order_layer.update_item( + key=KeyPair(new_image['id'], '0'), + update_expr='SET #status = :status, update_date = :update_date', + expr_attr_names={ + '#status': 'status', + }, + expr_attr_values={ + ':status': 'PAID', + ':update_date': now(), + }, + ) + + return True diff --git a/order-management/template.yaml b/order-management/template.yaml index a0f3e12..6a908cb 100644 --- a/order-management/template.yaml +++ b/order-management/template.yaml @@ -20,7 +20,7 @@ Globals: Architectures: - x86_64 Layers: - - !Sub arn:aws:lambda:sa-east-1:336641857101:layer:layercake:65 + - !Sub arn:aws:lambda:sa-east-1:336641857101:layer:layercake:67 Environment: Variables: TZ: America/Sao_Paulo @@ -53,7 +53,7 @@ Resources: Type: EventBridgeRule Properties: Pattern: - resources: [betaeducacao-prod-orders] + resources: [!Ref OrderTable] detail-type: [INSERT] detail: new_image: @@ -62,3 +62,54 @@ Resources: - exists: true metadata__tenant_id: - exists: false + + EventAssignTenantCpfFunction: + Type: AWS::Serverless::Function + Properties: + Handler: events.assign_tenant_cpf.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 + metadata__tenant_id: + - exists: false + + EventSetAsPaidFunction: + Type: AWS::Serverless::Function + Properties: + Handler: events.stopgap.set_as_paid.lambda_handler + LoggingConfig: + LogGroup: !Ref EventLog + Policies: + - DynamoDBWritePolicy: + TableName: !Ref OrderTable + Events: + Event: + Type: EventBridgeRule + Properties: + Pattern: + resources: [!Ref OrderTable] + detail-type: [INSERT] + detail: + new_image: + sk: ["0"] + cnpj: + - exists: true + total: [0] + status: [PENDING] + payment_method: [MANUAL] diff --git a/order-management/tests/events/stopgap/__init__.py b/order-management/tests/events/stopgap/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/order-management/tests/events/stopgap/test_set_as_paid.py b/order-management/tests/events/stopgap/test_set_as_paid.py new file mode 100644 index 0000000..13dd4f2 --- /dev/null +++ b/order-management/tests/events/stopgap/test_set_as_paid.py @@ -0,0 +1,24 @@ +from aws_lambda_powertools.utilities.typing import LambdaContext +from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair + +import events.stopgap.set_as_paid as app + + +def test_set_as_paid( + dynamodb_seeds, + dynamodb_persistence_layer: DynamoDBPersistenceLayer, + lambda_context: LambdaContext, +): + event = { + 'detail': { + 'new_image': { + 'id': '9omWNKymwU5U4aeun6mWzZ', + } + } + } + assert app.lambda_handler(event, lambda_context) # type: ignore + + doc = dynamodb_persistence_layer.get_item( + key=KeyPair('9omWNKymwU5U4aeun6mWzZ', '0'), + ) + print(doc) diff --git a/order-management/tests/seeds.jsonl b/order-management/tests/seeds.jsonl index 2d147ac..b1124e4 100644 --- a/order-management/tests/seeds.jsonl +++ b/order-management/tests/seeds.jsonl @@ -1,6 +1,6 @@ {"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "0"}, "name": {"S": "EDUSEG"}} {"id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}, "sk": {"S": "metadata#payment_policy"}, "due_days": {"N": "90"}} -{"id": {"S": "9omWNKymwU5U4aeun6mWzZ"}, "sk": {"S": "0"}, "total": {"N": "398"}} +{"id": {"S": "9omWNKymwU5U4aeun6mWzZ"}, "sk": {"S": "0"}, "total": {"N": "398"}, "status": {"S": "PENDING"}} {"id": {"S": "9omWNKymwU5U4aeun6mWzZ"}, "sk": {"S": "metadata#tenant"}, "org_id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}} {"id": {"S": "cnpj"}, "sk": {"S": "15608435000190"}, "user_id": {"S": "cJtK9SsnJhKPyxESe7g3DG"}} {"id": {"S": "email"}, "sk": {"S": "sergio@somosbeta.com.br"}, "user_id": {"S": "5OxmMjL-ujoR5IMGegQz"}} diff --git a/order-management/uv.lock b/order-management/uv.lock index 2aadedf..ea52d32 100644 --- a/order-management/uv.lock +++ b/order-management/uv.lock @@ -495,7 +495,7 @@ wheels = [ [[package]] name = "layercake" -version = "0.3.3" +version = "0.3.5" source = { directory = "../layercake" } dependencies = [ { name = "arnparse" },