from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.crud import attachment_point_name as apn_crud from app.crud import audit as audit_crud from app.deps import require_permission from app.models.user import User from app.schemas.attachment_point_name import ( AttachmentPointNameCreate, AttachmentPointNameRead, AttachmentPointNameUpdate, ) router = APIRouter() @router.get("", response_model=list[AttachmentPointNameRead]) async def list_attachment_point_names( skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db), _: User = Depends(require_permission("attachment_point_names:read")), ): return await apn_crud.list_all(db, skip=skip, limit=limit) @router.post( "", response_model=AttachmentPointNameRead, status_code=status.HTTP_201_CREATED ) async def create_attachment_point_name( payload: AttachmentPointNameCreate, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("attachment_point_names:write")), ): if await apn_crud.get_by_name(db, payload.name): raise HTTPException( status_code=409, detail="Attachment point name already exists" ) apn = await apn_crud.create(db, name=payload.name) await audit_crud.log( db, actor=actor, action="create", resource_type="AttachmentPointName", resource_id=apn.id, description=audit_crud.describe_create("AttachmentPointName", apn.id, apn.name), ) return apn @router.get("/{apn_id}", response_model=AttachmentPointNameRead) async def get_attachment_point_name( apn_id: int, db: AsyncSession = Depends(get_db), _: User = Depends(require_permission("attachment_point_names:read")), ): apn = await apn_crud.get(db, apn_id) if apn is None: raise HTTPException(status_code=404, detail="Attachment point name not found") return apn @router.patch("/{apn_id}", response_model=AttachmentPointNameRead) async def update_attachment_point_name( apn_id: int, payload: AttachmentPointNameUpdate, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("attachment_point_names:write")), ): apn = await apn_crud.get(db, apn_id) if apn is None: raise HTTPException(status_code=404, detail="Attachment point name not found") changes = payload.model_dump(exclude_unset=True) if "name" in changes: existing = await apn_crud.get_by_name(db, changes["name"]) if existing is not None and existing.id != apn.id: raise HTTPException( status_code=409, detail="Attachment point name already exists" ) apn = await apn_crud.update(db, apn, changes) await audit_crud.log( db, actor=actor, action="update", resource_type="AttachmentPointName", resource_id=apn.id, description=audit_crud.describe_update("AttachmentPointName", apn.id, changes), ) return apn @router.delete("/{apn_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_attachment_point_name( apn_id: int, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("attachment_point_names:delete")), ): apn = await apn_crud.get(db, apn_id) if apn is None: raise HTTPException(status_code=404, detail="Attachment point name not found") name = apn.name await apn_crud.delete(db, apn) await audit_crud.log( db, actor=actor, action="delete", resource_type="AttachmentPointName", resource_id=apn_id, description=audit_crud.describe_delete("AttachmentPointName", apn_id, name), )