Fix project detail 500 error and round deletion data integrity

- Add missing migration for FileRequirement table and ProjectFile.requirementId
  column (existed in Prisma schema but had no migration, causing all queries
  with `include: { files: true }` to fail with column not found)
- Make projectTags query resilient with try-catch in project.get
- Reset project status to SUBMITTED when round is deleted (prevents orphaned
  ASSIGNED status after ON DELETE SET NULL nullifies roundId)
- Fix round creation/update to allow requiredReviews=0 for filtering rounds
- Parse Zod validation errors in round creation error display

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 00:20:28 +01:00
parent 0631dbb64f
commit 7e3d600eed
4 changed files with 65 additions and 11 deletions

View File

@@ -111,7 +111,7 @@ export const roundRouter = router({
programId: z.string(),
name: z.string().min(1).max(255),
roundType: z.enum(['FILTERING', 'EVALUATION', 'LIVE_EVENT']).default('EVALUATION'),
requiredReviews: z.number().int().min(1).max(10).default(3),
requiredReviews: z.number().int().min(0).max(10).default(3),
minAssignmentsPerJuror: z.number().int().min(1).max(50).default(5),
maxAssignmentsPerJuror: z.number().int().min(1).max(100).default(20),
sortOrder: z.number().int().optional(),
@@ -208,7 +208,7 @@ export const roundRouter = router({
name: z.string().min(1).max(255).optional(),
slug: z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional().nullable(),
roundType: z.enum(['FILTERING', 'EVALUATION', 'LIVE_EVENT']).optional(),
requiredReviews: z.number().int().min(1).max(10).optional(),
requiredReviews: z.number().int().min(0).max(10).optional(),
minAssignmentsPerJuror: z.number().int().min(1).max(50).optional(),
maxAssignmentsPerJuror: z.number().int().min(1).max(100).optional(),
submissionDeadline: z.date().optional().nullable(),
@@ -615,6 +615,12 @@ export const roundRouter = router({
userAgent: ctx.userAgent,
})
// Reset status for projects that will lose their roundId (ON DELETE SET NULL)
await tx.project.updateMany({
where: { roundId: input.id },
data: { status: 'SUBMITTED' },
})
// Delete evaluations first to avoid FK constraint on Evaluation.formId
// (formId FK may not have CASCADE in older DB schemas)
await tx.evaluation.deleteMany({