Skip to content

feat: allow authorized staff users to delete non-default staff roles#302

Open
henry-casper wants to merge 10 commits into
mainfrom
feat/Allow-Authorized-Staff-Users-to-Delete-Non-Default-Staff-Roles
Open

feat: allow authorized staff users to delete non-default staff roles#302
henry-casper wants to merge 10 commits into
mainfrom
feat/Allow-Authorized-Staff-Users-to-Delete-Non-Default-Staff-Roles

Conversation

@henry-casper

@henry-casper henry-casper commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Staff users with staffRolePermissions.canRemoveRole can delete non-default StaffRoles from the staff-role details page. Deletion raises a StaffRoleDeletedEvent whose integration handler reassigns every staff user holding the deleted role to the default StaffRole matching the deleted role's enterpriseAppRole (idempotent; missing default role is logged and surfaced as a processing failure).

  • domain: StaffRole.requestDelete() (visa canRemoveRole, default roles never deletable), StaffRoleDeletedEvent carrying enterpriseAppRole, StaffRoleDeletedReassignmentService, canRemoveRole in UserDomainPermissions and passports; remove legacy deleteAndReassignTo
  • persistence: StaffUserRepository.getAllAssignedToRole
  • application-services: StaffRole.delete (replaces delete-and-reassign)
  • event-handler: staff-role-deleted--reassign-staff-users wired into integration handler registration
  • graphql: staffRoleDelete mutation + command mapper + resolver tests; isDefault exposed on staff-role detail fragment
  • ui: red Delete button with Popconfirm on staff-role details page, gated by canRemoveRole and non-default role; progress/failure feedback; navigate back and refetch list on success; Storybook coverage for deletable/default/no-permission/confirmation/pending/failure states
  • verification: 8 shared Gherkin scenarios implemented across acceptance-api (31/31), acceptance-ui (32/32), and e2e (28/28) with tasks/questions/notes and e2e interactions per contexts/community reference pattern
  • fix: staff-user.resolvers.test.ts step/feature mismatches (file failed at collection on main, masked by aggregate test counts)
  • security: clear pnpm audit/snyk gate failures — bump vitest family to 4.1.10, svgo ^3.3.4, fast-uri ^4.1.1, @opentelemetry/propagator-jaeger ^2.9.0, websocket-driver ^0.7.5, axios 1.18.0, ws 8.21.1; extend expired SNYK-JS-OPENTELEMETRYCORE-17373280 ignore to 2026-10-31

Summary by Sourcery

Introduce a full stack flow for deleting non-default staff roles, including permission-gated UI, GraphQL mutation, application service, domain event, and integration handler that reassigns affected staff users to matching default roles.

New Features:

  • Allow authorized staff users with the remove-role permission to delete non-default staff roles from the staff-role details page.
  • Emit a StaffRoleDeletedEvent on role deletion and handle it with a reassignment service that moves affected staff users to the default role matching the deleted role's enterprise app role.
  • Expose a staffRoleDelete GraphQL mutation and wire it through command mapping and application services to the domain deletion logic.
  • Add UI delete controls, confirmation messaging, and loading/error states for staff-role deletion, including Storybook stories and container wiring.
  • Add new default-role helpers and a default Tech Admin role factory in the staff-role domain.

Bug Fixes:

  • Correct mismatched staff-user resolver tests so scenarios align with the current GraphQL schema and behavior.

Enhancements:

  • Extend user-domain permissions and staff-user passports with a canRemoveRole flag and propagate it through IAM visas and authorization flows.
  • Add repository support for fetching all staff users assigned to a given role and export new user-domain services for reuse.
  • Improve staff user role display handling to be robust against select markup variations in tests and shared page objects.

Build:

  • Update pnpm workspace dependencies (Vitest, axios, svgo, fast-uri, OpenTelemetry, websocket libraries, etc.) and adjust audit configuration and Snyk ignore windows to clear security gates.

Documentation:

  • Expand Gherkin feature coverage for staff-role deletion, default-role protection, permission-based visibility of delete actions, confirmation cancel flows, and deletion failures across API, UI, and E2E suites.

Tests:

  • Add extensive domain, application-service, GraphQL resolver, repository, UI component, Storybook interaction, and verification tests for staff-role deletion, reassignment, permissions, and new user services.

Chores:

  • Register the new staff-role deletion integration handler in the event-handler layer and ensure production handlers are registered in the API acceptance environment.

Staff users with staffRolePermissions.canRemoveRole can delete non-default
StaffRoles from the staff-role details page. Deletion raises a
StaffRoleDeletedEvent whose integration handler reassigns every staff user
holding the deleted role to the default StaffRole matching the deleted
role's enterpriseAppRole (idempotent; missing default role is logged and
surfaced as a processing failure).

- domain: StaffRole.requestDelete() (visa canRemoveRole, default roles
  never deletable), StaffRoleDeletedEvent carrying enterpriseAppRole,
  StaffRoleDeletedReassignmentService, canRemoveRole in
  UserDomainPermissions and passports; remove legacy deleteAndReassignTo
