From 1d2e2c342d9edb538db089e1fa3e57065d4bab10 Mon Sep 17 00:00:00 2001 From: Leopoldadmin Date: Wed, 3 Jun 2026 23:52:11 +0000 Subject: [PATCH] Upload app/api/v1/accounts.py --- app/api/v1/accounts.py | 123 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 app/api/v1/accounts.py diff --git a/app/api/v1/accounts.py b/app/api/v1/accounts.py new file mode 100644 index 0000000..905dab8 --- /dev/null +++ b/app/api/v1/accounts.py @@ -0,0 +1,123 @@ +"""Account API endpoints.""" + +from __future__ import annotations + +from typing import Optional + +from fastapi import APIRouter, Depends, HTTPException, Query, Response, status +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.db import get_db +from app.core.deps import get_current_user +from app.models.account import AccountSize, Industry +from app.models.user import User +from app.schemas.account import AccountCreate, AccountOut, AccountUpdate +from app.services.account_service import ( + create_account as svc_create_account, + get_account as svc_get_account, + list_accounts as svc_list_accounts, + soft_delete_account as svc_soft_delete_account, + update_account as svc_update_account, +) + +router = APIRouter(prefix="/accounts", tags=["accounts"]) + + +@router.post( + "/", + response_model=AccountOut, + status_code=status.HTTP_201_CREATED, + summary="Create a new account", +) +async def create_account( + payload: AccountCreate, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +) -> AccountOut: + acc = await svc_create_account( + db, payload, org_id=current_user.org_id, owner_id=current_user.id + ) + return AccountOut.model_validate(acc) + + +@router.get( + "/", + response_model=list[AccountOut], + summary="List accounts (paginated, filterable)", +) +async def list_accounts( + skip: int = Query(0, ge=0), + limit: int = Query(20, ge=1, le=100), + industry: Optional[Industry] = None, + size: Optional[AccountSize] = None, + owner_id: Optional[int] = None, + q: Optional[str] = None, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +) -> list[AccountOut]: + accounts = await svc_list_accounts( + db, + org_id=current_user.org_id, + skip=skip, + limit=limit, + industry=industry.value if industry else None, + size=size.value if size else None, + owner_id=owner_id, + q=q, + ) + return [AccountOut.model_validate(a) for a in accounts] + + +@router.get( + "/{account_id}", + response_model=AccountOut, + summary="Get one account with all relations", +) +async def get_account( + account_id: int, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +) -> AccountOut: + acc = await svc_get_account(db, account_id, org_id=current_user.org_id) + if acc is None: + raise HTTPException(status_code=404, detail="Account not found") + return AccountOut.model_validate(acc) + + +@router.patch( + "/{account_id}", + response_model=AccountOut, + summary="Update an account", +) +async def update_account( + account_id: int, + payload: AccountUpdate, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +) -> AccountOut: + acc = await svc_get_account(db, account_id, org_id=current_user.org_id) + if acc is None: + raise HTTPException(status_code=404, detail="Account not found") + updated = await svc_update_account(db, acc, payload) + return AccountOut.model_validate(updated) + + +@router.delete( + "/{account_id}", + status_code=status.HTTP_204_NO_CONTENT, + response_class=Response, + summary="Soft-delete an account", +) +async def delete_account( + account_id: int, + current_user: User = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +) -> Response: + acc = await svc_get_account(db, account_id, org_id=current_user.org_id) + if acc is None: + raise HTTPException(status_code=404, detail="Account not found") + await svc_soft_delete_account(db, acc) + return Response(status_code=status.HTTP_204_NO_CONTENT) + + +__all__ = ["router"]