mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
Check the link before the code is redeemed and refuse a live session first, so a refused claim spends nothing at the provider.
105 lines
4.7 KiB
TypeScript
105 lines
4.7 KiB
TypeScript
/**
|
|
* Query keys — account sharing (v1.36.0).
|
|
* Part of the centralized factory; aggregated in `./index.ts`.
|
|
*
|
|
* Note what these keys deliberately do NOT carry: the acting account. That
|
|
* dimension lives on the QueryClient's `queryKeyHashFn`
|
|
* (`./record-scope.ts`), which folds it into every entry in the app at once
|
|
* — including these. Adding it here as well would partition the same cache
|
|
* twice under two rules, which is the two-deciders shape in miniature.
|
|
*
|
|
* The reads below are all non-delegable by construction: `/api/account/grants`
|
|
* and the record-activity feed both resolve through a bare `requireAuth()` and
|
|
* refuse while a switch is on. They are still record-scoped like everything
|
|
* else, so a session that switches out and back never reads a grant list
|
|
* cached under the wrong scope.
|
|
*/
|
|
export const sharingKeys = {
|
|
/**
|
|
* Grants in both directions (`GET /api/account/grants`). One key for one
|
|
* endpoint: the route answers "who can see my record, and whose can I see"
|
|
* in a single payload precisely so no client renders half of it.
|
|
*/
|
|
accountGrants: () => ["account", "grants"] as const,
|
|
|
|
/**
|
|
* The owner's record-activity feed (`GET /api/account/activity`) — who
|
|
* opened their record, and when.
|
|
*/
|
|
accountActivity: () => ["account", "activity"] as const,
|
|
|
|
/**
|
|
* v1.37.0 — the managed-profile family, as one prefix.
|
|
*
|
|
* Present so a grant transition can invalidate the whole family at once:
|
|
* accepting a Guardian invitation is an ordinary `POST
|
|
* /api/account/grants/{id}/accept`, and it moves a row on a roster that
|
|
* endpoint knows nothing about. Listing this prefix in `grantDependentKeys`
|
|
* is what keeps the two in step without the accept path having to know a
|
|
* managed profile exists.
|
|
*/
|
|
managedProfiles: () => ["managed-profiles"] as const,
|
|
|
|
/**
|
|
* Who looks after one managed profile (`GET
|
|
* /api/managed-profiles/{id}/guardians`). Keyed by profile because a
|
|
* Guardian may look after more than one, and a single key for all of them
|
|
* would be the same-key-different-shape collision the factory exists to
|
|
* prevent.
|
|
*/
|
|
managedProfileGuardians: (profileId: string) =>
|
|
["managed-profiles", profileId, "guardians"] as const,
|
|
|
|
/**
|
|
* One managed record's identity (`GET /api/managed-profiles/{id}`). Keyed by
|
|
* profile for the same reason the roster is, and under the same prefix so a
|
|
* grant transition invalidates it with the rest of the family.
|
|
*/
|
|
managedProfile: (profileId: string) =>
|
|
["managed-profiles", profileId, "profile"] as const,
|
|
|
|
/**
|
|
* v1.42 (#959) — whether a managed profile has an open handover link (`GET
|
|
* /api/managed-profiles/{id}/handover`). Under the family prefix so a grant
|
|
* transition refreshes it with the rest.
|
|
*/
|
|
managedProfileHandover: (profileId: string) =>
|
|
["managed-profiles", profileId, "handover"] as const,
|
|
|
|
/**
|
|
* v1.42 (#959) — the decision a new owner owes about their former
|
|
* Guardians (`GET /api/account/handover-decision`). Under `account` like
|
|
* the grant list it changes.
|
|
*/
|
|
handoverDecision: () => ["account", "handover-decision"] as const,
|
|
|
|
/**
|
|
* v1.42 (#959) — the anonymous preview of a handover link. The token is
|
|
* deliberately NOT part of the key: a cache key is a place a credential
|
|
* should never be written to, and one claim page reads one link.
|
|
*/
|
|
profileClaimPreview: () => ["profile-claim", "preview"] as const,
|
|
|
|
/** Mutation keys — kept in the factory so no bare array reaches a call site. */
|
|
accountGrantInvite: () => ["account", "grants", "invite"] as const,
|
|
accountGrantAccept: () => ["account", "grants", "accept"] as const,
|
|
accountGrantRevoke: () => ["account", "grants", "revoke"] as const,
|
|
accountGrantRenounce: () => ["account", "grants", "renounce"] as const,
|
|
accountSwitchMutation: () => ["account", "switch"] as const,
|
|
managedProfileCreate: () => ["managed-profiles", "create"] as const,
|
|
managedProfileUpdate: () => ["managed-profiles", "update"] as const,
|
|
managedProfileDelete: () => ["managed-profiles", "delete"] as const,
|
|
managedProfileGuardianInvite: () =>
|
|
["managed-profiles", "guardian", "invite"] as const,
|
|
managedProfileGuardianRemove: () =>
|
|
["managed-profiles", "guardian", "remove"] as const,
|
|
managedProfileHandoverCreate: () =>
|
|
["managed-profiles", "handover", "create"] as const,
|
|
managedProfileHandoverRevoke: () =>
|
|
["managed-profiles", "handover", "revoke"] as const,
|
|
handoverDecide: () => ["account", "handover-decision", "decide"] as const,
|
|
profileClaim: () => ["profile-claim", "submit"] as const,
|
|
/** v1.43 (#959) — starting the claim through single sign-on. */
|
|
profileClaimSso: () => ["profile-claim", "sso"] as const,
|
|
};
|