from aiohttp import web from aiohttp_apispec import docs, headers_schema, json_schema from apollo_utils.service.clients.aiohttp.utils.response import dump_response_schema from apollo_utils.service.exceptions import BadRequest, NotFound from apollo_utils.service.schemas.headers import AppHeader from http import HTTPStatus from server.constants.core import BASE_API_PREFIX from server.db.models.core import Account from server.db.models.users import Favorites from server.schemas.accounts.favorites import AccountFavorites router = web.RouteTableDef() @router.post(BASE_API_PREFIX + "/v2/accounts/favorites/") @docs( tags=["accounts", "v2", "favorites"], summary="Add an entity to account favorites.", ) @headers_schema(AppHeader) @json_schema(AccountFavorites.Create.Request) @dump_response_schema(AccountFavorites.Create.Response, apply=True, code=HTTPStatus.CREATED) async def create_account_favorite(request: web.Request) -> web.Response: app_slug, params = request["headers"]["app"], request["json"] account_id, entity_id, entity_type = params["account_id"], params["entity_id"], params["entity_type"] account = await Account.get(id=account_id, app_slug=app_slug) if not account: raise NotFound(f"Account {account_id} is not found for application {app_slug}.") entity_data = dict(account_id=account_id, entity_id=entity_id, entity_type=entity_type) entity = await Favorites.get(**entity_data) if entity: raise BadRequest(f"Entity {entity_type}|{entity_id} is already starred for account {account_id}.") return await Favorites.create(entity_data | {"data": params["data"]}) @router.delete(BASE_API_PREFIX + "/v2/accounts/favorites/") @docs( tags=["accounts", "v2", "favorites"], summary="Remove an entity from account favorites.", ) @headers_schema(AppHeader) @json_schema(AccountFavorites.Delete.Request) async def delete_account_favorite(request: web.Request) -> web.Response: app_slug, params = request["headers"]["app"], request["json"] result = await Favorites.delete( account_id=params["account_id"], entity_id=params["entity_id"], entity_type=params["entity_type"], ) if not result: raise NotFound(f"An entity with the following parameters is not starred: {params}.") return web.Response(status=204)