from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.crud import audit as audit_crud from app.crud import unc_thread as unc_thread_crud from app.deps import require_permission from app.models.user import User from app.schemas.unc_thread import UncThreadCreate, UncThreadRead, UncThreadUpdate router = APIRouter() @router.get("", response_model=list[UncThreadRead]) async def list_unc_threads( skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db), _: User = Depends(require_permission("unc_threads:read")), ): return await unc_thread_crud.list_all(db, skip=skip, limit=limit) @router.post("", response_model=UncThreadRead, status_code=status.HTTP_201_CREATED) async def create_unc_thread( payload: UncThreadCreate, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("unc_threads:write")), ): thread = await unc_thread_crud.create( db, diameter_fraction=payload.diameter_fraction, tpi=payload.tpi, series=payload.series, depth_in=payload.depth_in, ) await audit_crud.log( db, actor=actor, action="create", resource_type="UncThread", resource_id=thread.id, description=audit_crud.describe_create("UncThread", thread.id, f"{thread.diameter_fraction}-{thread.tpi} {thread.series.value}"), ) return thread @router.get("/{unc_thread_id}", response_model=UncThreadRead) async def get_unc_thread( unc_thread_id: int, db: AsyncSession = Depends(get_db), _: User = Depends(require_permission("unc_threads:read")), ): thread = await unc_thread_crud.get(db, unc_thread_id) if thread is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="UNC thread not found") return thread @router.patch("/{unc_thread_id}", response_model=UncThreadRead) async def update_unc_thread( unc_thread_id: int, payload: UncThreadUpdate, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("unc_threads:write")), ): thread = await unc_thread_crud.get(db, unc_thread_id) if thread is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="UNC thread not found") changes = payload.model_dump(exclude_unset=True) thread = await unc_thread_crud.update(db, thread, changes) await audit_crud.log( db, actor=actor, action="update", resource_type="UncThread", resource_id=thread.id, description=audit_crud.describe_update("UncThread", thread.id, changes), ) return thread @router.delete("/{unc_thread_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_unc_thread( unc_thread_id: int, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("unc_threads:delete")), ): thread = await unc_thread_crud.get(db, unc_thread_id) if thread is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="UNC thread not found") name = f"{thread.diameter_fraction}-{thread.tpi} {thread.series.value}" await unc_thread_crud.delete(db, thread) await audit_crud.log( db, actor=actor, action="delete", resource_type="UncThread", resource_id=unc_thread_id, description=audit_crud.describe_delete("UncThread", unc_thread_id, name), )