Files
bakery-ia/services/alert_processor/README.md

308 lines
8.9 KiB
Markdown
Raw Normal View History

2025-12-05 20:07:01 +01:00
# Alert Processor Service v2.0
2025-12-05 20:07:01 +01:00
Clean, well-structured event processing and alert management system with sophisticated enrichment pipeline.
2025-11-06 14:10:04 +01:00
## Overview
2025-12-05 20:07:01 +01:00
The Alert Processor Service receives **minimal events** from other services (inventory, production, procurement, etc.) and enriches them with:
- **i18n message generation** - Parameterized titles and messages for frontend
- **Multi-factor priority scoring** - Business impact (40%), Urgency (30%), User agency (20%), Confidence (10%)
- **Business impact analysis** - Financial impact, affected orders, customer impact
- **Urgency assessment** - Time until consequence, deadlines, escalation
- **User agency analysis** - Can user fix? External dependencies? Blockers?
- **AI orchestrator context** - Query for AI actions already taken
- **Smart action generation** - Contextual buttons with deep links
- **Entity linking** - References to related entities (POs, batches, orders)
## Architecture
```
Services → RabbitMQ → [Alert Processor] → PostgreSQL
Notification Service
Redis (SSE Pub/Sub)
Frontend
```
### Enrichment Pipeline
1. **Message Generator**: Creates i18n keys and parameters from metadata
2. **Orchestrator Client**: Queries AI orchestrator for context
3. **Business Impact Analyzer**: Calculates financial and operational impact
4. **Urgency Analyzer**: Assesses time sensitivity and deadlines
5. **User Agency Analyzer**: Determines user's ability to act
6. **Priority Scorer**: Calculates weighted priority score (0-100)
7. **Smart Action Generator**: Creates contextual action buttons
8. **Entity Link Extractor**: Maps metadata to entity references
## Service Structure
```
alert_processor_v2/
├── app/
│ ├── main.py # FastAPI app + lifecycle
│ ├── core/
│ │ ├── config.py # Settings
│ │ └── database.py # Database session management
│ ├── models/
│ │ └── events.py # SQLAlchemy Event model
│ ├── schemas/
│ │ └── events.py # Pydantic schemas
│ ├── api/
│ │ ├── alerts.py # Alert endpoints
│ │ └── sse.py # SSE streaming
│ ├── consumer/
│ │ └── event_consumer.py # RabbitMQ consumer
│ ├── enrichment/
│ │ ├── message_generator.py # i18n generation
│ │ ├── priority_scorer.py # Priority calculation
│ │ ├── orchestrator_client.py # AI context
│ │ ├── smart_actions.py # Action buttons
│ │ ├── business_impact.py # Impact analysis
│ │ ├── urgency_analyzer.py # Urgency assessment
│ │ └── user_agency.py # Agency analysis
│ ├── repositories/
│ │ └── event_repository.py # Database queries
│ ├── services/
│ │ ├── enrichment_orchestrator.py # Pipeline coordinator
│ │ └── sse_service.py # SSE pub/sub
│ └── utils/
│ └── message_templates.py # Alert type mappings
├── migrations/
│ └── versions/
│ └── 20251205_clean_unified_schema.py
└── requirements.txt
```
## Environment Variables
2025-11-06 14:10:04 +01:00
```bash
# Service
SERVICE_NAME=alert-processor
2025-12-05 20:07:01 +01:00
VERSION=2.0.0
DEBUG=false
# Database
2025-12-05 20:07:01 +01:00
DATABASE_URL=postgresql+asyncpg://user:pass@localhost/db
# RabbitMQ
2025-12-05 20:07:01 +01:00
RABBITMQ_URL=amqp://guest:guest@localhost/
RABBITMQ_EXCHANGE=events.exchange
RABBITMQ_QUEUE=alert_processor.queue
2025-12-05 20:07:01 +01:00
# Redis
REDIS_URL=redis://localhost:6379/0
REDIS_SSE_PREFIX=alerts
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
# Orchestrator Service
ORCHESTRATOR_URL=http://orchestrator:8000
ORCHESTRATOR_TIMEOUT=10
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
# Notification Service
NOTIFICATION_URL=http://notification:8000
NOTIFICATION_TIMEOUT=5
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
# Cache
CACHE_ENABLED=true
CACHE_TTL_SECONDS=300
```
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
## Running the Service
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
### Local Development
```bash
# Install dependencies
pip install -r requirements.txt
2025-12-05 20:07:01 +01:00
# Run database migrations
alembic upgrade head
# Start service
python -m app.main
2025-12-05 20:07:01 +01:00
# or
uvicorn app.main:app --reload
2025-11-06 14:10:04 +01:00
```
2025-12-05 20:07:01 +01:00
### Docker
```bash
2025-12-05 20:07:01 +01:00
docker build -t alert-processor:2.0 .
docker run -p 8000:8000 --env-file .env alert-processor:2.0
```
2025-12-05 20:07:01 +01:00
## API Endpoints
2025-12-05 20:07:01 +01:00
### Alert Management
2025-12-05 20:07:01 +01:00
- `GET /api/v1/tenants/{tenant_id}/alerts` - List alerts with filters
- `GET /api/v1/tenants/{tenant_id}/alerts/summary` - Get dashboard summary
- `GET /api/v1/tenants/{tenant_id}/alerts/{alert_id}` - Get single alert
- `POST /api/v1/tenants/{tenant_id}/alerts/{alert_id}/acknowledge` - Acknowledge alert
- `POST /api/v1/tenants/{tenant_id}/alerts/{alert_id}/resolve` - Resolve alert
- `POST /api/v1/tenants/{tenant_id}/alerts/{alert_id}/dismiss` - Dismiss alert
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
### Real-Time Streaming
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
- `GET /api/v1/sse/alerts/{tenant_id}` - SSE stream for real-time alerts
2025-11-06 14:10:04 +01:00
### Health Check
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
- `GET /health` - Service health status
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
## Event Flow
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
### 1. Service Emits Minimal Event
```python
2025-12-05 20:07:01 +01:00
from shared.messaging.event_publisher import EventPublisher
await publisher.publish_alert(
tenant_id=tenant_id,
event_type="critical_stock_shortage",
event_domain="inventory",
severity="urgent",
metadata={
"ingredient_id": "...",
"ingredient_name": "Flour",
"current_stock": 10.5,
"required_stock": 50.0,
"shortage_amount": 39.5
}
)
```
2025-12-05 20:07:01 +01:00
### 2. Alert Processor Enriches
2025-12-05 20:07:01 +01:00
- Generates i18n: `alerts.critical_stock_shortage.title` with params
- Queries orchestrator for AI context
- Analyzes business impact: €197.50 financial impact
- Assesses urgency: 12 hours until consequence
- Determines user agency: Can create PO, requires supplier
- Calculates priority: Score 78 → "important"
- Generates smart actions: [Create PO, Call Supplier, Dismiss]
- Extracts entity links: `{ingredient: "..."}`
2025-12-05 20:07:01 +01:00
### 3. Stores Enriched Event
```json
{
2025-12-05 20:07:01 +01:00
"id": "...",
"event_type": "critical_stock_shortage",
"priority_score": 78,
"priority_level": "important",
"i18n": {
"title_key": "alerts.critical_stock_shortage.title",
"title_params": {"ingredient_name": "Flour"},
"message_key": "alerts.critical_stock_shortage.message_generic",
"message_params": {
"current_stock_kg": 10.5,
"required_stock_kg": 50.0
}
},
"business_impact": {...},
"urgency": {...},
"user_agency": {...},
"smart_actions": [...]
}
```
2025-12-05 20:07:01 +01:00
### 4. Sends Notification
2025-12-05 20:07:01 +01:00
Calls notification service with event details for delivery via WhatsApp, Email, Push, etc.
2025-12-05 20:07:01 +01:00
### 5. Publishes to SSE
2025-12-05 20:07:01 +01:00
Publishes to Redis channel `alerts:{tenant_id}` for real-time frontend updates.
2025-12-05 20:07:01 +01:00
## Priority Scoring Algorithm
2025-12-05 20:07:01 +01:00
**Formula**: `Total = (Impact × 0.4) + (Urgency × 0.3) + (Agency × 0.2) + (Confidence × 0.1)`
2025-12-05 20:07:01 +01:00
**Business Impact Score (0-100)**:
- Financial impact > €1000: +30
- Affected orders > 10: +15
- High customer impact: +15
- Production delay > 4h: +10
- Revenue loss > €500: +10
2025-12-05 20:07:01 +01:00
**Urgency Score (0-100)**:
- Time until consequence < 2h: +40
- Deadline present: +5
- Can't wait until tomorrow: +10
- Peak hour relevant: +5
2025-12-05 20:07:01 +01:00
**User Agency Score (0-100)**:
- User can fix: +30
- Requires external party: -10
- Has blockers: -5 per blocker
- Has workaround: +5
2025-12-05 20:07:01 +01:00
**Escalation Boost** (up to +30):
- Pending > 72h: +20
- Deadline < 6h: +30
2025-12-05 20:07:01 +01:00
## Alert Types
2025-12-05 20:07:01 +01:00
See [app/utils/message_templates.py](app/utils/message_templates.py) for complete list.
2025-12-05 20:07:01 +01:00
Key alert types:
- `critical_stock_shortage`
- `low_stock_warning`
- `production_delay`
- `equipment_failure`
- `po_approval_needed`
- `temperature_breach`
- `delivery_overdue`
- `expired_products`
2025-12-05 20:07:01 +01:00
## Database Schema
2025-12-05 20:07:01 +01:00
**events table** with JSONB enrichment:
- Core: `id`, `tenant_id`, `created_at`, `event_type`
- i18n: `i18n_title_key`, `i18n_title_params`, `i18n_message_key`, `i18n_message_params`
- Priority: `priority_score` (0-100), `priority_level` (critical/important/standard/info)
- Enrichment: `orchestrator_context`, `business_impact`, `urgency`, `user_agency` (JSONB)
- Actions: `smart_actions` (JSONB array)
- Status: `status` (active/acknowledged/resolved/dismissed)
2025-12-05 20:07:01 +01:00
## Monitoring
2025-12-05 20:07:01 +01:00
Structured JSON logs with:
- `enrichment_started` - Event received
- `enrichment_completed` - Enrichment pipeline finished
- `event_stored` - Saved to database
- `notification_sent` - Notification queued
- `sse_event_published` - Published to SSE stream
2025-12-05 20:07:01 +01:00
## Testing
2025-12-05 20:07:01 +01:00
```bash
# Run tests
pytest
2025-12-05 20:07:01 +01:00
# Test enrichment pipeline
pytest tests/test_enrichment_orchestrator.py
2025-12-05 20:07:01 +01:00
# Test priority scoring
pytest tests/test_priority_scorer.py
2025-12-05 20:07:01 +01:00
# Test message generation
pytest tests/test_message_generator.py
```
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
## Migration from v1
See [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md) for migration steps from old alert_processor.
2025-11-06 14:10:04 +01:00
2025-12-05 20:07:01 +01:00
Key changes:
- Services send minimal events (no hardcoded messages)
- All enrichment moved to alert_processor
- Unified Event table (no separate alert/notification tables)
- i18n-first architecture
- Sophisticated multi-factor priority scoring
- Smart action generation