mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
docs(sharing): say that the writable-section list is existential, not per verb
`writableDomains` answers "is there at least one delegated write route in this section this grant satisfies". Its docblock promised a per-section answer the table cannot give: within a section the split runs by verb, and three of the four sections marked writable carry MANAGE-only creates beside their WRITE ones — an allergy and a family-history entry under `profile`, a water entry and a checkup reminder under `measurements`, a snooze and a re-recorded dose under `medications`. No shipped control is wrong because of it: the allergy and family-history forms already ask the manage question, and so does the water entry. But the name and the sentence beside it invite a control to read "my section is writable, therefore my create is", and that reading is wrong in three sections out of four. Documentation only, in the three places the claim is made — the published field, the function that derives it, and the guard that holds it against the routes, whose green run now says what it does not prove. A per-verb table would be a second place the route declarations live, and the declarations are what decides; the control keeps asking the hook for its own verb class.
This commit is contained in:
1 parent
c809971a23
commit
4410a496cc
3 files changed
+35
-5
No files matched your search
@@ -24,6 +24,16 @@
|
||||
* domain outside the vocabulary other than `record` fails the run outright,
|
||||
* because the table is keyed on the vocabulary and would silently lack it.
|
||||
*
|
||||
* What it deliberately does not hold, stated so nobody reads more into a green
|
||||
* run than it earns: the table is EXISTENTIAL per section. It answers "does
|
||||
* any route in this section accept this need", and within a section the answer
|
||||
* varies by verb — `POST /api/encounters` is WRITE while `POST /api/allergies`
|
||||
* beside it is MANAGE, both under `profile`. So this guard proves the table
|
||||
* and the routes agree about the section, never that one control's own verb is
|
||||
* covered. That is the control's job: it asks the hook for its own verb class,
|
||||
* and a control that read "my section is writable, therefore my create is"
|
||||
* would be wrong in three of the four sections marked writable.
|
||||
*
|
||||
* Mutation checks, run:
|
||||
* - set `mind.write` to `true` in the table → "agrees with the routes" red;
|
||||
* - change `requireRecordAuth("manage", "mind")` in `mood-entries/route.ts`
|
||||
|
||||
@@ -113,11 +113,22 @@ export interface AccountAccessEntry {
|
||||
*/
|
||||
canWrite: boolean;
|
||||
/**
|
||||
* v1.38.12 — the sections this grant can add to, resolved server-side from
|
||||
* the grant's level and scope against the delegated write routes that
|
||||
* exist (`domain-write-support.ts`). In the consent screen's order. Empty
|
||||
* for a READ grant, and empty for any section whose routes accept no
|
||||
* delegated write at all — the vault, today.
|
||||
* v1.38.12 — the sections with AT LEAST ONE delegated write route this
|
||||
* grant satisfies, resolved server-side from its level and scope against
|
||||
* the routes that exist (`domain-write-support.ts`). In the consent
|
||||
* screen's order. Empty for a READ grant, and empty for any section whose
|
||||
* routes accept no delegated write at all — the vault, today.
|
||||
*
|
||||
* Existential, and the word matters: within a section the answer varies by
|
||||
* verb, and this list cannot say which. `profile` is writable because a
|
||||
* visit, a practitioner and a dose answer at WRITE, while an allergy and a
|
||||
* family-history entry are MANAGE creates; `measurements` is writable
|
||||
* because a reading is, while a water entry and a checkup reminder are
|
||||
* MANAGE. So a control does not read "my section is writable, therefore my
|
||||
* create is": it asks the hook for its own verb class —
|
||||
* `canWriteDomain` for a create the WRITE level covers, `canManageDomain`
|
||||
* for one it does not. A per-verb table would be a second place the route
|
||||
* declarations live, and the declarations are the thing that decides.
|
||||
*
|
||||
* A list rather than a boolean because the answer differs per section, and
|
||||
* the client's per-control question is "this section", never "any".
|
||||
|
||||
@@ -74,6 +74,15 @@ const LEVEL_RANK: Record<AccountAccessLevel, number> = {
|
||||
* `sections === null` is the entire record. A MANAGE grant always carries it
|
||||
* (`grants.ts` refuses a scope on a MANAGE invitation), a WRITE grant may.
|
||||
*
|
||||
* The answer is EXISTENTIAL per section, never per verb: "is there a route in
|
||||
* this section at this need the grant satisfies". Three of the four sections
|
||||
* that answer `write: true` also carry MANAGE-only creates — an allergy and a
|
||||
* family-history entry under `profile`, a water entry and a checkup reminder
|
||||
* under `measurements`, a snooze and a re-recorded dose under `medications` —
|
||||
* and no list keyed on the section can distinguish them. A control asks the
|
||||
* hook for its own verb class instead; the route declarations stay the one
|
||||
* place the split is decided.
|
||||
*
|
||||
* For `need === "write"` the answer is "is there a non-read route in this
|
||||
* section the grant satisfies": a WRITE grant reaches the section's `"write"`
|
||||
* routes, a MANAGE grant reaches those and its `"manage"` routes as well.
|
||||
|
||||
Reference in new issue
Block a user