Expand description
Page-level feature catalog — the single source of truth for
per-account page visibility (see backend auth::require_features).
Each variant maps 1:1 to a navigable SPA page (the sidebar entries in
web/src/components/Sidebar.tsx). An account’s allowed_features
column (users.allowed_features, JSON array of these string keys) is
an allow-list: NULL means “unrestricted — every page”, any array
restricts the account to exactly those pages (plus the always-open
commons: the login/self-service routes and the Dashboard landing feed).
Backend and SPA share these string keys so a page can’t be gated on one
side without the other agreeing on its name. The keys match the SPA
route path without the leading slash (/compliance → "compliance").
Enforcement is hard (backend 403), not merely a hidden nav item:
the routes owned by a page are gated by Feature in
crate::api::feature_map on the backend, so a restricted account can’t
reach the data by typing the URL or calling the API directly either.
Enums§
- Feature
- A gatable SPA page.
serde(de)serializes each variant as its lowercase route key (Compliance⇄"compliance"), which is exactly the string stored inusers.allowed_featuresand returned by/api/auth/me.