From 29a726fa3d1c0724bafdb6e1d0b2d780ca11d002 Mon Sep 17 00:00:00 2001 From: Flea Flicker Date: Thu, 16 Apr 2026 05:04:52 +0000 Subject: [PATCH] feat(GRO-690): add groomer persona seed support via env vars Extend seed.ts with SEED_UAT_GROOMER_EMAILS and SEED_UAT_GROOMER_NAMES env vars for persistent groomer personas (sam@sarah). Works in both SEED_KNOWN_USERS_ONLY=true and full seed modes. Co-Authored-By: Paperclip --- packages/db/src/seed.ts | 56 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/packages/db/src/seed.ts b/packages/db/src/seed.ts index 9d0808c..a19f254 100644 --- a/packages/db/src/seed.ts +++ b/packages/db/src/seed.ts @@ -462,6 +462,37 @@ async function seedKnownUsers() { } } + // ── Staff: UAT Groomer Personas (SEED_UAT_GROOMER_EMAILS + SEED_UAT_GROOMER_NAMES) ── + const groomerEmails = process.env.SEED_UAT_GROOMER_EMAILS?.split(",").map((e) => e.trim()).filter(Boolean) ?? []; + const groomerNames = process.env.SEED_UAT_GROOMER_NAMES?.split(",").map((n) => n.trim()).filter(Boolean) ?? []; + const groomerCount = Math.min(groomerEmails.length, groomerNames.length); + for (let i = 0; i < groomerCount; i++) { + const email = groomerEmails[i]!; + const name = groomerNames[i]!; + // Use deterministic IDs in the 00000000-0000-0000-0000-000000000005+ range + const staffId = `00000000-0000-0000-0000-${String(5 + i).padStart(12, "0")}`; + const [existingGroomer] = await db + .select() + .from(schema.staff) + .where(eq(schema.staff.email, email)) + .limit(1); + + if (existingGroomer) { + console.log(`✓ Staff groomer '${existingGroomer.name}' already exists — skipping`); + } else { + await db.insert(schema.staff).values({ + id: staffId, + name, + email, + oidcSub: email, + role: "groomer", + isSuperUser: false, + active: true, + }); + console.log(`✓ Created staff groomer '${name}' (${email})`); + } + } + // ── Services: idempotent upsert using name as unique key ───────────────────── // UNIQUE constraint on services.name (migration 0020) must exist first. // Uses b0000001-... IDs to match main seed servicesDef for same-named services. @@ -629,6 +660,31 @@ async function seed() { console.log(`✓ Upserted admin staff '${adminName}' (${adminEmail})`); } + // ── UAT Groomer Personas (SEED_UAT_GROOMER_EMAILS + SEED_UAT_GROOMER_NAMES) ── + const groomerEmails = process.env.SEED_UAT_GROOMER_EMAILS?.split(",").map((e) => e.trim()).filter(Boolean) ?? []; + const groomerNames = process.env.SEED_UAT_GROOMER_NAMES?.split(",").map((n) => n.trim()).filter(Boolean) ?? []; + const groomerCount = Math.min(groomerEmails.length, groomerNames.length); + for (let i = 0; i < groomerCount; i++) { + const email = groomerEmails[i]!; + const name = groomerNames[i]!; + const staffId = `00000000-0000-0000-0000-${String(5 + i).padStart(12, "0")}`; + await db.insert(schema.staff) + .values({ + id: staffId, + name, + email, + oidcSub: email, + role: "groomer", + isSuperUser: false, + active: true, + }) + .onConflictDoUpdate({ + target: schema.staff.email, + set: { id: staffId, name, role: "groomer", isSuperUser: false, active: true }, + }); + console.log(`✓ Upserted groomer '${name}' (${email})`); + } + // ── Services ── // Upsert services using name as unique key. With deterministic IDs in // servicesDef and TRUNCATE clearing downstream tables first, this is