Competition/Round architecture: full platform rewrite (Phases 1-9)
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:
2026-02-15 23:04:15 +01:00
parent 9ab4717f96
commit 6ca39c976b
349 changed files with 69938 additions and 28767 deletions

View File

@@ -58,17 +58,17 @@ export default function ProjectPoolPage() {
const stages = (selectedProgramData?.stages || []) as Array<{ id: string; name: string }>
const utils = trpc.useUtils()
const assignMutation = trpc.projectPool.assignToStage.useMutation({
const assignMutation = trpc.projectPool.assignToRound.useMutation({
onSuccess: (result) => {
utils.project.list.invalidate()
utils.program.get.invalidate()
toast.success(`Assigned ${result.assignedCount} project${result.assignedCount !== 1 ? 's' : ''} to stage`)
toast.success(`Assigned ${result.assignedCount} project${result.assignedCount !== 1 ? 's' : ''} to round`)
setSelectedProjects([])
setAssignDialogOpen(false)
setTargetStageId('')
refetch()
},
onError: (error) => {
onError: (error: any) => {
toast.error(error.message || 'Failed to assign projects')
},
})
@@ -77,14 +77,14 @@ export default function ProjectPoolPage() {
if (selectedProjects.length === 0 || !targetStageId) return
assignMutation.mutate({
projectIds: selectedProjects,
stageId: targetStageId,
roundId: targetStageId,
})
}
const handleQuickAssign = (projectId: string, stageId: string) => {
const handleQuickAssign = (projectId: string, roundId: string) => {
assignMutation.mutate({
projectIds: [projectId],
stageId,
roundId,
})
}
@@ -242,7 +242,7 @@ export default function ProjectPoolPage() {
<Skeleton className="h-9 w-[200px]" />
) : (
<Select
onValueChange={(stageId) => handleQuickAssign(project.id, stageId)}
onValueChange={(roundId) => handleQuickAssign(project.id, roundId)}
disabled={assignMutation.isPending}
>
<SelectTrigger className="w-[200px]">