fix(admin): unified user search across live + deleted, incl. the retention journal
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 1m6s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 2m2s

The email/name/external-id search was scoped to one tab and only looked in the live
identities table, so a deleted account (whose credentials moved to retained_identities on
deletion) could not be found by the email/id it held. Now a people search spans live and
deleted accounts in one query (robots only on the Robots tab) and also matches the
retention journal and the retained real name; results carry a 'deleted' badge. Integration
test: a deleted account is found by its held email and external id.
This commit is contained in:
Ilia Denisov
2026-07-03 14:15:02 +02:00
parent 3faca690dd
commit 4cc37e5760
5 changed files with 66 additions and 21 deletions
+24 -1
View File
@@ -155,10 +155,15 @@ func TestUserListDeletedFilter(t *testing.T) {
if err != nil {
t.Fatalf("provision live: %v", err)
}
gone, _, err := store.ProvisionTelegram(ctx, "tg-"+uuid.NewString(), "en", "", "Gone", "")
goneTg := "tg-" + uuid.NewString()
gone, _, err := store.ProvisionTelegram(ctx, goneTg, "en", "", "Gone", "")
if err != nil {
t.Fatalf("provision gone: %v", err)
}
goneEmail := "gone-" + uuid.NewString() + "@example.com"
if err := store.AttachIdentity(ctx, gone.ID, account.KindEmail, goneEmail, true); err != nil {
t.Fatalf("attach gone email: %v", err)
}
if err := deleter.AnonymizeAndTombstone(ctx, gone.ID); err != nil {
t.Fatalf("delete: %v", err)
}
@@ -183,6 +188,24 @@ func TestUserListDeletedFilter(t *testing.T) {
if listHasID(deleted, live.ID) {
t.Error("a live account must not appear in the Deleted list")
}
// A search spans both lists and reaches the retention journal: a deleted account is
// still found by the email and external id it held (both moved to retained_identities
// on deletion, out of the live identities table).
byEmail, err := store.ListUsers(ctx, account.UserFilter{EmailExact: goneEmail}, 5000, 0)
if err != nil {
t.Fatalf("search by email: %v", err)
}
if !listHasID(byEmail, gone.ID) {
t.Error("a deleted account must be found by the email it held (retention journal)")
}
byExt, err := store.ListUsers(ctx, account.UserFilter{ExternalIDMask: goneTg}, 5000, 0)
if err != nil {
t.Fatalf("search by external id: %v", err)
}
if !listHasID(byExt, gone.ID) {
t.Error("a deleted account must be found by the external id it held (retention journal)")
}
}
// TestConfirmCodeClearsGuest: confirming an email on a guest via ConfirmCode promotes it to