- persistence: StaffUserRepository.getAllAssignedToRole
- application-services: StaffRole.delete (replaces delete-and-reassign)
- event-handler: staff-role-deleted--reassign-staff-users wired into
  integration handler registration
- graphql: staffRoleDelete mutation + command mapper + resolver tests;
  isDefault exposed on staff-role detail fragment
- ui: red Delete button with Popconfirm on staff-role details page, gated
  by canRemoveRole and non-default role; progress/failure feedback;
  navigate back and refetch list on success; Storybook coverage for
  deletable/default/no-permission/confirmation/pending/failure states
- verification: 8 shared Gherkin scenarios implemented across
  acceptance-api (31/31), acceptance-ui (32/32), and e2e (28/28) with
  tasks/questions/notes and e2e interactions per contexts/community
  reference pattern
- fix: staff-user.resolvers.test.ts step/feature mismatches (file failed
  at collection on main, masked by aggregate test counts)
- security: clear pnpm audit/snyk gate failures — bump vitest family to
  4.1.10, svgo ^3.3.4, fast-uri ^4.1.1, @opentelemetry/propagator-jaeger
  ^2.9.0, websocket-driver ^0.7.5, axios 1.18.0, ws 8.21.1; extend expired
  SNYK-JS-OPENTELEMETRYCORE-17373280 ignore to 2026-10-31

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@henry-casper
henry-casper requested review from a team, Copilot and noce-nick July 22, 2026 19:09
@henry-casper
henry-casper requested a review from a team as a code owner July 22, 2026 19:09
@sourcery-ai

sourcery-ai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Implements domain-driven, end-to-end support for deleting non-default staff roles by authorized staff, emitting a StaffRoleDeletedEvent and asynchronously reassigning affected staff users to matching default roles, with full GraphQL, UI, verification, and security dependency coverage and removal of the legacy delete-and-reassign flow.

Sequence diagram for staff role deletion and default-role reassignment

sequenceDiagram
  actor StaffUser
  participant StaffRoleEditUI
  participant GraphQLAPI
  participant StaffRoleAppService
  participant StaffRoleDomain
  participant EventBus
  participant StaffRoleDeletedReassignmentService
  participant StaffUserRepository
  participant StaffUserDomain

  StaffUser->>StaffRoleEditUI: Click "Delete Role" and confirm
  StaffRoleEditUI->>GraphQLAPI: staffRoleDelete(input: { id })
  GraphQLAPI->>StaffRoleAppService: User.StaffRole.delete({ roleId })
  StaffRoleAppService->>StaffRoleDomain: requestDelete()
  StaffRoleDomain->>EventBus: publish StaffRoleDeletedEvent
  GraphQLAPI-->>StaffRoleEditUI: { status: { success: true | false } }

  rect rgb(240,240,240)
    EventBus-->>StaffRoleDeletedReassignmentService: StaffRoleDeletedEvent
    StaffRoleDeletedReassignmentService->>StaffUserRepository: getAllAssignedToRole(deletedRoleId)
    StaffUserRepository-->>StaffRoleDeletedReassignmentService: staffUsers[]
    loop for each staff user not already in default role
      StaffRoleDeletedReassignmentService->>StaffUserDomain: requestRoleAssignment(defaultRole, description, staffUserId)
      StaffRoleDeletedReassignmentService->>StaffUserRepository: save(staffUser)
    end
  end
Loading

File-Level Changes

Change Details Files
Introduce StaffRole.requestDelete domain behavior and StaffRoleDeletedEvent, replacing legacy delete-and-reassign semantics and wiring reassignment via a new domain service and integration event handler.
  • Rename the staff-role deletion method from deleteAndReassignTo to requestDelete, enforcing that default roles cannot be deleted and that canRemoveRole or system account is required, making repeated deletions idempotent.
  • Replace RoleDeletedReassignEvent with StaffRoleDeletedEvent carrying deletedRoleId and enterpriseAppRole, and update staff-role domain tests and feature specs accordingly.
  • Add StaffRoleDeletedReassignmentService under domain services, which looks up the default role by enterpriseAppRole, fetches all staff users assigned to the deleted role, and reassigns them to the matching default role in a system-passport transaction, logging and rethrowing when no default role exists.
  • Register a new integration event handler staff-role-deleted--reassign-staff-users that listens for StaffRoleDeletedEvent on the Domain event bus and invokes the reassignment service, and export the service under Domain.Services.User.
  • Extend the StaffUserRepository domain and persistence contracts with getAllAssignedToRole and implement it using a mongoose find+populate, with cucumber-style tests and feature specs for non-empty and empty results.
