Initial commit - production deployment
This commit is contained in:
6
services/production/app/core/__init__.py
Normal file
6
services/production/app/core/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# ================================================================
|
||||
# services/production/app/core/__init__.py
|
||||
# ================================================================
|
||||
"""
|
||||
Core configuration and database setup
|
||||
"""
|
||||
101
services/production/app/core/config.py
Normal file
101
services/production/app/core/config.py
Normal 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()
|
||||
51
services/production/app/core/database.py
Normal file
51
services/production/app/core/database.py
Normal 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
|
||||
Reference in New Issue
Block a user