# ================================================================ # services/orders/app/models/alerts.py # ================================================================ """ Alert system database models for Orders Service """ import uuid from datetime import datetime from decimal import Decimal from typing import Optional from sqlalchemy import Column, String, Boolean, DateTime, Numeric, Text, Integer from sqlalchemy.dialects.postgresql import UUID, JSONB from sqlalchemy.sql import func from app.core.database import Base class OrderAlert(Base): """Alert system for orders and procurement issues""" __tablename__ = "order_alerts" # Primary identification id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True) alert_code = Column(String(50), nullable=False, index=True) # Alert categorization alert_type = Column(String(50), nullable=False, index=True) # Alert types: order_issue, procurement_shortage, payment_problem, delivery_delay, # quality_concern, high_value_order, rush_order, customer_issue, supplier_problem severity = Column(String(20), nullable=False, default="medium", index=True) # Severity levels: critical, high, medium, low category = Column(String(50), nullable=False, index=True) # Categories: operational, financial, quality, customer, supplier, compliance # Alert source and context source_entity_type = Column(String(50), nullable=False) # order, customer, procurement_plan, etc. source_entity_id = Column(UUID(as_uuid=True), nullable=False, index=True) source_entity_reference = Column(String(100), nullable=True) # Human-readable reference # Alert content title = Column(String(200), nullable=False) description = Column(Text, nullable=False) detailed_message = Column(Text, nullable=True) # Alert conditions and triggers trigger_condition = Column(String(200), nullable=True) threshold_value = Column(Numeric(15, 4), nullable=True) actual_value = Column(Numeric(15, 4), nullable=True) variance = Column(Numeric(15, 4), nullable=True) # Context data alert_data = Column(JSONB, nullable=True) # Additional context-specific data business_impact = Column(Text, nullable=True) customer_impact = Column(Text, nullable=True) financial_impact = Column(Numeric(12, 2), nullable=True) # Alert status and lifecycle status = Column(String(50), nullable=False, default="active", index=True) # Status values: active, acknowledged, in_progress, resolved, dismissed, expired alert_state = Column(String(50), nullable=False, default="new") # new, escalated, recurring # Resolution and follow-up resolution_action = Column(String(200), nullable=True) resolution_notes = Column(Text, nullable=True) resolution_cost = Column(Numeric(10, 2), nullable=True) # Timing and escalation first_occurred_at = Column(DateTime(timezone=True), nullable=False, index=True) last_occurred_at = Column(DateTime(timezone=True), nullable=False) acknowledged_at = Column(DateTime(timezone=True), nullable=True) resolved_at = Column(DateTime(timezone=True), nullable=True) expires_at = Column(DateTime(timezone=True), nullable=True) # Occurrence tracking occurrence_count = Column(Integer, nullable=False, default=1) is_recurring = Column(Boolean, nullable=False, default=False) recurrence_pattern = Column(String(100), nullable=True) # Responsibility and assignment assigned_to = Column(UUID(as_uuid=True), nullable=True) assigned_role = Column(String(50), nullable=True) # orders_manager, procurement_manager, etc. escalated_to = Column(UUID(as_uuid=True), nullable=True) escalation_level = Column(Integer, nullable=False, default=0) # Notification tracking notification_sent = Column(Boolean, nullable=False, default=False) notification_methods = Column(JSONB, nullable=True) # [email, sms, whatsapp, dashboard] notification_recipients = Column(JSONB, nullable=True) # List of recipients last_notification_sent = Column(DateTime(timezone=True), nullable=True) # Customer communication customer_notified = Column(Boolean, nullable=False, default=False) customer_notification_method = Column(String(50), nullable=True) customer_message = Column(Text, nullable=True) # Recommended actions recommended_actions = Column(JSONB, nullable=True) # List of suggested actions automated_actions_taken = Column(JSONB, nullable=True) # Actions performed automatically manual_actions_required = Column(JSONB, nullable=True) # Actions requiring human intervention # Priority and urgency priority_score = Column(Integer, nullable=False, default=50) # 1-100 scale urgency = Column(String(20), nullable=False, default="normal") # immediate, urgent, normal, low business_priority = Column(String(20), nullable=False, default="normal") # Related entities related_orders = Column(JSONB, nullable=True) # Related order IDs related_customers = Column(JSONB, nullable=True) # Related customer IDs related_suppliers = Column(JSONB, nullable=True) # Related supplier IDs related_alerts = Column(JSONB, nullable=True) # Related alert IDs # Performance tracking detection_time = Column(DateTime(timezone=True), nullable=True) # When issue was detected response_time_minutes = Column(Integer, nullable=True) # Time to acknowledge resolution_time_minutes = Column(Integer, nullable=True) # Time to resolve # Quality and feedback alert_accuracy = Column(Boolean, nullable=True) # Was this a valid alert? false_positive = Column(Boolean, nullable=False, default=False) feedback_notes = Column(Text, nullable=True) # Compliance and audit compliance_related = Column(Boolean, nullable=False, default=False) audit_trail = Column(JSONB, nullable=True) # Changes and actions taken regulatory_impact = Column(String(200), nullable=True) # Integration and external systems external_system_reference = Column(String(100), nullable=True) external_ticket_number = Column(String(50), nullable=True) erp_reference = Column(String(100), nullable=True) # 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) created_by = Column(UUID(as_uuid=True), nullable=True) updated_by = Column(UUID(as_uuid=True), nullable=True) # Additional metadata alert_metadata = Column(JSONB, nullable=True)