This commit is contained in:
2025-12-05 20:43:49 -03:00
parent b136d83f81
commit 3c1751f4bf
4 changed files with 127 additions and 7 deletions

View File

@@ -45,6 +45,7 @@ app.include_router(users.emails, prefix='/users')
app.include_router(users.orgs, prefix='/users')
app.include_router(users.password, prefix='/users')
app.include_router(orders.router, prefix='/orders')
app.include_router(orgs.router, prefix='/orgs')
app.include_router(orgs.admins, prefix='/orgs')
app.include_router(orgs.custom_pricing, prefix='/orgs')
app.include_router(orgs.scheduled, prefix='/orgs')

View File

@@ -0,0 +1,10 @@
from http import HTTPStatus
from aws_lambda_powertools.event_handler.exceptions import (
ServiceError,
)
class ConflictError(ServiceError):
def __init__(self, msg: str | dict):
super().__init__(HTTPStatus.CONFLICT, msg)

View File

@@ -1,13 +1,16 @@
from http import HTTPStatus
from typing import Annotated
from uuid import uuid4
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.exceptions import NotFoundError
from aws_lambda_powertools.event_handler.openapi.params import Body
from layercake.dateutils import now
from layercake.dynamodb import DynamoDBPersistenceLayer
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
from layercake.extra_types import CnpjStr, NameStr
from pydantic import UUID4, BaseModel, EmailStr
from api_gateway import JSONResponse
from boto3clients import dynamodb_client
from config import INTERNAL_EMAIL_DOMAIN, USER_TABLE
from exceptions import ConflictError
@@ -24,7 +27,13 @@ dyn = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client)
__all__ = ['admins', 'custom_pricing', 'scheduled', 'users']
class OrgConflictError(ConflictError): ...
class CNPJConflictError(ConflictError): ...
class EmailConflictError(ConflictError): ...
class EmailNotFoundError(NotFoundError): ...
class User(BaseModel):
@@ -33,7 +42,7 @@ class User(BaseModel):
email: EmailStr
@router.post('/s')
@router.post('/')
def add_org(
name: Annotated[str, Body(embed=True)],
cnpj: Annotated[CnpjStr, Body(embed=True)],
@@ -41,6 +50,7 @@ def add_org(
):
now_ = now()
org_id = str(uuid4())
email = f'org+{cnpj}@{INTERNAL_EMAIL_DOMAIN}'
with dyn.transact_writer() as transact:
transact.put(
@@ -52,15 +62,80 @@ def add_org(
'created_at': now_,
},
cond_expr='attribute_not_exists(sk)',
exc_cls=OrgConflictError,
exc_cls=CNPJConflictError,
)
transact.put(
item={
# Post-migration (users): rename `email` to `EMAIL`
'id': 'email',
'sk': email,
'user_id': org_id,
'created_at': now_,
},
cond_expr='attribute_not_exists(sk)',
exc_cls=EmailConflictError,
)
transact.put(
item={
'id': org_id,
'sk': '0',
'name': name,
'email': f'org+{cnpj}@{INTERNAL_EMAIL_DOMAIN}',
'email': email,
'cnpj': cnpj,
'created_at': now_,
}
)
transact.put(
item={
'id': org_id,
# Post-migration: rename `emails` to `EMAIL`
'sk': f'emails#{email}',
'email_primary': True,
'email_verified': True,
'mx_record_exists': True,
'created_at': now_,
}
)
transact.put(
item={
'id': org_id,
# Post-migration (users): rename `admins#` to `ADMIN#`
'sk': f'admins#{user.id}',
'name': user.name,
'email': user.email,
'created_at': now_,
}
)
transact.put(
item={
'id': user.id,
# Post-migration (users): rename `orgs#` to `ORG#`
'sk': f'orgs#{org_id}',
'name': name,
'cnpj': cnpj,
'created_at': now_,
}
)
transact.put(
item={
# Post-migration (users): rename `orgmembers#` to `MEMBER#ORG#`
'id': f'orgmembers#{org_id}',
'sk': user.id,
'created_at': now_,
}
)
transact.condition(
# Post-migration (users): rename `email` to `EMAIL`
key=KeyPair('email', user.email),
cond_expr='attribute_exists(sk)',
exc_cls=EmailNotFoundError,
)
return JSONResponse(
status_code=HTTPStatus.CREATED,
body={
'id': org_id,
'name': name,
'email': email,
},
)