Competition/Round architecture: full platform rewrite (Phases 1-9)
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m45s
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m45s
Replace Pipeline/Stage system with Competition/Round architecture. New schema: Competition, Round (7 types), JuryGroup, AssignmentPolicy, ProjectRoundState, DeliberationSession, ResultLock, SubmissionWindow. New services: round-engine, round-assignment, deliberation, result-lock, submission-manager, competition-context, ai-prompt-guard. Full admin/jury/applicant/mentor UI rewrite. AI prompt hardening with structured prompts, retry logic, and injection detection. All legacy pipeline/stage code removed. 4 new migrations + seed aligned. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
117
src/server/routers/roundAssignment.ts
Normal file
117
src/server/routers/roundAssignment.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { z } from 'zod'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { router, adminProcedure, protectedProcedure, juryProcedure } from '../trpc'
|
||||
import {
|
||||
previewRoundAssignment,
|
||||
executeRoundAssignment,
|
||||
getRoundCoverageReport,
|
||||
getUnassignedQueue,
|
||||
} from '../services/round-assignment'
|
||||
|
||||
export const roundAssignmentRouter = router({
|
||||
/**
|
||||
* Preview round assignments without committing
|
||||
*/
|
||||
preview: adminProcedure
|
||||
.input(
|
||||
z.object({
|
||||
roundId: z.string(),
|
||||
honorIntents: z.boolean().default(true),
|
||||
requiredReviews: z.number().int().min(1).max(20).default(3),
|
||||
})
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
return previewRoundAssignment(
|
||||
input.roundId,
|
||||
{
|
||||
honorIntents: input.honorIntents,
|
||||
requiredReviews: input.requiredReviews,
|
||||
},
|
||||
ctx.prisma,
|
||||
)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Execute round assignments (create Assignment records)
|
||||
*/
|
||||
execute: adminProcedure
|
||||
.input(
|
||||
z.object({
|
||||
roundId: z.string(),
|
||||
assignments: z.array(
|
||||
z.object({
|
||||
userId: z.string(),
|
||||
projectId: z.string(),
|
||||
})
|
||||
).min(1),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const result = await executeRoundAssignment(
|
||||
input.roundId,
|
||||
input.assignments,
|
||||
ctx.user.id,
|
||||
ctx.prisma,
|
||||
)
|
||||
|
||||
if (result.errors.length > 0 && result.created === 0) {
|
||||
throw new TRPCError({
|
||||
code: 'INTERNAL_SERVER_ERROR',
|
||||
message: result.errors.join('; '),
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}),
|
||||
|
||||
/**
|
||||
* Get coverage report for a round
|
||||
*/
|
||||
coverageReport: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
roundId: z.string(),
|
||||
requiredReviews: z.number().int().min(1).max(20).default(3),
|
||||
})
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
return getRoundCoverageReport(input.roundId, input.requiredReviews, ctx.prisma)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Get projects below required reviews threshold
|
||||
*/
|
||||
unassignedQueue: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
roundId: z.string(),
|
||||
requiredReviews: z.number().int().min(1).max(20).default(3),
|
||||
})
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
return getUnassignedQueue(input.roundId, input.requiredReviews, ctx.prisma)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Get assignments for the current jury member in a specific round
|
||||
*/
|
||||
getMyAssignments: juryProcedure
|
||||
.input(z.object({ roundId: z.string() }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
return ctx.prisma.assignment.findMany({
|
||||
where: {
|
||||
roundId: input.roundId,
|
||||
userId: ctx.user.id,
|
||||
},
|
||||
include: {
|
||||
project: {
|
||||
select: { id: true, title: true, competitionCategory: true },
|
||||
},
|
||||
evaluation: {
|
||||
select: { id: true, status: true, globalScore: true },
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: 'asc' },
|
||||
})
|
||||
}),
|
||||
})
|
||||
Reference in New Issue
Block a user