Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
504795c
perf: shrink Therapy Compass browse payload
BigSimmo Jul 30, 2026
983c0c1
Merge branch 'main' into codex/complete-and-merge-p2-tasks-to-main
BigSimmo Jul 30, 2026
05440b4
test: prove Therapy search keeps full corpus
BigSimmo Jul 30, 2026
ec6a868
merge: sync Therapy Compass payload work
BigSimmo Jul 30, 2026
f3ed3ed
docs: record PR #1471 review
BigSimmo Jul 30, 2026
6e41a54
merge: sync Therapy Compass payload work with main
BigSimmo Jul 30, 2026
249ff87
merge: sync Therapy Compass payload after issue closure
BigSimmo Jul 30, 2026
8c642df
merge: sync Therapy Compass payload with current main
BigSimmo Jul 30, 2026
34a29ee
merge: resync Therapy Compass payload after issue guard
BigSimmo Jul 30, 2026
fc6b890
merge: sync Therapy payload after RAG extraction
BigSimmo Jul 30, 2026
4830234
Merge remote-tracking branch 'origin/main' into codex/review-pr1471
BigSimmo Jul 30, 2026
93ca3cf
Merge remote-tracking branch 'origin/main' into codex/review-pr1471
BigSimmo Jul 30, 2026
99d5ba5
Merge remote-tracking branch 'origin/main' into codex/review-pr1471
BigSimmo Jul 30, 2026
8bbf123
merge: sync Therapy Compass payload with current main
cursoragent Jul 31, 2026
bec8872
test: assert pathways keep compact Therapy browse index
cursoragent Jul 31, 2026
2ca7a4d
docs: record PR #1471 reopen-readiness review
cursoragent Jul 31, 2026
aea0064
merge: sync Therapy Compass payload with current main
cursoragent Jul 31, 2026
b10791a
merge: sync Therapy Compass payload with current main
cursoragent Jul 31, 2026
ea92b37
merge: sync Therapy Compass payload with current main
cursoragent Jul 31, 2026
c02e437
merge: sync Therapy Compass payload with current main
cursoragent Jul 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 46 additions & 40 deletions docs/branch-review-ledger.md

Large diffs are not rendered by default.

1,630 changes: 200 additions & 1,430 deletions public/therapy-compass-data/therapies-index.json

Large diffs are not rendered by default.

11 changes: 4 additions & 7 deletions scripts/build-therapies-index.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,13 +43,10 @@ const browserProjected = therapies
name: therapy.name,
category: therapy.category ?? null,
modality: therapy.modality ?? null,
clinicalSummary: therapy.clinicalSummary ?? null,
bestUsedFor: therapy.bestUsedFor ?? null,
indications: therapy.indications ?? null,
contraindicationsOrCautions: therapy.contraindicationsOrCautions ?? null,
targetSymptoms: therapy.targetSymptoms ?? null,
patientPopulation: therapy.patientPopulation ?? null,
setting: therapy.setting ?? null,
// The browser index is the browse/pathway payload, not the search corpus.
// Keep only the short subtitle the catalogue cards render. Search loads the
// full records so removing long clinical prose here cannot change recall.
bestUsedFor: therapy.bestUsedFor?.split(/(?<=\.)\s+/)[0] ?? null,
reviewStatus: therapy.reviewStatus ?? "needs_review",
patientSheetAvailable: Boolean(therapy.patientSheetAvailable),
briefInterventionAvailable: Boolean(therapy.briefInterventionAvailable),
Expand Down
6 changes: 5 additions & 1 deletion src/components/therapy-compass/bindings.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -203,7 +203,11 @@ export function TcProvider({ children }: { children: ReactNode }) {
const pathname = usePathname();
const searchParams = useSearchParams();
const { screen, slug: routeSlug } = resolveRoute(pathname);
const usesCatalogueIndex = screen === "home" || screen === "search" || screen === "pathways";
// Search needs the complete prose corpus to preserve its existing weighted
// matches. Browse/pathway screens need catalogue metadata only, so keeping
// the 2.5 MB full dataset off their critical path materially improves mobile
// paint without silently narrowing search recall.
const usesCatalogueIndex = screen === "home" || screen === "pathways";
const { data, loading, error, retry } = useTherapyData({
catalogue: usesCatalogueIndex ? "index" : "full",
includePathways: screen === "pathways",
Expand Down
42 changes: 42 additions & 0 deletions tests/therapy-compass-data-recovery.dom.test.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -160,4 +160,46 @@ describe("Therapy Compass required data recovery", () => {
await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1));
expect(String(fetchMock.mock.calls[0]?.[0])).toMatch(/\/therapies\.json$/);
});

it("keeps the full prose corpus on the search route", async () => {
navigation.pathname = "/therapy-compass/search";
const fetchMock = vi.fn(async (input: RequestInfo | URL) => {
const path = String(input);
if (path.endsWith("/therapies.json")) return response([therapy]);
throw new Error(`Unexpected fetch: ${path}`);
});
vi.stubGlobal("fetch", fetchMock);

render(
<TherapyCompassWorkspace>
<div>Search ready</div>
</TherapyCompassWorkspace>,
);

await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1));
expect(String(fetchMock.mock.calls[0]?.[0])).toMatch(/\/therapies\.json$/);
});

