Files
leocrm/app/models/outbox.py
T
Agent Zero 727d86614e Security fixes: P0-P2 complete (22 fixes)
P0 (7): Auth-bypass removed, migrations fixed, plugin-upload disabled, RLS FORCE+WITH CHECK, plugin double-registration fixed, persistent volume, domain removed
P1 (11): User/tenant model, Redis centralized, worker separated, transactional outbox, XSS fixed, DMS chunked streaming, permissions unified, password reset, metrics secured, config/docs fixed, cross-tenant FK
P2 (4): Contact model normalized, cross-imports reduced 94%, commands+state machines for contacts/dms/mail/calendar, SPA path-traversal

8 new migrations, 99 unit tests, 13 commands, 8 contracts, 72 files changed
2026-07-25 21:03:46 +02:00

57 lines
1.8 KiB
Python

"""SQLAlchemy model for the transactional event outbox table."""
from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import DateTime, Integer, String, func
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db import Base
class EventOutbox(Base):
"""Row in the ``event_outbox`` table.
Each row represents a domain event that was written within a business
transaction and is waiting to be published to the in-process event bus
by the outbox worker.
"""
__tablename__ = "event_outbox"
id: Mapped[uuid.UUID] = mapped_column(
PGUUID(as_uuid=True),
primary_key=True,
server_default=func.gen_random_uuid(),
)
tenant_id: Mapped[uuid.UUID] = mapped_column(
PGUUID(as_uuid=True), nullable=False, index=True,
)
event_name: Mapped[str] = mapped_column(String(255), nullable=False)
payload: Mapped[dict] = mapped_column(JSONB, nullable=False)
status: Mapped[str] = mapped_column(
String(20), nullable=False, server_default="pending",
)
attempts: Mapped[int] = mapped_column(
Integer, nullable=False, server_default="0",
)
max_attempts: Mapped[int] = mapped_column(
Integer, nullable=False, server_default="5",
)
next_retry_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), 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(),
)
published_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True,
)