Drive UI create/manage/edit affordances off the permission matrix (web + Android) #61
Labels
No labels
adr
android
area/calendar
area/design-system
area/i18n
area/jobs
area/offline
area/server
area/testing
bug
ci
duplicate
enhancement
help wanted
invalid
notifications
question
reliability
security
severity/low
severity/medium
tracking
web
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
eagraiclainne/app#61
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Make every create, manage and edit affordance in the clients honor the permission matrix, instead of a coarse hand-written role flag. Consume the matrix the server now exposes (
SystemService.GetPermissionMatrix, #69) so the UI shows exactly the controls a role is permitted — no more, no less. This also surfaces event editing, which the UI does not offer at all today.Why
The web gates create and manage controls on one flag,
canEdit = ADMIN || MEMBER(web/src/auth/auth.tsx). It excludes the child role wholesale, so a child sees no create controls even for events and jobs the server already permits, and — after #67 — none for the lists and meals a child may now run. Android gates on a per-membershipmanagerflag with the same kind of drift. Both are client-side guesses that diverge from the server's real matrix.#69 exposes the matrix over RPC. This issue makes the clients consume it.
Depends on
SystemService.GetPermissionMatrix(the data source).Scope
Web foundation (
web/src/auth/):GetPermissionMatrixonce per session, caches it inlocalStorage(static, non-sensitive), and hydrates synchronously to avoid affordance flicker.can(service, method)on the auth context — true when any of the member's roles appears in that matrix entry. An unknown entry denies, matching the server default.canEdit. Migrate every use to the specificcan(...)it needs.Web per-page migration:
can("ItemListService", …).can("MealService", …).can("MealRotaService", …). This splits a control today conflated undercanEdit, so a child sees the library controls but not the rota controls, per ADR-0028.can("ItemService", "Create").can("EventService", "Create").can("RewardService", …).canEditJob = isManager || owner === me).Event editing (the capability that does not exist yet):
mutate.events.update.EventService.Updatealready exists server-side.can("EventService", "Update").SplitOccurrencethenUpdatefor one occurrence;Updateon the parent for the series). A single non-recurring event edits in place.Android:
GetPermissionMatrixendpoint (or a generated helper over it) and replace the per-membershipmanager-flag gating for create and manage affordances, so a child sees the controls the matrix permits. Add the event-edit flow to the event sheet, mirroring the web.Canon:
CLAUDE.mdanddocs/frontend-plan.html: child accounts do not see "creation affordances absent entirely". Affordance absence tracks a real matrix denial, and the UI derives affordances from the matrix, not a role bucket (system rule 5).Definition of done
canEditis gone.docs/frontend-plan.htmlandCLAUDE.mdupdated.make checkpasses. Verified on both surfaces as a child and as a member against the live deploy.Surface event editing on web and Android (wire EventService.Update)to Drive UI create/manage/edit affordances off the permission matrix (web + Android)Done — all five parts merged to main: web affordances (#70), web event edit (#71), Android affordances (#72), Android event edit (#73), recurring event edit (#74). Deferred repeat-rule editing was never in scope here.