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

@@ -26,8 +26,8 @@ export function StepContact({ form, config }: StepContactProps) {
const showCity = !config || isFieldVisible(config, 'city')
const phoneRequired = !config || isFieldRequired(config, 'contactPhone')
const countryRequired = !config || isFieldRequired(config, 'country')
const phoneLabel = config ? getFieldConfig(config, 'contactPhone').label : undefined
const countryLabel = config ? getFieldConfig(config, 'country').label : undefined
const phoneLabel = config ? getFieldConfig(config, 'contactPhone')?.label : undefined
const countryLabel = config ? getFieldConfig(config, 'country')?.label : undefined
return (
<WizardStepContent

View File

@@ -29,7 +29,7 @@ export function StepProject({ form, oceanIssues, config }: StepProjectProps) {
const oceanIssue = watch('oceanIssue')
const description = watch('description') || ''
const showTeamName = !config || isFieldVisible(config, 'teamName')
const descriptionLabel = config ? getFieldConfig(config, 'description').label : undefined
const descriptionLabel = config ? getFieldConfig(config, 'description')?.label : undefined
return (
<WizardStepContent

View File

@@ -51,12 +51,12 @@ import { TeamMemberRole } from '@prisma/client'
// ---------------------------------------------------------------------------
interface ApplyWizardDynamicProps {
mode: 'edition' | 'stage' | 'round'
mode: 'edition' | 'round' | 'stage'
config: WizardConfig
programName: string
programYear: number
programId?: string
stageId?: string
roundId?: string
isOpen: boolean
submissionDeadline?: Date | string | null
onSubmit: (data: Record<string, unknown>) => Promise<void>
@@ -390,7 +390,7 @@ export function ApplyWizardDynamic({
programName,
programYear,
programId,
stageId,
roundId,
isOpen,
submissionDeadline,
onSubmit,

View File

@@ -320,7 +320,7 @@ export function EvaluationForm({
toast.success('Evaluation submitted successfully!')
startTransition(() => {
router.push('/jury/stages')
router.push('/jury/competitions')
router.refresh()
})
} catch (error) {