GRO-1921: Fix UAT reset CronJob to seed full UAT profile with extended pet fields (#106)
CI / Test (push) Successful in 11s
CI / Test (pull_request) Successful in 10s
CI / Lint & Typecheck (push) Successful in 16s
CI / Lint & Typecheck (pull_request) Successful in 16s
CI / Build & Push Docker Images (push) Successful in 57s
CI / Build & Push Docker Images (pull_request) Successful in 1m2s
CI / Test (push) Successful in 11s
CI / Test (pull_request) Successful in 10s
CI / Lint & Typecheck (push) Successful in 16s
CI / Lint & Typecheck (pull_request) Successful in 16s
CI / Build & Push Docker Images (push) Successful in 57s
CI / Build & Push Docker Images (pull_request) Successful in 1m2s
This commit was merged in pull request #106.
This commit is contained in:
+92
-93
@@ -385,78 +385,19 @@ const servicesDef = [
|
|||||||
{ id: "b0000001-0000-0000-0000-00000000000a", name: "Sanitary Trim", desc: "Hygienic trim of paw pads, face, and sanitary areas", price: 2500, dur: 20 },
|
{ id: "b0000001-0000-0000-0000-00000000000a", name: "Sanitary Trim", desc: "Hygienic trim of paw pads, face, and sanitary areas", price: 2500, dur: 20 },
|
||||||
];
|
];
|
||||||
|
|
||||||
// ── Known-users-only seed (prod/demo) ───────────────────────────────────────
|
// ── UAT staff account seeding (shared between seed paths) ─────────────────────
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Seeds only the minimal known users for prod/demo environments.
|
* Seeds or upserts the deterministic UAT staff accounts with numeric OIDC subs
|
||||||
* Creates: Demo Manager staff + Demo Client + Demo Dog + basic services.
|
* from SEED_UAT_*_OIDC_SUB / SEED_UAT_GROOMER_OIDC_SUBS env vars.
|
||||||
* Idempotent: skips creation if records already exist.
|
*
|
||||||
|
* In the full seed path this must run AFTER random staff are created so the
|
||||||
|
* deterministic upserts land on the correct rows (groomers referenced by the
|
||||||
|
* UAT test-client appointment logic use groomers[0] etc.).
|
||||||
|
*
|
||||||
|
* In seedKnownUsers() this replaces the inline UAT-staff block.
|
||||||
*/
|
*/
|
||||||
async function seedKnownUsers() {
|
async function seedUatStaffAccounts(db: ReturnType<typeof drizzle>) {
|
||||||
const url = process.env.DATABASE_URL;
|
|
||||||
if (!url) {
|
|
||||||
console.error("DATABASE_URL is not set");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const client = postgres(url, { max: 5 });
|
|
||||||
const db = drizzle(client, { schema });
|
|
||||||
|
|
||||||
console.log("Seeding known users (prod/demo mode)...\n");
|
|
||||||
|
|
||||||
const KNOWN_STAFF_ID = "00000000-0000-0000-0000-000000000001";
|
|
||||||
const DEMO_CLIENT_ID = "00000000-0000-0000-0000-000000000002";
|
|
||||||
const DEMO_PET_ID = "00000000-0000-0000-0000-000000000003";
|
|
||||||
|
|
||||||
// ── Staff: Demo Manager ──
|
|
||||||
const [existingStaff] = await db
|
|
||||||
.select()
|
|
||||||
.from(schema.staff)
|
|
||||||
.where(eq(schema.staff.email, "demo-manager@groombook.dev"))
|
|
||||||
.limit(1);
|
|
||||||
|
|
||||||
if (existingStaff) {
|
|
||||||
console.log(`✓ Staff '${existingStaff.name}' already exists — skipping`);
|
|
||||||
} else {
|
|
||||||
await db.insert(schema.staff).values({
|
|
||||||
id: KNOWN_STAFF_ID,
|
|
||||||
name: "Demo Manager",
|
|
||||||
email: "demo-manager@groombook.dev",
|
|
||||||
oidcSub: "demo-manager-001",
|
|
||||||
role: "manager",
|
|
||||||
isSuperUser: true,
|
|
||||||
active: true,
|
|
||||||
});
|
|
||||||
console.log("✓ Created staff 'Demo Manager' (oidcSub: demo-manager-001)");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Staff: SEED_ADMIN_EMAIL admin ──
|
|
||||||
const adminEmail = process.env.SEED_ADMIN_EMAIL;
|
|
||||||
if (adminEmail) {
|
|
||||||
const adminName = process.env.SEED_ADMIN_NAME ?? "Admin";
|
|
||||||
const ADMIN_STAFF_ID = "00000000-0000-0000-0000-000000000002";
|
|
||||||
const [existingAdmin] = await db
|
|
||||||
.select()
|
|
||||||
.from(schema.staff)
|
|
||||||
.where(eq(schema.staff.email, adminEmail))
|
|
||||||
.limit(1);
|
|
||||||
|
|
||||||
if (existingAdmin) {
|
|
||||||
console.log(`✓ Staff admin '${existingAdmin.name}' already exists — skipping`);
|
|
||||||
} else {
|
|
||||||
await db.insert(schema.staff).values({
|
|
||||||
id: ADMIN_STAFF_ID,
|
|
||||||
name: adminName,
|
|
||||||
email: adminEmail,
|
|
||||||
oidcSub: adminEmail,
|
|
||||||
role: "manager",
|
|
||||||
isSuperUser: true,
|
|
||||||
active: true,
|
|
||||||
});
|
|
||||||
console.log(`✓ Created staff admin '${adminName}' (${adminEmail})`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Staff: UAT Super User (oidcSub from SEED_UAT_SUPER_OIDC_SUB env var) ──
|
// ── Staff: UAT Super User (oidcSub from SEED_UAT_SUPER_OIDC_SUB env var) ──
|
||||||
const uatSuperOidcSub = process.env.SEED_UAT_SUPER_OIDC_SUB;
|
const uatSuperOidcSub = process.env.SEED_UAT_SUPER_OIDC_SUB;
|
||||||
if (uatSuperOidcSub) {
|
if (uatSuperOidcSub) {
|
||||||
@@ -680,6 +621,84 @@ async function seedKnownUsers() {
|
|||||||
console.log(`✓ Created UAT pet '${pet.name}'`);
|
console.log(`✓ Created UAT pet '${pet.name}'`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Known-users-only seed (prod/demo) ───────────────────────────────────────
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seeds only the minimal known users for prod/demo environments.
|
||||||
|
* Creates: Demo Manager staff + Demo Client + Demo Dog + basic services.
|
||||||
|
* Idempotent: skips creation if records already exist.
|
||||||
|
*/
|
||||||
|
async function seedKnownUsers() {
|
||||||
|
const url = process.env.DATABASE_URL;
|
||||||
|
if (!url) {
|
||||||
|
console.error("DATABASE_URL is not set");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = postgres(url, { max: 5 });
|
||||||
|
const db = drizzle(client, { schema });
|
||||||
|
|
||||||
|
console.log("Seeding known users (prod/demo mode)...\n");
|
||||||
|
|
||||||
|
const KNOWN_STAFF_ID = "00000000-0000-0000-0000-000000000001";
|
||||||
|
const DEMO_CLIENT_ID = "00000000-0000-0000-0000-000000000002";
|
||||||
|
const DEMO_PET_ID = "00000000-0000-0000-0000-000000000003";
|
||||||
|
|
||||||
|
// ── Staff: Demo Manager ──
|
||||||
|
const [existingStaff] = await db
|
||||||
|
.select()
|
||||||
|
.from(schema.staff)
|
||||||
|
.where(eq(schema.staff.email, "demo-manager@groombook.dev"))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (existingStaff) {
|
||||||
|
console.log(`✓ Staff '${existingStaff.name}' already exists — skipping`);
|
||||||
|
} else {
|
||||||
|
await db.insert(schema.staff).values({
|
||||||
|
id: KNOWN_STAFF_ID,
|
||||||
|
name: "Demo Manager",
|
||||||
|
email: "demo-manager@groombook.dev",
|
||||||
|
oidcSub: "demo-manager-001",
|
||||||
|
role: "manager",
|
||||||
|
isSuperUser: true,
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
console.log("✓ Created staff 'Demo Manager' (oidcSub: demo-manager-001)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Staff: SEED_ADMIN_EMAIL admin ──
|
||||||
|
const adminEmail = process.env.SEED_ADMIN_EMAIL;
|
||||||
|
if (adminEmail) {
|
||||||
|
const adminName = process.env.SEED_ADMIN_NAME ?? "Admin";
|
||||||
|
const ADMIN_STAFF_ID = "00000000-0000-0000-0000-000000000002";
|
||||||
|
const [existingAdmin] = await db
|
||||||
|
.select()
|
||||||
|
.from(schema.staff)
|
||||||
|
.where(eq(schema.staff.email, adminEmail))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (existingAdmin) {
|
||||||
|
console.log(`✓ Staff admin '${existingAdmin.name}' already exists — skipping`);
|
||||||
|
} else {
|
||||||
|
await db.insert(schema.staff).values({
|
||||||
|
id: ADMIN_STAFF_ID,
|
||||||
|
name: adminName,
|
||||||
|
email: adminEmail,
|
||||||
|
oidcSub: adminEmail,
|
||||||
|
role: "manager",
|
||||||
|
isSuperUser: true,
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
console.log(`✓ Created staff admin '${adminName}' (${adminEmail})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── UAT staff accounts + Better Auth credentials (shared impl) ──────────────
|
||||||
|
// Extracted into seedUatStaffAccounts() so it runs in both seedKnownUsers()
|
||||||
|
// and the full seed() UAT branch.
|
||||||
|
await seedUatStaffAccounts(db);
|
||||||
|
|
||||||
// ── Services: idempotent upsert using name as unique key ─────────────────────
|
// ── Services: idempotent upsert using name as unique key ─────────────────────
|
||||||
// UNIQUE constraint on services.name (migration 0020) must exist first.
|
// UNIQUE constraint on services.name (migration 0020) must exist first.
|
||||||
@@ -847,30 +866,10 @@ async function seed() {
|
|||||||
console.log(`✓ Upserted admin staff '${adminName}' (${adminEmail})`);
|
console.log(`✓ Upserted admin staff '${adminName}' (${adminEmail})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── UAT Groomer Personas (SEED_UAT_GROOMER_EMAILS + SEED_UAT_GROOMER_NAMES) ──
|
// ── UAT staff accounts + Better Auth credentials (shared impl) ──────────────
|
||||||
const groomerEmails = process.env.SEED_UAT_GROOMER_EMAILS?.split(",").map((e) => e.trim()).filter(Boolean) ?? [];
|
// Seeds deterministic UAT staff with numeric OIDC subs and Better Auth credentials.
|
||||||
const groomerNames = process.env.SEED_UAT_GROOMER_NAMES?.split(",").map((n) => n.trim()).filter(Boolean) ?? [];
|
// Must run AFTER random staff are created so upserts land correctly.
|
||||||
const groomerCount = Math.min(groomerEmails.length, groomerNames.length);
|
await seedUatStaffAccounts(db);
|
||||||
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 ──
|
// ── Services ──
|
||||||
// Upsert services using name as unique key. With deterministic IDs in
|
// Upsert services using name as unique key. With deterministic IDs in
|
||||||
|
|||||||
Reference in New Issue
Block a user