"""AbacusOutbox Model.""" import uuid from datetime import datetime from abacus_common_logic.connectors.database import db from abacus_common_logic.models.base import CRUDMixin from sqlalchemy import ( JSON, BigInteger, Column, DateTime, Enum, Integer, SmallInteger, String, Text, ) from sqlalchemy.orm import Mapped from abacus_file_upload.constants import EVENT_PROCESSING_STATUSES class AbacusOutbox(db.Model, CRUDMixin): """AbacusOutbox Model.""" __tablename__ = 'abacus_outbox' abacus_outbox_id: Mapped[int] = Column( Integer, primary_key=True, autoincrement=True, comment='Primary key.' ) target_type: Mapped[str] = Column( String(50), nullable=False, comment='Entity type (e.g., file_upload, contract, account).', ) target_id: Mapped[int] = Column( BigInteger, nullable=False, comment='Primary key of target entity.', ) event_type: Mapped[str] = Column( String(100), nullable=False, comment='Event type using dot notation (e.g., file_upload.completed, file_upload.failed).', ) correlation_id: Mapped[str] = Column( String(36), default=lambda: str(uuid.uuid4()), comment='Correlation ID (UUID) for tracing events across systems and ensuring idempotency.', ) details: Mapped[str] = Column( JSON, nullable=True, comment='Optional event data as JSON. Used to include data needed for event processing. Max recommended size: 64KB. Larger payloads should use external storage.', ) status: Mapped[str] = Column( Enum(*EVENT_PROCESSING_STATUSES, name='status', create_type=False), default=EVENT_PROCESSING_STATUSES.PENDING, server_default=EVENT_PROCESSING_STATUSES.PENDING, comment='Event processing status.', ) retry_count: Mapped[int] = Column( SmallInteger, nullable=False, default=0, comment='Number of processing retry attempts.', ) max_retries: Mapped[int] = Column( SmallInteger, nullable=False, default=3, comment='Maximum number of retry attempts before marking as failed.', ) next_retry_at: Mapped[datetime] = Column( DateTime, nullable=True, comment='Scheduled time for next retry attempt (for exponential backoff).', ) error_message: Mapped[str] = Column( Text, nullable=True, comment='Error message if processing failed.', ) processed_at: Mapped[datetime] = Column( DateTime, nullable=True, comment='Timestamp when the event was successfully processed.', )