User Lifecycle – Frontend¶
Technical documentation for the User lifecycle frontend in Alan Home (eu-home-app). Intended for developers debugging or developing on the feature. This page focuses on the frontend implementation and, in particular, role request and approval.
Location¶
- App:
frontend/apps/eu-home-app - Main component:
app/components/UserRoleManagement.tsx— exportsRolesManagementGeneric(generic roles UI for all user types) - Role UI:
app/components/roles/(modals and helpers) - Utils:
utils/roles.ts(queries, mutations, types)
Where the UI appears¶
User lifecycle and role management are exposed in:
- Alaner profile:
app/pages/AlanerProfile/RolesManagement.tsxwrapsRolesManagementGenericfor alaners. - External user profile:
app/pages/ExternalUserProfile/RolesManagement.tsxwrapsRolesManagementGenericfor external users. - Service account:
app/pages/ServiceAccountManager/RolesManagement.tsxwrapsRolesManagementGenericfor service accounts. - Team area:
app/pages/Team/MembersTab.tsxusesTeamMembershipRequestModalfor role grants/requests in the team context. - Oncall roster:
app/pages/Oncall/OncallRosterTab.tsxuses the same role-request flow when adding/removing members (e.g. link to role request byrole_request_id). - Role definitions review:
app/pages/RoleWithGrantRulesReview.tsx— read-only table of all role definitions grouped by scope (prefix before first:), showing grant rules (with GitHub links),grant_management_permitted_for, and self-service eligibility.
Role request flow (frontend)¶
- Request a role
- User clicks “Request a role” (or equivalent), opening
RoleRequestModal(app/components/roles/RoleRequestModal.tsx). - Modal is prefillable via URL search params:
role,sub-scope,scope,request-reason,start-at. - User selects scope (e.g. area, unit, crew, oncall group), optional sub-scope, role, start/end dates, duration (if applicable), and request reason.
- Submit uses
useAddUserRoleRequestMutation(POST to/{alaners|external-users|service-accounts}/{id}/role-requests). On success, the UI shows either “auto-approved” or a link to the Slack thread for approval. -
For team membership,
TeamMembershipRequestModalreuses the same mutation to request the appropriate org role (e.g. area/crew/oncall member). -
Pending requests list
UserRoleManagementloads pending requests withuseUserRoleRequests(userId, isServiceAccount)(GET/{type}/{id}/role-requests).-
Pending requests are those with
approved_at === nullandrescinded_at === null. They are listed and can be opened for approval or rescission. -
Approval / denial
- Clicking a pending request opens
RoleApprovalModal(app/components/roles/RoleApprovalModal.tsx). - Approvers see requester, grantee, role id, dates, and request reason. They can optionally edit reason and end date via
useUpdateRoleRequestMutation(PATCH on the role request). - Approve/deny is done with
useAnswerRoleRequestMutation(PUT/{type}/{id}/role-requests/{roleRequestId}with body{ approved: true|false, ... }). Success invalidates role-requests and role-grants queries. -
Visibility of the “Approve”/“Deny” actions is gated by
roleDefinitions[roleRequest.role_id].grant_management_permitted_for(and, where used,useUserPermission/ policy checks). -
Rescission
- Requester or grantee can rescind a request (or an active grant that came from a request) via
useRescindUserRoleRequestMutation(DELETE/{type}/{id}/role-requests/{roleRequestId}with rescission reason). - Rescission is offered from the same table row or grant row that shows the request/grant (e.g. in
UserRoleManagement).
Data layer (roles)¶
All hooks and types live in utils/roles.ts. API paths follow /{alaners|external-users|service-accounts}/{id}/role-requests and .../role-grants as per backend.
- Queries:
useRoleDefinitions(),useRoleGrantRules(),useRoleDefinitionsWithGrantRules(),useUserRoleGrants(userId, isServiceAccount),useUserRoleRequests(userId, isServiceAccount),useUserRoleRequest(userId, roleRequestId, isServiceAccount),useLifecycleTaskLogs(userId, isServiceAccount). - Mutations:
useAddUserRoleRequestMutation,useAnswerRoleRequestMutation,useUpdateRoleRequestMutation,useRescindUserRoleRequestMutation,useRunLifecycleTasksMutation(to trigger lifecycle sync). - Types:
RoleRequest,RoleDefinition,RoleDefinitionWithGrantRules,RoleGrant,RoleGrantWithFutureFlag,UserLifecycleTaskLog,PrefilledModalParams(URL search param names for modal prefilling).
Role grants display¶
- Active and future grants are loaded with
useUserRoleGrants. Each grant can carryrole_request_id; when present, the UI fetchesuseUserRoleRequest(granteeId, grant.role_request_id)to show who approved and when (seegenerateRoleGrantTooltipLabelinapp/components/roles/utils.ts). - Tables list grants with optional “Requested”, “Approved by”, “Rescind” and “Reactivate” actions, depending on permissions and whether the grant stems from a request.
Lifecycle tasks¶
UserLifecycleTaskLogsModalshows task run history for the user (e.g. sync status). Triggering a run is done viauseRunLifecycleTasksMutationfrom the same UI.