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 augmented_part as augmented_part_crud from app.crud import augmented_part_note as augmented_part_note_crud from app.deps import require_permission from app.models.user import User from app.schemas.augmented_part import ( AugmentedPartCreate, AugmentedPartNoteCreate, AugmentedPartNoteRead, AugmentedPartRead, AugmentedPartSyncResult, AugmentedPartUpdate, ) from app.services import augmented_part_sync router = APIRouter() @router.get("", response_model=list[AugmentedPartRead]) async def list_augmented_parts( skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db), _: User = Depends(require_permission("augmented_parts:read")), ): return await augmented_part_crud.list_all(db, skip=skip, limit=limit) @router.post("", response_model=AugmentedPartRead, status_code=status.HTTP_201_CREATED) async def create_augmented_part( payload: AugmentedPartCreate, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("augmented_parts:write")), ): ap = await augmented_part_crud.create( db, sku=payload.sku, description=payload.description, colour_id=payload.colour_id, manufacturer_id=payload.manufacturer_id, scope_model_id=payload.scope_model_id, part_type_id=payload.part_type_id, sub_part_type_id=payload.sub_part_type_id, ) await audit_crud.log( db, actor=actor, action="create", resource_type="AugmentedPart", resource_id=ap.id, description=audit_crud.describe_create( "AugmentedPart", ap.id, ap.sku or ap.description ), ) return ap @router.post("/sync", response_model=AugmentedPartSyncResult) async def sync_augmented_parts( db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("augmented_parts:write")), ): result = await augmented_part_sync.sync(db) await audit_crud.log( db, actor=actor, action="update", resource_type="AugmentedPart", resource_id=None, description=( f"Sync: {result.created} created, {result.deleted} deleted, " f"{result.skipped} skipped (no type match)" ), ) return result @router.get("/{augmented_part_id}", response_model=AugmentedPartRead) async def get_augmented_part( augmented_part_id: int, db: AsyncSession = Depends(get_db), _: User = Depends(require_permission("augmented_parts:read")), ): ap = await augmented_part_crud.get(db, augmented_part_id) if ap is None: raise HTTPException(status_code=404, detail="Augmented part not found") return ap @router.patch("/{augmented_part_id}", response_model=AugmentedPartRead) async def update_augmented_part( augmented_part_id: int, payload: AugmentedPartUpdate, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("augmented_parts:write")), ): ap = await augmented_part_crud.get(db, augmented_part_id) if ap is None: raise HTTPException(status_code=404, detail="Augmented part not found") changes = payload.model_dump(exclude_unset=True) ap = await augmented_part_crud.update(db, ap, changes) await audit_crud.log( db, actor=actor, action="update", resource_type="AugmentedPart", resource_id=ap.id, description=audit_crud.describe_update("AugmentedPart", ap.id, changes), ) return ap @router.delete("/{augmented_part_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_augmented_part( augmented_part_id: int, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("augmented_parts:delete")), ): ap = await augmented_part_crud.get(db, augmented_part_id) if ap is None: raise HTTPException(status_code=404, detail="Augmented part not found") label = ap.sku or ap.description await augmented_part_crud.delete(db, ap) await audit_crud.log( db, actor=actor, action="delete", resource_type="AugmentedPart", resource_id=augmented_part_id, description=audit_crud.describe_delete( "AugmentedPart", augmented_part_id, label ), ) @router.post( "/{augmented_part_id}/notes", response_model=AugmentedPartNoteRead, status_code=status.HTTP_201_CREATED, ) async def create_augmented_part_note( augmented_part_id: int, payload: AugmentedPartNoteCreate, db: AsyncSession = Depends(get_db), actor: User = Depends(require_permission("augmented_parts:write")), ): ap = await augmented_part_crud.get(db, augmented_part_id) if ap is None: raise HTTPException(status_code=404, detail="Augmented part not found") return await augmented_part_note_crud.create( db, augmented_part=ap, author=actor, body=payload.body )