From 4fb0c7b14d3e1b2c7c74df8cd63fc19588ff86f7 Mon Sep 17 00:00:00 2001 From: Barkley Trimsworth Date: Mon, 30 Mar 2026 18:09:09 +0000 Subject: [PATCH] fix(api): use valid staff ID for dev-session impersonation The hardcoded DEV_STAFF_ID (all zeros) did not exist in the staff table, causing a foreign-key violation and 500 error. Now falls back to the demo-manager (KNOWN_STAFF_ID from seed) or any active staff record instead. Co-Authored-By: Paperclip --- apps/api/src/routes/portal.ts | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/apps/api/src/routes/portal.ts b/apps/api/src/routes/portal.ts index 4d0b704..7d3289c 100644 --- a/apps/api/src/routes/portal.ts +++ b/apps/api/src/routes/portal.ts @@ -477,15 +477,36 @@ portalRouter.post( return c.json({ error: "Client not found" }, 404); } - // Create a long-lived impersonation session for the dev client. - // Use a fixed "dev-staff" staffId so multiple dev sessions don't conflict - // with the one-active-session-per-staff rule in the real impersonation flow. - const DEV_STAFF_ID = "00000000-0000-0000-0000-000000000000"; + // Find a staff record to associate with the dev impersonation session. + // Use the demo-manager if it exists (created by seed with known ID), + // otherwise fall back to the first active staff record. + // This avoids hardcoding a UUID that may not exist in all environments. + const DEMO_STAFF_ID = "00000000-0000-0000-0000-000000000001"; + + let staffId = DEMO_STAFF_ID; + const [demoStaff] = await db + .select({ id: staff.id }) + .from(staff) + .where(eq(staff.id, DEMO_STAFF_ID)) + .limit(1); + + if (!demoStaff) { + // Fall back to any active staff member + const [firstStaff] = await db + .select({ id: staff.id }) + .from(staff) + .where(eq(staff.active, true)) + .limit(1); + if (!firstStaff) { + return c.json({ error: "No staff records found. Run the database seed." }, 500); + } + staffId = firstStaff.id; + } const [session] = await db .insert(impersonationSessions) .values({ - staffId: DEV_STAFF_ID, + staffId, clientId: body.clientId, reason: "dev-mode-client-portal", expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours