# ================================================================ # services/forecasting/app/schemas/forecasts.py # ================================================================ """ Forecast schemas for request/response validation """ from pydantic import BaseModel, Field, validator from datetime import datetime, date from typing import Optional, List, Dict, Any from enum import Enum class BusinessType(str, Enum): INDIVIDUAL = "individual" CENTRAL_WORKSHOP = "central_workshop" class AlertType(str, Enum): HIGH_DEMAND = "high_demand" LOW_DEMAND = "low_demand" STOCKOUT_RISK = "stockout_risk" OVERPRODUCTION = "overproduction" class ForecastRequest(BaseModel): """Request schema for generating forecasts""" tenant_id: str = Field(..., description="Tenant ID") product_name: str = Field(..., description="Product name") forecast_date: date = Field(..., description="Starting date for forecast") forecast_days: int = Field(1, ge=1, le=30, description="Number of days to forecast") location: str = Field(..., description="Location identifier") # Optional parameters - internally handled confidence_level: float = Field(0.8, ge=0.5, le=0.95, description="Confidence level") @validator('forecast_date') def validate_forecast_date(cls, v): if v < date.today(): raise ValueError("Forecast date cannot be in the past") return v class BatchForecastRequest(BaseModel): """Request schema for batch forecasting""" tenant_id: str = Field(..., description="Tenant ID") batch_name: str = Field(..., description="Batch name for tracking") products: List[str] = Field(..., description="List of product names") forecast_days: int = Field(7, ge=1, le=30, description="Number of days to forecast") class ForecastResponse(BaseModel): """Response schema for forecast results""" id: str tenant_id: str product_name: str location: str forecast_date: datetime # Predictions predicted_demand: float confidence_lower: float confidence_upper: float confidence_level: float # Model info model_id: str model_version: str algorithm: str # Context business_type: str is_holiday: bool is_weekend: bool day_of_week: int # External factors weather_temperature: Optional[float] weather_precipitation: Optional[float] weather_description: Optional[str] traffic_volume: Optional[int] # Metadata created_at: datetime processing_time_ms: Optional[int] features_used: Optional[Dict[str, Any]] class BatchForecastResponse(BaseModel): """Response schema for batch forecast requests""" id: str tenant_id: str batch_name: str status: str total_products: int completed_products: int failed_products: int # Timing requested_at: datetime completed_at: Optional[datetime] processing_time_ms: Optional[int] # Results forecasts: Optional[List[ForecastResponse]] error_message: Optional[str] class AlertResponse(BaseModel): """Response schema for forecast alerts""" id: str tenant_id: str forecast_id: str alert_type: str severity: str message: str is_active: bool created_at: datetime acknowledged_at: Optional[datetime] notification_sent: bool