mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 20:55:41 +02:00
115 lines
4.3 KiB
Python
115 lines
4.3 KiB
Python
"""
|
|
Modelli RoutingRule, RoutingRuleCondition, RoutingRuleAction.
|
|
|
|
Le regole di smistamento automatico vengono valutate a ogni messaggio in arrivo:
|
|
1. Si caricano tutte le regole attive del tenant, ordinate per priority ASC
|
|
2. Per ogni regola si valutano le condizioni (AND tra le condizioni della stessa regola)
|
|
3. Se tutte le condizioni sono soddisfatte, si eseguono le azioni
|
|
4. Se stop_processing=True, si ferma l'elaborazione (non vengono valutate regole successive)
|
|
"""
|
|
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import Boolean, DateTime, ForeignKey, Index, Integer, String, Text, func
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from app.database import Base
|
|
|
|
|
|
class RoutingRule(Base):
|
|
__tablename__ = "routing_rules"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
|
|
)
|
|
tenant_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
name: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
description: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
|
priority: Mapped[int] = mapped_column(Integer, nullable=False, default=100)
|
|
# Se True, le regole successive non vengono valutate una volta che questa fa match
|
|
stop_processing: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
|
created_by: Mapped[uuid.UUID | None] = mapped_column(
|
|
UUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True
|
|
)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, server_default=func.now()
|
|
)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
|
|
)
|
|
|
|
# Relazioni
|
|
conditions: Mapped[list["RoutingRuleCondition"]] = relationship(
|
|
"RoutingRuleCondition", back_populates="rule", cascade="all, delete-orphan"
|
|
)
|
|
actions: Mapped[list["RoutingRuleAction"]] = relationship(
|
|
"RoutingRuleAction", back_populates="rule", cascade="all, delete-orphan"
|
|
)
|
|
|
|
__table_args__ = (
|
|
Index("idx_routing_rules_tenant", "tenant_id"),
|
|
Index("idx_routing_rules_active", "tenant_id", "priority"),
|
|
)
|
|
|
|
def __repr__(self) -> str:
|
|
return f"<RoutingRule {self.name!r} priority={self.priority}>"
|
|
|
|
|
|
class RoutingRuleCondition(Base):
|
|
"""
|
|
Singola condizione di una regola.
|
|
|
|
field : from_address | to_address | subject | mailbox_id | pec_type
|
|
operator : contains | equals | starts_with | ends_with | regex | not_contains
|
|
value : valore da confrontare (stringa)
|
|
"""
|
|
|
|
__tablename__ = "routing_rule_conditions"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
|
|
)
|
|
rule_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True), ForeignKey("routing_rules.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
field: Mapped[str] = mapped_column(String(50), nullable=False)
|
|
operator: Mapped[str] = mapped_column(String(30), nullable=False, default="contains")
|
|
value: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
|
rule: Mapped["RoutingRule"] = relationship("RoutingRule", back_populates="conditions")
|
|
|
|
__table_args__ = (
|
|
Index("idx_routing_conditions_rule", "rule_id"),
|
|
)
|
|
|
|
|
|
class RoutingRuleAction(Base):
|
|
"""
|
|
Singola azione di una regola.
|
|
|
|
action_type : apply_label | assign_vbox | mark_read | mark_starred | notify_webhook
|
|
action_value : UUID della label/vbox, o URL del webhook
|
|
"""
|
|
|
|
__tablename__ = "routing_rule_actions"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
|
|
)
|
|
rule_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True), ForeignKey("routing_rules.id", ondelete="CASCADE"), nullable=False
|
|
)
|
|
action_type: Mapped[str] = mapped_column(String(50), nullable=False)
|
|
action_value: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
rule: Mapped["RoutingRule"] = relationship("RoutingRule", back_populates="actions")
|
|
|
|
__table_args__ = (
|
|
Index("idx_routing_actions_rule", "rule_id"),
|
|
)
|