Permissions + roles
Help Tutorials has two privilege keys controlling who can edit, plus an open read path for every authenticated admin.
Privilege matrix
| Action | Required privilege | Notes |
|---|---|---|
| Open the help panel on any admin page | None (any authenticated admin) | The fetch hits GET /admin/help-tutorials/{pageKey} which auto-seeds the row if missing — every operator triggers the seed implicitly. |
| Mark a tutorial as read | None | POST /admin/help-tutorials/{pageKey}/read is gated only by auth. |
| List tutorials at /admin/help-tutorials | manage_help OR manage_settings | Page-level <RequirePrivilege privilege="manage_settings"> wraps the route. |
| Create a tutorial | manage_help OR manage_settings | POST /admin/help-tutorials/. |
| Edit a tutorial | manage_help OR manage_settings | PUT /admin/help-tutorials/{id}. |
| Delete a tutorial | manage_help OR manage_settings | DELETE /admin/help-tutorials/{id}. |
| Re-seed defaults | manage_help OR manage_settings | POST /admin/help-tutorials/seed. |
| Bulk existence probe (sidebar dots) | None | GET /admin/help-tutorials/exists?keys=... — used by the admin shell. |
| Per-user unread list | None (user's own data only) | GET /admin/help-tutorials/unread returns the current user's unread page_keys. |
Why the dual privilege
The Wave 11 split separated manage_help from manage_settings so a small docs / support team could author tutorials without inheriting the wider settings-admin keyring (payment gateway secrets, tax rules, vendor commission policies, etc.). A tenant whose ops + docs are one person can ignore the split and grant manage_settings only — the route accepts either.
Suggested groupings
| Role you want | Privileges to grant |
|---|---|
| Store owner / sole admin | manage_settings covers everything including tutorials. |
| Customer support docs author | manage_help (only). Lets them edit tutorials but not settings panels. |
| Customer support agent | Nothing — they read tutorials by default. |
| Marketing / merchandising admin | Whatever their role normally has + nothing extra for tutorials (reading is free). |
| Sub-tenant brand admin | manage_help if you want them to localise tutorials per their brand. |
Granting in the admin UI
- Open /admin/users/usergroups.
- Pick the usergroup that should own tutorial authoring.
- Find Manage Help Tutorials (key:
manage_help). - Toggle ON.
- Save.
Users already in that group inherit the privilege on their next login (the privilege cache flushes on usergroup save).
IO-platform vs tenant separation
The /admin/io/... route group is the IO platform admin (eCart's own ops dashboard), gated by RequireIOPermission. Help tutorials does NOT render the help button on those routes — the resolver returns early when pathname.startsWith("/admin/io"). This is intentional: IO operators use different help surfaces; tenant tutorials would be confusing in that context.
What happens to privileges when the module is disabled
When help-tutorials is toggled OFF:
- The page-level
useModuleEnabled("help-tutorials")returns false → the page renders the "module disabled" placeholder. - The route-level
RequireModule(s.moduleSvc, "help-tutorials")middleware on the backend returns 403 module_disabled for every/admin/help-tutorials/*request. - The
manage_helpprivilege still exists in the user's role; it's just inactive — no path is currently writable.
Re-enabling the module restores write access automatically. No privilege re-grant is needed.
