P7 people-store providerUserId dedupe #4
No files matched your search
@@ -82,6 +82,26 @@ describe('network-people-store: CRUD', () => {
|
||||
expect(list).toHaveLength(1); // merged, not duplicated
|
||||
});
|
||||
|
||||
test('upsertPerson merges by providerUserId when id is omitted (wizard after provider sync)', async () => {
|
||||
const synced = await store.upsertPerson({
|
||||
displayName: 'SamiAhmed7777',
|
||||
providerUserId: 'ughVnuLDu621CNTRL',
|
||||
});
|
||||
expect(synced.groups).toEqual(['Admin']); // bootstrap identity
|
||||
|
||||
const fromWizard = await store.upsertPerson({
|
||||
displayName: 'Sami Ahmed',
|
||||
providerUserId: 'ughVnuLDu621CNTRL',
|
||||
});
|
||||
|
||||
expect(fromWizard.id).toBe(synced.id);
|
||||
expect(fromWizard.displayName).toBe('Sami Ahmed');
|
||||
expect(fromWizard.groups).toEqual(['Admin']);
|
||||
expect(fromWizard.protectedAt).toBe(synced.protectedAt);
|
||||
const list = await store.listPeople();
|
||||
expect(list).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('updatePerson patches only provided fields', async () => {
|
||||
const p = await store.upsertPerson({ displayName: 'Bob', providerUserId: 'ts-2', groups: ['G'] });
|
||||
const u = await store.updatePerson(p.id, { displayName: 'Bobby' });
|
||||
|
||||
@@ -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