fix block

add check name to subscription
This commit is contained in:
2026-01-19 11:59:52 -03:00
parent 2f390ab202
commit 6b472110e2
6 changed files with 531 additions and 386 deletions

View File

@@ -11,6 +11,20 @@ class ConflictError(ServiceError):
super().__init__(HTTPStatus.CONFLICT, msg)
class NotAcceptableError(ServiceError):
def __init__(self, msg: str | dict):
super().__init__(HTTPStatus.NOT_ACCEPTABLE, msg)
class SubscriptionRequiredError(NotAcceptableError): ...
class SubscriptionFrozenError(NotAcceptableError): ...
class SubscriptionConflictError(ConflictError): ...
class OrgNotFoundError(NotFoundError): ...

View File

@@ -1,14 +1,10 @@
from datetime import date, datetime, time, timedelta
from http import HTTPStatus
from typing import Annotated, TypedDict
from uuid import uuid4
import pytz
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.exceptions import (
ServiceError,
)
from aws_lambda_powertools.event_handler.openapi.params import Body
from aws_lambda_powertools.shared.functions import extract_event_from_common_models
from layercake.batch import BatchProcessor
@@ -20,7 +16,7 @@ from pydantic import UUID4, BaseModel, EmailStr, Field, FutureDate
from boto3clients import dynamodb_client
from config import DEDUP_WINDOW_OFFSET_DAYS, ENROLLMENT_TABLE, TZ, USER_TABLE
from exceptions import ConflictError
from exceptions import ConflictError, SubscriptionFrozenError, SubscriptionRequiredError
from middlewares.authentication_middleware import User as Authenticated
logger = Logger(__name__)
@@ -29,16 +25,6 @@ dyn = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
processor = BatchProcessor()
class SubscriptionRequiredError(ServiceError):
def __init__(self, msg: str | dict):
super().__init__(HTTPStatus.NOT_ACCEPTABLE, msg)
class SubscriptionFrozenError(ServiceError):
def __init__(self, msg: str | dict):
super().__init__(HTTPStatus.NOT_ACCEPTABLE, msg)
class DeduplicationConflictError(ConflictError): ...
@@ -139,7 +125,7 @@ def enroll(
dyn.put_item(item=item)
except Exception as exc:
logger.exception(exc)
finally:
else:
return item

View File

@@ -10,14 +10,17 @@ from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
from api_gateway import JSONResponse
from boto3clients import dynamodb_client
from config import USER_TABLE
from exceptions import OrgNotFoundError
from exceptions import (
OrgNotFoundError,
SubscriptionConflictError,
SubscriptionRequiredError,
)
router = Router()
dyn = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client)
class PaymentMethod(str, Enum):
PIX = 'PIX'
BANK_SLIP = 'BANK_SLIP'
MANUAL = 'MANUAL'
@@ -26,7 +29,7 @@ class PaymentMethod(str, Enum):
def add(
org_id: str,
name: Annotated[str, Body(embed=True)],
billing_day: Annotated[int, Body(embed=True, ge=1)],
billing_day: Annotated[int, Body(embed=True, ge=1, le=31)],
payment_method: Annotated[PaymentMethod, Body(embed=True)],
):
now_ = now()
@@ -35,11 +38,15 @@ def add(
transact.update(
key=KeyPair(org_id, '0'),
update_expr='SET subscription_covered = :true, updated_at = :now',
cond_expr='attribute_exists(sk) AND #name = :name',
expr_attr_names={
'#name': 'name',
},
expr_attr_values={
':name': name,
':true': True,
':now': now_,
},
cond_expr='attribute_exists(sk)',
exc_cls=OrgNotFoundError,
)
transact.put(
@@ -49,7 +56,9 @@ def add(
'billing_day': billing_day,
'payment_method': payment_method.value,
'created_at': now_,
}
},
cond_expr='attribute_not_exists(sk)',
exc_cls=SubscriptionConflictError,
)
transact.put(
item={
@@ -59,6 +68,71 @@ def add(
'created_at': now_,
},
cond_expr='attribute_not_exists(sk)',
exc_cls=SubscriptionConflictError,
)
return JSONResponse(status_code=HTTPStatus.CREATED)
@router.put('/<org_id>/subscription')
def edit(
org_id: str,
billing_day: Annotated[int, Body(embed=True, ge=1, le=31)],
payment_method: Annotated[PaymentMethod, Body(embed=True)],
subscription_frozen: Annotated[bool, Body(embed=True)] = False,
):
now_ = now()
with dyn.transact_writer() as transact:
transact.condition(
key=KeyPair('SUBSCRIPTION', f'ORG#{org_id}'),
cond_expr='attribute_exists(sk)',
exc_cls=SubscriptionRequiredError,
)
transact.update(
key=KeyPair(org_id, 'METADATA#SUBSCRIPTION'),
update_expr='SET billing_day = :billing_day, \
payment_method = :payment_method, \
updated_at = :now',
expr_attr_values={
':billing_day': billing_day,
':payment_method': payment_method.value,
':now': now_,
},
cond_expr='attribute_exists(sk)',
exc_cls=OrgNotFoundError,
)
if subscription_frozen:
transact.put(
item={
'id': 'SUBSCRIPTION#FREEZE',
'sk': f'ORG#{org_id}',
'created_at': now_,
}
)
else:
transact.delete(key=KeyPair('SUBSCRIPTION#FREEZE', f'ORG#{org_id}'))
return JSONResponse(status_code=HTTPStatus.NO_CONTENT)
@router.delete('/<org_id>/subscription')
def remove(org_id: str):
now_ = now()
with dyn.transact_writer() as transact:
transact.update(
key=KeyPair(org_id, '0'),
update_expr='SET updated_at = :now REMOVE subscription_covered',
expr_attr_values={
':now': now_,
},
cond_expr='attribute_exists(sk)',
exc_cls=OrgNotFoundError,
)
transact.delete(key=KeyPair(org_id, 'METADATA#SUBSCRIPTION'))
transact.delete(key=KeyPair('SUBSCRIPTION', f'ORG#{org_id}'))
transact.delete(key=KeyPair('SUBSCRIPTION#FREEZE', f'ORG#{org_id}'))
return JSONResponse(status_code=HTTPStatus.NO_CONTENT)