Files
PecHub/backend/app/api/v1/signatures.py
T
2026-06-04 20:54:49 +02:00

175 lines
5.8 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.
"""
Router firme automatiche.
Endpoint:
GET /signatures lista firme del tenant
POST /signatures crea firma (admin)
GET /signatures/{id} dettaglio firma
PUT /signatures/{id} aggiorna firma (admin)
DELETE /signatures/{id} elimina firma (admin)
GET /signatures/assignments lista assegnazioni (con filtri opzionali)
POST /signatures/assignments crea/sostituisce assegnazione (admin)
DELETE /signatures/assignments/{id} rimuovi assegnazione (admin)
"""
import uuid
from fastapi import APIRouter, Query, status
from app.dependencies import AdminUser, CurrentUser, DB
from app.schemas.signature import (
SignatureAssignmentCreate,
SignatureAssignmentListResponse,
SignatureAssignmentResponse,
SignatureCreate,
SignatureListResponse,
SignatureResponse,
SignatureUpdate,
)
from app.services.signature_service import SignatureService
router = APIRouter(tags=["Signatures"])
# ─── Firme ────────────────────────────────────────────────────────────────────
@router.get("/signatures", response_model=SignatureListResponse)
async def list_signatures(
current_user: CurrentUser,
db: DB,
q: str | None = Query(None, description="Filtro per nome"),
) -> SignatureListResponse:
"""Elenca le firme del tenant corrente."""
svc = SignatureService(db)
items, total = await svc.list_signatures(current_user.tenant_id, q=q)
return SignatureListResponse(
items=[SignatureResponse.model_validate(s) for s in items],
total=total,
)
@router.post("/signatures", response_model=SignatureResponse, status_code=status.HTTP_201_CREATED)
async def create_signature(
data: SignatureCreate,
current_user: AdminUser,
db: DB,
) -> SignatureResponse:
"""Crea una nuova firma (solo admin)."""
svc = SignatureService(db)
sig = await svc.create_signature(current_user.tenant_id, data, created_by=current_user.id)
return SignatureResponse.model_validate(sig)
@router.get("/signatures/assignments", response_model=SignatureAssignmentListResponse)
async def list_assignments(
current_user: AdminUser,
db: DB,
mailbox_id: uuid.UUID | None = Query(None),
virtual_box_id: uuid.UUID | None = Query(None),
) -> SignatureAssignmentListResponse:
"""Elenca le assegnazioni firma del tenant, con filtri opzionali."""
svc = SignatureService(db)
items, total = await svc.list_assignments(
current_user.tenant_id,
mailbox_id=mailbox_id,
virtual_box_id=virtual_box_id,
)
return SignatureAssignmentListResponse(
items=[SignatureAssignmentResponse.model_validate(i) for i in items],
total=total,
)
@router.post(
"/signatures/assignments",
response_model=SignatureAssignmentResponse,
status_code=status.HTTP_201_CREATED,
)
async def create_assignment(
data: SignatureAssignmentCreate,
current_user: AdminUser,
db: DB,
) -> SignatureAssignmentResponse:
"""
Crea (o sostituisce) l'assegnazione firma per una casella/vbox+contesto.
Se esiste gia' un'assegnazione per la stessa coppia, viene sovrascritta.
"""
svc = SignatureService(db)
result = await svc.create_assignment(current_user.tenant_id, data)
return SignatureAssignmentResponse.model_validate(result)
@router.delete(
"/signatures/assignments/{assignment_id}",
status_code=status.HTTP_204_NO_CONTENT,
)
async def delete_assignment(
assignment_id: uuid.UUID,
current_user: AdminUser,
db: DB,
) -> None:
"""Rimuove un'assegnazione firma (solo admin)."""
svc = SignatureService(db)
await svc.delete_assignment(current_user.tenant_id, assignment_id)
@router.get("/signatures/resolve", response_model=SignatureResponse | None)
async def resolve_signature(
current_user: CurrentUser,
db: DB,
context: str = Query("compose", description="Contesto: reply | compose"),
mailbox_id: uuid.UUID | None = Query(None),
virtual_box_id: uuid.UUID | None = Query(None),
) -> SignatureResponse | None:
"""
Restituisce la firma assegnata per una casella o virtual box nel contesto dato.
Usato dal ComposeModal per caricare automaticamente la firma.
"""
svc = SignatureService(db)
sig = await svc.resolve_signature(
current_user.tenant_id,
context=context,
mailbox_id=mailbox_id,
virtual_box_id=virtual_box_id,
)
if sig is None:
return None
return SignatureResponse.model_validate(sig)
@router.get("/signatures/{signature_id}", response_model=SignatureResponse)
async def get_signature(
signature_id: uuid.UUID,
current_user: CurrentUser,
db: DB,
) -> SignatureResponse:
"""Restituisce il dettaglio di una firma."""
svc = SignatureService(db)
sig = await svc.get_signature(current_user.tenant_id, signature_id)
return SignatureResponse.model_validate(sig)
@router.put("/signatures/{signature_id}", response_model=SignatureResponse)
async def update_signature(
signature_id: uuid.UUID,
data: SignatureUpdate,
current_user: AdminUser,
db: DB,
) -> SignatureResponse:
"""Aggiorna una firma esistente (solo admin)."""
svc = SignatureService(db)
sig = await svc.update_signature(current_user.tenant_id, signature_id, data)
return SignatureResponse.model_validate(sig)
@router.delete("/signatures/{signature_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_signature(
signature_id: uuid.UUID,
current_user: AdminUser,
db: DB,
) -> None:
"""Elimina una firma (solo admin)."""
svc = SignatureService(db)
await svc.delete_signature(current_user.tenant_id, signature_id)