Per Devin review on #166: /api/health returns 'ok' or 'unhealthy';
'healthy' is the detailed endpoint's vocabulary (app/api/health.py:180).
The pre-existing OR-tuple was dead code and inconsistent with the rest
of this PR's alignment work.
`/api/health` is the auth-free LB probe — returns `status` + `db_schema`
only. `version` lives in `/api/version` and the richer
`services.duckdb_state` lives in `/api/health/detailed` (auth-gated).
The two e2e asserts had drifted and broke nightly on main.
Two assertions in the docker-marker test files had drifted from the live API
and were only caught by the scheduled nightly CI job (run #24947963804,
2026-04-26 04:12 UTC):
- tests/test_docker_full.py::test_app_returns_html_on_root expected 200 on
GET / — but app/web/router.py:189-193 always returns 302 (to /dashboard
for authenticated users, /login otherwise) since the auth middleware
landed. Updated to use follow_redirects=False and assert 302 + location.
- tests/test_e2e_docker.py::TestDockerHealth::test_health_has_duckdb read
data["checks"]["duckdb"|"database"] — but the health payload shape is
{"services": {"duckdb_state": ..., "data": ..., "users": ...}} and has
been since app/api/health.py was last refactored. Updated to read
services["duckdb_state"]["status"] — same pattern used by the (passing)
tests/test_api.py::TestHealth suite, so the two test layers now agree.
Both fixes are test-only; no application behavior changes.