New alert service
This commit is contained in:
@@ -165,7 +165,7 @@ class EnrichedAlert(BaseModel):
|
||||
trend_context: Optional[TrendContext] = Field(None, description="Trend analysis (if trend warning)")
|
||||
|
||||
# AI Reasoning
|
||||
ai_reasoning_summary: Optional[str] = Field(None, description="Plain language AI reasoning")
|
||||
ai_reasoning_i18n: Optional[Dict[str, Any]] = Field(None, description="i18n-ready AI reasoning with key and params")
|
||||
reasoning_data: Optional[Dict[str, Any]] = Field(None, description="Structured reasoning from orchestrator")
|
||||
confidence_score: Optional[float] = Field(None, description="AI confidence 0-1")
|
||||
|
||||
|
||||
146
shared/schemas/events.py
Normal file
146
shared/schemas/events.py
Normal file
@@ -0,0 +1,146 @@
|
||||
"""
|
||||
Minimal event schemas for services to emit events.
|
||||
|
||||
Services send minimal event data with only event_type and metadata.
|
||||
All enrichment, i18n generation, and priority calculation happens
|
||||
in the alert_processor service.
|
||||
"""
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Dict, Any, Literal, Optional
|
||||
from datetime import datetime
|
||||
from uuid import UUID
|
||||
|
||||
|
||||
class MinimalEvent(BaseModel):
|
||||
"""
|
||||
Minimal event structure sent by services.
|
||||
|
||||
Services only need to provide:
|
||||
- tenant_id: Who this event belongs to
|
||||
- event_class: alert, notification, or recommendation
|
||||
- event_domain: Business domain (inventory, production, supply_chain, etc.)
|
||||
- event_type: Specific event identifier (critical_stock_shortage, production_delay, etc.)
|
||||
- service: Source service name
|
||||
- metadata: Dictionary with event-specific data
|
||||
|
||||
The alert_processor service enriches this with:
|
||||
- i18n keys and parameters
|
||||
- Priority score and level
|
||||
- Orchestrator context (AI actions)
|
||||
- Business impact analysis
|
||||
- Urgency assessment
|
||||
- User agency determination
|
||||
- Smart actions
|
||||
"""
|
||||
|
||||
tenant_id: str = Field(..., description="Tenant UUID as string")
|
||||
event_class: Literal["alert", "notification", "recommendation"] = Field(
|
||||
...,
|
||||
description="Event classification - alert requires action, notification is FYI, recommendation is suggestion"
|
||||
)
|
||||
event_domain: str = Field(
|
||||
...,
|
||||
description="Business domain: inventory, production, supply_chain, demand, operations, distribution"
|
||||
)
|
||||
event_type: str = Field(
|
||||
...,
|
||||
description="Specific event type identifier, e.g., critical_stock_shortage, production_delay, po_approval_needed"
|
||||
)
|
||||
service: str = Field(..., description="Source service name, e.g., inventory, production, procurement")
|
||||
metadata: Dict[str, Any] = Field(
|
||||
default_factory=dict,
|
||||
description="Event-specific data - structure varies by event_type"
|
||||
)
|
||||
timestamp: Optional[datetime] = Field(
|
||||
default=None,
|
||||
description="Event timestamp, set automatically if not provided"
|
||||
)
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
json_schema_extra = {
|
||||
"examples": [
|
||||
{
|
||||
"tenant_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"event_class": "alert",
|
||||
"event_domain": "inventory",
|
||||
"event_type": "critical_stock_shortage",
|
||||
"service": "inventory",
|
||||
"metadata": {
|
||||
"ingredient_id": "123e4567-e89b-12d3-a456-426614174000",
|
||||
"ingredient_name": "Flour",
|
||||
"current_stock": 5.2,
|
||||
"required_stock": 10.0,
|
||||
"shortage_amount": 4.8,
|
||||
"supplier_name": "Flour Supplier Co.",
|
||||
"lead_time_days": 3,
|
||||
"po_id": "PO-12345",
|
||||
"po_amount": 2500.00,
|
||||
"po_status": "pending_approval",
|
||||
"delivery_date": "2025-12-10"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tenant_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"event_class": "alert",
|
||||
"event_domain": "production",
|
||||
"event_type": "production_delay",
|
||||
"service": "production",
|
||||
"metadata": {
|
||||
"batch_id": "987fbc97-4bed-5078-9f07-9141ba07c9f3",
|
||||
"product_name": "Croissant",
|
||||
"batch_number": "B-2025-001",
|
||||
"delay_minutes": 45,
|
||||
"affected_orders": 3,
|
||||
"customer_names": ["Customer A", "Customer B"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"tenant_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"event_class": "notification",
|
||||
"event_domain": "supply_chain",
|
||||
"event_type": "po_approved",
|
||||
"service": "procurement",
|
||||
"metadata": {
|
||||
"po_id": "PO-12345",
|
||||
"po_number": "PO-2025-001",
|
||||
"supplier_name": "Flour Supplier Co.",
|
||||
"total_amount": 2500.00,
|
||||
"currency": "EUR",
|
||||
"approved_at": "2025-12-05T10:30:00Z",
|
||||
"approved_by": "user@example.com"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# Event Domain Constants
|
||||
class EventDomain:
|
||||
"""Standard event domains"""
|
||||
INVENTORY = "inventory"
|
||||
PRODUCTION = "production"
|
||||
SUPPLY_CHAIN = "supply_chain"
|
||||
DEMAND = "demand"
|
||||
OPERATIONS = "operations"
|
||||
DISTRIBUTION = "distribution"
|
||||
FINANCE = "finance"
|
||||
|
||||
|
||||
# Event Class Constants
|
||||
class EventClass:
|
||||
"""Event classifications"""
|
||||
ALERT = "alert" # Requires user decision/action
|
||||
NOTIFICATION = "notification" # Informational, no action needed
|
||||
RECOMMENDATION = "recommendation" # Optimization suggestion
|
||||
|
||||
|
||||
# Severity Levels (for routing)
|
||||
class Severity:
|
||||
"""Alert severity levels for routing"""
|
||||
URGENT = "urgent" # Immediate attention required
|
||||
HIGH = "high" # Important, address soon
|
||||
MEDIUM = "medium" # Standard priority
|
||||
LOW = "low" # Minor, can wait
|
||||
INFO = "info" # Informational only
|
||||
Reference in New Issue
Block a user