from uuid import UUID from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import delete from sqlalchemy.orm import Session from app.api import deps from app.api.utils import update_object_from_payload, verify_id_list from app.models import ( Project, SlotTag, SlotTemplate, User, association_table_template_tags, ) from app.schemas.requests import TemplateCreateRequest, TemplateUpdateRequest from app.schemas.responses import TemplateResponse router = APIRouter() @router.get("/project/{project_id}/templates", response_model=list[TemplateResponse]) async def list_project_templates( project_id: UUID, current_user: User = Depends(deps.get_current_user), session: Session = Depends(deps.get_session), ): """List slots from project""" p = session.get(Project, project_id) if p is None: raise HTTPException(status_code=404, detail="Project not found") return p.templates @router.post("/project/{project_id}/template", response_model=TemplateResponse) async def create_template( project_id: UUID, payload: TemplateCreateRequest, current_user: User = Depends(deps.get_current_user), session: Session = Depends(deps.get_session), ): """Create a new template to the project""" p = session.get(Project, project_id) if p is None: raise HTTPException(status_code=404, detail="Project not found") template = SlotTemplate(project_id=p.id, title=payload.title) session.add(template) session.commit() dic = payload.model_dump(exclude_unset=True) if payload.tags is not None: del dic["tags"] if len(payload.tags) > 0: await verify_id_list( session, payload.tags, project_id, SlotTag, "Invalid template list" ) session.execute( association_table_template_tags.insert().values( [(template.id, t_id) for t_id in payload.tags] ) ) update_object_from_payload(template, dic) session.commit() return template @router.post( "/project/{project_id}/template/{template_id}", response_model=TemplateResponse ) async def update_template( project_id: UUID, template_id: UUID, payload: TemplateUpdateRequest, current_user: User = Depends(deps.get_current_user), session: Session = Depends(deps.get_session), ): """Update a template""" template = session.get(SlotTemplate, template_id) if (template is None) or (template.project_id != str(project_id)): raise HTTPException(status_code=404, detail="Template not found") if payload.title is not None: template.title = payload.title if payload.description is not None: template.description = payload.description if payload.responsible_contact is not None: template.responsible_contact = payload.responsible_contact if payload.place is not None: template.place = payload.place if payload.tags is not None: # Remove previous keys in association table session.execute( association_table_template_tags.delete().where( association_table_template_tags.c.description_id == template.id ) ) if len(payload.tags) > 0: await verify_id_list( session, payload.tags, project_id, SlotTag, "Invalid template list" ) session.execute( association_table_template_tags.insert().values( [(template.id, t_id) for t_id in payload.tags] ) ) session.commit() session.refresh(template) return template @router.delete("/project/{project_id}/template/{template_id}") async def delete_template( project_id: UUID, template_id: UUID, current_user: User = Depends(deps.get_current_user), session: Session = Depends(deps.get_session), ): """Delete a slot from the project""" session.execute( delete(SlotTemplate).where( (SlotTemplate.id == template_id) & (SlotTemplate.project_id == project_id) ) ) session.commit()