import { afterAll, describe, expect, it } from 'vitest' import { prisma, createCaller } from '../setup' import { createTestUser, createTestProgram, createTestProject, cleanupTestData, uid, } from '../helpers' import { finalistRouter } from '../../src/server/routers/finalist' describe('finalist.unconfirm', () => { const programIds: string[] = [] const userIds: string[] = [] afterAll(async () => { for (const programId of programIds) { await prisma.mentorAssignment.deleteMany({ where: { project: { programId } } }) await prisma.attendingMember.deleteMany({ where: { confirmation: { project: { programId } } }, }) await prisma.finalistConfirmation.deleteMany({ where: { project: { programId } } }) await cleanupTestData(programId, []) } if (userIds.length > 0) { await prisma.user.deleteMany({ where: { id: { in: userIds } } }) } }) async function setupConfirmedFinalist(programName: string) { const program = await createTestProgram({ name: programName }) const project = await createTestProject(program.id, { title: 'Test Finalist', competitionCategory: 'STARTUP', }) const confirmation = await prisma.finalistConfirmation.create({ data: { projectId: project.id, category: 'STARTUP', status: 'CONFIRMED', deadline: new Date(Date.now() + 86400000), token: `tok_${uid()}`, confirmedAt: new Date(), }, }) return { program, project, confirmation } } it('flips CONFIRMED → SUPERSEDED with audit log', async () => { const admin = await createTestUser('SUPER_ADMIN') userIds.push(admin.id) const { program, confirmation } = await setupConfirmedFinalist(`unconfirm-basic-${uid()}`) programIds.push(program.id) const caller = createCaller(finalistRouter, { id: admin.id, email: admin.email, role: 'SUPER_ADMIN', }) await caller.unconfirm({ confirmationId: confirmation.id, reason: 'Quota change required' }) const updated = await prisma.finalistConfirmation.findUniqueOrThrow({ where: { id: confirmation.id }, }) expect(updated.status).toBe('SUPERSEDED') // Audit log const audit = await prisma.auditLog.findFirst({ where: { action: 'FINALIST_UNCONFIRM', entityId: confirmation.id }, }) expect(audit).not.toBeNull() }) it('cascades to drop the active mentor assignment', async () => { const admin = await createTestUser('SUPER_ADMIN') userIds.push(admin.id) const mentor = await prisma.user.create({ data: { id: uid('user'), email: `m_${uid()}@test.local`, name: 'Mentor', role: 'MENTOR', roles: ['MENTOR'], status: 'ACTIVE', }, }) userIds.push(mentor.id) const { program, project, confirmation } = await setupConfirmedFinalist( `unconfirm-cascade-${uid()}`, ) programIds.push(program.id) const ma = await prisma.mentorAssignment.create({ data: { projectId: project.id, mentorId: mentor.id, method: 'MANUAL', assignedBy: admin.id, workspaceEnabled: true, }, }) const caller = createCaller(finalistRouter, { id: admin.id, email: admin.email, role: 'SUPER_ADMIN', }) await caller.unconfirm({ confirmationId: confirmation.id, reason: 'No longer attending' }) const droppedMa = await prisma.mentorAssignment.findUniqueOrThrow({ where: { id: ma.id } }) expect(droppedMa.droppedAt).not.toBeNull() expect(droppedMa.droppedBy).toBe('finalist_unconfirmed') expect(droppedMa.droppedReason).toContain('No longer attending') }) it('does not touch already-completed mentor assignments', async () => { const admin = await createTestUser('SUPER_ADMIN') userIds.push(admin.id) const mentor = await prisma.user.create({ data: { id: uid('user'), email: `mc_${uid()}@test.local`, name: 'M', role: 'MENTOR', roles: ['MENTOR'], status: 'ACTIVE', }, }) userIds.push(mentor.id) const { program, project, confirmation } = await setupConfirmedFinalist( `unconfirm-completed-${uid()}`, ) programIds.push(program.id) const ma = await prisma.mentorAssignment.create({ data: { projectId: project.id, mentorId: mentor.id, method: 'MANUAL', assignedBy: admin.id, completionStatus: 'completed', }, }) const caller = createCaller(finalistRouter, { id: admin.id, email: admin.email, role: 'SUPER_ADMIN', }) await caller.unconfirm({ confirmationId: confirmation.id, reason: 'Quota shrink' }) const stillCompleted = await prisma.mentorAssignment.findUniqueOrThrow({ where: { id: ma.id }, }) expect(stillCompleted.droppedAt).toBeNull() expect(stillCompleted.completionStatus).toBe('completed') }) it('rejects when confirmation is not in CONFIRMED status', async () => { const admin = await createTestUser('SUPER_ADMIN') userIds.push(admin.id) const program = await createTestProgram({ name: `unconfirm-pending-${uid()}` }) programIds.push(program.id) const project = await createTestProject(program.id, { title: 'Pending', competitionCategory: 'STARTUP', }) const confirmation = await prisma.finalistConfirmation.create({ data: { projectId: project.id, category: 'STARTUP', status: 'PENDING', deadline: new Date(Date.now() + 86400000), token: `tok_${uid()}`, }, }) const caller = createCaller(finalistRouter, { id: admin.id, email: admin.email, role: 'SUPER_ADMIN', }) await expect( caller.unconfirm({ confirmationId: confirmation.id, reason: 'Reason text here' }), ).rejects.toThrow(/CONFIRMED status/i) }) })