import uuid from typing import Any from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from pydantic import BaseModel from app.database import get_db from app.models.template import Template from app.utils.auth import get_current_user, require_global_admin from app.models.user import User router = APIRouter(prefix="/templates", tags=["templates"]) class TemplateOut(BaseModel): id: uuid.UUID name: str category_key: str standard_fields: Any component_schema: Any description: str | None is_active: bool model_config = {"from_attributes": True} class TemplateUpdate(BaseModel): name: str | None = None description: str | None = None is_active: bool | None = None standard_fields: Any = None component_schema: Any = None @router.get("", response_model=list[TemplateOut]) async def list_templates( include_inactive: bool = False, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): q = select(Template) # Non-admins always see only active templates if not include_inactive or user.role.value != "admin": q = q.where(Template.is_active == True) result = await db.execute(q) return result.scalars().all() @router.get("/{template_id}", response_model=TemplateOut) async def get_template( template_id: uuid.UUID, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): result = await db.execute(select(Template).where(Template.id == template_id)) t = result.scalar_one_or_none() if not t: raise HTTPException(404, detail="Template not found") return t @router.patch("/{template_id}", response_model=TemplateOut) async def update_template( template_id: uuid.UUID, body: TemplateUpdate, user: User = Depends(require_global_admin), db: AsyncSession = Depends(get_db), ): result = await db.execute(select(Template).where(Template.id == template_id)) t = result.scalar_one_or_none() if not t: raise HTTPException(404, detail="Template not found") for field, val in body.model_dump(exclude_unset=True).items(): setattr(t, field, val) await db.commit() await db.refresh(t) return t