fix(db): make seed script idempotent using upserts
Convert raw inserts to upserts (ON CONFLICT DO UPDATE) for: - staff: upsert on email (unique constraint) - services: upsert on id (deterministic UUID) - clients: upsert on email (unique constraint) - pets: upsert on id (deterministic UUID) This fixes the duplicate key violation when re-running the seed script against an existing database (e.g., after schema migrations or test restarts). Note: appointments, invoices, visit logs still use raw inserts and would need DELETE-before-insert for full idempotency. Those tables use deterministic UUIDs so a second seed run without prior DELETE would still fail. This is scoped to the immediate staff email constraint violation reported. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
committed by
Flea Flicker
parent
3834e45b66
commit
eb48d97ee3
+56
-18
@@ -407,14 +407,19 @@ async function seed() {
|
|||||||
|
|
||||||
const allStaff = [...managerStaff, ...receptionistStaff, ...groomers, ...bathers];
|
const allStaff = [...managerStaff, ...receptionistStaff, ...groomers, ...bathers];
|
||||||
for (const s of allStaff) {
|
for (const s of allStaff) {
|
||||||
await db.insert(schema.staff).values({
|
await db.insert(schema.staff)
|
||||||
id: s.id,
|
.values({
|
||||||
name: s.name,
|
id: s.id,
|
||||||
email: s.email,
|
name: s.name,
|
||||||
role: s.role,
|
email: s.email,
|
||||||
isSuperUser: s.isSuperUser,
|
role: s.role,
|
||||||
active: true,
|
isSuperUser: s.isSuperUser,
|
||||||
});
|
active: true,
|
||||||
|
})
|
||||||
|
.onConflictDoUpdate({
|
||||||
|
target: schema.staff.email,
|
||||||
|
set: { name: s.name, role: s.role, isSuperUser: s.isSuperUser, active: true },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
console.log(`✓ Created ${allStaff.length} staff (1 manager, 1 receptionist, 3 groomers, 3 bathers)`);
|
console.log(`✓ Created ${allStaff.length} staff (1 manager, 1 receptionist, 3 groomers, 3 bathers)`);
|
||||||
|
|
||||||
@@ -423,14 +428,19 @@ async function seed() {
|
|||||||
for (const s of servicesDef) {
|
for (const s of servicesDef) {
|
||||||
const id = uuid();
|
const id = uuid();
|
||||||
serviceIds.push(id);
|
serviceIds.push(id);
|
||||||
await db.insert(schema.services).values({
|
await db.insert(schema.services)
|
||||||
id,
|
.values({
|
||||||
name: s.name,
|
id,
|
||||||
description: s.desc,
|
name: s.name,
|
||||||
basePriceCents: s.price,
|
description: s.desc,
|
||||||
durationMinutes: s.dur,
|
basePriceCents: s.price,
|
||||||
active: true,
|
durationMinutes: s.dur,
|
||||||
});
|
active: true,
|
||||||
|
})
|
||||||
|
.onConflictDoUpdate({
|
||||||
|
target: schema.services.id,
|
||||||
|
set: { name: s.name, description: s.desc, basePriceCents: s.price, durationMinutes: s.dur, active: true },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
console.log(`✓ Created ${servicesDef.length} services`);
|
console.log(`✓ Created ${servicesDef.length} services`);
|
||||||
|
|
||||||
@@ -502,8 +512,36 @@ async function seed() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.insert(schema.clients).values(clientBatch);
|
for (const client of clientBatch) {
|
||||||
await db.insert(schema.pets).values(petBatch);
|
await db.insert(schema.clients)
|
||||||
|
.values(client)
|
||||||
|
.onConflictDoUpdate({
|
||||||
|
target: schema.clients.email,
|
||||||
|
set: { name: client.name, phone: client.phone, address: client.address, notes: client.notes, emailOptOut: client.emailOptOut },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const pet of petBatch) {
|
||||||
|
await db.insert(schema.pets)
|
||||||
|
.values(pet)
|
||||||
|
.onConflictDoUpdate({
|
||||||
|
target: schema.pets.id,
|
||||||
|
set: {
|
||||||
|
clientId: pet.clientId,
|
||||||
|
name: pet.name,
|
||||||
|
species: pet.species,
|
||||||
|
breed: pet.breed,
|
||||||
|
weightKg: pet.weightKg,
|
||||||
|
dateOfBirth: pet.dateOfBirth,
|
||||||
|
healthAlerts: pet.healthAlerts,
|
||||||
|
groomingNotes: pet.groomingNotes,
|
||||||
|
cutStyle: pet.cutStyle,
|
||||||
|
shampooPreference: pet.shampooPreference,
|
||||||
|
specialCareNotes: pet.specialCareNotes,
|
||||||
|
customFields: pet.customFields,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`✓ Created 500 clients with ${petRecords.length} pets`);
|
console.log(`✓ Created 500 clients with ${petRecords.length} pets`);
|
||||||
|
|||||||
Reference in New Issue
Block a user