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:
@@ -333,7 +333,7 @@ export const mentorRouter = router({
|
||||
// Get projects without mentors
|
||||
const projects = await ctx.prisma.project.findMany({
|
||||
where: {
|
||||
roundId: input.roundId,
|
||||
roundProjects: { some: { roundId: input.roundId } },
|
||||
mentorAssignment: null,
|
||||
wantsMentorship: true,
|
||||
},
|
||||
@@ -431,10 +431,17 @@ export const mentorRouter = router({
|
||||
include: {
|
||||
project: {
|
||||
include: {
|
||||
round: {
|
||||
program: { select: { name: true, year: true } },
|
||||
roundProjects: {
|
||||
include: {
|
||||
program: { select: { name: true, year: true } },
|
||||
round: {
|
||||
include: {
|
||||
program: { select: { name: true, year: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { addedAt: 'desc' },
|
||||
take: 1,
|
||||
},
|
||||
teamMembers: {
|
||||
include: {
|
||||
@@ -477,10 +484,17 @@ export const mentorRouter = router({
|
||||
const project = await ctx.prisma.project.findUniqueOrThrow({
|
||||
where: { id: input.projectId },
|
||||
include: {
|
||||
round: {
|
||||
program: { select: { id: true, name: true, year: true } },
|
||||
roundProjects: {
|
||||
include: {
|
||||
program: { select: { id: true, name: true, year: true } },
|
||||
round: {
|
||||
include: {
|
||||
program: { select: { id: true, name: true, year: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { addedAt: 'desc' },
|
||||
take: 1,
|
||||
},
|
||||
teamMembers: {
|
||||
include: {
|
||||
@@ -528,7 +542,7 @@ export const mentorRouter = router({
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
const where = {
|
||||
...(input.roundId && { project: { roundId: input.roundId } }),
|
||||
...(input.roundId && { project: { roundProjects: { some: { roundId: input.roundId } } } }),
|
||||
...(input.mentorId && { mentorId: input.mentorId }),
|
||||
}
|
||||
|
||||
@@ -541,9 +555,12 @@ export const mentorRouter = router({
|
||||
id: true,
|
||||
title: true,
|
||||
teamName: true,
|
||||
status: true,
|
||||
oceanIssue: true,
|
||||
competitionCategory: true,
|
||||
roundProjects: {
|
||||
select: { status: true },
|
||||
take: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
mentor: {
|
||||
|
||||
Reference in New Issue
Block a user