Files
leocrm/app/api/v1/accounts.py
T

130 lines
3.7 KiB
Python

"""Account API endpoints."""
from __future__ import annotations
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,
)
from app.services.account_service import (
get_account as svc_get_account,
)
from app.services.account_service import (
list_accounts as svc_list_accounts,
)
from app.services.account_service import (
soft_delete_account as svc_soft_delete_account,
)
from app.services.account_service import (
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: Industry | None = None,
size: AccountSize | None = None,
owner_id: int | None = None,
q: str | None = 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"]