packages/ocom/domain/src/domain/contexts/user/staff-role/staff-role.ts
packages/ocom/domain/src/domain/contexts/user/staff-role/staff-role.test.ts
packages/ocom/domain/src/domain/contexts/user/staff-role/features/staff-role.feature
packages/ocom/domain/src/domain/events/types/staff-role-deleted.ts
packages/ocom/domain/src/domain/events/types/index.ts
packages/ocom/domain/src/domain/services/user/staff-role-deleted-reassignment.service.ts
packages/ocom/domain/src/domain/services/user/staff-role-deleted-reassignment.service.test.ts
packages/ocom/domain/src/domain/services/user/index.ts
packages/ocom/domain/src/domain/services/user/index.test.ts
packages/ocom/domain/src/domain/contexts/user/staff-user/staff-user.repository.ts
packages/ocom/persistence/src/datasources/domain/user/staff-user/staff-user.repository.ts
packages/ocom/persistence/src/datasources/domain/user/staff-user/staff-user.repository.test.ts
packages/ocom/persistence/src/datasources/domain/user/staff-user/features/staff-user.repository.feature
packages/ocom/event-handler/src/handlers/integration/staff-role-deleted--reassign-staff-users.ts
packages/ocom/event-handler/src/handlers/integration/index.ts
Extend user/staff-role permission model with canRemoveRole, propagate it through passports and visas, and guard delete capabilities accordingly.
  • Add canRemoveRole to UserDomainPermissions and wire it through StaffUserUserPassport.forStaffRole using the role.permissions.staffRolePermissions.canRemoveRole field, with positive and negative cucumber tests.
  • Update member-related visas (end-user, staff-role, staff-user, vendor-user) and staff-user activity-log tests to initialize canRemoveRole to false to keep non-staff-user contexts unchanged.
  • Adjust test helpers (makePassport, makeStaffUser) and staff-role Gherkin feature wording to distinguish manage vs remove-role permissions and to use canRemoveRole for deletion scenarios.
packages/ocom/domain/src/domain/contexts/user/user.domain-permissions.ts
packages/ocom/domain/src/domain/iam/user/staff-user/contexts/staff-user.user.passport.ts
packages/ocom/domain/src/domain/iam/user/staff-user/contexts/staff-user.user.passport.test.ts
packages/ocom/domain/src/domain/iam/user/staff-user/contexts/features/staff-user.user.passport.feature
packages/ocom/domain/src/domain/iam/member/contexts/member.user.end-user.visa.ts
packages/ocom/domain/src/domain/iam/member/contexts/member.user.staff-role.visa.ts
packages/ocom/domain/src/domain/iam/member/contexts/member.user.staff-user.visa.ts
packages/ocom/domain/src/domain/iam/member/contexts/member.user.vendor-user.visa.ts
packages/ocom/domain/src/domain/contexts/user/staff-role/staff-role.test.ts
packages/ocom/domain/src/domain/contexts/user/staff-user/staff-user-activity-log.entity.additional.test.ts
Add GraphQL and application-service support for staff role deletion, replacing the old delete-and-reassign API and mapping the new domain behavior into the schema.
  • Replace the StaffRoleApplicationService.deleteAndReassign with a new delete(command) method that loads a role by id, calls requestDelete, and saves within a scoped transaction, plus cucumber tests for success, not-found, and domain-refusal cases.
  • Add StaffRoleDeleteCommand and deleteStaffRole application-service function with feature coverage, and wire it into StaffRole index.ts and its index.feature tests.
  • Extend the GraphQL schema with StaffRoleDeleteInput and StaffRoleDeleteMutationResult, expose a staffRoleDelete mutation, and implement the resolver to require a verified JWT, build a delete command, call applicationServices.User.StaffRole.delete, and translate errors into MutationStatus.
  • Add a command mapper buildStaffRoleDeleteCommand and tests for the staff-role delete resolver behavior (success, unauthorized, and application-service error).
  • Ensure domain services index now exports User services alongside Community, and that acceptance-api application services factory registers integration event handlers (including the new reassignment handler) exactly once for tests.
