Files

138 lines
4.2 KiB
Python

from http import HTTPStatus
from typing import Annotated
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.openapi.params import Body
from layercake.dateutils import now
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,
SubscriptionConflictError,
SubscriptionRequiredError,
)
router = Router()
dyn = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client)
@router.post('/<org_id>/subscription')
def add(
org_id: str,
name: Annotated[str, Body(embed=True)],
billing_day: Annotated[int, Body(embed=True, ge=1, le=31)],
subscription_frozen: Annotated[bool, Body(embed=True)] = False,
):
now_ = now()
with dyn.transact_writer() as transact:
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_,
},
exc_cls=OrgNotFoundError,
)
transact.put(
item={
'id': org_id,
'sk': 'METADATA#SUBSCRIPTION',
'billing_day': billing_day,
'created_at': now_,
},
cond_expr='attribute_not_exists(sk)',
exc_cls=SubscriptionConflictError,
)
transact.put(
item={
'id': 'SUBSCRIPTION',
'sk': f'ORG#{org_id}',
'name': name,
'created_at': now_,
},
cond_expr='attribute_not_exists(sk)',
exc_cls=SubscriptionConflictError,
)
if subscription_frozen:
transact.put(
item={
'id': 'SUBSCRIPTION#FROZEN',
'sk': f'ORG#{org_id}',
'created_at': now_,
}
)
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)],
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, \
updated_at = :now',
expr_attr_values={
':billing_day': billing_day,
':now': now_,
},
cond_expr='attribute_exists(sk)',
exc_cls=SubscriptionRequiredError,
)
if subscription_frozen:
transact.put(
item={
'id': 'SUBSCRIPTION#FROZEN',
'sk': f'ORG#{org_id}',
'created_at': now_,
}
)
else:
transact.delete(key=KeyPair('SUBSCRIPTION#FROZEN', 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#FROZEN', f'ORG#{org_id}'))
return JSONResponse(status_code=HTTPStatus.NO_CONTENT)