Decouple projects from rounds with RoundProject join table
Projects now exist at the program level instead of being locked to a single round. A new RoundProject join table enables many-to-many relationships with per-round status tracking. Rounds have sortOrder for configurable progression paths. - Add RoundProject model, programId on Project, sortOrder on Round - Migration preserves existing data (roundId -> RoundProject entries) - Update all routers to query through RoundProject join - Add assign/remove/advance/reorder round endpoints - Add Assign, Advance, Remove Projects dialogs on round detail page - Add round reorder controls (up/down arrows) on rounds list - Show all rounds on project detail page Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,7 +56,6 @@ async function AssignmentsContent({
|
||||
title: true,
|
||||
teamName: true,
|
||||
description: true,
|
||||
status: true,
|
||||
files: {
|
||||
select: {
|
||||
id: true,
|
||||
|
||||
@@ -45,7 +45,6 @@ async function JuryDashboardContent() {
|
||||
id: true,
|
||||
title: true,
|
||||
teamName: true,
|
||||
status: true,
|
||||
},
|
||||
},
|
||||
round: {
|
||||
|
||||
@@ -34,11 +34,18 @@ async function EvaluateContent({ projectId }: { projectId: string }) {
|
||||
redirect('/login')
|
||||
}
|
||||
|
||||
// Get project with assignment info for this user
|
||||
const project = await prisma.project.findUnique({
|
||||
where: { id: projectId },
|
||||
// Check if user is assigned to this project
|
||||
const assignment = await prisma.assignment.findFirst({
|
||||
where: {
|
||||
projectId,
|
||||
userId,
|
||||
},
|
||||
include: {
|
||||
files: true,
|
||||
evaluation: {
|
||||
include: {
|
||||
form: true,
|
||||
},
|
||||
},
|
||||
round: {
|
||||
include: {
|
||||
program: {
|
||||
@@ -53,25 +60,18 @@ async function EvaluateContent({ projectId }: { projectId: string }) {
|
||||
},
|
||||
})
|
||||
|
||||
// Get project details
|
||||
const project = await prisma.project.findUnique({
|
||||
where: { id: projectId },
|
||||
include: {
|
||||
files: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (!project) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
// Check if user is assigned to this project
|
||||
const assignment = await prisma.assignment.findFirst({
|
||||
where: {
|
||||
projectId,
|
||||
userId,
|
||||
},
|
||||
include: {
|
||||
evaluation: {
|
||||
include: {
|
||||
form: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!assignment) {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
@@ -95,7 +95,7 @@ async function EvaluateContent({ projectId }: { projectId: string }) {
|
||||
)
|
||||
}
|
||||
|
||||
const round = project.round
|
||||
const round = assignment.round
|
||||
const now = new Date()
|
||||
|
||||
// Check voting window
|
||||
|
||||
@@ -49,10 +49,18 @@ async function EvaluationContent({ projectId }: { projectId: string }) {
|
||||
redirect('/login')
|
||||
}
|
||||
|
||||
// Get project with assignment info for this user
|
||||
const project = await prisma.project.findUnique({
|
||||
where: { id: projectId },
|
||||
// Check if user is assigned to this project
|
||||
const assignment = await prisma.assignment.findFirst({
|
||||
where: {
|
||||
projectId,
|
||||
userId,
|
||||
},
|
||||
include: {
|
||||
evaluation: {
|
||||
include: {
|
||||
form: true,
|
||||
},
|
||||
},
|
||||
round: {
|
||||
include: {
|
||||
program: {
|
||||
@@ -67,25 +75,20 @@ async function EvaluationContent({ projectId }: { projectId: string }) {
|
||||
},
|
||||
})
|
||||
|
||||
// Get project details
|
||||
const project = await prisma.project.findUnique({
|
||||
where: { id: projectId },
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
teamName: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (!project) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
// Check if user is assigned to this project
|
||||
const assignment = await prisma.assignment.findFirst({
|
||||
where: {
|
||||
projectId,
|
||||
userId,
|
||||
},
|
||||
include: {
|
||||
evaluation: {
|
||||
include: {
|
||||
form: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!assignment) {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
@@ -145,7 +148,7 @@ async function EvaluationContent({ projectId }: { projectId: string }) {
|
||||
const criterionScores =
|
||||
(evaluation.criterionScoresJson as unknown as Record<string, number>) || {}
|
||||
|
||||
const round = project.round
|
||||
const round = assignment.round
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
|
||||
@@ -43,11 +43,14 @@ async function ProjectContent({ projectId }: { projectId: string }) {
|
||||
redirect('/login')
|
||||
}
|
||||
|
||||
// Get project with assignment info for this user
|
||||
const project = await prisma.project.findUnique({
|
||||
where: { id: projectId },
|
||||
// Check if user is assigned to this project
|
||||
const assignment = await prisma.assignment.findFirst({
|
||||
where: {
|
||||
projectId,
|
||||
userId,
|
||||
},
|
||||
include: {
|
||||
files: true,
|
||||
evaluation: true,
|
||||
round: {
|
||||
include: {
|
||||
program: {
|
||||
@@ -62,21 +65,18 @@ async function ProjectContent({ projectId }: { projectId: string }) {
|
||||
},
|
||||
})
|
||||
|
||||
// Get project details
|
||||
const project = await prisma.project.findUnique({
|
||||
where: { id: projectId },
|
||||
include: {
|
||||
files: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (!project) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
// Check if user is assigned to this project
|
||||
const assignment = await prisma.assignment.findFirst({
|
||||
where: {
|
||||
projectId,
|
||||
userId,
|
||||
},
|
||||
include: {
|
||||
evaluation: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (!assignment) {
|
||||
// User is not assigned to this project
|
||||
return (
|
||||
@@ -99,7 +99,7 @@ async function ProjectContent({ projectId }: { projectId: string }) {
|
||||
}
|
||||
|
||||
const evaluation = assignment.evaluation
|
||||
const round = project.round
|
||||
const round = assignment.round
|
||||
const now = new Date()
|
||||
|
||||
// Check voting window
|
||||
|
||||
Reference in New Issue
Block a user