refactor(query-keys): flatten medicationIntakeList params for cache-key stability

The W3-QUERYKEY-LONGTAIL `medicationIntakeList` factory entry packed
the params as an object at index 4: `["medications", id, "intake",
"list", {sortBy, sortDir, limit, offset, status}]`. TanStack hashes
queryKeys via stable JSON, so the object form happens to work today,
but two sibling factory entries (`chartData`, `adminAuditLogFiltered`)
decompose params into a flat tuple precisely to avoid the deep-equal
trap — a future refactor that reorders the object keys or adds a
transient field would break the hash silently while every existing
caller looks correct.

Flatten the entry to match — the cache key now reads `["medications",
id, "intake", "list", sortBy, sortDir, limit, offset, status]`. The
unit-test walker pins the full tuple shape; the `intake-history-list-v2`
component test seed routes through the factory itself instead of a
hand-built bare literal so the params shape stays in lockstep with the
component's read.
This commit is contained in:
Marc-André Bombeck committed 2026-05-21 19:23:59 +02:00
1 parent f11df655a2
commit 958e2491e4
3 files changed
+34 -14

No files matched your search

@@ -4,6 +4,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { I18nProvider } from "@/lib/i18n/context";
import { IntakeHistoryListV2 } from "@/components/medications/intake-history-list-v2";
import { queryKeys } from "@/lib/query-keys";
/**
* v1.4.36 W4a — IntakeHistoryListV2 SSR smoke tests.
@@ -62,16 +63,17 @@ function seedIntake(
const limit = opts.limit ?? 25;
const offset = opts.offset ?? 0;
// v1.4.37 W3 — the component pins `status:"completed"` on the
// server-side query and threads it through the cache key, so the
// seed mirrors that shape verbatim.
// server-side query and threads it through the cache key. The seed
// routes through the canonical factory so the params shape stays in
// lockstep with the component's read.
client.setQueryData(
[
"medications",
medId,
"intake",
"list",
{ sortBy, sortDir, limit, offset, status: "completed" },
],
queryKeys.medicationIntakeList(medId, {
sortBy,
sortDir,
limit,
offset,
status: "completed",
}),
{ events: rows, meta: { total, limit, offset } },
);
}
+11 -4
View File
@@ -137,10 +137,17 @@ describe("queryKeys factory", () => {
offset: 0,
status: "completed",
});
expect(listKey[0]).toBe("medications");
expect(listKey[1]).toBe("med1");
expect(listKey[2]).toBe("intake");
expect(listKey[3]).toBe("list");
expect(listKey).toEqual([
"medications",
"med1",
"intake",
"list",
"takenAt",
"desc",
25,
0,
"completed",
]);
});
it("exposes withingsStatus under the withings prefix", () => {
+12 -1
View File
@@ -104,7 +104,18 @@ export const queryKeys = {
offset: number;
status: string;
},
) => ["medications", medicationId, "intake", "list", params] as const,
) =>
[
"medications",
medicationId,
"intake",
"list",
params.sortBy,
params.sortDir,
params.limit,
params.offset,
params.status,
] as const,
/**
* v1.4.40 W-RSC — the dashboard-level compliance chart (aggregate
* across every scheduled medication) was a bare `["medication-