diff --git a/src/server/routers/applicant.ts b/src/server/routers/applicant.ts index e73f341..cc61c08 100644 --- a/src/server/routers/applicant.ts +++ b/src/server/routers/applicant.ts @@ -1301,22 +1301,52 @@ export const applicantRouter = router({ } const programId = project.programId - const openRounds = programId - ? await ctx.prisma.round.findMany({ - where: { - competition: { programId }, - status: 'ROUND_ACTIVE', - }, - orderBy: { sortOrder: 'asc' }, - select: { - id: true, - name: true, - slug: true, - roundType: true, - windowCloseAt: true, - }, + let openRounds: Array<{ id: string; name: string; slug: string | null; roundType: string; windowCloseAt: Date | null }> = [] + if (programId) { + const allActiveRounds = await ctx.prisma.round.findMany({ + where: { + competition: { programId }, + status: 'ROUND_ACTIVE', + }, + orderBy: { sortOrder: 'asc' }, + select: { + id: true, + name: true, + slug: true, + roundType: true, + windowCloseAt: true, + specialAwardId: true, + specialAward: { select: { name: true } }, + }, + }) + + // Filter rounds based on award track: only show rounds the project is actually in + const projectRoundIds = new Set( + (await ctx.prisma.projectRoundState.findMany({ + where: { projectId: project.id }, + select: { roundId: true }, + })).map((prs) => prs.roundId) + ) + const isInAwardTrack = allActiveRounds.some( + (r) => r.specialAwardId && projectRoundIds.has(r.id) + ) + + openRounds = allActiveRounds + .filter((r) => { + // Award round project isn't in → hide + if (r.specialAwardId && !projectRoundIds.has(r.id)) return false + // Main round when project is in award track and has no state in this round → hide + if (!r.specialAwardId && isInAwardTrack && !projectRoundIds.has(r.id)) return false + return true }) - : [] + .map((r) => ({ + id: r.id, + name: r.specialAward ? `${r.specialAward.name}: ${r.name}` : r.name, + slug: r.slug, + roundType: r.roundType, + windowCloseAt: r.windowCloseAt, + })) + } // Determine user's role in the project const userMembership = project.teamMembers.find((tm) => tm.userId === ctx.user.id) @@ -1391,13 +1421,22 @@ export const applicantRouter = router({ const hasMentor = !!project.mentorAssignment // Check if there are EVALUATION rounds (CLOSED/ARCHIVED) with applicantVisibility.enabled + // Only consider rounds the project actually participated in (award track filtering) let hasEvaluationRounds = false if (project.programId) { + const projectRoundIds = new Set( + (await ctx.prisma.projectRoundState.findMany({ + where: { projectId: project.id }, + select: { roundId: true }, + })).map((prs) => prs.roundId) + ) + const closedEvalRounds = await ctx.prisma.round.findMany({ where: { competition: { programId: project.programId }, roundType: 'EVALUATION', status: { in: ['ROUND_CLOSED', 'ROUND_ARCHIVED'] }, + ...(projectRoundIds.size > 0 ? { id: { in: [...projectRoundIds] } } : {}), }, select: { configJson: true }, }) @@ -1666,12 +1705,20 @@ export const applicantRouter = router({ if (!project?.programId) return [] - // Get closed/archived EVALUATION rounds for this competition + // Get closed/archived EVALUATION rounds — only ones this project participated in + const projectRoundIds = new Set( + (await ctx.prisma.projectRoundState.findMany({ + where: { projectId: project.id }, + select: { roundId: true }, + })).map((prs) => prs.roundId) + ) + const evalRounds = await ctx.prisma.round.findMany({ where: { competition: { programId: project.programId }, roundType: 'EVALUATION', status: { in: ['ROUND_CLOSED', 'ROUND_ARCHIVED'] }, + ...(projectRoundIds.size > 0 ? { id: { in: [...projectRoundIds] } } : {}), }, select: { id: true, @@ -1758,7 +1805,7 @@ export const applicantRouter = router({ { teamMembers: { some: { userId: ctx.user.id } } }, ], }, - select: { programId: true }, + select: { id: true, programId: true }, }) if (!project?.programId) return [] @@ -1774,14 +1821,33 @@ export const applicantRouter = router({ id: true, name: true, windowCloseAt: true, + specialAwardId: true, + specialAward: { select: { name: true } }, }, orderBy: { windowCloseAt: 'asc' }, }) - return rounds.map((r) => ({ - roundName: r.name, - windowCloseAt: r.windowCloseAt!, - })) + // Filter by award track membership + const projectRoundIds = new Set( + (await ctx.prisma.projectRoundState.findMany({ + where: { projectId: project.id }, + select: { roundId: true }, + })).map((prs) => prs.roundId) + ) + const isInAwardTrack = rounds.some( + (r) => r.specialAwardId && projectRoundIds.has(r.id) + ) + + return rounds + .filter((r) => { + if (r.specialAwardId && !projectRoundIds.has(r.id)) return false + if (!r.specialAwardId && isInAwardTrack && !projectRoundIds.has(r.id)) return false + return true + }) + .map((r) => ({ + roundName: r.specialAward ? `${r.specialAward.name}: ${r.name}` : r.name, + windowCloseAt: r.windowCloseAt!, + })) }), /** @@ -1805,7 +1871,7 @@ export const applicantRouter = router({ if (!project?.programId) return [] // Find active rounds with file requirements - const rounds = await ctx.prisma.round.findMany({ + const allRounds = await ctx.prisma.round.findMany({ where: { competition: { programId: project.programId }, status: 'ROUND_ACTIVE', @@ -1814,6 +1880,8 @@ export const applicantRouter = router({ select: { id: true, name: true, + specialAwardId: true, + specialAward: { select: { name: true } }, fileRequirements: { select: { id: true }, }, @@ -1821,6 +1889,22 @@ export const applicantRouter = router({ orderBy: { sortOrder: 'asc' }, }) + // Filter by award track membership + const projectRoundIds = new Set( + (await ctx.prisma.projectRoundState.findMany({ + where: { projectId: project.id }, + select: { roundId: true }, + })).map((prs) => prs.roundId) + ) + const isInAwardTrack = allRounds.some( + (r) => r.specialAwardId && projectRoundIds.has(r.id) + ) + const rounds = allRounds.filter((r) => { + if (r.specialAwardId && !projectRoundIds.has(r.id)) return false + if (!r.specialAwardId && isInAwardTrack && !projectRoundIds.has(r.id)) return false + return true + }) + const results: Array<{ roundId: string; roundName: string; required: number; uploaded: number }> = [] for (const round of rounds) { @@ -1836,7 +1920,7 @@ export const applicantRouter = router({ results.push({ roundId: round.id, - roundName: round.name, + roundName: round.specialAward ? `${round.specialAward.name}: ${round.name}` : round.name, required: requirementIds.length, uploaded, })