mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 06:06:10 +00:00
docs: publish the last-Guardian refusal where it is actually raised
The floor was described on the one route that cannot reach it and left unsaid on the two that answer it every time: withdrawing the last Guardian grant and renouncing it both raise `managed_profile.guardian.required`, and both published only 'that access had already ended'. Both 409s now name their two codes, and the annotation on the removal route enumerates all four emitters rather than three. A guard closes the class rather than the instance: every route module that raises the refusal must publish it on its own operation, with the emitters discovered from the sources. The freeze guard gains its containment leg — a module becomes delegable by review, not by discovery, so every file contributing a fenced verb has to be a member of one of the surface guard's frozen allowlists.
This commit is contained in:
1 parent
84475ea2f2
commit
4d86dceb99
4 files changed
+145
-8
No files matched your search
@@ -596,7 +596,8 @@ export const accountSharingPaths: NonNullable<ZodOpenApiObject["paths"]> = {
|
||||
content: { "application/json": { schema: errorEnvelope } },
|
||||
},
|
||||
"409": {
|
||||
description: "That access had already ended.",
|
||||
description:
|
||||
"Two refusals share this status. `meta.errorCode: sharing.revoke.already_ended` — that access had already ended, and nothing changed. `meta.errorCode: managed_profile.guardian.required` — the grant is the last active Guardian grant on a managed profile, and ending it would leave a record with nobody able to open it. The floor is real and this is one of the four routes that enforce it; the way past it is to invite another Guardian and wait for them to accept, or to delete the profile.",
|
||||
content: { "application/json": { schema: errorEnvelope } },
|
||||
},
|
||||
},
|
||||
@@ -630,7 +631,8 @@ export const accountSharingPaths: NonNullable<ZodOpenApiObject["paths"]> = {
|
||||
content: { "application/json": { schema: errorEnvelope } },
|
||||
},
|
||||
"409": {
|
||||
description: "That access had already ended.",
|
||||
description:
|
||||
"Two refusals share this status. `meta.errorCode: sharing.renounce.already_ended` — that access had already ended, and nothing changed. `meta.errorCode: managed_profile.guardian.required` — the caller is the last active Guardian of a managed profile, so handing this access back would strand the record. Invite somebody and wait for them to accept, or delete the profile; a Guardian may not simply walk away from a record that has no self.",
|
||||
content: { "application/json": { schema: errorEnvelope } },
|
||||
},
|
||||
},
|
||||
@@ -830,7 +832,7 @@ export const accountSharingPaths: NonNullable<ZodOpenApiObject["paths"]> = {
|
||||
},
|
||||
"409": {
|
||||
description:
|
||||
"The record would be left with nobody looking after it (`meta.errorCode: managed_profile.guardian.required`). **Not reachable through this route today**, and published anyway rather than silently: the caller must already be one active Guardian and the target is never the caller, so an active target is always a second one — and two is never the one the floor refuses. The same code IS emitted by the renounce route, by Guardian account deletion and by a data wipe, so a shared client resolver keeps this arm. It is documented here so that a change making it reachable is a change somebody notices.",
|
||||
"The record would be left with nobody looking after it (`meta.errorCode: managed_profile.guardian.required`). **Not reachable through this route today**, and published anyway rather than silently: the caller must already be one active Guardian and the target is never the caller, so an active target is always a second one — and two is never the one the floor refuses. The routes that DO emit this code are `DELETE /api/account/grants/{id}` (the owner withdrawing the last Guardian grant), `POST /api/account/grants/{id}/renounce` (a Guardian handing their own access back), Guardian account deletion and a data wipe — a client resolves the code the same way wherever it arrives, which is why this arm stays. It is documented here so that a change making it reachable through this route is a change somebody notices.",
|
||||
content: { "application/json": { schema: errorEnvelope } },
|
||||
},
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user