Create new services: inventory, recipes, suppliers

This commit is contained in:
Urtzi Alfaro
2025-08-13 17:39:35 +02:00
parent fbe7470ad9
commit 16b8a9d50c
151 changed files with 35799 additions and 857 deletions

View File

@@ -0,0 +1 @@
# services/recipes/app/core/__init__.py

View File

@@ -0,0 +1,82 @@
# services/recipes/app/core/config.py
"""
Configuration management for Recipe Service
"""
import os
from typing import Optional
class Settings:
"""Recipe service configuration settings"""
# Service identification
SERVICE_NAME: str = "recipes"
SERVICE_VERSION: str = "1.0.0"
# API settings
API_V1_PREFIX: str = "/api/v1"
# Database
DATABASE_URL: str = os.getenv(
"RECIPES_DATABASE_URL",
"postgresql://recipes_user:recipes_pass@localhost:5432/recipes_db"
)
# Redis (if needed for caching)
REDIS_URL: str = os.getenv("REDIS_URL", "redis://localhost:6379/0")
# External service URLs
INVENTORY_SERVICE_URL: str = os.getenv(
"INVENTORY_SERVICE_URL",
"http://inventory:8000"
)
SALES_SERVICE_URL: str = os.getenv(
"SALES_SERVICE_URL",
"http://sales:8000"
)
# Authentication
SECRET_KEY: str = os.getenv("SECRET_KEY", "your-secret-key-here")
ACCESS_TOKEN_EXPIRE_MINUTES: int = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "30"))
# Logging
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
# Production configuration
ENVIRONMENT: str = os.getenv("ENVIRONMENT", "development")
DEBUG: bool = os.getenv("DEBUG", "False").lower() == "true"
# CORS settings
ALLOWED_ORIGINS: list = os.getenv("ALLOWED_ORIGINS", "http://localhost:3000").split(",")
# Recipe-specific settings
MAX_RECIPE_INGREDIENTS: int = int(os.getenv("MAX_RECIPE_INGREDIENTS", "50"))
MAX_BATCH_SIZE_MULTIPLIER: float = float(os.getenv("MAX_BATCH_SIZE_MULTIPLIER", "10.0"))
DEFAULT_RECIPE_VERSION: str = "1.0"
# Production settings
MAX_PRODUCTION_BATCHES_PER_DAY: int = int(os.getenv("MAX_PRODUCTION_BATCHES_PER_DAY", "100"))
PRODUCTION_SCHEDULE_DAYS_AHEAD: int = int(os.getenv("PRODUCTION_SCHEDULE_DAYS_AHEAD", "7"))
# Cost calculation settings
OVERHEAD_PERCENTAGE: float = float(os.getenv("OVERHEAD_PERCENTAGE", "15.0")) # Default 15% overhead
LABOR_COST_PER_HOUR: float = float(os.getenv("LABOR_COST_PER_HOUR", "25.0")) # Default €25/hour
# Quality control
MIN_QUALITY_SCORE: float = float(os.getenv("MIN_QUALITY_SCORE", "6.0")) # Minimum acceptable quality score
MAX_DEFECT_RATE: float = float(os.getenv("MAX_DEFECT_RATE", "5.0")) # Maximum 5% defect rate
# Messaging/Events (if using message queues)
RABBITMQ_URL: Optional[str] = os.getenv("RABBITMQ_URL")
KAFKA_BOOTSTRAP_SERVERS: Optional[str] = os.getenv("KAFKA_BOOTSTRAP_SERVERS")
# Health check settings
HEALTH_CHECK_TIMEOUT: int = int(os.getenv("HEALTH_CHECK_TIMEOUT", "30"))
class Config:
case_sensitive = True
# Global settings instance
settings = Settings()

View File

@@ -0,0 +1,77 @@
# services/recipes/app/core/database.py
"""
Database configuration and session management for Recipe Service
"""
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session
from sqlalchemy.pool import StaticPool
from contextlib import contextmanager
from typing import Generator
from .config import settings
# Create database engine
engine = create_engine(
settings.DATABASE_URL,
poolclass=StaticPool,
pool_pre_ping=True,
pool_recycle=300,
echo=settings.DEBUG,
)
# Create session factory
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def get_db() -> Generator[Session, None, None]:
"""
Dependency to get database session
"""
db = SessionLocal()
try:
yield db
finally:
db.close()
@contextmanager
def get_db_context() -> Generator[Session, None, None]:
"""
Context manager for database session
"""
db = SessionLocal()
try:
yield db
db.commit()
except Exception:
db.rollback()
raise
finally:
db.close()
class DatabaseManager:
"""Database management utilities"""
@staticmethod
def create_all_tables():
"""Create all database tables"""
from shared.database.base import Base
Base.metadata.create_all(bind=engine)
@staticmethod
def drop_all_tables():
"""Drop all database tables (for testing)"""
from shared.database.base import Base
Base.metadata.drop_all(bind=engine)
@staticmethod
def get_session() -> Session:
"""Get a new database session"""
return SessionLocal()
# Database manager instance
db_manager = DatabaseManager()