Clearview — Sign in
-
+
@@ -17,12 +17,12 @@
-
+
+
"
+ )
+ html = raw.replace("", head, 1)
+ # no-store on the HTML shell so a browser never serves a stale page after a
+ # redeploy or a move behind/along the proxy.
+ return HTMLResponse(html, headers={"Cache-Control": "no-store"})
+
+
+def _prefix(request: Request) -> str:
+ return request.headers.get("x-forwarded-prefix", "").rstrip("/")
+
+
@app.get("/")
-def index() -> FileResponse:
- return FileResponse(SITE_DIR / "index.html")
+def index(request: Request) -> HTMLResponse:
+ return _render_page("index.html", _prefix(request))
+
+
+@app.get("/login.html")
+def login_page(request: Request) -> HTMLResponse:
+ return _render_page("login.html", _prefix(request))
+
+
+@app.get("/setup.html")
+def setup_page(request: Request) -> HTMLResponse:
+ return _render_page("setup.html", _prefix(request))
app.mount("/", StaticFiles(directory=SITE_DIR, html=True), name="site")
diff --git a/containers/clearview/src/clearview_app/version.py b/containers/clearview/src/clearview_app/version.py
index 5e296ba..201ae44 100644
--- a/containers/clearview/src/clearview_app/version.py
+++ b/containers/clearview/src/clearview_app/version.py
@@ -7,7 +7,7 @@ history, so operators can see exactly which image build is running.
from __future__ import annotations
VERSION = "v0.2.0"
-BUILD = 0
+BUILD = 1
def display_version() -> str:
diff --git a/docs/changelog-develop.md b/docs/changelog-develop.md
index 7040b88..404dfb1 100644
--- a/docs/changelog-develop.md
+++ b/docs/changelog-develop.md
@@ -2,6 +2,20 @@
This file documents changes on the develop branch of this project.
+## 2026-06-19 — Path-prefix routing support (run behind the landing proxy)
+
+### Added
+- Clearview can now be served under a path prefix (e.g. `http://10.19.3.32:8210/clearview/`) by the landing reverse proxy, which strips the prefix and passes it in `X-Forwarded-Prefix` — part of the shared path-prefix routing effort. With no header the app behaves exactly as on direct access.
+- `main.py` now serves the three HTML pages (`index.html`, `login.html`, `setup.html`) through `_render_page`, which injects `` plus a small **fetch shim** that prefixes same-origin absolute API calls (`fetch('/api/...')`). This is a vanilla-JS app (no build step) with ~35 absolute `/api` calls across `app.js`/`auth.js`/inline scripts, so shimming `fetch` in one place is far less invasive than rewriting each call. `index.html`/`login.html`/`setup.html` got explicit routes (registered before the `StaticFiles` mount) and the pages are now sent with `Cache-Control: no-store` so a stale shell is never served after a redeploy.
+
+### Changed
+- Made the few **non-fetch** URLs prefix-aware in the site files, since the fetch shim only covers `fetch()`:
+ - `login.html`/`setup.html`: stylesheet/`auth.js` references made relative (`/styles.css` → `styles.css`, `/auth.js` → `auth.js`) so they resolve under the prefix via the document URL.
+ - Page navigations (`window.location.replace('/login.html' | '/setup.html' | '/')` in `app.js`, `login.html`, `setup.html`) now prepend `window.__BASE_PATH__`.
+ - The scan-job export download (`window.location.href = '/api/scan-jobs/.../export'`, a browser navigation, not `fetch`) prepends `window.__BASE_PATH__`.
+- `index.html` needed no changes — its asset refs were already relative and it uses hash routing. `auth.js` needed none — its `fetch()` calls go through the shim.
+- Verified: `main.py` compiles, the injection produces a single `window.__BASE_PATH__` assignment + shim per page (empty-prefix variant is a no-op), and no breaking absolute asset/nav refs remain in the site.
+
## 2026-05-28 — Released as v0.2.0
## 2026-05-28 — Release: drop unused `version.txt`