from pathlib import Path from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from app.api import api_router from app.config import get_settings from app.db import SessionLocal, init_db from app.services.user_service import ensure_default_admin FRONTEND_DIST = Path(__file__).resolve().parent.parent / "dist" SSL_DIR = Path(__file__).resolve().parent.parent.parent / "ssl" SSL_CERT_FILE = SSL_DIR / "finai.ctc-zc.com.pem" SSL_KEY_FILE = SSL_DIR / "finai.ctc-zc.com.key" def create_app() -> FastAPI: settings = get_settings() app = FastAPI(title=settings.app_name) app.add_middleware( CORSMiddleware, allow_origins=settings.cors_origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(api_router) @app.on_event("startup") def startup() -> None: init_db() db = SessionLocal() try: ensure_default_admin(db) db.commit() finally: db.close() @app.get("/health") def health() -> dict: return {"status": "ok", "app": settings.app_name} _mount_frontend(app) return app def _mount_frontend(app: FastAPI) -> None: if not FRONTEND_DIST.is_dir(): return assets_dir = FRONTEND_DIST / "assets" if assets_dir.is_dir(): app.mount("/assets", StaticFiles(directory=assets_dir), name="assets") index_file = FRONTEND_DIST / "index.html" @app.get("/", include_in_schema=False) def _spa_root() -> FileResponse: return FileResponse(index_file) @app.get("/{full_path:path}", include_in_schema=False) def _spa_fallback(full_path: str) -> FileResponse: if full_path.startswith(("api/", "assets/", "health")): raise HTTPException(status_code=404) candidate = FRONTEND_DIST / full_path if candidate.is_file(): return FileResponse(candidate) return FileResponse(index_file) app = create_app() if __name__ == "__main__": import uvicorn ssl_kwargs: dict = {} if SSL_CERT_FILE.is_file() and SSL_KEY_FILE.is_file(): ssl_kwargs = { "ssl_certfile": str(SSL_CERT_FILE), "ssl_keyfile": str(SSL_KEY_FILE), } uvicorn.run( "app.main:app", host="0.0.0.0", port=8775, reload=True, **ssl_kwargs, )