it("keeps the compact browse index on the pathways route", async () => {
navigation.pathname = "/therapy-compass/pathways";
const fetchMock = vi.fn(async (input: RequestInfo | URL) => {
const path = String(input);
if (path.endsWith("/therapies-index.json")) return response([therapy]);
if (path.endsWith("/pathways.json")) return response([]);
throw new Error(`Unexpected fetch: ${path}`);
});
vi.stubGlobal("fetch", fetchMock);

render(
<TherapyCompassWorkspace>
<div>Pathways ready</div>
</TherapyCompassWorkspace>,
);

await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(2));
const fetched = fetchMock.mock.calls.map((call) => String(call[0]));
expect(fetched.some((url) => /\/therapies-index\.json$/.test(url))).toBe(true);
expect(fetched.some((url) => /\/pathways\.json$/.test(url))).toBe(true);
expect(fetched.some((url) => /\/therapies\.json$/.test(url))).toBe(false);
});
});
7 changes: 5 additions & 2 deletions tests/therapy-compass-mode-wiring.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@ const loaderSrc = readFileSync(
new URL("../src/components/therapy-compass/data/use-therapy-data.ts", import.meta.url),
"utf8",
);
const bindingsSrc = readFileSync(new URL("../src/components/therapy-compass/bindings.tsx", import.meta.url), "utf8");
const dataDir = new URL("../public/therapy-compass-data/", import.meta.url);
const therapyMetadataFiles = [
"../src/app/(search-app)/therapy-compass/page.tsx",
Expand DownExpand Up@@ -80,11 +81,13 @@ describe("Therapy Compass production-mode wiring", () => {
}
});

it("ships a materially smaller catalogue index for browse and search routes", () => {
it("ships a compact browse index without narrowing the full-prose search corpus", () => {
const fullSize = readFileSync(new URL("therapies.json", dataDir)).byteLength;
const indexSize = readFileSync(new URL("therapies-index.json", dataDir)).byteLength;
expect(indexSize).toBeLessThan(fullSize * 0.4);
expect(indexSize).toBeLessThan(fullSize * 0.1);
expect(loaderSrc).toContain('options.catalogue === "full" ? "therapies.json" : "therapies-index.json"');
expect(bindingsSrc).toContain('screen === "home" || screen === "pathways"');
expect(bindingsSrc).not.toContain('screen === "home" || screen === "search" || screen === "pathways"');
});

it("keeps therapy-compass route-owned when the shared composer has a submitted query", () => {
Expand Down
Loading