|
18 | 18 |
|
19 | 19 | import { drizzle } from 'drizzle-orm/postgres-js' |
20 | 20 | import postgres from 'postgres' |
21 | | -import { eq } from 'drizzle-orm' |
| 21 | +import { eq, and } from 'drizzle-orm' |
22 | 22 | import { hashPassword } from 'better-auth/crypto' |
23 | 23 | import * as schema from '../database/schema' |
24 | 24 |
|
@@ -358,46 +358,97 @@ function generateResponses(jobIndex: number, candidateIndex: number): Record<str |
358 | 358 | async function seed() { |
359 | 359 | console.log('🌱 Seeding Reqcore demo data...\n') |
360 | 360 |
|
361 | | - // Check if demo org already exists |
| 361 | + const hashedPassword = await hashPassword(DEMO_PASSWORD) |
| 362 | + |
| 363 | + // ── Step 1: Upsert demo user (always runs, even if org already exists) ────── |
| 364 | + // This repairs broken states where the org exists but the user was never |
| 365 | + // created (or was created with an old email/password after a rename). |
| 366 | + |
| 367 | + const existingUser = await db |
| 368 | + .select() |
| 369 | + .from(schema.user) |
| 370 | + .where(eq(schema.user.email, DEMO_EMAIL)) |
| 371 | + .limit(1) |
| 372 | + |
| 373 | + let userId: string |
| 374 | + |
| 375 | + if (existingUser.length > 0 && existingUser[0]) { |
| 376 | + // User exists — ensure their credential password is current |
| 377 | + userId = existingUser[0].id |
| 378 | + await db |
| 379 | + .update(schema.account) |
| 380 | + .set({ password: hashedPassword, updatedAt: new Date() }) |
| 381 | + .where( |
| 382 | + and( |
| 383 | + eq(schema.account.userId, userId), |
| 384 | + eq(schema.account.providerId, 'credential'), |
| 385 | + ), |
| 386 | + ) |
| 387 | + console.log(`✅ Demo user verified/updated: ${DEMO_EMAIL}`) |
| 388 | + } |
| 389 | + else { |
| 390 | + // User doesn't exist — create user + credential account |
| 391 | + userId = id() |
| 392 | + |
| 393 | + await db.insert(schema.user).values({ |
| 394 | + id: userId, |
| 395 | + name: 'Demo Recruiter', |
| 396 | + email: DEMO_EMAIL, |
| 397 | + emailVerified: true, |
| 398 | + createdAt: daysAgo(30), |
| 399 | + updatedAt: daysAgo(30), |
| 400 | + }) |
| 401 | + |
| 402 | + await db.insert(schema.account).values({ |
| 403 | + id: id(), |
| 404 | + userId, |
| 405 | + accountId: userId, |
| 406 | + providerId: 'credential', |
| 407 | + password: hashedPassword, |
| 408 | + createdAt: daysAgo(30), |
| 409 | + updatedAt: daysAgo(30), |
| 410 | + }) |
| 411 | + |
| 412 | + console.log(`✅ Created demo user: ${DEMO_EMAIL}`) |
| 413 | + } |
| 414 | + |
| 415 | + // ── Step 2: Check if demo org already exists ──────────────────────────────── |
362 | 416 | const existingOrg = await db |
363 | 417 | .select() |
364 | 418 | .from(schema.organization) |
365 | 419 | .where(eq(schema.organization.slug, DEMO_ORG_SLUG)) |
366 | 420 | .limit(1) |
367 | 421 |
|
368 | 422 | if (existingOrg.length > 0) { |
369 | | - console.log('⚠️ Demo organization already exists. Skipping seed.') |
370 | | - console.log(' To re-seed, delete the organization first or reset the database.') |
| 423 | + // Ensure user is a member of the org (guards against user/org mismatch) |
| 424 | + const existingMember = await db |
| 425 | + .select() |
| 426 | + .from(schema.member) |
| 427 | + .where( |
| 428 | + and( |
| 429 | + eq(schema.member.userId, userId), |
| 430 | + eq(schema.member.organizationId, existingOrg[0]!.id), |
| 431 | + ), |
| 432 | + ) |
| 433 | + .limit(1) |
| 434 | + |
| 435 | + if (existingMember.length === 0) { |
| 436 | + await db.insert(schema.member).values({ |
| 437 | + id: id(), |
| 438 | + userId, |
| 439 | + organizationId: existingOrg[0]!.id, |
| 440 | + role: 'owner', |
| 441 | + createdAt: new Date(), |
| 442 | + }) |
| 443 | + console.log('✅ Re-linked demo user to existing organization.') |
| 444 | + } |
| 445 | + |
| 446 | + console.log('⚠️ Demo organization already exists. Skipping full seed.') |
| 447 | + console.log(' To re-seed all data, delete the organization first or reset the database.') |
371 | 448 | await client.end() |
372 | 449 | return |
373 | 450 | } |
374 | 451 |
|
375 | | - // 1. Create demo user |
376 | | - const userId = id() |
377 | | - const hashedPassword = await hashPassword(DEMO_PASSWORD) |
378 | | - |
379 | | - await db.insert(schema.user).values({ |
380 | | - id: userId, |
381 | | - name: 'Demo Recruiter', |
382 | | - email: DEMO_EMAIL, |
383 | | - emailVerified: true, |
384 | | - createdAt: daysAgo(30), |
385 | | - updatedAt: daysAgo(30), |
386 | | - }) |
387 | | - |
388 | | - // Create account (email/password provider) |
389 | | - await db.insert(schema.account).values({ |
390 | | - id: id(), |
391 | | - userId, |
392 | | - accountId: userId, |
393 | | - providerId: 'credential', |
394 | | - password: hashedPassword, |
395 | | - createdAt: daysAgo(30), |
396 | | - updatedAt: daysAgo(30), |
397 | | - }) |
398 | | - |
399 | | - console.log(`✅ Created demo user: ${DEMO_EMAIL}`) |
400 | | - |
401 | 452 | // 2. Create organization |
402 | 453 | const orgId = id() |
403 | 454 |
|
|
0 commit comments