Skip to content

Wire Therapy Compass into the app as a routed mode + universal search#825

Merged
BigSimmo merged 12 commits into
mainfrom
claude/therapy-pages-navigation-tmapa5
Jul 18, 2026
Merged

Wire Therapy Compass into the app as a routed mode + universal search#825
BigSimmo merged 12 commits into
mainfrom
claude/therapy-pages-navigation-tmapa5

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Promote Therapy Compass from a single /therapy-compass route (client-side screen switching) to a first-class, URL-driven mode with real pages, and expose its 211-therapy library to cross-entity universal search.
  • Routing: the eight in-tool screens become real routes — /therapy-compass (home), /search, /recommend, /compare, /pathways, /review, /[slug] (detail), /[slug]/brief, /[slug]/sheet. Detail/brief/sheet are server components with generateStaticParams + generateMetadata + notFound over all 211 therapies. Screen UI is unchanged — TcProvider now derives the active screen from the pathname and the selected therapy from the [slug] param, so nav + selection drive the URL (back/forward, deep links, new tabs). Provider + nav mount once in a layout-level workspace so the dataset and interaction state are shared across the route family (including main's conservative-failure data-error + Retry state).
  • Universal search: new therapies domain backed by a server catalogue (src/lib/therapies.ts + a trimmed src/data/therapies-index.json projection generated by scripts/build-therapies-index.mjs). Wires the adapter, dispatch table, view-all href, mode↔domain mapping, and command-surface heading. Hits deep-link to /therapy-compass/[slug] and surface review status inline.
  • Visibility: removed the devOnly gate so the mode appears in the production sidebar, MODE dropdown, and universal search (per explicit maintainer direction). Unreviewed records keep their "Needs source review" badge at the point of use.
  • Retires the superseded /mockups/therapy-compass prototype, regenerates docs/site-map.md, and updates the app-modes / universal-search / provider tests. Merged latest main.

Verification

  • npm run verify:pr-local

Ran the constituent offline checks (full gate not run in-sandbox):

  • npm run typecheck (clean, post-merge)

  • npm run lint (clean on touched files)

  • npm run test — 2761 passed / 2 skipped; 1 pre-existing, unrelated failure (pdf-extraction-budget.test.ts, a Python child-process deadline test; the Python OCR stack is unavailable in-sandbox; it touches no file in this change and fails identically on a clean tree)

  • npm run sitemap:check (regenerated + current)

  • npm run build (all nine /therapy-compass/* routes present; client-bundle secret-surface check passed)

  • ✅ Manual browser pass on the running app (home sidebar entry, /search with ?q seeding, /[slug] detail with server-generated title)

  • npm run verify:ui — UI verification not run: the Chromium/Playwright gate wasn't run in-sandbox (missing @axe-core/playwright). Route generation confirmed via the production build + a manual Playwright browser pass; the URL-driven provider is covered by therapy-compass-provider-seed.dom.test.tsx.

For search/ranking: the new therapies domain is an isolated local-catalogue scorer; it does not alter document retrieval, ranking, selection, chunking, or the answer contract, so eval:retrieval:quality (36/36) is unaffected. No RAG-pipeline code changed.

Risk and rollout

  • Risk: medium — a routing refactor plus a new, isolated local-catalogue search domain; no RAG/document-retrieval/Supabase code changed. The material risk is governance rather than code: flipping devOnly surfaces the therapy library (205/211 records still needs_review, 12 incomplete pathways) into production discovery, each kept behind its visible "Needs source review" badge, matching how the app already ships clearly-labelled draft content.
  • Rollback: re-add devOnly: true to the therapy-compass entry in src/lib/app-modes.ts to hide the mode from the sidebar, MODE dropdown, and universal search (the routes + therapies domain go inert with no discovery entry point); or revert the merge/feature commits to remove the change entirely.
  • Provider or production effects: None — the therapies domain is fully local (static JSON); it touches no Supabase, OpenAI, or network path and behaves identically in demo and live modes.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed

Notes

Basis for the preflight checks above:

  • No Supabase / keys / PII: the therapies domain is a server-only module (src/lib/therapies.ts) reading a static JSON projection — no Supabase calls, no service-role keys, no private-document access, no patient-identifiable workflow.
  • Conservative source/review behavior: every unreviewed therapy keeps its "Needs source review" badge in universal-search results and on its detail page; a catalogue load failure renders an error + Retry (no substitute results shown).
  • Classification / decision to proceed: the change surfaces existing, clearly-labelled draft therapy content into production discovery — it generates no new clinical claims and no automated clinical decisions. Enabling the mode in production is an explicit maintainer decision (@BigSimmo: "add it as its own mode now" / "open PR for merge"). 205/211 therapy records remain needs_review and stay badged at the point of use; record-level qualified-clinician sign-off continues as an ongoing content-curation task, not a code gate. Re-gating is one flag (devOnly: true) away if that call changes.
  • check:production-readiness was not run in-sandbox (provider-confirmation boundary) — recommend running it before deploy.
  • No dependency or lockfile changes are included.

Summary by CodeRabbit

  • New Features
    • Expanded Therapy Compass into shareable, deep-linkable routes for therapy details, brief interventions, patient sheets, comparisons, clinical pathways, recommendations, reviews, and search.
    • Therapy Compass navigation is now URL-driven, enabling consistent routing across the route family and redirecting query runs to the dedicated search page.
    • Added a searchable therapy catalogue with review/status indicators and availability-aware “view all” support in universal search.
  • Bug Fixes
    • Patient-sheet and brief/sheet actions now only appear for therapies that have the corresponding available artifacts, with automatic fallback to the therapy detail page when unavailable.
  • Documentation
    • Updated the site map to include the full Therapy Compass route set and therapy slug inventories.

Promote Therapy Compass from a single client-side screen-switching route to
a first-class, URL-driven mode, and expose its 211-therapy library to
cross-entity universal search.

Routing
- Convert the eight in-tool screens to real routes under /therapy-compass:
  /search, /recommend, /compare, /pathways, /review, /[slug] (detail),
  /[slug]/brief, /[slug]/sheet. Detail/brief/sheet are server components with
  generateStaticParams + generateMetadata + notFound over all 211 therapies.
- Rewrite the TcProvider to derive the active screen from the pathname and the
  selected therapy from the [slug] param; nav + selection now update the URL
  (back/forward, deep links, new tabs). Screen UI is unchanged.
- Mount the provider + nav once in a layout-level workspace so the dataset and
  interaction state are shared across every /therapy-compass/* route.

Universal search
- Add a "therapies" domain backed by a new server catalogue (src/lib/therapies.ts
  + a trimmed src/data/therapies-index.json projection generated by
  scripts/build-therapies-index.mjs). Wire the adapter, dispatch table,
  view-all href, mode<->domain mapping, and command-surface heading. Hits
  deep-link to /therapy-compass/[slug]; review status is surfaced inline.

Visibility
- Remove the devOnly gate so the mode appears in the production sidebar, MODE
  dropdown, and universal search. Unreviewed records keep their "Needs source
  review" badge at the point of use.

Also retires the now-superseded /mockups/therapy-compass prototype, regenerates
docs/site-map.md, and updates the app-modes / universal-search / provider tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DG9gLBEwDZiqsZcVFCNmCh
@supabase

supabase Bot commented Jul 18, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 90f95ecf-2b6a-4f5c-8d22-e8926e33e2bf

📥 Commits

Reviewing files that changed from the base of the PR and between df59095 and 8c82e45.

📒 Files selected for processing (2)
  • docs/site-map.md
  • scripts/generate-site-map.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/site-map.md
  • scripts/generate-site-map.ts

📝 Walkthrough

Walkthrough

Therapy Compass is converted from a mockup-oriented page into a route family with URL-driven navigation, server-backed therapy data, searchable universal-search integration, shared workspace state, static metadata, and generated sitemap coverage.

Changes

Therapy catalogue and universal search

Layer / File(s) Summary
Therapy catalogue and search integration
scripts/build-therapies-index.mjs, src/data/therapies-index.json, src/lib/therapies.ts, src/lib/universal-search*.ts, src/components/clinical-dashboard/universal-search-command-surface.tsx, tests/*
A trimmed therapy index, lookup and ranking helpers, the therapies universal-search domain, Therapy Compass mode mappings, result links, and related tests are added.

URL-driven workspace and routes

Layer / File(s) Summary
URL-driven state and shared workspace
src/components/therapy-compass/*, src/app/therapy-compass/layout.tsx, src/app/therapy-compass/page.tsx, tests/therapy-compass-*
Therapy Compass navigation and query seeding derive from pathname and search parameters, while the shared workspace provides navigation, route content, footer, and retry/error rendering.
Therapy Compass route pages
src/app/therapy-compass/**/page.tsx
Home, search, comparison, pathway, recommendation, review, detail, brief, and patient-sheet routes are added with metadata and capability-based slug validation.

Production route inventory

Layer / File(s) Summary
Sitemap and mockup-route cleanup
scripts/generate-site-map.ts, docs/site-map.md, src/app/mockups/mockups-layout-client.tsx
Therapy Compass routes and therapy slugs are added to sitemap generation and documentation, while the former mockup route entry and composer special case are removed.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: codex

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: Therapy Compass is now a routed mode with universal search.
Description check ✅ Passed The description matches the required template and covers summary, verification, risk, governance, and notes with specific details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/therapy-pages-navigation-tmapa5

Comment @coderabbitai help to get the list of available commands.

@BigSimmo
BigSimmo marked this pull request as ready for review July 18, 2026 07:13
claude added 3 commits July 18, 2026 07:20
…navigation-tmapa5

# Conflicts:
#	src/components/therapy-compass/bindings.tsx
#	src/components/therapy-compass/therapy-compass-page.tsx
@BigSimmo
BigSimmo enabled auto-merge (squash) July 18, 2026 07:36

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/generate-site-map.ts`:
- Around line 473-474: Add "/therapy-compass/[slug]" to the productRoutes
exclusion list in the route-generation logic, matching the exclusions used for
other dynamic slug inventories. Keep the therapy slug inventory rendered
separately through renderSlugInventory("Therapy slugs", ...).

In `@src/app/therapy-compass/`[slug]/brief/page.tsx:
- Around line 7-22: The brief route must only generate and render records with
briefInterventionAvailable enabled; update generateStaticParams and
TherapyCompassBriefRoute to filter or return notFound for unavailable briefs.
Apply the corresponding change in src/app/therapy-compass/[slug]/sheet/page.tsx
lines 7-22 using patientSheetAvailable, so unavailable sheet records also return
notFound or are excluded from generation.

In `@src/components/therapy-compass/bindings.tsx`:
- Around line 259-262: Update the query synchronization logic in the bindings
component so `search.query` is also reset when `qParam` is absent, while
preserving the existing assignment when it is present. Keep `seededQuery`
synchronized with `qParam` and ensure navigation from a URL containing `q` to
one without it clears the stale search query.
- Around line 228-231: Wrap the TcProvider component’s useSearchParams-dependent
rendering in a React Suspense boundary, adding an appropriate fallback while
preserving the existing provider behavior. Ensure the boundary covers the
TcProvider usage under the therapy-compass layout so prerendering can complete
successfully.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a353731-9b14-4947-9483-21c7540719d5

📥 Commits

Reviewing files that changed from the base of the PR and between 731eb7a and 1c53c73.

📒 Files selected for processing (31)
  • docs/site-map.md
  • scripts/build-therapies-index.mjs
  • scripts/generate-site-map.ts
  • src/app/mockups/mockups-layout-client.tsx
  • src/app/mockups/therapy-compass/page.tsx
  • src/app/therapy-compass/[slug]/brief/page.tsx
  • src/app/therapy-compass/[slug]/page.tsx
  • src/app/therapy-compass/[slug]/sheet/page.tsx
  • src/app/therapy-compass/compare/page.tsx
  • src/app/therapy-compass/layout.tsx
  • src/app/therapy-compass/page.tsx
  • src/app/therapy-compass/pathways/page.tsx
  • src/app/therapy-compass/recommend/page.tsx
  • src/app/therapy-compass/review/page.tsx
  • src/app/therapy-compass/search/page.tsx
  • src/components/clinical-dashboard/universal-search-command-surface.tsx
  • src/components/therapy-compass/bindings.tsx
  • src/components/therapy-compass/index.ts
  • src/components/therapy-compass/styles.tsx
  • src/components/therapy-compass/therapy-compass-page.tsx
  • src/components/therapy-compass/workspace.tsx
  • src/data/therapies-index.json
  • src/lib/app-modes.ts
  • src/lib/therapies.ts
  • src/lib/universal-search-domains.ts
  • src/lib/universal-search-mode-context.ts
  • src/lib/universal-search.ts
  • tests/app-modes.test.ts
  • tests/therapy-compass-mode-wiring.test.ts
  • tests/therapy-compass-provider-seed.dom.test.tsx
  • tests/universal-search.test.ts
💤 Files with no reviewable changes (3)
  • src/app/mockups/therapy-compass/page.tsx
  • src/components/therapy-compass/therapy-compass-page.tsx
  • src/app/mockups/mockups-layout-client.tsx

Comment thread scripts/generate-site-map.ts
Comment thread src/app/therapy-compass/[slug]/brief/page.tsx
Comment thread src/components/therapy-compass/bindings.tsx
Comment thread src/components/therapy-compass/bindings.tsx
claude and others added 3 commits July 18, 2026 07:49
…emap, Suspense

- 404 the /[slug]/brief and /[slug]/sheet routes for therapies whose record has no
  brief-intervention / patient-sheet version (generateStaticParams now filters to
  available slugs; the route notFound()s unavailable ones) instead of rendering an
  unsupported workflow.
- Reset the in-tool search query when `q` is removed from the URL so the rendered
  state matches the address bar (unconditional render-phase sync; live typing is
  still preserved because it only fires when the `q` param changes). Adds a
  regression test.
- Exclude /therapy-compass/[slug] from the sitemap's main product-routes list so it
  is only listed once (under the therapy slug inventory), matching the other modes.
- Wrap the workspace in an explicit Suspense boundary so the route family's
  useSearchParams prerenders independently of the shared shell's boundary.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DG9gLBEwDZiqsZcVFCNmCh
@BigSimmo

Copy link
Copy Markdown
Owner Author

@copilot resolve the merge conflicts on this branch.

auto-merge was automatically disabled July 18, 2026 08:19

Head branch was pushed to by a user without write access

Copilot AI commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts on this branch.

Resolved. The two conflicts were comment-wording differences in src/lib/app-modes.ts and tests/app-modes.test.ts — both caused by the concurrent PR #827 landing a slightly different description for the same therapy-compass production-visibility change. I took origin/main's wording in both cases and completed the merge commit ed2f7612. Typecheck is clean and 22 targeted tests pass.

@BigSimmo
BigSimmo enabled auto-merge July 18, 2026 08:23
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

The agent ran but didn't make any changes. The issues may already be fixed or require manual intervention.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

The agent ran but didn't make any changes. The issues may already be fixed or require manual intervention.

@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed2f761215

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/therapy-compass/bindings.tsx
Comment thread src/components/therapy-compass/bindings.tsx Outdated
BigSimmo and others added 2 commits July 18, 2026 16:47
…routes

Resolves the two Codex P2 findings on the brief/sheet routing (their fixes
landed on separate PRs, not this branch):

- Availability-guard every brief/sheet entry point in the provider: openBrief/
  openSheet, the no-arg goBrief/goSheets nav actions, and (new) the picker
  `select()` now route to the artifact subroute only when the record ships it,
  falling back to the therapy's detail page otherwise — so nav/detail/recommend
  actions never dead-end on the notFound() brief/sheet routes (e.g. `emdr`,
  `behavioural-activation`).
- Fix picker selection on routed brief/sheet screens: on those subroutes the URL
  slug wins over `selectedSlug`, so `select()` now navigates to the chosen
  therapy's matching subroute instead of only setting state (which left the
  visible selection pinned to the URL).
- Filter the patient-sheet picker to sheet-available records, and hide the detail
  "Generate patient sheet" action for records without a sheet (matching the
  already-guarded brief action).
- Add DOM regression coverage for subroute picker navigation and the unavailable-
  artifact detail fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DG9gLBEwDZiqsZcVFCNmCh
auto-merge was automatically disabled July 18, 2026 09:09

Pull Request is not mergeable

@BigSimmo
BigSimmo enabled auto-merge July 18, 2026 10:42
@BigSimmo
BigSimmo merged commit 41bf4ac into main Jul 18, 2026
16 checks passed
@BigSimmo
BigSimmo deleted the claude/therapy-pages-navigation-tmapa5 branch July 18, 2026 10:48
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.

3 participants