fix(medications): refetch an invalidated prefetch on mount

A hover prefetch excused the mount refetch even after a dose logged
elsewhere had invalidated the medication reads, so the page showed the
compliance from before the dose. An invalidated entry now always
refetches.
This commit is contained in:
Marc-André Bombeck committed 2026-10-04 21:13:28 +02:00
1 parent 5e5e387fab
commit 4be7109a2b
2 files changed
+30 -1

No files matched your search

@@ -125,6 +125,28 @@ describe("refetchMedicationsOnMount", () => {
unsubscribe();
});
it("refetches a prefetched read that was invalidated before the mount", async () => {
// Hover the nav link, then log a dose elsewhere before the page mounts:
// the dose invalidates the medication reads, and the prefetched answer
// no longer holds the compliance the user just changed.
const { client, calls } = setup();
prefetchMedicationsList(client);
await vi.waitFor(() => expect(calls("/api/medications")).toBe(1));
await vi.waitFor(() =>
expect(client.getQueryState(queryKeys.medications())?.status).toBe(
"success",
),
);
await client.invalidateQueries({ queryKey: queryKeys.medications() });
expect(client.getQueryState(queryKeys.medications())?.isInvalidated).toBe(
true,
);
const { refetched, unsubscribe } = await mountList(client);
expect(refetched).toBe(true);
unsubscribe();
});
it("still refetches on mount when the cache holds an older read", async () => {
const { client } = setup();
const queryFn = vi.fn(async () => []);
+8 -1
View File
@@ -93,11 +93,18 @@ export function prefetchMedicationsList(
* the identical request a second time, a few hundred milliseconds after the
* first answer landed, on every visit to the page. A return to the page with
* an older cache entry, or a direct load, still refetches on mount.
*
* An invalidated entry always refetches: a dose logged elsewhere in the app
* between the prefetch and the mount invalidates these reads, and the
* prefetched answer is then the stale one.
*/
export function refetchMedicationsOnMount(
read: MedicationsRead,
): (query: { state: { dataUpdatedAt: number } }) => boolean | "always" {
): (query: {
state: { dataUpdatedAt: number; isInvalidated: boolean };
}) => boolean | "always" {
return (query) => {
if (query.state.isInvalidated) return "always";
const startedAt = prefetchStartedAt.get(read);
const answeredThisVisit =
startedAt !== undefined &&