Files
bakery-ia/services/ai_insights/app/schemas/insight.py
2025-11-05 13:34:56 +01:00

94 lines
2.9 KiB
Python

"""Pydantic schemas for AI Insights."""
from pydantic import BaseModel, Field, ConfigDict
from typing import Optional, Dict, Any, List
from datetime import datetime
from uuid import UUID
from decimal import Decimal
class AIInsightBase(BaseModel):
"""Base schema for AI Insight."""
type: str = Field(..., description="optimization, alert, prediction, recommendation, insight, anomaly")
priority: str = Field(..., description="low, medium, high, critical")
category: str = Field(..., description="forecasting, inventory, production, procurement, customer, etc.")
title: str = Field(..., max_length=255)
description: str
impact_type: Optional[str] = Field(None, description="cost_savings, revenue_increase, waste_reduction, etc.")
impact_value: Optional[Decimal] = None
impact_unit: Optional[str] = Field(None, description="euros, percentage, hours, units, etc.")
confidence: int = Field(..., ge=0, le=100, description="Confidence score 0-100")
metrics_json: Optional[Dict[str, Any]] = Field(default_factory=dict)
actionable: bool = True
recommendation_actions: Optional[List[Dict[str, str]]] = Field(default_factory=list)
source_service: Optional[str] = None
source_data_id: Optional[str] = None
class AIInsightCreate(AIInsightBase):
"""Schema for creating a new AI Insight."""
tenant_id: UUID
class AIInsightUpdate(BaseModel):
"""Schema for updating an AI Insight."""
status: Optional[str] = Field(None, description="new, acknowledged, in_progress, applied, dismissed, expired")
applied_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)
class AIInsightResponse(AIInsightBase):
"""Schema for AI Insight response."""
id: UUID
tenant_id: UUID
status: str
created_at: datetime
updated_at: datetime
applied_at: Optional[datetime] = None
expired_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)
class AIInsightList(BaseModel):
"""Paginated list of AI Insights."""
items: List[AIInsightResponse]
total: int
page: int
page_size: int
total_pages: int
class InsightMetrics(BaseModel):
"""Aggregate metrics for insights."""
total_insights: int
actionable_insights: int
average_confidence: float
high_priority_count: int
medium_priority_count: int
low_priority_count: int
critical_priority_count: int
by_category: Dict[str, int]
by_status: Dict[str, int]
total_potential_impact: Optional[Decimal] = None
class InsightFilters(BaseModel):
"""Filters for querying insights."""
category: Optional[str] = None
priority: Optional[str] = None
status: Optional[str] = None
actionable_only: bool = False
min_confidence: int = 0
source_service: Optional[str] = None
from_date: Optional[datetime] = None
to_date: Optional[datetime] = None