Initial commit - production deployment

This commit is contained in:
2026-01-21 17:17:16 +01:00
commit c23d00dd92
2289 changed files with 638440 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
# ================================================================
# services/production/app/core/__init__.py
# ================================================================
"""
Core configuration and database setup
"""

View File

@@ -0,0 +1,101 @@
# ================================================================
# PRODUCTION SERVICE CONFIGURATION
# services/production/app/core/config.py
# ================================================================
"""
Production service configuration
Production planning and batch management
"""
from shared.config.base import BaseServiceSettings
import os
class ProductionSettings(BaseServiceSettings):
"""Production service specific settings"""
# Service Identity
APP_NAME: str = "Production Service"
SERVICE_NAME: str = "production-service"
VERSION: str = "1.0.0"
DESCRIPTION: str = "Production planning and batch management"
# Database configuration (secure approach - build from components)
@property
def DATABASE_URL(self) -> str:
"""Build database URL from secure components"""
# Try complete URL first (for backward compatibility)
complete_url = os.getenv("PRODUCTION_DATABASE_URL")
if complete_url:
return complete_url
# Build from components (secure approach)
user = os.getenv("PRODUCTION_DB_USER", "production_user")
password = os.getenv("PRODUCTION_DB_PASSWORD", "production_pass123")
host = os.getenv("PRODUCTION_DB_HOST", "localhost")
port = os.getenv("PRODUCTION_DB_PORT", "5432")
name = os.getenv("PRODUCTION_DB_NAME", "production_db")
return f"postgresql+asyncpg://{user}:{password}@{host}:{port}/{name}"
# Redis Database (for production queues and caching)
REDIS_DB: int = 3
# Service URLs for communication
GATEWAY_URL: str = os.getenv("GATEWAY_URL", "http://gateway-service:8000")
ORDERS_SERVICE_URL: str = os.getenv("ORDERS_SERVICE_URL", "http://orders-service:8000")
INVENTORY_SERVICE_URL: str = os.getenv("INVENTORY_SERVICE_URL", "http://inventory-service:8000")
RECIPES_SERVICE_URL: str = os.getenv("RECIPES_SERVICE_URL", "http://recipes-service:8000")
SALES_SERVICE_URL: str = os.getenv("SALES_SERVICE_URL", "http://sales-service:8000")
FORECASTING_SERVICE_URL: str = os.getenv("FORECASTING_SERVICE_URL", "http://forecasting-service:8000")
# Production Planning Configuration
PLANNING_HORIZON_DAYS: int = int(os.getenv("PLANNING_HORIZON_DAYS", "7"))
MINIMUM_BATCH_SIZE: float = float(os.getenv("MINIMUM_BATCH_SIZE", "1.0"))
MAXIMUM_BATCH_SIZE: float = float(os.getenv("MAXIMUM_BATCH_SIZE", "100.0"))
PRODUCTION_BUFFER_PERCENTAGE: float = float(os.getenv("PRODUCTION_BUFFER_PERCENTAGE", "10.0"))
# Capacity Management
DEFAULT_WORKING_HOURS_PER_DAY: int = int(os.getenv("DEFAULT_WORKING_HOURS_PER_DAY", "12"))
MAX_OVERTIME_HOURS: int = int(os.getenv("MAX_OVERTIME_HOURS", "4"))
CAPACITY_UTILIZATION_TARGET: float = float(os.getenv("CAPACITY_UTILIZATION_TARGET", "0.85"))
CAPACITY_WARNING_THRESHOLD: float = float(os.getenv("CAPACITY_WARNING_THRESHOLD", "0.95"))
# Quality Control
QUALITY_CHECK_ENABLED: bool = os.getenv("QUALITY_CHECK_ENABLED", "true").lower() == "true"
MINIMUM_YIELD_PERCENTAGE: float = float(os.getenv("MINIMUM_YIELD_PERCENTAGE", "85.0"))
QUALITY_SCORE_THRESHOLD: float = float(os.getenv("QUALITY_SCORE_THRESHOLD", "8.0"))
# Batch Management
BATCH_AUTO_NUMBERING: bool = os.getenv("BATCH_AUTO_NUMBERING", "true").lower() == "true"
BATCH_NUMBER_PREFIX: str = os.getenv("BATCH_NUMBER_PREFIX", "PROD")
BATCH_TRACKING_ENABLED: bool = os.getenv("BATCH_TRACKING_ENABLED", "true").lower() == "true"
# Production Scheduling
SCHEDULE_OPTIMIZATION_ENABLED: bool = os.getenv("SCHEDULE_OPTIMIZATION_ENABLED", "true").lower() == "true"
PREP_TIME_BUFFER_MINUTES: int = int(os.getenv("PREP_TIME_BUFFER_MINUTES", "30"))
CLEANUP_TIME_BUFFER_MINUTES: int = int(os.getenv("CLEANUP_TIME_BUFFER_MINUTES", "15"))
# Business Rules for Bakery Operations
BUSINESS_HOUR_START: int = 6 # 6 AM - early start for fresh bread
BUSINESS_HOUR_END: int = 22 # 10 PM
PEAK_PRODUCTION_HOURS_START: int = 4 # 4 AM
PEAK_PRODUCTION_HOURS_END: int = 10 # 10 AM
# Weekend and Holiday Adjustments
WEEKEND_PRODUCTION_FACTOR: float = float(os.getenv("WEEKEND_PRODUCTION_FACTOR", "0.7"))
HOLIDAY_PRODUCTION_FACTOR: float = float(os.getenv("HOLIDAY_PRODUCTION_FACTOR", "0.3"))
SPECIAL_EVENT_PRODUCTION_FACTOR: float = float(os.getenv("SPECIAL_EVENT_PRODUCTION_FACTOR", "1.5"))
# Cost Management
COST_TRACKING_ENABLED: bool = os.getenv("COST_TRACKING_ENABLED", "true").lower() == "true"
LABOR_COST_PER_HOUR: float = float(os.getenv("LABOR_COST_PER_HOUR", "15.0"))
OVERHEAD_COST_PERCENTAGE: float = float(os.getenv("OVERHEAD_COST_PERCENTAGE", "20.0"))
# Integration Settings
INVENTORY_INTEGRATION_ENABLED: bool = os.getenv("INVENTORY_INTEGRATION_ENABLED", "true").lower() == "true"
AUTOMATIC_INGREDIENT_RESERVATION: bool = os.getenv("AUTOMATIC_INGREDIENT_RESERVATION", "true").lower() == "true"
REAL_TIME_INVENTORY_UPDATES: bool = os.getenv("REAL_TIME_INVENTORY_UPDATES", "true").lower() == "true"
settings = ProductionSettings()

View File

@@ -0,0 +1,51 @@
# ================================================================
# services/production/app/core/database.py
# ================================================================
"""
Database configuration for production service
"""
import structlog
from shared.database import DatabaseManager, create_database_manager
from shared.database.base import Base
from shared.database.transactions import TransactionManager
from app.core.config import settings
logger = structlog.get_logger()
# Create database manager following shared pattern
database_manager = create_database_manager(
settings.DATABASE_URL,
settings.SERVICE_NAME
)
# Transaction manager for the service
transaction_manager = TransactionManager(database_manager)
# Use exactly the same pattern as training/forecasting services
async def get_db():
"""Database dependency"""
async with database_manager.get_session() as db:
yield db
def get_db_transaction():
"""Get database transaction manager"""
return database_manager.get_transaction()
async def get_db_health():
"""Check database health"""
try:
health_status = await database_manager.health_check()
return health_status.get("healthy", False)
except Exception as e:
logger.error(f"Database health check failed: {e}")
return False
async def init_database():
"""Initialize database tables"""
try:
await database_manager.create_tables()
logger.info("Production service database initialized successfully")
except Exception as e:
logger.error(f"Failed to initialize database: {e}")
raise