""" Movie Map Backend - FastAPI application """ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from pathlib import Path import os import logging from contextlib import asynccontextmanager from app.api import collection, watched, pins, admin, tmdb, missing_locations from app.core.config import settings from app.core.database import init_db, close_db logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): """Startup and shutdown events""" # Startup logger.info("Initializing database connection...") await init_db() yield # Shutdown logger.info("Closing database connection...") await close_db() app = FastAPI(title="Movie Map API", version="1.0.0", lifespan=lifespan) # CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["*"], # In production, restrict this allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # API routes app.include_router(collection.router, prefix="/api/collection", tags=["collection"]) app.include_router(watched.router, prefix="/api/watched", tags=["watched"]) app.include_router(pins.router, prefix="/api/pins", tags=["pins"]) app.include_router(admin.router, prefix="/admin", tags=["admin"]) app.include_router(tmdb.router, prefix="/api/tmdb", tags=["tmdb"]) app.include_router(missing_locations.router, prefix="/api/collection/missing-locations", tags=["missing-locations"]) # Serve frontend static files # Check multiple possible locations (dev, Nix build, etc.) frontend_paths = [ Path(__file__).parent.parent / "frontend" / "dist", # Dev mode Path(__file__).parent / "frontend" / "dist", # Nix build Path(__file__).parent / "frontend", # Fallback ] frontend_path = None for path in frontend_paths: if path.exists(): frontend_path = path break if frontend_path: logger.info(f"Serving frontend from {frontend_path}") app.mount("/", StaticFiles(directory=str(frontend_path), html=True), name="static") else: logger.warning("Frontend static files not found - API only mode") @app.get("/api/health") async def health(): """Health check endpoint""" return {"status": "ok"}