Wire Therapy Compass into the app as a routed mode + universal search#825
Conversation
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
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughTherapy 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. ChangesTherapy catalogue and universal search
URL-driven workspace and routes
Production route inventory
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
…navigation-tmapa5 # Conflicts: # src/components/therapy-compass/bindings.tsx # src/components/therapy-compass/therapy-compass-page.tsx
…navigation-tmapa5
…navigation-tmapa5
There was a problem hiding this comment.
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
📒 Files selected for processing (31)
docs/site-map.mdscripts/build-therapies-index.mjsscripts/generate-site-map.tssrc/app/mockups/mockups-layout-client.tsxsrc/app/mockups/therapy-compass/page.tsxsrc/app/therapy-compass/[slug]/brief/page.tsxsrc/app/therapy-compass/[slug]/page.tsxsrc/app/therapy-compass/[slug]/sheet/page.tsxsrc/app/therapy-compass/compare/page.tsxsrc/app/therapy-compass/layout.tsxsrc/app/therapy-compass/page.tsxsrc/app/therapy-compass/pathways/page.tsxsrc/app/therapy-compass/recommend/page.tsxsrc/app/therapy-compass/review/page.tsxsrc/app/therapy-compass/search/page.tsxsrc/components/clinical-dashboard/universal-search-command-surface.tsxsrc/components/therapy-compass/bindings.tsxsrc/components/therapy-compass/index.tssrc/components/therapy-compass/styles.tsxsrc/components/therapy-compass/therapy-compass-page.tsxsrc/components/therapy-compass/workspace.tsxsrc/data/therapies-index.jsonsrc/lib/app-modes.tssrc/lib/therapies.tssrc/lib/universal-search-domains.tssrc/lib/universal-search-mode-context.tssrc/lib/universal-search.tstests/app-modes.test.tstests/therapy-compass-mode-wiring.test.tstests/therapy-compass-provider-seed.dom.test.tsxtests/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
…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
…navigation-tmapa5
|
@copilot resolve the merge conflicts on this branch. |
Head branch was pushed to by a user without write access
Resolved. The two conflicts were comment-wording differences in |
|
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. |
|
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. |
|
@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. |
There was a problem hiding this comment.
💡 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".
…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
Pull Request is not mergeable
Summary
/therapy-compassroute (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./therapy-compass(home),/search,/recommend,/compare,/pathways,/review,/[slug](detail),/[slug]/brief,/[slug]/sheet. Detail/brief/sheet are server components withgenerateStaticParams+generateMetadata+notFoundover all 211 therapies. Screen UI is unchanged —TcProvidernow 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).therapiesdomain backed by a server catalogue (src/lib/therapies.ts+ a trimmedsrc/data/therapies-index.jsonprojection generated byscripts/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.devOnlygate 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./mockups/therapy-compassprototype, regeneratesdocs/site-map.md, and updates the app-modes / universal-search / provider tests. Merged latestmain.Verification
npm run verify:pr-localRan 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,
/searchwith?qseeding,/[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 bytherapy-compass-provider-seed.dom.test.tsx.For search/ranking: the new
therapiesdomain is an isolated local-catalogue scorer; it does not alter document retrieval, ranking, selection, chunking, or the answer contract, soeval:retrieval:quality(36/36) is unaffected. No RAG-pipeline code changed.Risk and rollout
devOnlysurfaces the therapy library (205/211 records stillneeds_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.devOnly: trueto thetherapy-compassentry insrc/lib/app-modes.tsto hide the mode from the sidebar, MODE dropdown, and universal search (the routes +therapiesdomain go inert with no discovery entry point); or revert the merge/feature commits to remove the change entirely.therapiesdomain is fully local (static JSON); it touches no Supabase, OpenAI, or network path and behaves identically in demo and live modes.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)Notes
Basis for the preflight checks above:
therapiesdomain 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.needs_reviewand 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-readinesswas not run in-sandbox (provider-confirmation boundary) — recommend running it before deploy.Summary by CodeRabbit