mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
The top of an answer is one line that says what the Coach is doing right now (thinking, fetching a metric, summarising the readings, writing), live from the activity frames, with the seconds so far. It never opens by itself: the trail stays closed while the turn runs, when it asks, when it stops early, after the answer and after a reload, and opens only on a tap. Once the answer is in, the line settles into one summary of lookups and seconds. A table read during the turn shows as a one-line preview with a sparkline until the answer takes it over. Clarifying choices, follow-ups and the answers to a fact or plan proposal share one pattern: quiet pills in the answer's column whose tap sends the label as the person's own message. The clarification card and the in-thread plan card are gone. A fact the Coach kept is one meta line with Undo, an assumption one line with Change. The remember button on a message now keeps it in the Coach's memory.
106 lines
4.8 KiB
TypeScript
106 lines
4.8 KiB
TypeScript
/**
|
|
* Query keys — Coach preferences, facts, about-me, and nudge state.
|
|
* Part of the centralized factory; aggregated in `./index.ts`.
|
|
*/
|
|
export const coachKeys = {
|
|
coachPrefs: () => ["coach-prefs"] as const,
|
|
coachFacts: () => ["coach-facts"] as const,
|
|
/** v1.15.20 — Settings → AI "about me" self-description. */
|
|
coachAboutMe: () => ["coach-about-me"] as const,
|
|
/** v1.16.0 — pending clarifying questions (Coach composer chips). */
|
|
coachAboutMeQuestions: () => ["coach-about-me", "questions"] as const,
|
|
/** Encrypted, effective-dated structured anamnesis facts. */
|
|
healthProfileFacts: () => ["health-profile-facts"] as const,
|
|
/** v1.16.1 — unseen proactive-nudge state for the floating Coach bubble. */
|
|
coachNudgeStatus: () => ["coach-nudge-status"] as const,
|
|
/** v1.18.6 (CCH-03) — mark-Coach-seen mutation (clears the FAB unread dot). */
|
|
coachMarkSeen: () => ["coach-mark-seen"] as const,
|
|
/**
|
|
* v1.18.7 — the Coach conversation rail list (`GET /api/insights/chat`).
|
|
* Previously a hook-local bare `["coachConversations"]`; centralised so
|
|
* the optimistic delete and the streaming hook's post-turn invalidation
|
|
* share one factory-routed key.
|
|
*/
|
|
coachConversations: () => ["coachConversations"] as const,
|
|
/**
|
|
* v1.30.2 — the full, paginated + searchable rail history
|
|
* (`useInfiniteQuery` over `GET /api/insights/chat?cursor&q`). Nested under
|
|
* the `coachConversations` prefix (not a sibling key) so the existing
|
|
* delete-mutation + post-turn invalidation (`coachConversations()`) still
|
|
* reaches every cached search variant of this infinite list — TanStack's
|
|
* default `invalidateQueries` match is prefix-based, so no extra
|
|
* invalidation call site was needed. `search` is the trimmed query text;
|
|
* empty string keys the unfiltered ("browse everything") variant.
|
|
*/
|
|
coachConversationHistory: (search = "") =>
|
|
["coachConversations", "history", search.trim()] as const,
|
|
/**
|
|
* v1.18.7 — one decrypted Coach conversation (`GET /api/insights/chat/[id]`).
|
|
* Keyed on the conversation id so two open threads never share a cache slot;
|
|
* the streaming hook invalidates this slot once the persisted twin lands.
|
|
*/
|
|
coachConversation: (id: string | null) => ["coachConversation", id] as const,
|
|
/**
|
|
* v1.29.x (S7) — mutationKey for the attach/detach document mutations on a
|
|
* fenced conversation (`POST`/`DELETE /api/insights/chat/{id}/attachments`).
|
|
* Nested under the conversation key so the mutation and the detail read stay
|
|
* co-located in the factory.
|
|
*/
|
|
coachAttachmentMutation: (conversationId: string) =>
|
|
["coachConversation", conversationId, "attachments"] as const,
|
|
/**
|
|
* v1.39.4 — the stored tables of one assistant message
|
|
* (`GET /api/insights/chat/{id}/messages/{messageId}/results`). Nested under
|
|
* the conversation key so deleting or invalidating the conversation reaches
|
|
* every message's tables with the existing prefix match.
|
|
*/
|
|
coachMessageResults: (conversationId: string, messageId: string) =>
|
|
[
|
|
"coachConversation",
|
|
conversationId,
|
|
"messages",
|
|
messageId,
|
|
"results",
|
|
] as const,
|
|
/**
|
|
* v1.41 — the owner-only model text of one assistant message's trail
|
|
* (`GET /api/insights/chat/{id}/messages/{messageId}/trail`), read when
|
|
* the person opens the trail. Nested under the conversation key like the
|
|
* tables.
|
|
*/
|
|
coachMessageTrail: (conversationId: string, messageId: string) =>
|
|
[
|
|
"coachConversation",
|
|
conversationId,
|
|
"messages",
|
|
messageId,
|
|
"trail",
|
|
] as const,
|
|
/**
|
|
* v1.21.2 (A3) — today's most notable derived signal, resolved into the
|
|
* Coach hero's pre-seeded relevance opener
|
|
* (`GET /api/insights/coach/seeded-question`).
|
|
*/
|
|
coachSeededQuestion: () => ["coach-seeded-question"] as const,
|
|
/**
|
|
* v1.22 (B2/B6) — the user's Coach episodic reminders (`GET /api/coach/
|
|
* reminders`). The optional `status` arg keys the in-app tile read
|
|
* (`due,surfaced`) separately from the full ledger list so the two never
|
|
* share a cache slot.
|
|
*/
|
|
coachReminders: (status?: string) =>
|
|
["coach-reminders", status ?? "all"] as const,
|
|
/** Prefix key — invalidates every `coachReminders(status)` slot at once. */
|
|
coachRemindersAll: () => ["coach-reminders"] as const,
|
|
/**
|
|
* v1.27.x — the user's Coach goal / if-then plans (`GET /api/coach/plans`).
|
|
* The `filter` arg keys the chat thread's proposal read (`status:proposed`)
|
|
* separately from the management page's ledger read (`scope:all`) so the
|
|
* two never share a cache slot.
|
|
*/
|
|
coachPlans: (filter?: string) =>
|
|
["coach-plans", filter ?? "default"] as const,
|
|
/** Prefix key — invalidates every `coachPlans(filter)` slot at once. */
|
|
coachPlansAll: () => ["coach-plans"] as const,
|
|
};
|