Delete legacy alerts
This commit is contained in:
@@ -48,11 +48,6 @@ class OrdersSettings(BaseServiceSettings):
|
||||
MAX_ORDER_VALUE: float = float(os.getenv("MAX_ORDER_VALUE", "100000.0"))
|
||||
VALIDATE_PRODUCT_AVAILABILITY: bool = os.getenv("VALIDATE_PRODUCT_AVAILABILITY", "true").lower() == "true"
|
||||
|
||||
# Alert Thresholds
|
||||
HIGH_VALUE_ORDER_THRESHOLD: float = float(os.getenv("HIGH_VALUE_ORDER_THRESHOLD", "5000.0"))
|
||||
LARGE_QUANTITY_ORDER_THRESHOLD: int = int(os.getenv("LARGE_QUANTITY_ORDER_THRESHOLD", "100"))
|
||||
RUSH_ORDER_HOURS_THRESHOLD: int = int(os.getenv("RUSH_ORDER_HOURS_THRESHOLD", "24"))
|
||||
PROCUREMENT_SHORTAGE_THRESHOLD: float = float(os.getenv("PROCUREMENT_SHORTAGE_THRESHOLD", "90.0"))
|
||||
|
||||
# Payment and Pricing
|
||||
PAYMENT_VALIDATION_ENABLED: bool = os.getenv("PAYMENT_VALIDATION_ENABLED", "true").lower() == "true"
|
||||
|
||||
@@ -58,7 +58,6 @@ async def init_database():
|
||||
from app.models.order import CustomerOrder, OrderItem, OrderStatusHistory
|
||||
from app.models.customer import Customer, CustomerContact
|
||||
from app.models.procurement import ProcurementPlan, ProcurementRequirement
|
||||
from app.models.alerts import OrderAlert
|
||||
|
||||
# Create all tables
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
# ================================================================
|
||||
# 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)
|
||||
@@ -17,7 +17,6 @@ from shared.clients import (
|
||||
ProductionServiceClient,
|
||||
SalesServiceClient
|
||||
)
|
||||
from shared.notifications.alert_integration import AlertIntegration
|
||||
from shared.database.transactions import transactional
|
||||
|
||||
from app.core.config import settings
|
||||
@@ -52,7 +51,6 @@ class OrdersService:
|
||||
inventory_client: InventoryServiceClient,
|
||||
production_client: ProductionServiceClient,
|
||||
sales_client: SalesServiceClient,
|
||||
alert_integration: AlertIntegration
|
||||
):
|
||||
self.order_repo = order_repo
|
||||
self.customer_repo = customer_repo
|
||||
@@ -61,7 +59,6 @@ class OrdersService:
|
||||
self.inventory_client = inventory_client
|
||||
self.production_client = production_client
|
||||
self.sales_client = sales_client
|
||||
self.alert_integration = alert_integration
|
||||
|
||||
@transactional
|
||||
async def create_order(
|
||||
@@ -137,8 +134,6 @@ class OrdersService:
|
||||
if business_model:
|
||||
order.business_model = business_model
|
||||
|
||||
# 9. Check for high-value or rush orders for alerts
|
||||
await self._check_order_alerts(db, order, order_data.tenant_id)
|
||||
|
||||
# 10. Integrate with production service if auto-processing is enabled
|
||||
if settings.ORDER_PROCESSING_ENABLED:
|
||||
@@ -440,46 +435,6 @@ class OrdersService:
|
||||
# Fallback to UUID
|
||||
return f"ORD-{uuid.uuid4().hex[:8].upper()}"
|
||||
|
||||
async def _check_order_alerts(self, db, order, tenant_id: UUID):
|
||||
"""Check for conditions that require alerts"""
|
||||
try:
|
||||
alerts = []
|
||||
|
||||
# High-value order alert
|
||||
if order.total_amount > settings.HIGH_VALUE_ORDER_THRESHOLD:
|
||||
alerts.append({
|
||||
"type": "high_value_order",
|
||||
"severity": "medium",
|
||||
"message": f"High-value order created: ${order.total_amount}"
|
||||
})
|
||||
|
||||
# Rush order alert
|
||||
if order.order_type == "rush":
|
||||
time_to_delivery = order.requested_delivery_date - order.order_date
|
||||
if time_to_delivery.total_seconds() < settings.RUSH_ORDER_HOURS_THRESHOLD * 3600:
|
||||
alerts.append({
|
||||
"type": "rush_order",
|
||||
"severity": "high",
|
||||
"message": f"Rush order with tight deadline: {order.order_number}"
|
||||
})
|
||||
|
||||
# Large quantity alert
|
||||
total_items = sum(item.quantity for item in order.items)
|
||||
if total_items > settings.LARGE_QUANTITY_ORDER_THRESHOLD:
|
||||
alerts.append({
|
||||
"type": "large_quantity_order",
|
||||
"severity": "medium",
|
||||
"message": f"Large quantity order: {total_items} items"
|
||||
})
|
||||
|
||||
# Send alerts if any
|
||||
for alert in alerts:
|
||||
await self._send_alert(tenant_id, order.id, alert)
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Error checking order alerts",
|
||||
order_id=str(order.id),
|
||||
error=str(e))
|
||||
|
||||
async def _notify_production_service(self, order):
|
||||
"""Notify production service of new order"""
|
||||
@@ -526,21 +481,3 @@ class OrdersService:
|
||||
order_id=str(order.id),
|
||||
error=str(e))
|
||||
|
||||
async def _send_alert(self, tenant_id: UUID, order_id: UUID, alert: Dict[str, Any]):
|
||||
"""Send alert notification"""
|
||||
try:
|
||||
if self.notification_client:
|
||||
await self.notification_client.send_alert(
|
||||
str(tenant_id),
|
||||
{
|
||||
"alert_type": alert["type"],
|
||||
"severity": alert["severity"],
|
||||
"message": alert["message"],
|
||||
"source_entity_id": str(order_id),
|
||||
"source_entity_type": "order"
|
||||
}
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning("Failed to send alert",
|
||||
tenant_id=str(tenant_id),
|
||||
error=str(e))
|
||||
Reference in New Issue
Block a user