packages/ocom/application-services/src/contexts/user/staff-role/index.ts
packages/ocom/application-services/src/contexts/user/staff-role/index.test.ts
packages/ocom/application-services/src/contexts/user/staff-role/delete.ts
packages/ocom/application-services/src/contexts/user/staff-role/delete.test.ts
packages/ocom/application-services/src/contexts/user/staff-role/features/delete.feature
packages/ocom/application-services/src/contexts/user/staff-role/features/index.feature
packages/ocom/graphql/src/schema/types/staff-role.graphql
packages/ocom/graphql/src/schema/types/staff-role.command-mapper.ts
packages/ocom/graphql/src/schema/types/staff-role.resolvers.ts
packages/ocom/graphql/src/schema/types/staff-role.resolvers.test.ts
packages/ocom/graphql/src/schema/types/features/staff-role.resolvers.feature
packages/ocom/domain/src/domain/services/index.ts
packages/ocom/domain/src/domain/services/index.test.ts
packages/ocom/domain/src/domain/services/features/index.feature
packages/ocom-verification/acceptance-api/src/mock-application-services.ts
packages/ocom-verification/acceptance-api/package.json
Implement UI affordances and client GraphQL wiring for deleting staff roles from the staff portal, with Storybook coverage and mocked backend support.
  • Extend StaffRoleCreate form component to accept showDelete, onDelete, deleting props and render a red Delete Role button with an antd Popconfirm that explains reassignment to the matching default role and exposes appropriate loading and cancel/confirm behavior, plus unit tests around visibility and confirmation semantics.
  • Update StaffRoleEditContainer to query isDefault, compute canRemoveRole from StaffAuthContext, generate a StaffRoleDelete mutation and useMutation hook, and pass showDelete/onDelete/deleting so only non-default roles for users with canRemoveRole show the delete action; handle success with a toast and navigation back to the list, and handle failure with error messaging.
  • Add component and container stories (StaffRoleCreate, StaffRoleEditContainer) to cover deletable/default/no-permission, confirmation, pending, and server-failure states using Storybook interactions and Apollo mocks.
  • Extend the staff-role edit container GraphQL fragment and documents to include isDefault and the new StaffRoleDelete mutation, and adjust the Storybook preview MockedProvider to use typename-aware defaults.
packages/ocom/ui-staff-route-user-management/src/components/staff-role-create.tsx
packages/ocom/ui-staff-route-user-management/src/components/staff-role-create.test.tsx
packages/ocom/ui-staff-route-user-management/src/components/staff-role-edit.container.tsx
packages/ocom/ui-staff-route-user-management/src/components/staff-role-edit.container.graphql
packages/ocom/ui-staff-route-user-management/src/components/staff-role-edit.stories.tsx
packages/ocom/ui-staff-route-user-management/src/components/staff-role-edit.container.stories.tsx
packages/ocom/ui-staff-route-user-management/.storybook/preview.tsx
Update verification (acceptance API/UI and E2E) to cover staff-role delete flows, reassignment behavior, and UI edge cases, including new page objects and tasks.
  • Extend the shared staff-role-management.feature with scenarios for deleting non-default roles, reassignment to defaults, default-role deletion protection, permission-based visibility, confirmation cancel, and failure handling.
  • Add staff-role delete tasks and questions across acceptance-ui, acceptance-api, and e2e: delete via form, start/cancel deletion, visibility of delete action and confirmation text, list exclusion checks, and outcome tracking via notes and mutation status.
  • Enhance mock staff-role backend used in acceptance-ui to track isDefault, support StaffRoleDeleteDocument when generated, allow toggleable delete failures, and include isDefault in GraphQL payload and edit initial values.
  • Introduce staff-user pages and flows (StaffUserDetailPage, StaffUsersListPage) plus abilities and tasks to assign staff roles to users via the UI and E2E, and questions that poll for reassigned roles given asynchronous integration handling.
  • Wire up acceptance-api abilities and tasks to call the new STAFF_ROLE_DELETE_MUTATION, store deletion status, and add polling logic in staff role/user questions to wait for reassignment after deletion.
packages/ocom-verification/verification-shared/src/scenarios/staff/staff-role-management.feature
packages/ocom-verification/acceptance-ui/src/contexts/staff-role/abilities/mock-staff-role-backend.ts
packages/ocom-verification/acceptance-ui/src/contexts/staff-role/questions/staff-role-screen.ts
packages/ocom-verification/acceptance-ui/src/contexts/staff-role/tasks/delete-staff-role.ts
packages/ocom-verification/acceptance-ui/src/contexts/staff-role/step-definitions/staff-role-management.steps.tsx
packages/ocom-verification/acceptance-api/src/shared/graphql/staff-role-operations.ts
packages/ocom-verification/acceptance-api/src/shared/abilities/delete-staff-role.ts
packages/ocom-verification/acceptance-api/src/shared/abilities/index.ts
packages/ocom-verification/acceptance-api/src/contexts/staff-role/tasks/delete-staff-role.ts
packages/ocom-verification/acceptance-api/src/contexts/staff-role/step-definitions/staff-role-management.steps.ts
packages/ocom-verification/acceptance-api/src/world.ts
packages/ocom-verification/e2e-tests/src/contexts/staff-role/questions/staff-role-screen.ts
packages/ocom-verification/e2e-tests/src/contexts/staff-role/questions/staff-user-screen.ts
packages/ocom-verification/e2e-tests/src/contexts/staff-role/abilities/staff-user-page.ts
packages/ocom-verification/e2e-tests/src/contexts/staff-role/interactions/delete-staff-role-actions.ts
packages/ocom-verification/e2e-tests/src/contexts/staff-role/interactions/open-edit-staff-role-form.ts
packages/ocom-verification/e2e-tests/src/contexts/staff-role/tasks/delete-staff-role.ts
packages/ocom-verification/e2e-tests/src/contexts/staff-role/tasks/assign-staff-role-to-user.ts
packages/ocom-verification/e2e-tests/src/contexts/staff-role/step-definitions/staff-role-management.steps.ts
packages/ocom-verification/verification-shared/src/pages/staff-role-form.page.ts
packages/ocom-verification/verification-shared/src/pages/staff-users-list.page.ts
packages/ocom-verification/verification-shared/src/pages/staff-user-detail.page.ts
packages/ocom-verification/verification-shared/src/pages/index.ts
Minor fixes and security dependency updates to keep the test suite and tooling green.
  • Fix staff-user.resolvers.test.ts feature/step expectation mismatches to align with current resolver behavior around permission delegation and error messages.
  • Tighten a StaffUserDetail test to be resilient across antd versions by looking for either .ant-select-selection-item or .ant-select-content when checking displayed role labels.
  • Upgrade vitest-related packages, axios, svgo, fast-uri, @opentelemetry/propagator-jaeger, websocket-driver, and ws via pnpm-workspace catalog/overrides, and extend the SNYK opentelemetry-core ignore expiry to 2026-10-31.
