Files
skeleton-api/app/api/attachment_points.py
T
2026-07-02 14:06:18 -03:00

119 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 as attachment_point_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 import (
AttachmentPointCreate,
AttachmentPointRead,
AttachmentPointUpdate,
)
router = APIRouter()
def _connection_label(ap) -> str:
if ap.iso_thread:
return f"M{ap.iso_thread.diameter_mm}×{ap.iso_thread.pitch_mm}"
if ap.unc_thread:
return f"{ap.unc_thread.diameter_fraction}-{ap.unc_thread.tpi} {ap.unc_thread.series}"
if ap.clamp_connection:
cc = ap.clamp_connection
if cc.min_mm is not None:
return f"{cc.min_mm}–{cc.max_mm} mm"
return f"{cc.min_in}–{cc.max_in} in"
if ap.static_connection:
return f"{ap.static_connection.od_mm} mm OD"
return "—"
@router.get("", response_model=list[AttachmentPointRead])
async def list_attachment_points(
skip: int = 0,
limit: int = 100,
db: AsyncSession = Depends(get_db),
_: User = Depends(require_permission("attachment_points:read")),
):
return await attachment_point_crud.list_all(db, skip=skip, limit=limit)
@router.post("", response_model=AttachmentPointRead, status_code=status.HTTP_201_CREATED)
async def create_attachment_point(
payload: AttachmentPointCreate,
db: AsyncSession = Depends(get_db),
actor: User = Depends(require_permission("attachment_points:write")),
):
conn_ids = [
payload.iso_thread_id,
payload.unc_thread_id,
payload.clamp_connection_id,
payload.static_connection_id,
]
if sum(v is not None for v in conn_ids) != 1:
raise HTTPException(
status_code=400,
detail="Exactly one connection (iso_thread, unc_thread, clamp_connection, or static_connection) must be provided.",
)
ap = await attachment_point_crud.create(db, **payload.model_dump())
await audit_crud.log(
db, actor=actor, action="create", resource_type="AttachmentPoint",
resource_id=ap.id,
description=audit_crud.describe_create(
"AttachmentPoint", ap.id, _connection_label(ap)
),
)
return ap
@router.get("/{attachment_point_id}", response_model=AttachmentPointRead)
async def get_attachment_point(
attachment_point_id: int,
db: AsyncSession = Depends(get_db),
_: User = Depends(require_permission("attachment_points:read")),
):
ap = await attachment_point_crud.get(db, attachment_point_id)
if ap is None:
raise HTTPException(status_code=404, detail="Attachment point not found")
return ap
@router.patch("/{attachment_point_id}", response_model=AttachmentPointRead)
async def update_attachment_point(
attachment_point_id: int,
payload: AttachmentPointUpdate,
db: AsyncSession = Depends(get_db),
actor: User = Depends(require_permission("attachment_points:write")),
):
ap = await attachment_point_crud.get(db, attachment_point_id)
if ap is None:
raise HTTPException(status_code=404, detail="Attachment point not found")
changes = payload.model_dump(exclude_unset=True)
ap = await attachment_point_crud.update(db, ap, changes)
await audit_crud.log(
db, actor=actor, action="update", resource_type="AttachmentPoint",
resource_id=ap.id,
description=audit_crud.describe_update("AttachmentPoint", ap.id, changes),
)
return ap
@router.delete("/{attachment_point_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_attachment_point(
attachment_point_id: int,
db: AsyncSession = Depends(get_db),
actor: User = Depends(require_permission("attachment_points:delete")),
):
ap = await attachment_point_crud.get(db, attachment_point_id)
if ap is None:
raise HTTPException(status_code=404, detail="Attachment point not found")
label = _connection_label(ap)
await attachment_point_crud.delete(db, ap)
await audit_crud.log(
db, actor=actor, action="delete", resource_type="AttachmentPoint",
resource_id=attachment_point_id,
description=audit_crud.describe_delete("AttachmentPoint", attachment_point_id, label),
)