"""Client CRUD API — POST /clients, GET /clients.""" from __future__ import annotations from pathlib import Path from fastapi import APIRouter, Form, Request from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from peewee import IntegrityError from imptune.db.models import Client router = APIRouter(prefix="/clients") templates = Jinja2Templates( directory=str(Path(__file__).parent.parent / "templates") ) def _error_response(message: str, status_code: int = 400) -> HTMLResponse: """Return an HTMX-friendly error fragment swapped into #client-list.""" return HTMLResponse( content=f"

{message}

", status_code=status_code, ) def _render_client_list(request: Request) -> HTMLResponse: """Render the client list partial for HTMX swap.""" clients = list(Client.select().order_by(Client.name)) return templates.TemplateResponse( request=request, name="partials/client_list.html", context={"clients": clients}, ) @router.post("", response_class=HTMLResponse) def create_client(request: Request, name: str = Form(...)) -> HTMLResponse: """Create a new client. Accepts form-encoded `name`. Validates non-empty. Returns HTMX partial with updated client list on success, or error fragment on failure. """ name = name.strip() if not name: return _error_response("Client name is required.") try: Client.create(name=name) except IntegrityError: return _error_response(f"Client '{name}' already exists.", status_code=409) return _render_client_list(request)