Skip to content

Commit 26dee90

Browse files
committed
docs(approvals): document the admin override + viewer.can_override (#3424)
Note the platform/tenant admin recovery path for a request routed to an unstaffed position (approve / reject / reassign / recall), and add `can_override` to the per-viewer block description. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmQPXXbgomoqrXtoxr3CS2
1 parent 7472a06 commit 26dee90

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

content/docs/automation/approvals.mdx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,20 +281,38 @@ service attaches to every request it returns:
281281

282282
```jsonc
283283
// getRequest / listRequests responses carry, per the calling user:
284-
"viewer": { "can_act": true, "is_submitter": false }
284+
"viewer": { "can_act": true, "is_submitter": false, "can_override": false }
285285
```
286286

287287
- `can_act` — the caller is a **current pending approver** (their id is in the
288288
resolved `pending_approvers` while the request is `pending`). This is the same
289289
check the decision routes authorize with, so it already reflects
290290
position/team/manager resolution.
291291
- `is_submitter` — the caller submitted the request.
292+
- `can_override` — the caller is a **platform or tenant admin** who may act on a
293+
`pending` request despite holding no slot (see the admin-override callout
294+
below).
292295

293296
Approver actions gate on `record.viewer.can_act`, submitter levers
294-
(remind/recall/resubmit) on `record.viewer.is_submitter`. So a submitter viewing
297+
(remind/recall/resubmit) on `record.viewer.is_submitter`, and Approve/Reject/
298+
Reassign additionally OR in `record.viewer.can_override`. So a submitter viewing
295299
their own pending request never sees Approve/Reject/Reassign (buttons the server
296-
would 403 anyway), and a position-addressed approver is never wrongly hidden.
297-
The service stays the sole authority — the predicate only trims the UI.
300+
would 403 anyway), a position-addressed approver is never wrongly hidden, and an
301+
admin can rescue a stuck request. The service stays the sole authority — the
302+
predicate only trims the UI.
303+
304+
<Callout type="info">
305+
**Admin override — recovering a stuck request.** An approval routed to a
306+
`position` / `team` / `department` with **no holders** resolves to only an
307+
unresolvable `position:<name>` literal in `pending_approvers`: no concrete user
308+
can act, and (with `lockRecord`) the record stays locked. A **platform admin**
309+
(`admin_full_access`) or **tenant admin** (`organization_admin`, org-scoped) may
310+
act on any `pending` request — **approve, reject, reassign** it to a real
311+
approver, or **recall** it — releasing the lock. An admin decision is
312+
authoritative: it finalizes the node even under `unanimous`/`quorum`/`per_group`,
313+
and is audited under the admin's own id. Prefer a guaranteed-staffed fallback
314+
approver so the set is never empty in the first place.
315+
</Callout>
298316

299317
### Progress and notification deep links
300318

0 commit comments

Comments
 (0)