Files
bakery-ia/services/forecasting/app/models/forecasts.py

91 lines
3.4 KiB
Python

# ================================================================
# services/forecasting/app/models/forecasts.py
# ================================================================
"""
Forecast models for the forecasting service
"""
from sqlalchemy import Column, String, Integer, Float, DateTime, Boolean, Text, JSON
from sqlalchemy.dialects.postgresql import UUID
from datetime import datetime, timezone
import uuid
from shared.database.base import Base
class Forecast(Base):
"""Forecast model for storing prediction results"""
__tablename__ = "forecasts"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
inventory_product_id = Column(UUID(as_uuid=True), nullable=False, index=True) # Reference to inventory service
product_name = Column(String(255), nullable=True, index=True) # Product name (optional - use inventory_product_id as reference)
location = Column(String(255), nullable=False, index=True)
# Forecast period
forecast_date = Column(DateTime(timezone=True), nullable=False, index=True)
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
# Prediction results
predicted_demand = Column(Float, nullable=False)
confidence_lower = Column(Float, nullable=False)
confidence_upper = Column(Float, nullable=False)
confidence_level = Column(Float, default=0.8)
# Model information
model_id = Column(String(255), nullable=False)
model_version = Column(String(50), nullable=False)
algorithm = Column(String(50), default="prophet")
# Business context
business_type = Column(String(50), default="individual") # individual or central_workshop
day_of_week = Column(Integer, nullable=False)
is_holiday = Column(Boolean, default=False)
is_weekend = Column(Boolean, default=False)
# External factors
weather_temperature = Column(Float)
weather_precipitation = Column(Float)
weather_description = Column(String(100))
traffic_volume = Column(Integer)
# Metadata
processing_time_ms = Column(Integer)
features_used = Column(JSON)
def __repr__(self):
return f"<Forecast(id={self.id}, inventory_product_id={self.inventory_product_id}, date={self.forecast_date})>"
class PredictionBatch(Base):
"""Batch prediction requests"""
__tablename__ = "prediction_batches"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
# Batch information
batch_name = Column(String(255), nullable=False)
requested_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
completed_at = Column(DateTime(timezone=True))
# Status
status = Column(String(50), default="pending") # pending, processing, completed, failed
total_products = Column(Integer, default=0)
completed_products = Column(Integer, default=0)
failed_products = Column(Integer, default=0)
# Configuration
forecast_days = Column(Integer, default=7)
business_type = Column(String(50), default="individual")
# Results
error_message = Column(Text)
processing_time_ms = Column(Integer)
cancelled_by = Column(String, nullable=True)
def __repr__(self):
return f"<PredictionBatch(id={self.id}, status={self.status})>"