Modifiche varie

This commit is contained in:
2026-06-04 20:54:49 +02:00
parent ccc4167e28
commit e31676d22e
31 changed files with 3058 additions and 153 deletions
+174
View File
@@ -0,0 +1,174 @@
"""
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)