packages/ocom/graphql/src/schema/types/staff-user.resolvers.test.ts
packages/ocom/ui-staff-route-user-management/src/components/staff-user-detail.test.tsx
pnpm-workspace.yaml
.snyk
pnpm-lock.yaml

Possibly linked issues

  • #Allow Authorized Staff Users to Delete Non-Default Staff Roles: PR fulfills the issue: adds guarded delete API/UI, StaffRoleDeletedEvent, reassignment handler, Storybook, and verification tests.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

Fixed security issues:

  • @opentelemetry/propagator-jaeger (link)

  • @vitest/browser (link)

  • axios (link)

  • fast-uri (link)

  • svgo (link)

  • websocket-driver (link)

  • The new StaffRoleDeletedReassignmentService logs and then rethrows (and in one branch recreates) errors for missing default roles, which leads to duplicated, slightly inconsistent error messages; consider centralizing this into a single error construction/logging path so downstream handlers see a consistent error type/message.

  • The new StaffUserAssignedRole E2E question implements its own 30-second polling loop with setTimeout; it might be more maintainable and less flaky to use a shared wait helper (similar to waitUntil) with a shorter default timeout and configurable interval instead of hand-rolled sleeps.

  • Both the UI component tests and the new page objects rely on specific antd class names/selectors (e.g. .ant-select-selection-item, .ant-select-content, .ant-popconfirm); to reduce fragility on library upgrades, consider encapsulating these selectors in a single utility or page-object layer and avoiding duplicated selector strings across tests.

Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `StaffRoleDeletedReassignmentService` logs and then rethrows (and in one branch recreates) errors for missing default roles, which leads to duplicated, slightly inconsistent error messages; consider centralizing this into a single error construction/logging path so downstream handlers see a consistent error type/message.
- The new `StaffUserAssignedRole` E2E question implements its own 30-second polling loop with `setTimeout`; it might be more maintainable and less flaky to use a shared wait helper (similar to `waitUntil`) with a shorter default timeout and configurable interval instead of hand-rolled sleeps.
- Both the UI component tests and the new page objects rely on specific antd class names/selectors (e.g. `.ant-select-selection-item, .ant-select-content`, `.ant-popconfirm`); to reduce fragility on library upgrades, consider encapsulating these selectors in a single utility or page-object layer and avoiding duplicated selector strings across tests.

## Individual Comments

### Comment 1
<location path="packages/ocom/domain/src/domain/services/user/staff-role-deleted-reassignment.service.ts" line_range="19" />
<code_context>
+	export class StaffRoleDeletedReassignmentService {
</code_context>
<issue_to_address>
**suggestion:** Error handling for missing default role is a bit redundant and could be simplified while still logging context

`reassignStaffUsersToDefaultRole` both logs/rethrows in the `catch` and then has a separate `if (!defaultRole)` that logs/throws again. Given `getDefaultRoleByEnterpriseAppRole` currently rejects when not found, the `if (!defaultRole)` branch is unreachable and could lead to duplicate logging if the repo is later changed. It would be clearer to keep a single error path: either rely on the repo throwing and handle/log/throw only in the `catch`, or change the repo to return `null` and handle only the `!defaultRole` case.
</issue_to_address>

### Comment 2
<location path="packages/ocom/ui-staff-route-user-management/src/components/staff-role-edit.container.graphql" line_range="19" />
<code_context>
 	}
 }

