Skip to content

Let admin components run administration flows and lifecycle actions - #57

Open
brionmario wants to merge 1 commit into
thunder-id:mainfrom
brionmario:feat-admin-components-flow-mode
Open

brionmario wants to merge 1 commit into
thunder-id:mainfrom
brionmario:feat-admin-components-flow-mode

Conversation

@brionmario

@brionmario brionmario commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Purpose

Port of thunder-id/javascript-sdks#141. The admin components called the management API directly, so an app that cleans up runtime state through the server's administration flows (revoking grants and ending sessions before a record changes) couldn't use them. They also had no way to suspend, unsuspend or unlock an identity, which only work through flows. This implements UI requirement 8 of the SDK specification (thunder-id/thunderid#6080).

Approach

  • administrationMode (default native) on UserDetails, GroupMembers, RoleAssignments and ApplicationDetails, passed to the user deletion, group member removal, role assignment removal, application deletion and client secret regeneration calls. Agent details has none, because agent deletion has no flow.
  • lifecycleActions (default off) on user, agent and application details. When on, the component reads the configured flows (only then) and offers the actions the record's status allows whose flow is configured: ACTIVE → suspend; LOCKED → unlock, suspend; SUSPENDED → unsuspend. Applications are never locked. Suspend and unsuspend ask for confirmation inline, a user or agent suspension takes an optional operator note (up to 100 characters), and unlock runs straight away. The record and its list reload afterwards.
  • Base variants and the custom render (builder states: UserDetailsState, AgentDetailsState, ApplicationDetailsState) receive lifecycleActions, onLifecycleAction and isRunningLifecycleAction. These apply to read-only records too, since they change only runtime state.
  • Status and errors: the access status shows as a translated label. A failed read of the configured flows shows admin.common.lifecycle.load_error, and a failed action shows admin.common.lifecycle.error.
  • Core: AccessStatus (with AccessStatusDetails and AccessLockedMethod) read on ManagedUser, Agent and Application. Unknown values are kept as sent. AccountLifecycleAction, and AccountLifecycleSubjectKind with its flowConfigKeys. The client gains runAccountLifecycleAction(...), which refuses an application unlock with invalidInput, plus a top-level getAccountLifecycleActions. The state layer gains accountLifecycleFlowsQuery, accountLifecycleMutation, and administrationMode on the affected mutations.
  • Strings: new admin.common.status.*, admin.common.lifecycle.* and admin.common.columns.status keys. This SDK ships English defaults only, so there are no other locales to fill.
  • Fix: Application.status is now typed and no longer kept in additionalFields. It used to be sent back on updates, which the server never accepts. The round-trip test checks it.
  • Application details now use the shared status label, so all three details views match.
  • Playground: lifecycle, status and administrationMode controls on the admin stories, and lifecycle actions in the custom-render user card.

Related Issues

Related PRs

Checklist

  • Followed the contribution guidelines.
  • Manual test round performed and verified.
  • Documentation provided. (doc comments on the new options, and playground stories)
  • Tests provided.
    • Unit Tests: 38 new (18 widget, 20 core); flutter test 532 passed; flutter analyze clean
    • Integration Tests
  • Breaking changes. (Fill if applicable)
    • Breaking changes section filled.
    • breaking change label added.
  • Cross-SDK parity. Exactly one of parity/prs-raised or parity/prs-not-needed added.
    • If parity/prs-raised, the port links are posted as a reply on the parity check's comment.

Security checks

  • Followed secure coding standards.
  • Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.

The admin widgets called the management API directly, so an app that
cleans up runtime state through administration flows (revoking grants and
ending sessions) could not use them, and they had no way to suspend,
unsuspend or unlock an identity.

- `administrationMode` (default `native`) on UserDetails, GroupMembers,
  RoleAssignments and ApplicationDetails, passed to the delete, member
  removal, assignment removal and secret regeneration mutations.
- `lifecycleActions` on UserDetails, AgentDetails and ApplicationDetails.
  When on, the widget reads the configured flows and offers only the
  actions the identity's status allows and whose flow is configured.
  Suspend and unsuspend confirm inline, a suspension of a user or agent
  takes an optional operator note (max 100), and unlock runs straight
  away. The Base variants and their builder state get `lifecycleActions`,
  `onLifecycleAction` and `isRunningLifecycleAction`.
- The access status is typed on users, agents and applications
  (`AccessStatus`) and shown as a translated label; an application no
  longer sends its server-set status back on an update.
- Core: `getAccountLifecycleActions`, `runAccountLifecycleAction`,
  `AccountLifecycleAction` and `AccountLifecycleSubjectKind`, plus the
  state-layer query and mutation; new strings in the bundled locale.
- Tests, and playground controls for the details, members and
  assignments stories.

Signed-off-by: Brion <info@brionmario.com>
@coderabbitai

coderabbitai Bot commented Oct 28, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

🔀 Cross-SDK feature parity, ports raised

This pull request is labelled parity/prs-raised, so the capability it introduces is expected in the other ThunderID SDKs as well.

Ports (DO NOT EDIT)

  • thunder-id/javascript-sdks, JavaScript (React, Vue, Nuxt, Next.js, Express, React Router, TanStack Router, Browser, Node) => #141
  • thunder-id/ios-sdks, iOS => #36
  • thunder-id/android-sdks, Android => #44

3 of 3 sibling SDKs accounted for.

Every sibling SDK is accounted for.

The contract is in the SDK development specification.

@brionmario

Copy link
Copy Markdown
Member Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

parity/prs-raised Ports exist in the other SDKs, or are recorded as not applying there

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant