fix(delete): review follow-ups — admin Deleted filter, guest gate, dialog spacing
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 16s
CI / ui (pull_request) Successful in 1m5s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m46s

- Admin /users gains a Deleted scope (between People and Robots); every other scope now
  hides tombstoned accounts (deleted_at filter in UserFilter).
- Admin delete-user is offered for any non-deleted account (drop the not-guest gate, so a
  stale is_guest account can still be tombstoned).
- Harden EmailService.ConfirmCode to ClearGuest — defence-in-depth so no confirmed-email
  path leaves is_guest set (the currently-live paths already do).
- Space the delete/change dialog's action row from its input field.
Integration tests: the Deleted filter scoping + ConfirmCode guest promotion.
This commit is contained in:
Ilia Denisov
2026-07-03 13:59:43 +02:00
parent c2a8426b74
commit 3faca690dd
8 changed files with 113 additions and 9 deletions
@@ -134,6 +134,7 @@ func (s *Server) consoleUsers(c *gin.Context) {
page := consolePage(c)
filter := account.UserFilter{
Robots: c.Query("kind") == "robots",
Deleted: c.Query("kind") == "deleted",
NameMask: c.Query("name"),
ExternalIDMask: c.Query("ext"),
EmailExact: c.Query("email"),
@@ -148,6 +149,9 @@ func (s *Server) consoleUsers(c *gin.Context) {
if filter.Robots {
q.Set("kind", "robots")
}
if filter.Deleted {
q.Set("kind", "deleted")
}
if strings.TrimSpace(filter.NameMask) != "" {
q.Set("name", filter.NameMask)
}
@@ -159,7 +163,7 @@ func (s *Server) consoleUsers(c *gin.Context) {
}
view := adminconsole.UsersView{
Pager: adminconsole.NewPager(page, adminPageSize, total),
Robots: filter.Robots, NameMask: filter.NameMask, ExternalIDMask: filter.ExternalIDMask,
Robots: filter.Robots, Deleted: filter.Deleted, NameMask: filter.NameMask, ExternalIDMask: filter.ExternalIDMask,
EmailExact: filter.EmailExact,
FilterQuery: template.URL(q.Encode()),
}