fix(server): stats endpoint 500s in sync-only mode (AI disabled) - #88
Merged
Conversation
…I is disabled A sync-only deployment (`QUIRE_SERVER_AI_ENABLED=false`) never applies the `ai` alembic branch, so `book_insights` / `book_themes` do not exist. The library router mounts on `progress_enabled`, so `GET /library/v1/stats` is still reachable — and it unconditionally joined those AI-only tables, producing `relation "book_themes" does not exist` and a blanket HTTP 500. Operators had to boot once with AI enabled (to apply the migration) before sync-only mode would work. Gate the whole `top_themes` computation on `settings.ai_enabled`. Skipping only the final `BookTheme` join is not enough — the pick-one CTE still references the absent `book_insights` — so the entire block is guarded. Themes are an AI-only feature, so `top_themes=[]` is the correct sync-only answer; the other stats (counts, top authors) are unaffected. Adds a regression test that provisions a fresh Postgres migrated with `ai_enabled=False` and asserts the endpoint returns 200 with `top_themes=[]`. The existing suite never caught this because conftest always migrates with `ai_enabled=True`. Closes #87
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #87. A sync-only server (
QUIRE_SERVER_AI_ENABLED=false) started from a fresh database returns HTTP 500 onGET /library/v1/stats(and the endpoint stays broken) because the query joins tables that only exist when AI is enabled.Root cause
progress_enabled(defaulttrue), not onai_enabled— so/library/v1/statsis live in sync-only mode.get_statsunconditionally computestop_themes, which joinsbook_insights(pick-one CTE) andbook_themes.aialembic branch, which the deploy migrator applies only whenQUIRE_SERVER_AI_ENABLED=true.relation "book_themes" does not exist→ blanket 500. Booting once with AI enabled applies the migration and "fixes" it permanently — exactly the workaround the reporter found.Fix
Gate the entire
top_themesblock onsettings.ai_enabledand returntop_themes=[]when AI is off (reporter's option B). Gating only the finalBookThemejoin is insufficient — the pick-one CTE still references the absentbook_insights. Themes are an AI-only feature, so an empty list is the correct sync-only answer; all other stats (counts, top authors) are unchanged. When AI is enabled, behavior is identical to before (only indentation moved).Test
New
tests/integration/test_stats_sync_only.pyprovisions a fresh Postgres migrated withai_enabled=False(sobook_insights/book_themesgenuinely don't exist), builds a sync-only app, and asserts/library/v1/statsreturns 200 withtop_themes=[]while the non-AI stats still compute. The test also asserts the AI tables are absent so it can't silently degrade.The existing suite never caught this because
conftest.pyalways migrates withai_enabled=True.Verification
ruff check+ruff format --checkclean.