import { afterAll, beforeAll, describe, expect, it } from 'vitest' import { prisma, createCaller } from '../setup' import { createTestUser, createTestProgram, createTestCompetition, createTestRound, createTestProject, createTestProjectRoundState, createTestAssignment, createTestEvaluation, createTestEvaluationForm, cleanupTestData, uid, } from '../helpers' import { analyticsRouter } from '../../src/server/routers/analytics' describe('analytics.getProjectDetail round scoping', () => { let programId: string let admin: { id: string; email: string; role: 'SUPER_ADMIN' } let projectId: string let roundAId: string let roundBId: string const userIds: string[] = [] beforeAll(async () => { const program = await createTestProgram({ name: `bal-scope-${uid()}` }) programId = program.id const competition = await createTestCompetition(programId) const roundA = await createTestRound(competition.id, { name: 'Round A', sortOrder: 0, status: 'ROUND_CLOSED' }) const roundB = await createTestRound(competition.id, { name: 'Round B', sortOrder: 1, status: 'ROUND_ACTIVE' }) roundAId = roundA.id roundBId = roundB.id const formA = await createTestEvaluationForm(roundA.id) const formB = await createTestEvaluationForm(roundB.id) const project = await createTestProject(programId) projectId = project.id await createTestProjectRoundState(projectId, roundA.id, { state: 'PASSED' }) await createTestProjectRoundState(projectId, roundB.id, { state: 'IN_PROGRESS' }) // 2 evaluations on Round A: 7.0, 8.0 (mean 7.5) for (const score of [7, 8]) { const juror = await createTestUser('JURY_MEMBER') userIds.push(juror.id) const a = await createTestAssignment(juror.id, projectId, roundA.id) await createTestEvaluation(a.id, formA.id, { status: 'SUBMITTED', globalScore: score, submittedAt: new Date() }) } // 3 evaluations on Round B: 9.0, 8.0, 8.0 (mean 8.333…) for (const score of [9, 8, 8]) { const juror = await createTestUser('JURY_MEMBER') userIds.push(juror.id) const a = await createTestAssignment(juror.id, projectId, roundB.id) await createTestEvaluation(a.id, formB.id, { status: 'SUBMITTED', globalScore: score, submittedAt: new Date() }) } const adminUser = await createTestUser('SUPER_ADMIN') userIds.push(adminUser.id) admin = { id: adminUser.id, email: adminUser.email, role: 'SUPER_ADMIN' } }) afterAll(async () => { await cleanupTestData(programId, userIds) }) it('returns only round-B stats when roundId=roundB is passed', async () => { const caller = createCaller(analyticsRouter, admin) const result = await caller.getProjectDetail({ id: projectId, roundId: roundBId }) expect(result.stats).not.toBeNull() expect(result.stats!.totalEvaluations).toBe(3) expect(result.stats!.averageGlobalScore).toBeCloseTo(8.333, 2) }) it('returns aggregated stats across all rounds when roundId is omitted', async () => { const caller = createCaller(analyticsRouter, admin) const result = await caller.getProjectDetail({ id: projectId }) expect(result.stats!.totalEvaluations).toBe(5) }) })