+mutation StaffRoleDelete($input: StaffRoleDeleteInput!) {
+	staffRoleDelete(input: $input) {
+		status {
</code_context>
<issue_to_address>
**issue (review_instructions):** This container GraphQL file does not follow the required directory structure under `layouts/<AreaName>/components/`.

Per the conventions, container GraphQL files should live under `ui-<PortalName>/src/components/layouts/<AreaName>/components/<componentName>.container.graphql`. This file is currently at `ui-staff-route-user-management/src/components/staff-role-edit.container.graphql`, which is missing the `layouts/<AreaName>/components` segments. Please relocate it (and its corresponding container component, if applicable) to match the required path pattern.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.container.graphql`

**Instructions:**
container graphql files should be found in the following path pattern: ui-<PortalName>/src/components/layouts/<AreaName>/components/<componentName>.container.graphql

</details>
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements an end-to-end “delete non-default staff role” flow across domain, persistence, application services, GraphQL, UI, and verification suites. The deletion emits a StaffRoleDeletedEvent and an integration handler reassigns staff users from the deleted role to the matching default role by enterpriseAppRole.

Changes:

  • Adds StaffRole.requestDelete() + StaffRoleDeletedEvent + reassignment domain service + integration handler wiring.
  • Introduces staffRoleDelete GraphQL mutation and wires it through application services to the domain, plus UI delete action (Popconfirm + loading/error feedback).
  • Expands repositories and verification coverage (acceptance-api/acceptance-ui/e2e) and updates security-related dependency overrides/Snyk ignore.

Blocking review notes (requires changes)

  • packages/ocom/ui-staff-route-user-management/tsconfig.vitest.json uses "extends": [...] (an array). TypeScript tsconfig.json extends expects a single string, so this is very likely to fail config parsing in Vitest/tsc. Use a single extends target (and merge the other config’s options) or introduce an intermediate config file that extends one base and is then extended by the other.

Reviewed changes

Copilot reviewed 80 out of 81 changed files in this pull request and generated no comments.

Show a summary per file
File Description
pnpm-workspace.yaml Bumps Vitest and security-related overrides (axios/svgo/ws/fast-uri/etc.) to clear audit/Snyk gates.
packages/ocom/ui-staff-route-user-management/tsconfig.vitest.json Adds Vitest TS config (currently uses invalid extends array).
packages/ocom/ui-staff-route-user-management/src/components/staff-user-detail.test.tsx Makes role-display assertion resilient to antd markup differences.
packages/ocom/ui-staff-route-user-management/src/components/staff-role-edit.stories.tsx Adds Storybook scenarios for deletable/default/no-permission/confirm/loading states.
packages/ocom/ui-staff-route-user-management/src/components/staff-role-edit.container.tsx Wires delete mutation, gating by canRemoveRole and !isDefault, with success/error navigation & feedback.
packages/ocom/ui-staff-route-user-management/src/components/staff-role-edit.container.stories.tsx Adds container-level Storybook coverage for delete failure path via Apollo mocks.
packages/ocom/ui-staff-route-user-management/src/components/staff-role-edit.container.graphql Adds StaffRoleDelete mutation and exposes isDefault in edit fragment.
packages/ocom/ui-staff-route-user-management/src/components/staff-role-create.tsx Adds delete button + Popconfirm + loading state to the edit header of the form component.
packages/ocom/ui-staff-route-user-management/src/components/staff-role-create.test.tsx Adds unit tests for delete button visibility, confirmation behavior, and loading state.
packages/ocom/ui-staff-route-user-management/.storybook/preview.tsx Adjusts MockedProvider setup for Storybook decorators.
packages/ocom/persistence/src/datasources/domain/user/staff-user/staff-user.repository.ts Adds getAllAssignedToRole for bulk role reassignment.
packages/ocom/persistence/src/datasources/domain/user/staff-user/staff-user.repository.test.ts Adds Cucumber/Vitest scenarios covering getAllAssignedToRole.
packages/ocom/persistence/src/datasources/domain/user/staff-user/features/staff-user.repository.feature Adds feature scenarios for getAllAssignedToRole.
packages/ocom/graphql/src/schema/types/staff-user.resolvers.test.ts Fixes resolver test expectations/mocking for role update/permission paths.
packages/ocom/graphql/src/schema/types/staff-role.resolvers.ts Adds staffRoleDelete resolver mapping to application service delete command.
packages/ocom/graphql/src/schema/types/staff-role.resolvers.test.ts Adds resolver tests for success/unauthorized/error handling for staffRoleDelete.
packages/ocom/graphql/src/schema/types/staff-role.graphql Adds StaffRoleDeleteInput, result type, and staffRoleDelete mutation.
packages/ocom/graphql/src/schema/types/staff-role.command-mapper.ts Adds command mapper for delete (roleId).
packages/ocom/graphql/src/schema/types/features/staff-user.resolvers.feature Updates Gherkin scenario naming/expectations to match resolver behavior.
packages/ocom/graphql/src/schema/types/features/staff-role.resolvers.feature Adds Gherkin coverage for staff role delete resolver behavior.
packages/ocom/event-handler/src/handlers/integration/staff-role-deleted--reassign-staff-users.ts Registers integration handler to reassign staff users after role deletion.
packages/ocom/event-handler/src/handlers/integration/index.ts Wires new staff-role-deleted integration handler into registration.
packages/ocom/domain/src/domain/services/user/staff-role-deleted-reassignment.service.ts Implements reassignment to matching default role; logs and fails when default role is missing.
packages/ocom/domain/src/domain/services/user/staff-role-deleted-reassignment.service.test.ts Adds Cucumber/Vitest tests for reassignment success/idempotency/missing-default failure.
packages/ocom/domain/src/domain/services/user/index.ts Exposes StaffRoleDeletedReassignmentService via Domain.Services.User.
packages/ocom/domain/src/domain/services/user/index.test.ts Tests Domain.Services.User export shape.
packages/ocom/domain/src/domain/services/user/features/staff-role-deleted-reassignment.service.feature Gherkin coverage for reassignment service behavior.
packages/ocom/domain/src/domain/services/user/features/index.feature Gherkin coverage for user services index export.
packages/ocom/domain/src/domain/services/index.ts Exports User services alongside Community.
packages/ocom/domain/src/domain/services/index.test.ts Tests services index exports include User.
packages/ocom/domain/src/domain/services/features/index.feature Updates Gherkin for services index export coverage.
packages/ocom/domain/src/domain/iam/user/staff-user/contexts/staff-user.user.passport.ts Propagates canRemoveRole into user-domain permissions for staff users.
packages/ocom/domain/src/domain/iam/user/staff-user/contexts/staff-user.user.passport.test.ts Adds passport tests for canRemoveRole mapping.
packages/ocom/domain/src/domain/iam/user/staff-user/contexts/features/staff-user.user.passport.feature Adds Gherkin scenarios for canRemoveRole mapping.
packages/ocom/domain/src/domain/iam/member/contexts/member.user.vendor-user.visa.ts Extends member visa permissions with canRemoveRole: false.
packages/ocom/domain/src/domain/iam/member/contexts/member.user.staff-user.visa.ts Extends member visa permissions with canRemoveRole: false.
packages/ocom/domain/src/domain/iam/member/contexts/member.user.staff-role.visa.ts Extends member visa permissions with canRemoveRole: false.
packages/ocom/domain/src/domain/iam/member/contexts/member.user.end-user.visa.ts Extends member visa permissions with canRemoveRole: false.
packages/ocom/domain/src/domain/events/types/staff-role-deleted.ts Introduces StaffRoleDeletedEvent payload carrying enterpriseAppRole.
packages/ocom/domain/src/domain/events/types/index.ts Exports StaffRoleDeletedEvent.
packages/ocom/domain/src/domain/contexts/user/user.domain-permissions.ts Adds canRemoveRole to shared UserDomainPermissions.
packages/ocom/domain/src/domain/contexts/user/staff-user/staff-user.repository.ts Extends domain repository contract with getAllAssignedToRole.
packages/ocom/domain/src/domain/contexts/user/staff-user/staff-user-activity-log.entity.additional.test.ts Updates test permissions object to include canRemoveRole.
packages/ocom/domain/src/domain/contexts/user/staff-role/staff-role.ts Replaces legacy delete-and-reassign with requestDelete() that emits StaffRoleDeletedEvent and enforces permission/default-role rules.
packages/ocom/domain/src/domain/contexts/user/staff-role/staff-role.test.ts Updates unit tests/features for requestDelete, idempotency, and new default-role helpers.
packages/ocom/domain/src/domain/contexts/user/staff-role/features/staff-role.feature Updates Gherkin for delete semantics (requestDelete) and idempotency.
packages/ocom/application-services/src/contexts/user/staff-role/index.ts Replaces deleteAndReassign with delete service entry point.
packages/ocom/application-services/src/contexts/user/staff-role/index.test.ts Updates application service delegation tests for delete.
packages/ocom/application-services/src/contexts/user/staff-role/features/index.feature Updates Gherkin for application service delete delegation.
packages/ocom/application-services/src/contexts/user/staff-role/features/delete.feature Adds Gherkin for delete service behavior.
packages/ocom/application-services/src/contexts/user/staff-role/features/delete-and-reassign.feature Removes legacy delete-and-reassign Gherkin.
packages/ocom/application-services/src/contexts/user/staff-role/delete.ts Implements delete app-service calling requestDelete() and saving.
packages/ocom/application-services/src/contexts/user/staff-role/delete.test.ts Adds tests for delete service success/not-found/domain-refusal paths.
packages/ocom/application-services/src/contexts/user/staff-role/delete-and-reassign.ts Removes legacy delete-and-reassign implementation.
packages/ocom/application-services/src/contexts/user/staff-role/delete-and-reassign.test.ts Removes legacy delete-and-reassign tests.
packages/ocom-verification/verification-shared/src/scenarios/staff/staff-role-management.feature Adds shared Gherkin scenarios for delete flow, permission gating, cancel, and failure behavior.
packages/ocom-verification/verification-shared/src/pages/staff-users-list.page.ts Adds page object for staff users list (used by acceptance/e2e).
packages/ocom-verification/verification-shared/src/pages/staff-user-detail.page.ts Adds page object for staff user detail screen (role select + displayed role name).
packages/ocom-verification/verification-shared/src/pages/staff-role-form.page.ts Adds delete-action elements and helpers to staff role form page object.
packages/ocom-verification/verification-shared/src/pages/index.ts Exports new staff user page objects.
packages/ocom-verification/e2e-tests/src/contexts/staff-role/tasks/delete-staff-role.ts Adds e2e tasks for delete / start delete / cancel delete.
packages/ocom-verification/e2e-tests/src/contexts/staff-role/tasks/assign-staff-role-to-user.ts Adds e2e task to assign staff role to user via staff user detail flow.
packages/ocom-verification/e2e-tests/src/contexts/staff-role/step-definitions/staff-role-management.steps.ts Adds step definitions for delete flow and reassignment assertion.
packages/ocom-verification/e2e-tests/src/contexts/staff-role/questions/staff-user-screen.ts Adds polling question for post-delete reassignment completion.
packages/ocom-verification/e2e-tests/src/contexts/staff-role/questions/staff-role-screen.ts Adds questions for delete action visibility/confirmation text/list exclusion.
packages/ocom-verification/e2e-tests/src/contexts/staff-role/interactions/delete-staff-role-actions.ts Adds low-level delete/cancel/confirm interactions.
packages/ocom-verification/e2e-tests/src/contexts/staff-role/abilities/staff-user-page.ts Adds Playwright ability helpers to navigate users list and open detail screen.
packages/ocom-verification/acceptance-ui/src/contexts/staff-role/tasks/delete-staff-role.ts Adds DOM-acceptance UI tasks for delete flow (start/confirm/cancel).
packages/ocom-verification/acceptance-ui/src/contexts/staff-role/step-definitions/staff-role-management.steps.tsx Adds acceptance-ui step definitions for delete/cancel/failure gating.
packages/ocom-verification/acceptance-ui/src/contexts/staff-role/questions/staff-role-screen.ts Adds acceptance-ui questions for delete action/confirmation/list exclusion.
packages/ocom-verification/acceptance-ui/src/contexts/staff-role/abilities/mock-staff-role-backend.ts Extends mock backend with delete mutation mocking and isDefault handling.
packages/ocom-verification/acceptance-api/src/world.ts Registers delete staff role ability for acceptance-api actors.
packages/ocom-verification/acceptance-api/src/shared/graphql/staff-role-operations.ts Adds delete mutation string for API verification client.
packages/ocom-verification/acceptance-api/src/shared/abilities/index.ts Exports delete ability.
packages/ocom-verification/acceptance-api/src/shared/abilities/delete-staff-role.ts Adds Serenity ability to delete staff roles via GraphQL mutation.
packages/ocom-verification/acceptance-api/src/mock-application-services.ts Registers production event handlers once so integration events run in acceptance-api environment.
packages/ocom-verification/acceptance-api/src/contexts/staff-role/tasks/delete-staff-role.ts Adds acceptance-api task to delete a staff role and record outcome notes.
packages/ocom-verification/acceptance-api/src/contexts/staff-role/step-definitions/staff-role-management.steps.ts Adds API steps for delete flow and polling for async reassignment completion.
packages/ocom-verification/acceptance-api/package.json Adds dependency on @ocom/event-handler for acceptance-api handler registration.
.snyk Extends ignore expiry for SNYK-JS-OPENTELEMETRYCORE-17373280.

Apply focused fixes for failure propagation, assignment races, permission consistency, and audit attribution on top of the original staff-role deletion implementation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@henry-casper
henry-casper force-pushed the feat/Allow-Authorized-Staff-Users-to-Delete-Non-Default-Staff-Roles branch from 3c24594 to 0c2f3b8 Compare July 23, 2026 02:34
@henry-casper
henry-casper requested a review from Copilot July 23, 2026 02:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 93 out of 94 changed files in this pull request and generated no new comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 109 out of 110 changed files in this pull request and generated no new comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 109 out of 110 changed files in this pull request and generated no new comments.

henry-casper and others added 2 commits July 23, 2026 11:42
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 132 out of 133 changed files in this pull request and generated no new comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@henry-casper
henry-casper requested a review from Copilot July 23, 2026 18:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 136 out of 137 changed files in this pull request and generated no new comments.

Reassign deleted-role users in bounded transactions so later failures preserve completed batches, and decouple deletion success from list refresh failures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 136 out of 137 changed files in this pull request and generated no new comments.

Treat post-commit reassignment failures as a successful deletion with a recovery warning so the UI clears stale role data and navigates away.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 136 out of 137 changed files in this pull request and generated no new comments.

Retry the remote pipeline after an unrelated acceptance UI timing failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 136 out of 137 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow Authorized Staff Users to Delete Non-Default Staff Roles

2 participants