# ================================================================ # services/orchestrator/app/models/orchestration_run.py # ================================================================ """ Orchestration Run Models - Audit trail for orchestration executions """ import uuid import enum from datetime import datetime, timezone from sqlalchemy import Column, String, DateTime, Integer, Text, Boolean, Enum as SQLEnum from sqlalchemy.dialects.postgresql import UUID, JSONB from sqlalchemy.sql import func from shared.database.base import Base class OrchestrationStatus(enum.Enum): """Orchestration run status""" pending = "pending" running = "running" completed = "completed" partial_success = "partial_success" failed = "failed" cancelled = "cancelled" class OrchestrationRun(Base): """Audit trail for orchestration executions""" __tablename__ = "orchestration_runs" # Primary identification id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) run_number = Column(String(50), nullable=False, unique=True, index=True) # Run details tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True) status = Column(SQLEnum(OrchestrationStatus), nullable=False, default=OrchestrationStatus.pending, index=True) run_type = Column(String(50), nullable=False, default="scheduled") # scheduled, manual, test priority = Column(String(20), nullable=False, default="normal") # normal, high, critical # Timing started_at = Column(DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc)) completed_at = Column(DateTime(timezone=True), nullable=True) duration_seconds = Column(Integer, nullable=True) # Step tracking forecasting_started_at = Column(DateTime(timezone=True), nullable=True) forecasting_completed_at = Column(DateTime(timezone=True), nullable=True) forecasting_status = Column(String(20), nullable=True) # success, failed, skipped forecasting_error = Column(Text, nullable=True) production_started_at = Column(DateTime(timezone=True), nullable=True) production_completed_at = Column(DateTime(timezone=True), nullable=True) production_status = Column(String(20), nullable=True) # success, failed, skipped production_error = Column(Text, nullable=True) procurement_started_at = Column(DateTime(timezone=True), nullable=True) procurement_completed_at = Column(DateTime(timezone=True), nullable=True) procurement_status = Column(String(20), nullable=True) # success, failed, skipped procurement_error = Column(Text, nullable=True) notification_started_at = Column(DateTime(timezone=True), nullable=True) notification_completed_at = Column(DateTime(timezone=True), nullable=True) notification_status = Column(String(20), nullable=True) # success, failed, skipped notification_error = Column(Text, nullable=True) # AI Insights tracking ai_insights_started_at = Column(DateTime(timezone=True), nullable=True) ai_insights_completed_at = Column(DateTime(timezone=True), nullable=True) ai_insights_status = Column(String(20), nullable=True) # success, failed, skipped ai_insights_error = Column(Text, nullable=True) ai_insights_generated = Column(Integer, nullable=False, default=0) ai_insights_posted = Column(Integer, nullable=False, default=0) # Results summary forecasts_generated = Column(Integer, nullable=False, default=0) production_batches_created = Column(Integer, nullable=False, default=0) procurement_plans_created = Column(Integer, nullable=False, default=0) purchase_orders_created = Column(Integer, nullable=False, default=0) notifications_sent = Column(Integer, nullable=False, default=0) # Forecast data passed between services forecast_data = Column(JSONB, nullable=True) # Store forecast results for downstream services # Error handling retry_count = Column(Integer, nullable=False, default=0) max_retries_reached = Column(Boolean, nullable=False, default=False) error_message = Column(Text, nullable=True) error_details = Column(JSONB, nullable=True) # External references forecast_id = Column(UUID(as_uuid=True), nullable=True) production_schedule_id = Column(UUID(as_uuid=True), nullable=True) procurement_plan_id = Column(UUID(as_uuid=True), nullable=True) # Saga tracking saga_steps_total = Column(Integer, nullable=False, default=0) saga_steps_completed = Column(Integer, nullable=False, default=0) # Audit fields created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False) triggered_by = Column(String(100), nullable=True) # scheduler, user_id, api # Performance metrics fulfillment_rate = Column(Integer, nullable=True) # Percentage as integer (0-100) on_time_delivery_rate = Column(Integer, nullable=True) # Percentage as integer (0-100) cost_accuracy = Column(Integer, nullable=True) # Percentage as integer (0-100) quality_score = Column(Integer, nullable=True) # Rating as integer (0-100) # Metadata run_metadata = Column(JSONB, nullable=True)