/** * Dev helper: jump a password user to Session 11 chat (sessions 1–10 done, * pre-test done, training/post-test NOT done) so you can test the post-test handoff. * * Usage: * npx tsx scripts/jump-to-session-11.ts alireza@gmail.com */ import { AttemptPhase, AttemptStatus, SessionProgressStatus } from '@prisma/client'; import { prisma } from '../src/lib/prisma.ts'; import { PROGRAM_SESSION_COUNT } from '../src/modules/sessions/catalog.ts'; const emailArg = process.argv[2]?.trim().toLowerCase(); if (!emailArg) { console.error('Usage: npx tsx scripts/jump-to-session-11.ts '); process.exit(1); } async function main() { const identity = await prisma.authIdentity.findFirst({ where: { provider: 'password', OR: [{ email: emailArg }, { providerSubject: emailArg }], }, include: { user: { include: { journey: true, profile: true } }, }, }); if (!identity) { throw new Error(`No password account found for ${emailArg}`); } const userId = identity.userId; const now = new Date(); const hourAgo = (n: number) => new Date(now.getTime() - n * 60 * 60 * 1000); await prisma.$transaction(async (tx) => { await tx.learningJourney.upsert({ where: { userId }, create: { userId, currentStep: 'training_in_progress', preTestCompletedAt: hourAgo(20), trainingStartedAt: hourAgo(19), trainingCompletedAt: null, postTestCompletedAt: null, lastActivityAt: now, }, update: { currentStep: 'training_in_progress', preTestCompletedAt: identity.user.journey?.preTestCompletedAt ?? hourAgo(20), trainingStartedAt: identity.user.journey?.trainingStartedAt ?? hourAgo(19), trainingCompletedAt: null, postTestCompletedAt: null, lastActivityAt: now, }, }); const existingPre = await tx.assessmentAttempt.findFirst({ where: { userId, phase: AttemptPhase.pre, status: AttemptStatus.scored }, }); if (!existingPre) { const preAt = hourAgo(20); await tx.assessmentAttempt.create({ data: { userId, phase: AttemptPhase.pre, status: AttemptStatus.scored, submittedAt: preAt, scoredAt: preAt, }, }); } // Clear final-session / post-test leftovers so the handoff can be retested. await tx.sessionProgress.deleteMany({ where: { userId, sessionOrder: PROGRAM_SESSION_COUNT }, }); await tx.chatSession.deleteMany({ where: { userId, sessionOrder: PROGRAM_SESSION_COUNT }, }); await tx.assessmentAttempt.deleteMany({ where: { userId, phase: AttemptPhase.post }, }); for (let order = 1; order < PROGRAM_SESSION_COUNT; order += 1) { const completedAt = hourAgo(PROGRAM_SESSION_COUNT - order); await tx.sessionProgress.upsert({ where: { userId_sessionOrder: { userId, sessionOrder: order } }, create: { userId, sessionOrder: order, status: SessionProgressStatus.completed, startedAt: completedAt, completedAt, completionMetadata: { reason: 'Dev jump-to-session-11 helper', sessionComplete: true, }, }, update: { status: SessionProgressStatus.completed, startedAt: completedAt, completedAt, completionMetadata: { reason: 'Dev jump-to-session-11 helper', sessionComplete: true, }, }, }); } }); const progress = await prisma.sessionProgress.findMany({ where: { userId, status: SessionProgressStatus.completed }, select: { sessionOrder: true }, orderBy: { sessionOrder: 'asc' }, }); const journey = await prisma.learningJourney.findUnique({ where: { userId } }); console.log( JSON.stringify( { email: identity.email ?? identity.providerSubject, profileName: identity.user.profile?.name ?? null, completedSessions: progress.map((p) => p.sessionOrder), nextSession: PROGRAM_SESSION_COUNT, trainingCompletedAt: journey?.trainingCompletedAt ?? null, postTestCompletedAt: journey?.postTestCompletedAt ?? null, hint: 'Login → open Chat. You should land on Session 11 review. Finish the wrap-up to reach post-test.', }, null, 2, ), ); } main() .catch((err) => { console.error(err instanceof Error ? err.message : err); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });