.agents/features/users.md
Manages user identity, platform membership, roles, session security, and a gamification badge system. A User record ties a UserIdentity (the canonical email/password/OAuth identity) to a specific platform, enabling the same person to exist across multiple platforms. Platform roles gate what users can see and do. The badge system awards achievement badges via application events and notifies users in real time via WebSocket.
packages/server/api/src/app/user/user-service.ts — user CRUD, getMe, profile update, role assignmentpackages/server/api/src/app/user/user-entity.ts — User and UserIdentity entitiespackages/server/api/src/app/user/badges/badge-service.ts — badge award flow, event handling, email notificationpackages/server/api/src/app/user/badges/badge-entity.ts — UserBadge entitypackages/server/api/src/app/user/badges/badge-check.ts — badge check interfacepackages/server/api/src/app/user/badges/checks/active-flows-badges.ts — FLOW_UPDATED badge checkspackages/server/api/src/app/user/badges/checks/flow-runs-badges.ts — FLOW_RUN_FINISHED badge checkspackages/server/api/src/app/user/badges/checks/flow-content.ts — flow content badge checkspackages/server/api/src/app/user/platform/platform-user-controller.ts — platform admin user management endpoints (EE)packages/server/api/src/app/user/platform/platform-user-module.ts — platform user modulepackages/shared/src/lib/core/user/user.ts — User, UserWithMetaInformation, UserWithBadges schemas; PlatformRole and UserStatus enumspackages/shared/src/lib/core/user/badges/index.ts — UserBadge schemapackages/web/src/app/routes/platform/users/index.tsx — platform admin user list pagepackages/web/src/app/routes/platform/users/columns.tsx — user table column definitionspackages/web/src/app/routes/platform/users/actions/user-actions.tsx — action menu for a user rowpackages/web/src/app/routes/platform/users/actions/update-user-dialog.tsx — edit role/status dialogpackages/web/src/app/routes/platform/users/actions/edit-user-action.tsx — edit action triggerpackages/web/src/app/routes/platform/users/actions/toggle-user-status-action.tsx — activate/deactivate actionpackages/web/src/app/routes/platform/users/actions/delete-user-action.tsx — delete user actionpackages/web/src/features/authentication/components/sign-in-form.tsx — sign-in formpackages/web/src/features/authentication/components/sign-up-form.tsx — sign-up formpackages/web/src/features/authentication/components/change-password.tsx — password change formpackages/web/src/features/authentication/hooks/auth-hooks.ts — auth React Query hooksGET /v1/users/me, POST /v1/users/meplatform-user-controller.ts (list, update role, deactivate, delete)ADMIN (full control), MEMBER (own projects only), OPERATOR (read access to all projects)User: id, platformRole (ADMIN/MEMBER/OPERATOR), status (ACTIVE/INACTIVE), identityId (FK to UserIdentity), externalId (nullable), platformId (FK), lastActiveDate. Unique on (platformId, identityId).
UserIdentity: id, email, password (hashed), firstName, lastName, provider (EMAIL/GOOGLE/SAML/JWT), verified (boolean), tokenVersion (for session invalidation). One identity → many users (across platforms).
UserBadge: id, userId, name (badge key). Unique on (userId, name).
Check categories (event-driven via ApplicationEvents):
Active flows badges — triggered by FLOW_UPDATED (LOCK_AND_PUBLISH / CHANGE_STATUS):
first-build: >=1 active flowon-a-roll: >=5 active flowsautomation-addict: >=10 active flowscant-stop: >=50 active flowsFlow run badges — triggered by FLOW_RUN_FINISHED (production only):
victory: any SUCCEEDED runback-again: any FAILED run (encourages retry)Flow content badges — triggered by FLOW_UPDATED (LOCK_AND_PUBLISH):
webhook-wizard: flow contains webhook triggeragentic-genius: flow contains AI piececoding-chad: flow contains code stepAward flow: Event fires → processBadgeChecks() → evaluates checks → filters already-awarded → saves to DB → sends email → emits WebSocket BADGE_AWARDED event
tokenVersion in UserIdentity: incrementing invalidates all existing tokensGET /v1/users/me — get current user with identity infoPOST /v1/users/me — update profile (firstName, lastName, profilePicture)