Example: User Management System
Invite, role, suspend, and audit the people using your app. A complete admin section built on cluster accounts and a profiles storage.
Cluster accounts handle sign-in and tokens; your app adds profiles, roles, and lifecycle. This example builds the full admin section on top of both.
Accounts vs Profiles
- Cluster user: credentials, scopes, tokens; created by an admin via User Access Management or the users API.
- Profile document: your app's data about the person: display name, team, role, settings; stored in a
profilesstorage keyed by the user's guid.
Profile Document
{
"_meta": {
"cms": 1780531200274,
"created": 1780531200,
"entity": 1,
"expiry": -1,
"guid": "b9ee6a631b24e78d1aa48aef0dc067fff7bfbacd24a56ef4ed1f08e537d48b6b",
"removed": 0,
"ums": 1782166695586,
"update_hash": "2c6a91e4f7530bd8146ae9c30fb5724d81ea3f06",
"updated": 1782166695
},
"display_name": "sami b",
"preferences": {
"digest": "weekly",
"theme": "dark"
},
"role": "manager",
"status": "active",
"team": "engineering",
"user_guid": "b9ee6a631b24e78d1aa48aef0dc067fff7bfbacd24a56ef4ed1f08e537d48b6bd02"
}The Lifecycle
- Invite: admin creates the cluster user (+ their scopes), then a flow creates the profile with
status: invitedand a welcome email (Email System Setup). - First login. A flow on the member home page sees
status: invited, flips it toactive, and shows the onboarding checklist. - Role changes: update the profile's
rolefor app behavior, and the user'scustom_scopesfor API/page gating. Keep both in one admin flow so they never drift. - Suspend:
status: suspendedon the profile blocks app screens; removing the user's scopes blocks the APIs. Account deletion is the last resort, suspended keeps history.
The Admin Pages
- Directory: search profiles with filters (team, role, status). The list pattern from First CRUD App, scoped
*loggedin+people_admin. - Detail page: profile fields editable, scopes visible, activity summary (last login from the cluster's user activity).
- Self-service page: members edit only their own profile: fetched with
user_current→function_get_documentonuser_guid. See knowing who's calling.
Audit Trail
- Every admin action (invite, role change, suspend) writes an event document: actor (from
user_current), target, before/after. The activity-log model from Storage Examples. - Review per-user history with a term query on
target_guid, sorted by_meta.created.
