""" Distribution Service Main Application """ from fastapi import FastAPI from sqlalchemy import text from app.core.config import settings from app.core.database import database_manager from app.api.routes import router as distribution_router from app.api.shipments import router as shipments_router # from app.api.internal_demo import router as internal_demo_router # REMOVED: Replaced by script-based seed data loading from shared.service_base import StandardFastAPIService class DistributionService(StandardFastAPIService): """Distribution Service with standardized setup""" async def on_startup(self, app): """Custom startup logic including migration verification""" await self.verify_migrations() await super().on_startup(app) async def verify_migrations(self): """Verify database schema matches the latest migrations.""" try: async with self.database_manager.get_session() as session: # Check if alembic_version table exists result = await session.execute(text(""" SELECT EXISTS ( SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'alembic_version' ) """)) table_exists = result.scalar() if table_exists: # If table exists, check the version result = await session.execute(text("SELECT version_num FROM alembic_version")) version = result.scalar() self.logger.info(f"Migration verification successful: {version}") else: # If table doesn't exist, migrations might not have run yet # This is OK - the migration job should create it self.logger.warning("alembic_version table does not exist yet - migrations may not have run") except Exception as e: self.logger.warning(f"Migration verification failed (this may be expected during initial setup): {e}") def __init__(self): # Define expected database tables for health checks distribution_expected_tables = [ 'delivery_routes', 'shipments', 'route_assignments', 'delivery_points', 'vehicle_assignments', 'delivery_schedule', 'shipment_tracking', 'audit_logs' ] # Define custom metrics for distribution service distribution_custom_metrics = { "routes_generated_total": { "type": "counter", "description": "Total delivery routes generated" }, "shipments_processed_total": { "type": "counter", "description": "Total shipments processed" }, "route_optimization_time_seconds": { "type": "histogram", "description": "Time to optimize delivery routes" }, "shipment_processing_time_seconds": { "type": "histogram", "description": "Time to process shipment request" }, "delivery_completion_rate": { "type": "counter", "description": "Delivery completion rate by status", "labels": ["status"] } } super().__init__( service_name="distribution-service", app_name="Distribution Service", description="Distribution and logistics service for enterprise tier bakery management", version="1.0.0", log_level=settings.LOG_LEVEL, api_prefix="", # Empty because RouteBuilder already includes /api/v1 database_manager=database_manager, expected_tables=distribution_expected_tables, custom_metrics=distribution_custom_metrics ) async def on_shutdown(self, app: FastAPI): """Custom shutdown logic for distribution service""" self.logger.info("Distribution Service shutdown complete") def get_service_features(self): """Return distribution-specific features""" return [ "delivery_route_optimization", "shipment_tracking", "vehicle_assignment", "distribution_planning", "delivery_point_management" ] # Create service instance service = DistributionService() # Create FastAPI app with standardized setup app = service.create_app( docs_url="/docs", redoc_url="/redoc" ) # Setup standard endpoints service.setup_standard_endpoints() # Include routers with specific configurations # Note: Routes now use RouteBuilder which includes full paths, so no prefix needed service.add_router(distribution_router, tags=["distribution"]) service.add_router(shipments_router, tags=["shipments"]) # service.add_router(internal_demo_router, tags=["internal-demo"]) # REMOVED: Replaced by script-based seed data loading