Skip to content

Commit 701ff08

Browse files
authored
Merge pull request #38 from vcon-dev/CON-488/fix-upsert-on-duplicate-vcon-submission
fix: upsert vCon on duplicate UUID submission
2 parents a9b6285 + 542d722 commit 701ff08

2 files changed

Lines changed: 13 additions & 4 deletions

File tree

src/db/queries.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ export class VConQueries {
7171
}
7272
}
7373

74-
// Insert main vcon
74+
// Upsert main vcon — idempotent on re-submission of same UUID
7575
// Set id = uuid so they match (id is the PK, uuid is the vCon document UUID)
7676
const { data: vconData, error: vconError } = await this.supabase
7777
.from('vcons')
78-
.insert({
78+
.upsert({
7979
id: vcon.uuid, // Explicitly set id to match uuid
8080
uuid: vcon.uuid,
8181
vcon_version: vcon.vcon ?? '0.3.0',
@@ -87,7 +87,7 @@ export class VConQueries {
8787
redacted: vcon.redacted || {},
8888
appended: vcon.appended || {}, // ✅ Added per spec
8989
tenant_id: tenantId, // ✅ Added for RLS multi-tenant support
90-
})
90+
}, { onConflict: 'id' })
9191
.select('id, uuid')
9292
.single();
9393

@@ -99,6 +99,14 @@ export class VConQueries {
9999
throw vconError;
100100
}
101101

102+
// Delete existing child rows so re-submission replaces them cleanly
103+
await Promise.all([
104+
this.supabase.from('parties').delete().eq('vcon_id', vconData.id),
105+
this.supabase.from('dialog').delete().eq('vcon_id', vconData.id),
106+
this.supabase.from('analysis').delete().eq('vcon_id', vconData.id),
107+
this.supabase.from('attachments').delete().eq('vcon_id', vconData.id),
108+
]);
109+
102110
// Insert parties
103111
if (vcon.parties.length > 0) {
104112
const partiesData = vcon.parties.map((party, index) => ({

tests/db-queries.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ describe('VConQueries', () => {
1919
from: vi.fn(),
2020
select: vi.fn(),
2121
insert: vi.fn(),
22+
upsert: vi.fn(),
2223
update: vi.fn(),
2324
delete: vi.fn(),
2425
eq: vi.fn(),
@@ -70,7 +71,7 @@ describe('VConQueries', () => {
7071

7172
expect(result.uuid).toBe(testVCon.uuid);
7273
expect(mockSupabase.from).toHaveBeenCalledWith('vcons');
73-
expect(mockSupabase.insert).toHaveBeenCalled();
74+
expect(mockSupabase.upsert).toHaveBeenCalled();
7475
});
7576

7677
it('should create vCon with all components (dialog, analysis, attachments)', async () => {

0 commit comments

Comments
 (0)