Module IA within the global shell (00-shared/05). The module owns the
Users & Roles surface (/users, 05_Global_Information_Architecture.md:47)
for admin/HR, plus the account/profile self-service surface
(05_Global_IA §8: avatar menu → profile, password, 2FA, devices,
preferences). Routes are (planned) — no client repo exists; they follow
go_router conventions (00-shared/11 §6).
Role-gating note: GET /rbac/members requires org_admin
(rbac.controller.ts:21-22); if the Users list must show role chips to
non-org_admin viewers, that data source is unavailable — role chips degrade
to "—" for those viewers (planned) server-side join.
List → Detail → Edit → back to Detail (refresh). List → Create → back to
List (refresh). List → Import → Result → back to List (refresh).
Detail tabs fetch from three sources: GET /users/:id (profile),
GET /rbac/members (membership — join by userId),
GET /users/:id/preferences (preferences).
Preferences manager view and self-profile preferences share the
same screen component (PATCH target differs only by :id).
Status change happens from Detail (top-bar action) and from list row
context menu.
Detail tabs use TabBarView keep-alive (00-shared/03 AppTabs); switching
bottom-nav destinations preserves tab state (00-shared/05 §3).
Import wizard state (file, preview, errors) survives screen navigation via
the BulkImportCubit (13_State_Management.md §6) — never re-parse a file
the user already validated unless they pick a new one.
Status filter and role filter are (planned) — no query params exist in
users.service.ts:90-115. Until then the client filter bar filters the
loaded pages client-side (explicitly labeled, and honest about the
limitation) or defers until server support lands.