mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 22:02:16 +00:00
A lab panel files itself against the visit it came from, and never has to. The OCR review and the manual form both offer the suggestion through the one shared field, anchored on the draw date rather than on now, so backdating a reading moves the offer with it. The commit writes one link PER RESULT ROW, which is why the join is m:n: a marker re-run on a different day belongs to its own visit. Best-effort by design — the readings are the write that matters and must not be lost to a link that could not be made. The condition side gets a Visits about this card with an action that pre-links the episode. From the episode side only, and that is a decision: an episode spans weeks and a visit is a point, so matching the other way would be wrong often enough to teach a person to ignore every suggestion in the product. A due checkup gains a second action beside erledigt. Filing the visit as done satisfies the checkup through the same forward-only, idempotent primitive the checkbox uses, so doing both is one satisfaction and no error. The two actions answer different questions — one says it happened, the other says where. An appointment now appears where a person looks, and NEITHER surface relaxes the reminder-table exclusion that keeps it out of the preventive-care lists. Both read the visit table: a quiet line under the dashboard checkup block for anything inside two weeks, and one rail item for today or tomorrow. A diff in either that touches origin is the wrong fix. A visit write now also refreshes the reminder reads. Closing a checkup moves its next-due date on three surfaces that would otherwise keep showing it due until their own poll. OpenAPI regenerated in the same commit.
76 lines
3.3 KiB
TypeScript
76 lines
3.3 KiB
TypeScript
/**
|
|
* Query keys — visits and the address book behind them.
|
|
* Part of the centralized factory; aggregated in `./index.ts`.
|
|
*
|
|
* These exist before any client reads them, because the in-repo
|
|
* `healthlog/queryKey-factory` rule errors on a bare array: the first
|
|
* component that lists visits cannot compile without a slot here. Same key
|
|
* with a different `queryFn` shape silently poisons the cache, which is the
|
|
* whole reason the factory is the only legal source.
|
|
*
|
|
* There is deliberately no matching `invalidateUserVisits` in
|
|
* `src/lib/cache/invalidate.ts`. That module evicts SERVER-side cached
|
|
* payloads, and no cached payload reads a visit: the dashboard snapshot, the
|
|
* insights targets and the analytics buckets are all computed from
|
|
* measurements, medications and mood. Adding a sweep over caches nothing reads
|
|
* would be a placeholder that looks like coverage. It belongs in the release
|
|
* that puts visits into one of those payloads, alongside the reader that makes
|
|
* it necessary.
|
|
*/
|
|
export const encounterKeys = {
|
|
/**
|
|
* The root prefix every visit write invalidates through
|
|
* (`encounterDependentKeys` in `./index.ts`). TanStack's hierarchical
|
|
* prefix semantics mean evicting `["encounters"]` clears the windowed list
|
|
* and every open detail in one tick, so a visit edited in a sheet and the
|
|
* list behind it never disagree.
|
|
*/
|
|
encounters: () => ["encounters"] as const,
|
|
/**
|
|
* The windowed list. The window is part of the key: the page can ask for a
|
|
* year at a time, and two windows are two different answers rather than one
|
|
* answer that overwrites the other.
|
|
*/
|
|
encounterList: (
|
|
from: string | null,
|
|
to: string | null,
|
|
status?: string,
|
|
episodeId?: string,
|
|
) =>
|
|
[
|
|
"encounters",
|
|
"list",
|
|
from,
|
|
to,
|
|
status ?? null,
|
|
episodeId ?? null,
|
|
] as const,
|
|
encounter: (id: string) => ["encounters", "detail", id] as const,
|
|
/**
|
|
* The "which visit does this belong to" verdict for one anchor date. The
|
|
* anchor is part of the key because it IS the question: a document dated the
|
|
* 3rd and one dated the 20th get different answers, and one overwriting the
|
|
* other would pre-select the wrong visit on the second review step.
|
|
*/
|
|
encounterSuggestion: (anchor: string) =>
|
|
["encounters", "suggest", anchor] as const,
|
|
/**
|
|
* The address book. Under its own root rather than nested beneath
|
|
* `["encounters"]`: a practitioner outlives the visits that name it, and a
|
|
* visit write should not evict a list that did not change.
|
|
*/
|
|
practitioners: () => ["practitioners"] as const,
|
|
practitionerList: (q?: string) =>
|
|
["practitioners", "list", q ?? null] as const,
|
|
practitioner: (id: string) => ["practitioners", "detail", id] as const,
|
|
|
|
/* ── mutation keys ──────────────────────────────────────────────── */
|
|
|
|
encounterCreate: () => ["encounters", "create"] as const,
|
|
encounterUpdate: () => ["encounters", "update"] as const,
|
|
encounterDelete: () => ["encounters", "delete"] as const,
|
|
practitionerCreate: () => ["practitioners", "create"] as const,
|
|
practitionerUpdate: () => ["practitioners", "update"] as const,
|
|
practitionerDelete: () => ["practitioners", "delete"] as const,
|
|
};
|