diff --git a/app/frontend_static.py b/app/frontend_static.py index ab53446..5ba4544 100644 --- a/app/frontend_static.py +++ b/app/frontend_static.py @@ -120,3 +120,16 @@ def register_frontend_static_routes(app: FastAPI, frontend_dir: Path) -> bool: logger.info("Serving frontend from %s", frontend_dir) return True + + +def register_frontend_missing_fallback(app: FastAPI) -> None: + """Register a fallback route that tells the user to build the frontend.""" + + @app.get("/", include_in_schema=False) + async def frontend_not_built(): + return JSONResponse( + status_code=404, + content={ + "detail": "Frontend not built. Run: cd frontend && npm install && npm run build" + }, + ) diff --git a/app/main.py b/app/main.py index 0504d39..59914d8 100644 --- a/app/main.py +++ b/app/main.py @@ -8,7 +8,7 @@ from fastapi.responses import JSONResponse from app.config import setup_logging from app.database import db -from app.frontend_static import register_frontend_static_routes +from app.frontend_static import register_frontend_missing_fallback, register_frontend_static_routes from app.radio import RadioDisconnectedError, radio_manager from app.radio_sync import ( stop_message_polling, @@ -109,4 +109,5 @@ app.include_router(ws.router, prefix="/api") # Serve frontend static files in production FRONTEND_DIR = Path(__file__).parent.parent / "frontend" / "dist" -register_frontend_static_routes(app, FRONTEND_DIR) +if not register_frontend_static_routes(app, FRONTEND_DIR): + register_frontend_missing_fallback(app) diff --git a/tests/test_frontend_static.py b/tests/test_frontend_static.py index 3043f34..42230ac 100644 --- a/tests/test_frontend_static.py +++ b/tests/test_frontend_static.py @@ -3,7 +3,7 @@ import logging from fastapi import FastAPI from fastapi.testclient import TestClient -from app.frontend_static import register_frontend_static_routes +from app.frontend_static import register_frontend_missing_fallback, register_frontend_static_routes def test_missing_dist_logs_error_and_keeps_app_running(tmp_path, caplog): @@ -16,9 +16,14 @@ def test_missing_dist_logs_error_and_keeps_app_running(tmp_path, caplog): assert registered is False assert "Frontend build directory not found" in caplog.text + # Register the fallback like main.py does + register_frontend_missing_fallback(app) + with TestClient(app) as client: - # App still runs; no frontend route is registered. - assert client.get("/").status_code == 404 + resp = client.get("/") + assert resp.status_code == 404 + assert "npm install" in resp.json()["detail"] + assert "npm run build" in resp.json()["detail"] def test_missing_index_logs_error_and_skips_frontend_routes(tmp_path, caplog):