# ================================================================ # services/forecasting/app/models/sales_data_update.py # ================================================================ """ Sales Data Update Tracking Model Tracks when sales data is added or updated for past dates, enabling automated historical validation backfill. """ from sqlalchemy import Column, String, Integer, DateTime, Boolean, Index, Date from sqlalchemy.dialects.postgresql import UUID from datetime import datetime, timezone import uuid from shared.database.base import Base class SalesDataUpdate(Base): """Track sales data updates for historical validation""" __tablename__ = "sales_data_updates" __table_args__ = ( Index('ix_sales_updates_tenant_status', 'tenant_id', 'validation_status', 'created_at'), Index('ix_sales_updates_date_range', 'tenant_id', 'update_date_start', 'update_date_end'), Index('ix_sales_updates_validation_status', 'validation_status'), ) id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True) # Date range of sales data that was added/updated update_date_start = Column(Date, nullable=False, index=True) update_date_end = Column(Date, nullable=False, index=True) # Update metadata created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) update_source = Column(String(100), nullable=True) # import, manual, pos_sync records_affected = Column(Integer, default=0) # Validation tracking validation_status = Column(String(50), default="pending") # pending, processing, completed, failed validation_run_id = Column(UUID(as_uuid=True), nullable=True) validated_at = Column(DateTime(timezone=True), nullable=True) validation_error = Column(String(500), nullable=True) # Determines if this update should trigger validation requires_validation = Column(Boolean, default=True) # Additional context import_job_id = Column(String(255), nullable=True) # Link to sales import job if applicable notes = Column(String(500), nullable=True) def __repr__(self): return ( f"" ) def to_dict(self): """Convert to dictionary for API responses""" return { 'id': str(self.id), 'tenant_id': str(self.tenant_id), 'update_date_start': self.update_date_start.isoformat() if self.update_date_start else None, 'update_date_end': self.update_date_end.isoformat() if self.update_date_end else None, 'created_at': self.created_at.isoformat() if self.created_at else None, 'update_source': self.update_source, 'records_affected': self.records_affected, 'validation_status': self.validation_status, 'validation_run_id': str(self.validation_run_id) if self.validation_run_id else None, 'validated_at': self.validated_at.isoformat() if self.validated_at else None, 'validation_error': self.validation_error, 'requires_validation': self.requires_validation, 'import_job_id': self.import_job_id, 'notes': self.notes }