Add supplier and imporve inventory frontend
This commit is contained in:
@@ -13,11 +13,10 @@ class AlertProcessorConfig(BaseServiceSettings):
|
||||
APP_NAME: str = "Alert Processor Service"
|
||||
DESCRIPTION: str = "Central alert and recommendation processor"
|
||||
|
||||
# Use the notification database for alert storage
|
||||
# This makes sense since alerts and notifications are closely related
|
||||
# Use dedicated database for alert storage
|
||||
DATABASE_URL: str = os.getenv(
|
||||
"NOTIFICATION_DATABASE_URL",
|
||||
"postgresql+asyncpg://notification_user:notification_pass123@notification-db:5432/notification_db"
|
||||
"ALERT_PROCESSOR_DATABASE_URL",
|
||||
"postgresql+asyncpg://alert_processor_user:alert_processor_pass123@alert-processor-db:5432/alert_processor_db"
|
||||
)
|
||||
|
||||
# Use dedicated Redis DB for alert processing
|
||||
|
||||
@@ -206,42 +206,47 @@ class AlertProcessorService:
|
||||
|
||||
async def store_item(self, item: dict) -> dict:
|
||||
"""Store alert or recommendation in database"""
|
||||
from sqlalchemy import text
|
||||
|
||||
query = text("""
|
||||
INSERT INTO alerts (
|
||||
id, tenant_id, item_type, alert_type, severity, status,
|
||||
service, title, message, actions, metadata,
|
||||
created_at
|
||||
) VALUES (:id, :tenant_id, :item_type, :alert_type, :severity, :status,
|
||||
:service, :title, :message, :actions, :metadata, :created_at)
|
||||
RETURNING *
|
||||
""")
|
||||
|
||||
from app.models.alerts import Alert, AlertSeverity, AlertStatus
|
||||
from sqlalchemy import select
|
||||
|
||||
async with self.db_manager.get_session() as session:
|
||||
result = await session.execute(
|
||||
query,
|
||||
{
|
||||
'id': item['id'],
|
||||
'tenant_id': item['tenant_id'],
|
||||
'item_type': item['item_type'], # 'alert' or 'recommendation'
|
||||
'alert_type': item['type'],
|
||||
'severity': item['severity'],
|
||||
'status': 'active',
|
||||
'service': item['service'],
|
||||
'title': item['title'],
|
||||
'message': item['message'],
|
||||
'actions': json.dumps(item.get('actions', [])),
|
||||
'metadata': json.dumps(item.get('metadata', {})),
|
||||
'created_at': item['timestamp']
|
||||
}
|
||||
# Create alert instance
|
||||
alert = Alert(
|
||||
id=item['id'],
|
||||
tenant_id=item['tenant_id'],
|
||||
item_type=item['item_type'], # 'alert' or 'recommendation'
|
||||
alert_type=item['type'],
|
||||
severity=AlertSeverity(item['severity']),
|
||||
status=AlertStatus.ACTIVE,
|
||||
service=item['service'],
|
||||
title=item['title'],
|
||||
message=item['message'],
|
||||
actions=item.get('actions', []),
|
||||
alert_metadata=item.get('metadata', {}),
|
||||
created_at=datetime.fromisoformat(item['timestamp']) if isinstance(item['timestamp'], str) else item['timestamp']
|
||||
)
|
||||
|
||||
row = result.fetchone()
|
||||
|
||||
session.add(alert)
|
||||
await session.commit()
|
||||
|
||||
await session.refresh(alert)
|
||||
|
||||
logger.debug("Item stored in database", item_id=item['id'])
|
||||
return dict(row._mapping)
|
||||
|
||||
# Convert to dict for return
|
||||
return {
|
||||
'id': str(alert.id),
|
||||
'tenant_id': str(alert.tenant_id),
|
||||
'item_type': alert.item_type,
|
||||
'alert_type': alert.alert_type,
|
||||
'severity': alert.severity.value,
|
||||
'status': alert.status.value,
|
||||
'service': alert.service,
|
||||
'title': alert.title,
|
||||
'message': alert.message,
|
||||
'actions': alert.actions,
|
||||
'metadata': alert.alert_metadata,
|
||||
'created_at': alert.created_at
|
||||
}
|
||||
|
||||
async def stream_to_sse(self, tenant_id: str, item: dict):
|
||||
"""Publish item to Redis for SSE streaming"""
|
||||
|
||||
1
services/alert_processor/app/models/__init__.py
Normal file
1
services/alert_processor/app/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# services/alert_processor/app/models/__init__.py
|
||||
56
services/alert_processor/app/models/alerts.py
Normal file
56
services/alert_processor/app/models/alerts.py
Normal file
@@ -0,0 +1,56 @@
|
||||
# services/alert_processor/app/models/alerts.py
|
||||
"""
|
||||
Alert models for the alert processor service
|
||||
"""
|
||||
|
||||
from sqlalchemy import Column, String, Text, DateTime, JSON, Enum
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from datetime import datetime
|
||||
import uuid
|
||||
import enum
|
||||
|
||||
from shared.database.base import Base
|
||||
|
||||
|
||||
class AlertStatus(enum.Enum):
|
||||
"""Alert status values"""
|
||||
ACTIVE = "active"
|
||||
RESOLVED = "resolved"
|
||||
ACKNOWLEDGED = "acknowledged"
|
||||
IGNORED = "ignored"
|
||||
|
||||
|
||||
class AlertSeverity(enum.Enum):
|
||||
"""Alert severity levels"""
|
||||
LOW = "low"
|
||||
MEDIUM = "medium"
|
||||
HIGH = "high"
|
||||
URGENT = "urgent"
|
||||
|
||||
|
||||
class Alert(Base):
|
||||
"""Alert records for the alert processor service"""
|
||||
__tablename__ = "alerts"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
|
||||
|
||||
# Alert classification
|
||||
item_type = Column(String(50), nullable=False) # 'alert' or 'recommendation'
|
||||
alert_type = Column(String(100), nullable=False) # e.g., 'overstock_warning'
|
||||
severity = Column(Enum(AlertSeverity), nullable=False, index=True)
|
||||
status = Column(Enum(AlertStatus), default=AlertStatus.ACTIVE, index=True)
|
||||
|
||||
# Source and content
|
||||
service = Column(String(100), nullable=False) # originating service
|
||||
title = Column(String(255), nullable=False)
|
||||
message = Column(Text, nullable=False)
|
||||
|
||||
# Actions and metadata
|
||||
actions = Column(JSON, nullable=True) # List of available actions
|
||||
alert_metadata = Column(JSON, nullable=True) # Additional alert-specific data
|
||||
|
||||
# Timestamps
|
||||
created_at = Column(DateTime, default=datetime.utcnow, index=True)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
resolved_at = Column(DateTime, nullable=True)
|
||||
Reference in New Issue
Block a user