""" Schemi Pydantic per Label (tag) e operazioni correlate. Esteso con supporto tassonomia gerarchica (Feature N2). """ import uuid from typing import Optional from pydantic import BaseModel, Field # ─── CRUD Label ─────────────────────────────────────────────────────────────── class LabelCreate(BaseModel): name: str = Field(..., min_length=1, max_length=100) color: Optional[str] = Field(None, pattern=r'^#[0-9A-Fa-f]{6}$') # Tassonomia: se valorizzato, questo nodo diventa figlio del parent indicato parent_id: Optional[uuid.UUID] = None description: Optional[str] = None class LabelUpdate(BaseModel): name: Optional[str] = Field(None, min_length=1, max_length=100) color: Optional[str] = Field(None, pattern=r'^#[0-9A-Fa-f]{6}$') parent_id: Optional[uuid.UUID] = None description: Optional[str] = None class LabelResponse(BaseModel): id: uuid.UUID tenant_id: uuid.UUID name: str color: Optional[str] = None parent_id: Optional[uuid.UUID] = None description: Optional[str] = None model_config = {"from_attributes": True} class LabelTreeResponse(BaseModel): """ Label con figli annidati per la vista ad albero della tassonomia. Struttura restituita da GET /labels/tree: [ Ambito1 { children: [ Processo1 { children: [ Classificazione1, ... ] } ] } ] """ id: uuid.UUID tenant_id: uuid.UUID name: str color: Optional[str] = None parent_id: Optional[uuid.UUID] = None description: Optional[str] = None children: list["LabelTreeResponse"] = [] model_config = {"from_attributes": True} # Necessario per il tipo ricorsivo LabelTreeResponse.model_rebuild() # ─── Richieste per assegnazione tag a messaggi ──────────────────────────────── class MessageLabelSetRequest(BaseModel): """Sostituisce tutti i tag di un messaggio con quelli indicati.""" label_ids: list[uuid.UUID] class MessageLabelAddRequest(BaseModel): """Aggiunge tag a un messaggio senza rimuovere quelli esistenti.""" label_ids: list[uuid.UUID] class MessageLabelRemoveRequest(BaseModel): """Rimuove specifici tag da un messaggio.""" label_ids: list[uuid.UUID] class MessageBulkLabelRequest(BaseModel): """Aggiunge o rimuove tag da più messaggi in blocco.""" message_ids: list[uuid.UUID] label_ids: list[uuid.UUID] action: str = Field(..., pattern=r'^(add|remove)$') class MessageBulkLabelResponse(BaseModel): updated: int