Repository navigation
Add a users (logins) deduper - #2662
Merged
Merged
Conversation
maebeale
force-pushed
the
maebeale/user-deduper-offer
branch
from
October 13, 2026 01:27
105b4b0 to
2bd06c5
Compare
maebeale
marked this pull request as ready for review
October 13, 2026 01:46
Collaborator
Author
|
@jmilljr24 we need this to resolve people merges that create a person w multiple users |
maebeale
force-pushed
the
maebeale/user-deduper-offer
branch
from
October 13, 2026 02:07
d08f71a to
f642bec
Compare
maebeale
force-pushed
the
maebeale/user-deduper-offer
branch
from
October 13, 2026 14:20
f642bec to
1898192
Compare
jmilljr24
approved these changes
Oct 13, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A person merge keeps both people's logins, so a person can end up with two. Admins had no way to fold the stale one away. Users now plug into the shared deduper: candidates are logins sharing a person, the most recently used is the suggested keeper, and logins of different people (or your own) can't be merged. The engine needed a few generic pieces for logins: reference columns without a DB foreign key (created_by/updated_by stamps, ahoy user_id), self-references on the model's own table, per-column labels when a table references the model twice, an editable-column allowlist on save, and credential filtering in the tracked deleted record. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Duplicate logins are often the unconfirmed or locked ones, and the shared user search only returns logins with access, so admins couldn't pick them by hand. The deduper's pickers now search every login and label each with its status. The suggested keeper also prefers a login that can sign in, so a stale unconfirmed login isn't suggested just because it was touched last. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
maebeale
force-pushed
the
maebeale/user-deduper-offer
branch
from
October 14, 2026 00:47
1898192 to
5ad6eca
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 suggested review level: 5 Inspect 🔬 deletes logins and changes the shared dedupe engine every deduper uses
Admins can now merge two logins into one — a person merge keeps both people's logins, and until now there was no way to fold the stale one away.
Users deduper (
/users/dedupe_index)user_any_statussearch model; the sharedusersearch is unchanged.whodunnit.Shared engine changes (affect every deduper)
reference_columns:— columns that point at the model without a DB foreign key. About 20 user stamp columns (grants, staff_tags, topic_subscriptions, …) andahoy_events.user_idhave none.organizations.parent_idandevent_registrations.transferred_from_registration_id. The keeper's own reference to the duplicate clears instead of pointing at itself.index_by(label)hid one of them.dedupe_update_keep/dedupe_performnow accept onlyeditable_columnswhen a config lists them. Before, they accepted every column (e.g.encrypted_password,super_user).dedupe.*event filters credential columns out ofdeleted_record. Emails are still kept for the audit trail.record_label(two logins of one person share a name) andread_only_columns.🤖 Generated with Claude Code