"""Customer routes (tenant management).""" from fastapi import APIRouter, Depends, Request from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.api.deps import client_ip, get_current_user from app.core.database import get_db from app.core.exceptions import ConflictError, NotFoundError from app.models.customer import Customer from app.models.user import User from app.schemas.customer import CustomerCreate, CustomerRead, CustomerUpdate from app.services.audit import AuditService router = APIRouter() @router.get("", response_model=list[CustomerRead]) async def list_customers( db: AsyncSession = Depends(get_db), _user: User = Depends(get_current_user), ) -> list[Customer]: result = await db.execute(select(Customer).order_by(Customer.name)) return list(result.scalars().all()) @router.post("", response_model=CustomerRead, status_code=201) async def create_customer( payload: CustomerCreate, request: Request, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ) -> Customer: existing = await db.execute( select(Customer).where((Customer.name == payload.name) | (Customer.slug == payload.slug)) ) if existing.scalar_one_or_none(): raise ConflictError("Kunde mit diesem Namen oder Slug existiert bereits") customer = Customer(**payload.model_dump()) db.add(customer) await db.flush() await AuditService(db).log( username=user.username, action="customer.create", target=customer.name, customer_id=customer.id, ip_address=client_ip(request), ) return customer @router.get("/{customer_id}", response_model=CustomerRead) async def get_customer( customer_id: int, db: AsyncSession = Depends(get_db), _user: User = Depends(get_current_user), ) -> Customer: customer = await db.get(Customer, customer_id) if not customer: raise NotFoundError("Kunde nicht gefunden") return customer @router.patch("/{customer_id}", response_model=CustomerRead) async def update_customer( customer_id: int, payload: CustomerUpdate, request: Request, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ) -> Customer: customer = await db.get(Customer, customer_id) if not customer: raise NotFoundError("Kunde nicht gefunden") for field, value in payload.model_dump(exclude_unset=True).items(): setattr(customer, field, value) await AuditService(db).log( username=user.username, action="customer.update", target=customer.name, customer_id=customer.id, ip_address=client_ip(request), ) return customer @router.delete("/{customer_id}", status_code=204) async def delete_customer( customer_id: int, request: Request, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ) -> None: customer = await db.get(Customer, customer_id) if not customer: raise NotFoundError("Kunde nicht gefunden") await AuditService(db).log( username=user.username, action="customer.delete", target=customer.name, customer_id=customer.id, ip_address=client_ip(request), ) await db.delete(customer)