/** * U-008: Override — Missing Reason Fields * * Tests that the decision.override procedure rejects mutations * with invalid or missing reasonCode via Zod validation. */ import { describe, it, expect, beforeAll, afterAll } from 'vitest' import { prisma, createTestContext } from '../setup' import { createTestUser, createTestProgram, createTestPipeline, createTestTrack, createTestStage, createTestProject, createTestPSS, cleanupTestData, } from '../helpers' import { decisionRouter } from '@/server/routers/decision' let programId: string let userIds: string[] = [] beforeAll(async () => { const program = await createTestProgram({ name: 'Override Test' }) programId = program.id }) afterAll(async () => { await cleanupTestData(programId, userIds) }) describe('U-008: Override — Missing Reason Fields', () => { it('rejects override with invalid reasonCode', async () => { const admin = await createTestUser('SUPER_ADMIN') userIds.push(admin.id) const pipeline = await createTestPipeline(programId) const track = await createTestTrack(pipeline.id) const stage = await createTestStage(track.id, { status: 'STAGE_ACTIVE' }) const project = await createTestProject(programId) const pss = await createTestPSS(project.id, track.id, stage.id, { state: 'PENDING' }) const ctx = createTestContext(admin) const caller = decisionRouter.createCaller(ctx) // Attempt override with invalid reasonCode — should be rejected by Zod await expect( caller.override({ entityType: 'ProjectStageState', entityId: pss.id, newValue: { state: 'PASSED' }, reasonCode: 'INVALID_CODE' as any, }) ).rejects.toThrow() }) it('accepts override with valid reasonCode and persists OverrideAction', async () => { const admin = await createTestUser('SUPER_ADMIN') userIds.push(admin.id) const pipeline = await createTestPipeline(programId) const track = await createTestTrack(pipeline.id) const stage = await createTestStage(track.id, { status: 'STAGE_ACTIVE' }) const project = await createTestProject(programId) const pss = await createTestPSS(project.id, track.id, stage.id, { state: 'PENDING' }) const ctx = createTestContext(admin) const caller = decisionRouter.createCaller(ctx) const result = await caller.override({ entityType: 'ProjectStageState', entityId: pss.id, newValue: { state: 'PASSED' }, reasonCode: 'ADMIN_DISCRETION', reasonText: 'Manually promoted by admin', }) expect(result.success).toBe(true) // Verify OverrideAction was created const overrideAction = await prisma.overrideAction.findFirst({ where: { entityType: 'ProjectStageState', entityId: pss.id }, }) expect(overrideAction).not.toBeNull() expect(overrideAction!.reasonCode).toBe('ADMIN_DISCRETION') expect(overrideAction!.reasonText).toBe('Manually promoted by admin') expect(overrideAction!.actorId).toBe(admin.id) // Verify the PSS state was actually updated const updatedPSS = await prisma.projectStageState.findUnique({ where: { id: pss.id }, }) expect(updatedPSS!.state).toBe('PASSED') // Verify DecisionAuditLog was created const auditLog = await prisma.decisionAuditLog.findFirst({ where: { entityType: 'ProjectStageState', entityId: pss.id, eventType: 'override.applied' }, }) expect(auditLog).not.toBeNull() }) })