150 lines
4.3 KiB
Python
150 lines
4.3 KiB
Python
"""
|
||
Schemi Pydantic per RoutingRule (Feature 2 – Regole di smistamento automatico).
|
||
"""
|
||
|
||
import uuid
|
||
from datetime import datetime
|
||
from typing import Literal
|
||
|
||
from pydantic import BaseModel, field_validator
|
||
|
||
# Valori validi per field nelle condizioni
|
||
CONDITION_FIELDS = Literal[
|
||
"from_address",
|
||
"to_address",
|
||
"subject",
|
||
"mailbox_id",
|
||
"pec_type",
|
||
# Tassonomia (N2): verifica se il messaggio ha gia' una specifica etichetta/nodo
|
||
"has_label",
|
||
# Rischio e Riservatezza (N3): verifica il livello gia' impostato
|
||
"risk_level",
|
||
"confidentiality",
|
||
# Campi aggiuntivi del messaggio
|
||
"has_attachments", # "true" / "false"
|
||
"direction", # "inbound" / "outbound"
|
||
"protocol_type", # "pec_it" / "rem_eu"
|
||
"body_contains", # testo nel corpo del messaggio (usa operator contains/regex)
|
||
]
|
||
# Operatori supportati
|
||
CONDITION_OPERATORS = Literal[
|
||
"contains", "equals", "starts_with", "ends_with", "regex", "not_contains"
|
||
]
|
||
# Tipi di azione
|
||
ACTION_TYPES = Literal[
|
||
"apply_label",
|
||
"assign_vbox",
|
||
"mark_read",
|
||
"mark_starred",
|
||
"notify_webhook",
|
||
# Tassonomia (N2): applica un nodo tassonomico (Ambito/Processo/Classificazione)
|
||
"apply_taxonomy",
|
||
# Rischio e Riservatezza (N3): imposta il livello di rischio o riservatezza
|
||
"set_risk_level",
|
||
"set_confidentiality",
|
||
# Gestione messaggio
|
||
"archive", # archivia il messaggio
|
||
"mark_for_conservation", # marca per la conservazione digitale immediata
|
||
# Scadenzario (Feature 4): imposta una scadenza relativa
|
||
# action_value = numero di giorni (es. "30") oppure "+30d", "+4w", "+1y"
|
||
# oppure JSON {"days": 30, "note": "Testo promemoria"}
|
||
"set_deadline",
|
||
# Fascicolazione (Feature N5): aggiunge il messaggio a un fascicolo esistente
|
||
# action_value = UUID del fascicolo
|
||
"add_to_fascicolo",
|
||
# Notifiche multi-canale: invia tramite un canale configurato (email/telegram/whatsapp/webhook)
|
||
# action_value = UUID del NotificationChannel
|
||
"notify_channel",
|
||
]
|
||
|
||
|
||
class RoutingRuleConditionCreate(BaseModel):
|
||
field: CONDITION_FIELDS
|
||
operator: CONDITION_OPERATORS = "contains"
|
||
value: str
|
||
|
||
@field_validator("value")
|
||
@classmethod
|
||
def value_not_empty(cls, v: str) -> str:
|
||
if not v.strip():
|
||
raise ValueError("Il valore della condizione non puo' essere vuoto")
|
||
return v.strip()
|
||
|
||
|
||
class RoutingRuleActionCreate(BaseModel):
|
||
action_type: ACTION_TYPES
|
||
action_value: str | None = None
|
||
|
||
|
||
class RoutingRuleCreate(BaseModel):
|
||
name: str
|
||
description: str | None = None
|
||
is_active: bool = True
|
||
priority: int = 100
|
||
stop_processing: bool = True
|
||
conditions: list[RoutingRuleConditionCreate] = []
|
||
actions: list[RoutingRuleActionCreate] = []
|
||
|
||
@field_validator("name")
|
||
@classmethod
|
||
def name_not_empty(cls, v: str) -> str:
|
||
if not v.strip():
|
||
raise ValueError("Il nome della regola non puo' essere vuoto")
|
||
return v.strip()
|
||
|
||
@field_validator("priority")
|
||
@classmethod
|
||
def priority_positive(cls, v: int) -> int:
|
||
if v < 1:
|
||
raise ValueError("La priorita' deve essere >= 1")
|
||
return v
|
||
|
||
|
||
class RoutingRuleUpdate(BaseModel):
|
||
name: str | None = None
|
||
description: str | None = None
|
||
is_active: bool | None = None
|
||
priority: int | None = None
|
||
stop_processing: bool | None = None
|
||
conditions: list[RoutingRuleConditionCreate] | None = None
|
||
actions: list[RoutingRuleActionCreate] | None = None
|
||
|
||
|
||
class RoutingRuleConditionResponse(BaseModel):
|
||
model_config = {"from_attributes": True}
|
||
|
||
id: uuid.UUID
|
||
field: str
|
||
operator: str
|
||
value: str
|
||
|
||
|
||
class RoutingRuleActionResponse(BaseModel):
|
||
model_config = {"from_attributes": True}
|
||
|
||
id: uuid.UUID
|
||
action_type: str
|
||
action_value: str | None = None
|
||
|
||
|
||
class RoutingRuleResponse(BaseModel):
|
||
model_config = {"from_attributes": True}
|
||
|
||
id: uuid.UUID
|
||
tenant_id: uuid.UUID
|
||
name: str
|
||
description: str | None = None
|
||
is_active: bool
|
||
priority: int
|
||
stop_processing: bool
|
||
conditions: list[RoutingRuleConditionResponse] = []
|
||
actions: list[RoutingRuleActionResponse] = []
|
||
created_by: uuid.UUID | None = None
|
||
created_at: datetime
|
||
updated_at: datetime
|
||
|
||
|
||
class RoutingRuleListResponse(BaseModel):
|
||
items: list[RoutingRuleResponse]
|
||
total: int
|