Skip to content

feat(admin): users-management page with admin/agent role toggles#57

Merged
mpge merged 1 commit into
mainfrom
feat/admin-users-management-ui
May 10, 2026
Merged

feat(admin): users-management page with admin/agent role toggles#57
mpge merged 1 commit into
mainfrom
feat/admin-users-management-ui

Conversation

@mpge
Copy link
Copy Markdown
Member

@mpge mpge commented May 10, 2026

Summary

Port escalated-laravel#94 (1b2c5b3e16a68056f1f9f90a6df6c733393a4519) to ASP.NET Core. Adds an admin users-management page so admins can grant or revoke admin / agent access from the panel — surfaces the same shared Vue page (Escalated/Admin/Users/Index) other host plugins already render.

  • New AdminUsersController (GET /support/admin/users, PATCH /support/admin/users/{userId}/role) emits/accepts the same JSON shape the canonical Laravel controller does, so the shared Vue page renders unchanged.
  • The .NET plugin does not own a host User entity, so identity reads (name + email + id) go through a new host-supplied IUserDirectory. NullUserDirectory ships as the default so the plugin boots before the host wires it up (the users page just shows an empty list until the host registers their own implementation).
  • Admin / agent membership is stored in the plugin's own role_user join against two well-known slugs (escalated-admin, escalated-agent). Admins are agents — same contract the Laravel reference emits.
  • Self-demote on admin is rejected so the admin cannot lock themselves out of the panel they are using.
  • Demoting an admin via the agent toggle revokes both flags in one step (otherwise the admin gate would stay on while the agent gate was off, which is confusing).

Notes for reviewers

  • The "current user" is taken from a currentUserId query param, mirroring the causerId pattern used elsewhere in the plugin (AdminTicketController, AgentTicketController) — the plugin defers auth identity to the host.
  • 7 xUnit cases mirror the 7 Pest cases in tests/Feature/Admin/UserControllerTest.php so any behavior change here is easy to compare against the canonical reference.
  • No package.json exists in this repo to bump for @escalated-dev/escalated — the .NET host app consumes the shared Vue bundle out-of-band.

Test plan

  • 7 new xUnit cases in tests/Escalated.Tests/Controllers/AdminUsersControllerTests.cs
  • CI: dotnet build + dotnet test (waited on for this PR)
  • Manual: a host that registers an IUserDirectory should be able to load /support/admin/users, search filters the list, toggling Admin grants both flags, and a self-demote is rejected.

Port escalated-laravel#94 to ASP.NET Core. Adds AdminUsersController
exposing the shared Vue page (Escalated/Admin/Users/Index) backed by:

  - IUserDirectory — host-supplied lookup of name/email/id (the plugin
    has no host User entity of its own); NullUserDirectory ships as the
    default so the plugin still boots before the host wires it up.
  - role_user join against two well-known role slugs (escalated-admin,
    escalated-agent) for the admin/agent flags. Admins are agents — the
    same contract the Laravel reference emits.

PATCH .../users/{userId}/role takes {role, value}. Self-demote on
admin is rejected so the admin cannot lock themselves out of the panel.

7 xUnit cases mirror the Pest cases in
tests/Feature/Admin/UserControllerTest.php so any behavior change
here is easy to compare against the canonical reference.
@mpge mpge merged commit 7e09c9e into main May 10, 2026
2 checks passed
@mpge mpge deleted the feat/admin-users-management-ui branch May 10, 2026 22:53
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.

1 participant