Roles, goals, permissions, and expected behavior for every consumer of Feature Flags.
Permission values are exact from src/modules/rbac/permissions.constants.ts:78-80
(feature-flags.read/update/delete). Important: the permissions exist in
ALL_PERMISSIONS but are not enforced on any flag endpoint today — RbacGuard allows
when no @Roles()/@Permissions() metadata is present (rbac.guard.ts:29) and the
controller declares only JwtAuthGuard (feature-flags.controller.ts:18). So every persona
below with a valid JWT can mutate flags; the UI must be built as if permissions will be
enforced (OQ-5).
feature-flags.read, feature-flags.update (custom role; possible today in RBAC config)
Goal
Batch-configure flags (e.g., enable SMS for all campuses), fix label/description typos, stage a module's rollout
Core job
PUT /feature-flags/bulk (feature-flags.controller.ts:48-52), editor with key/enabled/label/description/module (update-feature-flag.dto.ts:4-26)
Pain points
Bulk is sequential, no transaction (feature-flags.service.ts:40-44) → needs per-row result; editor's description/module are silently dropped by the server upsert (feature-flag.repository.ts:40)
Restrictions
No feature-flags.delete → delete affordance hidden (server would accept it anyway — OQ-5)
Expected behaviour
See per-flag success/failure after bulk; never "saved" when the server persisted only 2 of 5 fields
Mental model
"I configure the switches; the platform team owns the keys."
No consumer in src/ today (grep: only the flag module itself); PLAN.md:29 scenario 2.6 documents the intent ("Feature-toggle read in downstream services")
Roles/goal frequency: shared baseline 00-shared/01. Every persona's flag-facing need
collapses to: admin — "flip it and know it applied"; platform — "read it fast"; end user —
"never see what's off." The module's differentiators (module grouping, enabled-only set,
bulk, per-row results) are the admin-facing surface.