Skip to content

fix(insights): keep the overview reads open with the assistant switched off - #982

Merged
MBombeck merged 2 commits into
mainfrom
fix/insights-without-assistant
Sep 16, 2026
Merged

MBombeck merged 2 commits into
mainfrom
fix/insights-without-assistant

Conversation

@MBombeck

@MBombeck MBombeck commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Summary

With the assistant switched off on the server, the Insights overview did not load at all. Its main read and several tiles were gated on assistant surfaces even though none of them calls a provider, so the master flag turned every one of them into a 403 and the page showed an error instead of the overview. These reads now gate on the insights module only.

The report also noticed that switching the mood module off hid Mood from the tab strip but not from the overview. The trends row respects the module now too.

Refs #975 (the issue stays open until the reporter confirms on a released build)

Type of change

  • Bug fix (non-breaking change that fixes an issue)

Details

What was gated. requireAssistantSurface() guarded six handlers that carry no assistant prose:

  • GET /api/insights/comprehensive (Coach surface), the overview's main query
  • GET /api/insights/derived and GET /api/insights/derived/batch (status-card surface), the derived tiles
  • GET /api/insights/ecg, POST /api/insights/ecg and GET /api/insights/ecg/{id} (status-card surface), the ECG list, the live Apple Watch ingest and the strip
  • GET /api/insights/rhythm-events (status-card surface), the device-flagged events

The route-gate inventory already described most of them as pure compute or a pure DB read. The admin copy calls the master flag the switch for model-driven surfaces, so an operator who turns it off expects the prose to go, not the overview. The ingest was the sharpest case: with the assistant off, the server refused a watch recording.

Module gate. The five other handlers already call requireModuleEnabled(user.id, "insights"). comprehensive did not: the module route-gate inventory counted its Coach gate as the delegated gate, so dropping that left the route tied to no module at all. It now calls the same insights module gate. Every web caller of comprehensive lives under /insights, so hiding Insights still hides it.

What keeps its gate. The routes that serve generated assessments (metric-status, weight-status and the other *-status routes), narrative, generate, coach-read and the chat routes are unchanged. cards stays on the status-card surface because it feeds the same per-metric cards on iOS.

Contract. None of the six documented a 403 for this case. Four descriptions still said the route was gated on the status-card surface; they now say there is no assistant-surface gate, and docs/api/openapi.yaml is regenerated. No schema changes. For the iOS client this removes a refusal when the assistant is off. One case moves the other way: with the insights module switched off, comprehensive now answers 403 module.disabled like the other Insights reads, where it used to answer 200.

Mood on the overview. The tab strip already hides the Mood pill when the mood module is off (SUB_PAGE_MODULE). The trends row did not: it charted mood from a briefing finding and in its fallback triple. selectTrendCharts takes hiddenMetrics, and the overview passes mood when modules.mood is false. The catalog page checks no module besides nutrients, for sleep and glucose as much as for mood, so it is left for a separate change.

Test plan

  • comprehensive/__tests__/route.test.ts: new case, the route answers 200 with the master flag off. Mutation-checked: with the old gate restored, the case fails with a 403.
  • coach-route-gate-inventory.test.ts: the six files sit on NOT_COACH_OWNED_ROUTES
  • module-route-gate-inventory.test.ts: comprehensive is module-gated again. The first full run caught the missing gate after the Coach gate came out.
  • trend-chart-select.test.ts: 3 new cases (mood left out of the fallback, a hidden metric skipped on the briefing path, mood kept when nothing is hidden)
  • Integration against Postgres 16: insights-comprehensive-cache, ecg-ingest-roundtrip and health-score-configured-flag, 20 tests
  • Full suite green: 2038 files, 23,808 tests passed, 16 skipped
  • pnpm typecheck, pnpm lint, pnpm format:check, pnpm knip, pnpm check-env --file .env.production.example, pnpm openapi:check and pnpm build pass

…ed off

With the assistant switched off on the server, the Insights overview did
not load. Its main read, /api/insights/comprehensive, was gated on the
Coach surface, and the derived tiles, the ECG list, strip and live ingest,
and the rhythm events were gated on the status-card surface. The master
flag forces every surface off, so all of them answered 403 and the page
replaced the whole overview with an error.

None of these handlers calls a provider or returns assistant prose. They
now gate on the insights module only, like health-status, labs-changes and
patterns already do. comprehensive had no module gate of its own, only the
Coach gate, so it gains the insights module gate the other five already
call. Routes that serve generated text keep their gate.

The route-gate inventory moves the six files onto the not-Coach-owned
list, four OpenAPI descriptions drop the gate they no longer have, and a
comprehensive test pins a 200 with the master flag off.

Refs #975
The tab strip already hides the Mood pill when the mood module is off, but
the trends row still charted mood, both from a briefing finding and in its
blood pressure / weight / mood fallback. selectTrendCharts now takes the
metrics to leave out, and the overview passes mood when the module is off.

Refs #975
@MBombeck
MBombeck force-pushed the fix/insights-without-assistant branch from 0b90c6c to 2b51250 Compare September 16, 2026 11:01
@MBombeck
MBombeck merged commit c79cd3a into main Sep 16, 2026
25 checks passed
@MBombeck
MBombeck deleted the fix/insights-without-assistant branch September 16, 2026 11:40
@MBombeck MBombeck mentioned this pull request Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant