import os from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse from contextlib import asynccontextmanager from app.database import engine, Base from app import models # noqa: F401 - registers models with Base.metadata from app.routers import sources, jobs, executions, backups, settings, dashboard from backup.scheduler import backup_scheduler @asynccontextmanager async def lifespan(app: FastAPI): async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) backup_scheduler.start() await backup_scheduler.sync_schedules() yield backup_scheduler.shutdown() app = FastAPI( title="Backup Tool API", version="0.1.0", lifespan=lifespan ) app.add_middleware( CORSMiddleware, allow_origins=os.environ.get("CORS_ORIGINS", "http://localhost:3000").split(","), allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(sources.router) app.include_router(jobs.router) app.include_router(executions.router) app.include_router(backups.router) app.include_router(settings.router) app.include_router(dashboard.router) @app.get("/api/health") async def health_check(): return {"status": "healthy"} # Static files for production frontend_dist = os.path.join(os.path.dirname(__file__), "../../frontend/dist") if os.path.exists(frontend_dist): app.mount("/assets", StaticFiles(directory=os.path.join(frontend_dist, "assets")), name="assets") @app.get("/{path:path}") async def serve_frontend(path: str): index_file = os.path.join(frontend_dist, "index.html") if os.path.exists(index_file): return FileResponse(index_file) return {"detail": "Frontend not built"}