feat(scouts): add ScoutTriageQueue table + cloud_scout_configs gmail fields
Tasks 12+13 of Phase 2 — first new infra after rename. Alembic 008 creates scout_triage_queue with unique constraint on (scout_id, source_msg_ref) and partial index on expires_at for active rows. Adds four columns to cloud_scout_configs: auto_trash_spam, gmail_history_id, gmail_watch_expires_at, device_inactivity_pause_days. SQLAlchemy model ScoutTriageQueue added; CloudScoutConfig updated to match. Imports extended with UniqueConstraint and text.
This commit is contained in:
@@ -34,8 +34,10 @@ from sqlalchemy import (
|
||||
LargeBinary,
|
||||
String,
|
||||
Text,
|
||||
UniqueConstraint,
|
||||
Uuid,
|
||||
func,
|
||||
text,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
@@ -217,6 +219,10 @@ class CloudScoutConfig(Base):
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
auto_trash_spam: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default=text("false"))
|
||||
gmail_history_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||||
gmail_watch_expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
device_inactivity_pause_days: Mapped[int] = mapped_column(Integer, nullable=False, default=14, server_default="14")
|
||||
|
||||
run_logs: Mapped[list["ScoutRunLog"]] = relationship(
|
||||
back_populates="cloud_scout",
|
||||
@@ -227,6 +233,26 @@ class CloudScoutConfig(Base):
|
||||
)
|
||||
|
||||
|
||||
class ScoutTriageQueue(Base):
|
||||
__tablename__ = "scout_triage_queue"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("scout_id", "source_msg_ref", name="uq_scout_triage_queue_scout_msg"),
|
||||
)
|
||||
|
||||
id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True, default=_uuid)
|
||||
user_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True)
|
||||
scout_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), ForeignKey("cloud_scout_configs.id", ondelete="CASCADE"), nullable=False)
|
||||
source_type: Mapped[str] = mapped_column(String(50), nullable=False)
|
||||
source_msg_ref: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
triage_verdict: Mapped[str] = mapped_column(String(20), nullable=False)
|
||||
triage_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
status: Mapped[str] = mapped_column(String(20), nullable=False, default="queued", server_default="queued")
|
||||
triaged_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())
|
||||
delivered_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
acked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
||||
|
||||
|
||||
class ScoutRunLog(Base):
|
||||
__tablename__ = "scout_run_logs"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user