FuzeFront
▦
DO

Access — Countries

Per-list, per-action roles. Roles do not stack: a user holds exactly one role on this list.

User Role Granted by Granted Actions
Dana Okafor dana@northwind.example — (creator) 4 Aug 2026
Marc Lindqvist marc@northwind.example Dana Okafor 5 Aug 2026
Camille Roy camille@northwind.example Dana Okafor 6 Aug 2026
Priya Raman priya@northwind.example Marc Lindqvist 7 Aug 2026

Can't remove the last owner — 409 CONFLICT

Dana Okafor is the only list-owner. Demoting or removing them would leave the list with nobody who can grant access — unrecoverable without an org admin. Promote another person to list-owner first.

The error lands inline on Dana's row: the select snaps back to list-owner and Remove is re-enabled. The UI does not pre-emptively hide the control — the server is the authority on who the last owner is, and a client-side guess races every concurrent change.

What each role can do

Rolereadadd / update / remove value translateupdate / delete listmanage_access
list-owner✓✓✓✓✓
list-editor✓✓✓✓—
list-contributor✓✓———
list-translator✓—✓——
list-viewer✓————

A translator renders an existing vocabulary in another language and must not be able to add or remove values — that is the whole reason the role exists separately from contributor.

States

Only you have explicit access

Everyone in the organization can already read this list — that is the default on create. Add people here to let them edit or translate it.

+ Add person

Couldn't load access

No grants have been changed.

Read-only for your role — 403 FORBIDDEN

Changing access needs manage_access, held by list-owner and org admins. Everyone else sees this table with the selects disabled, Remove hidden and + Add person disabled — so the governance is visible even when it isn't editable.

Test hooks: [data-frame='10-access-panel'] · [data-panel='access'] · [data-panel='role-matrix'] · [data-grant='usr_01h455vb4pex5vsknk084sn02q'] · [data-sole-owner='true'] · [data-role-select] · [data-role='list-translator'] · [data-action='revoke-access'] · [data-action='add-access'] · [data-case='last-owner'] · [data-error='CONFLICT'] · [data-error='FORBIDDEN'] · [data-state='empty'] · [data-state='error']
Contract: GET …/access · PUT …/access/{userId} · DELETE …/access/{userId}. Last-owner demote/revoke ⇒ 409 CONFLICT.
Tokens only — no raw hex, spacing or type outside tokens.css / frame.css.

Review · selection-lists approve or reject each flow ↓
list-managementapproved · izzywdev
translation-workbenchapproved · izzywdev
access-controlapproved · izzywdev
pickerapproved · izzywdev