[grade=B urn:ump:bbfbsfru4nizg75wcxum7mwzhie6txhr22hw6jvz36wiihmgzmlq] P7 people store: dedupe upsert by providerUserId
Dogfood finding #3: upsertPerson resolved existing records by id only. The wizard upserts a bootstrap admin AFTER a provider sync has already created a person for the same Tailscale user (no id passed), so the same providerUserId was duplicated into two records. Resolve existing by providerUserId when no id is given; bootstrap Admin group + protectedAt are preserved on the merge. New regression test; full suite 3414/3414.
This commit is contained in:
2 files changed
+31
-1
No files matched your search
@@ -180,7 +180,17 @@ function createPeopleStore(opts = {}) {
|
||||
function upsertPerson(input = {}) {
|
||||
return _enqueue(() => {
|
||||
const data = _load();
|
||||
const existing = input.id ? data.people[input.id] : null;
|
||||
// Resolve the existing record by id when given, else by providerUserId
|
||||
// (dogfood finding 2026-10-04: the wizard upserts a person AFTER a
|
||||
// provider sync already created one for the same Tailscale user with no
|
||||
// id — without this lookup the same providerUserId was duplicated).
|
||||
const existing = input.id
|
||||
? data.people[input.id]
|
||||
: (input.providerUserId
|
||||
? Object.values(data.people).find(
|
||||
(p) => p.providerUserId && p.providerUserId === input.providerUserId
|
||||
) || null
|
||||
: null);
|
||||
const isFirst = Object.keys(data.people).length === 0;
|
||||
|
||||
const id = existing ? existing.id : (input.id || crypto.randomUUID());
|
||||
|
||||
Reference in new issue
Block a user