feat(final-docs): judges see all teams' prior-round files; revised uploads behind admin toggle
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m47s
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m47s
The finals jury needs the teams' EXISTING submissions (pitch deck, exec summary, business plan, videos from prior rounds) — which all 9 teams already have. So: - listFinalistDocumentsForReview now returns ALL of each finalist team's files across every round (labeled by doc type + round; finale uploads flagged 'Revised for finals'), with presigned URLs. NOT gated — judges always see. - Revised re-uploads are now an admin toggle (Round.configJson.allowFinalistRevisedUploads, default OFF): gates the banner/panel (getFinalDocumentStatusForProject), the upload guard (getUploadUrl/deleteFile), the documents-page round, and the reminders (manual + cron). When off, teams aren't prompted/able to upload. - finalist.get/setRevisedUploadSetting + a Switch on the admin finale overview. - judge review component rewritten to a per-team labeled file list. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1690,4 +1690,37 @@ export const finalistRouter = router({
|
||||
if (!allowed) throw new TRPCError({ code: 'FORBIDDEN', message: 'You do not have access to the finalist documents review.' })
|
||||
return listFinalistDocumentsForReview(ctx.prisma, input.programId)
|
||||
}),
|
||||
|
||||
/** Read whether finalists may upload revised grand-final documents (admin toggle). */
|
||||
getRevisedUploadSetting: adminProcedure
|
||||
.input(z.object({ roundId: z.string() }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const round = await ctx.prisma.round.findUnique({ where: { id: input.roundId }, select: { configJson: true } })
|
||||
const cfg = (round?.configJson ?? {}) as { allowFinalistRevisedUploads?: boolean }
|
||||
return { enabled: !!cfg.allowFinalistRevisedUploads }
|
||||
}),
|
||||
|
||||
/** Toggle whether finalists may upload revised grand-final documents (admin setting on the LIVE_FINAL round). */
|
||||
setRevisedUploadSetting: adminProcedure
|
||||
.input(z.object({ roundId: z.string(), enabled: z.boolean() }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const round = await ctx.prisma.round.findUnique({ where: { id: input.roundId }, select: { configJson: true, roundType: true } })
|
||||
if (!round || round.roundType !== 'LIVE_FINAL') {
|
||||
throw new TRPCError({ code: 'BAD_REQUEST', message: 'Not a grand-final round' })
|
||||
}
|
||||
const cfg = (round.configJson ?? {}) as Record<string, unknown>
|
||||
await ctx.prisma.round.update({
|
||||
where: { id: input.roundId },
|
||||
data: { configJson: { ...cfg, allowFinalistRevisedUploads: input.enabled } },
|
||||
})
|
||||
await logAudit({
|
||||
prisma: ctx.prisma,
|
||||
userId: ctx.user.id,
|
||||
action: 'FINALIST_REVISED_UPLOADS_TOGGLED',
|
||||
entityType: 'Round',
|
||||
entityId: input.roundId,
|
||||
detailsJson: { enabled: input.enabled },
|
||||
})
|
||||
return { ok: true, enabled: input.enabled }
|
||||
}),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user