-- ============================================================================= -- Phase 0+1: Add Competition/Round Architecture (additive -- no breaking changes) -- ============================================================================= -- New enums, new tables, new optional columns on existing tables. -- Old Pipeline/Track/Stage tables are untouched. -- --- New Enum Types --- DO $$ BEGIN CREATE TYPE "CompetitionStatus" AS ENUM ('DRAFT', 'ACTIVE', 'CLOSED', 'ARCHIVED'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "RoundType" AS ENUM ('INTAKE', 'FILTERING', 'EVALUATION', 'SUBMISSION', 'MENTORING', 'LIVE_FINAL', 'DELIBERATION'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "RoundStatus" AS ENUM ('ROUND_DRAFT', 'ROUND_ACTIVE', 'ROUND_CLOSED', 'ROUND_ARCHIVED'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "ProjectRoundStateValue" AS ENUM ('PENDING', 'IN_PROGRESS', 'PASSED', 'REJECTED', 'COMPLETED', 'WITHDRAWN'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "AdvancementRuleType" AS ENUM ('AUTO_ADVANCE', 'SCORE_THRESHOLD', 'TOP_N', 'ADMIN_SELECTION', 'AI_RECOMMENDED'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "CapMode" AS ENUM ('HARD', 'SOFT', 'NONE'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "DeadlinePolicy" AS ENUM ('HARD_DEADLINE', 'FLAG', 'GRACE'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "JuryGroupMemberRole" AS ENUM ('CHAIR', 'MEMBER', 'OBSERVER'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "AssignmentIntentSource" AS ENUM ('INVITE', 'ADMIN', 'SYSTEM'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "AssignmentIntentStatus" AS ENUM ('INTENT_PENDING', 'HONORED', 'OVERRIDDEN', 'EXPIRED', 'CANCELLED'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "MentorMessageRole" AS ENUM ('MENTOR_ROLE', 'APPLICANT_ROLE', 'ADMIN_ROLE'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "SubmissionPromotionSource" AS ENUM ('MENTOR_FILE', 'ADMIN_REPLACEMENT'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "DeliberationMode" AS ENUM ('SINGLE_WINNER_VOTE', 'FULL_RANKING'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "DeliberationStatus" AS ENUM ('DELIB_OPEN', 'VOTING', 'TALLYING', 'RUNOFF', 'DELIB_LOCKED'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "TieBreakMethod" AS ENUM ('TIE_RUNOFF', 'TIE_ADMIN_DECIDES', 'SCORE_FALLBACK'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "DeliberationParticipantStatus" AS ENUM ('REQUIRED', 'ABSENT_EXCUSED', 'REPLACED', 'REPLACEMENT_ACTIVE'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "AwardEligibilityMode" AS ENUM ('SEPARATE_POOL', 'STAY_IN_MAIN'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- Add FEATURE_FLAGS to SettingCategory enum DO $$ BEGIN ALTER TYPE "SettingCategory" ADD VALUE 'FEATURE_FLAGS'; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- --- New Tables --- -- Competition (replaces Pipeline) CREATE TABLE IF NOT EXISTS "Competition" ( "id" TEXT NOT NULL, "programId" TEXT NOT NULL, "name" TEXT NOT NULL, "slug" TEXT NOT NULL, "status" "CompetitionStatus" NOT NULL DEFAULT 'DRAFT', "categoryMode" TEXT NOT NULL DEFAULT 'SHARED', "startupFinalistCount" INTEGER NOT NULL DEFAULT 3, "conceptFinalistCount" INTEGER NOT NULL DEFAULT 3, "notifyOnRoundAdvance" BOOLEAN NOT NULL DEFAULT true, "notifyOnDeadlineApproach" BOOLEAN NOT NULL DEFAULT true, "deadlineReminderDays" INTEGER[] DEFAULT ARRAY[7, 3, 1]::INTEGER[], "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "Competition_pkey" PRIMARY KEY ("id") ); -- Round (replaces Stage) CREATE TABLE IF NOT EXISTS "Round" ( "id" TEXT NOT NULL, "competitionId" TEXT NOT NULL, "name" TEXT NOT NULL, "slug" TEXT NOT NULL, "roundType" "RoundType" NOT NULL, "status" "RoundStatus" NOT NULL DEFAULT 'ROUND_DRAFT', "sortOrder" INTEGER NOT NULL DEFAULT 0, "windowOpenAt" TIMESTAMP(3), "windowCloseAt" TIMESTAMP(3), "configJson" JSONB, "purposeKey" TEXT, "juryGroupId" TEXT, "submissionWindowId" TEXT, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "Round_pkey" PRIMARY KEY ("id") ); -- ProjectRoundState CREATE TABLE IF NOT EXISTS "ProjectRoundState" ( "id" TEXT NOT NULL, "projectId" TEXT NOT NULL, "roundId" TEXT NOT NULL, "state" "ProjectRoundStateValue" NOT NULL DEFAULT 'PENDING', "enteredAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "exitedAt" TIMESTAMP(3), "metadataJson" JSONB, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "ProjectRoundState_pkey" PRIMARY KEY ("id") ); -- AdvancementRule CREATE TABLE IF NOT EXISTS "AdvancementRule" ( "id" TEXT NOT NULL, "roundId" TEXT NOT NULL, "targetRoundId" TEXT, "ruleType" "AdvancementRuleType" NOT NULL, "configJson" JSONB NOT NULL, "isDefault" BOOLEAN NOT NULL DEFAULT true, "sortOrder" INTEGER NOT NULL DEFAULT 0, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "AdvancementRule_pkey" PRIMARY KEY ("id") ); -- JuryGroup CREATE TABLE IF NOT EXISTS "JuryGroup" ( "id" TEXT NOT NULL, "competitionId" TEXT NOT NULL, "name" TEXT NOT NULL, "slug" TEXT NOT NULL, "description" TEXT, "sortOrder" INTEGER NOT NULL DEFAULT 0, "defaultMaxAssignments" INTEGER NOT NULL DEFAULT 20, "defaultCapMode" "CapMode" NOT NULL DEFAULT 'SOFT', "softCapBuffer" INTEGER NOT NULL DEFAULT 2, "categoryQuotasEnabled" BOOLEAN NOT NULL DEFAULT false, "defaultCategoryQuotas" JSONB, "allowJurorCapAdjustment" BOOLEAN NOT NULL DEFAULT false, "allowJurorRatioAdjustment" BOOLEAN NOT NULL DEFAULT false, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "JuryGroup_pkey" PRIMARY KEY ("id") ); -- JuryGroupMember CREATE TABLE IF NOT EXISTS "JuryGroupMember" ( "id" TEXT NOT NULL, "juryGroupId" TEXT NOT NULL, "userId" TEXT NOT NULL, "role" "JuryGroupMemberRole" NOT NULL DEFAULT 'MEMBER', "joinedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "maxAssignmentsOverride" INTEGER, "capModeOverride" "CapMode", "categoryQuotasOverride" JSONB, "preferredStartupRatio" DOUBLE PRECISION, "availabilityNotes" TEXT, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "JuryGroupMember_pkey" PRIMARY KEY ("id") ); -- SubmissionWindow CREATE TABLE IF NOT EXISTS "SubmissionWindow" ( "id" TEXT NOT NULL, "competitionId" TEXT NOT NULL, "name" TEXT NOT NULL, "slug" TEXT NOT NULL, "roundNumber" INTEGER NOT NULL, "sortOrder" INTEGER NOT NULL DEFAULT 0, "windowOpenAt" TIMESTAMP(3), "windowCloseAt" TIMESTAMP(3), "deadlinePolicy" "DeadlinePolicy" NOT NULL DEFAULT 'FLAG', "graceHours" INTEGER, "lockOnClose" BOOLEAN NOT NULL DEFAULT true, "isLocked" BOOLEAN NOT NULL DEFAULT false, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "SubmissionWindow_pkey" PRIMARY KEY ("id") ); -- SubmissionFileRequirement CREATE TABLE IF NOT EXISTS "SubmissionFileRequirement" ( "id" TEXT NOT NULL, "submissionWindowId" TEXT NOT NULL, "label" TEXT NOT NULL, "slug" TEXT NOT NULL, "description" TEXT, "mimeTypes" TEXT[], "maxSizeMb" INTEGER, "required" BOOLEAN NOT NULL DEFAULT true, "sortOrder" INTEGER NOT NULL DEFAULT 0, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "SubmissionFileRequirement_pkey" PRIMARY KEY ("id") ); -- RoundSubmissionVisibility CREATE TABLE IF NOT EXISTS "RoundSubmissionVisibility" ( "id" TEXT NOT NULL, "roundId" TEXT NOT NULL, "submissionWindowId" TEXT NOT NULL, "canView" BOOLEAN NOT NULL DEFAULT true, "displayLabel" TEXT, CONSTRAINT "RoundSubmissionVisibility_pkey" PRIMARY KEY ("id") ); -- AssignmentIntent CREATE TABLE IF NOT EXISTS "AssignmentIntent" ( "id" TEXT NOT NULL, "juryGroupMemberId" TEXT NOT NULL, "roundId" TEXT NOT NULL, "projectId" TEXT NOT NULL, "source" "AssignmentIntentSource" NOT NULL, "status" "AssignmentIntentStatus" NOT NULL DEFAULT 'INTENT_PENDING', "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "AssignmentIntent_pkey" PRIMARY KEY ("id") ); -- AssignmentException CREATE TABLE IF NOT EXISTS "AssignmentException" ( "id" TEXT NOT NULL, "assignmentId" TEXT NOT NULL, "reason" TEXT NOT NULL, "overCapBy" INTEGER NOT NULL, "approvedById" TEXT NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "AssignmentException_pkey" PRIMARY KEY ("id") ); -- MentorFile CREATE TABLE IF NOT EXISTS "MentorFile" ( "id" TEXT NOT NULL, "mentorAssignmentId" TEXT NOT NULL, "uploadedByUserId" TEXT NOT NULL, "fileName" TEXT NOT NULL, "mimeType" TEXT NOT NULL, "size" INTEGER NOT NULL, "bucket" TEXT NOT NULL, "objectKey" TEXT NOT NULL, "description" TEXT, "isPromoted" BOOLEAN NOT NULL DEFAULT false, "promotedToFileId" TEXT, "promotedAt" TIMESTAMP(3), "promotedByUserId" TEXT, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "MentorFile_pkey" PRIMARY KEY ("id") ); -- MentorFileComment CREATE TABLE IF NOT EXISTS "MentorFileComment" ( "id" TEXT NOT NULL, "mentorFileId" TEXT NOT NULL, "authorId" TEXT NOT NULL, "content" TEXT NOT NULL, "parentCommentId" TEXT, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "MentorFileComment_pkey" PRIMARY KEY ("id") ); -- SubmissionPromotionEvent CREATE TABLE IF NOT EXISTS "SubmissionPromotionEvent" ( "id" TEXT NOT NULL, "projectId" TEXT NOT NULL, "roundId" TEXT NOT NULL, "slotKey" TEXT NOT NULL, "sourceType" "SubmissionPromotionSource" NOT NULL, "sourceFileId" TEXT, "promotedById" TEXT NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "SubmissionPromotionEvent_pkey" PRIMARY KEY ("id") ); -- DeliberationSession CREATE TABLE IF NOT EXISTS "DeliberationSession" ( "id" TEXT NOT NULL, "competitionId" TEXT NOT NULL, "roundId" TEXT NOT NULL, "category" "CompetitionCategory" NOT NULL, "mode" "DeliberationMode" NOT NULL, "showCollectiveRankings" BOOLEAN NOT NULL DEFAULT false, "showPriorJuryData" BOOLEAN NOT NULL DEFAULT false, "status" "DeliberationStatus" NOT NULL, "tieBreakMethod" "TieBreakMethod" NOT NULL, "adminOverrideResult" JSONB, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "DeliberationSession_pkey" PRIMARY KEY ("id") ); -- DeliberationVote CREATE TABLE IF NOT EXISTS "DeliberationVote" ( "id" TEXT NOT NULL, "sessionId" TEXT NOT NULL, "juryMemberId" TEXT NOT NULL, "projectId" TEXT NOT NULL, "rank" INTEGER, "isWinnerPick" BOOLEAN NOT NULL DEFAULT false, "runoffRound" INTEGER NOT NULL DEFAULT 0, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "DeliberationVote_pkey" PRIMARY KEY ("id") ); -- DeliberationResult CREATE TABLE IF NOT EXISTS "DeliberationResult" ( "id" TEXT NOT NULL, "sessionId" TEXT NOT NULL, "projectId" TEXT NOT NULL, "finalRank" INTEGER NOT NULL, "voteCount" INTEGER NOT NULL DEFAULT 0, "isAdminOverridden" BOOLEAN NOT NULL DEFAULT false, "overrideReason" TEXT, CONSTRAINT "DeliberationResult_pkey" PRIMARY KEY ("id") ); -- DeliberationParticipant CREATE TABLE IF NOT EXISTS "DeliberationParticipant" ( "id" TEXT NOT NULL, "sessionId" TEXT NOT NULL, "userId" TEXT NOT NULL, "status" "DeliberationParticipantStatus" NOT NULL, "replacedById" TEXT, CONSTRAINT "DeliberationParticipant_pkey" PRIMARY KEY ("id") ); -- ResultLock CREATE TABLE IF NOT EXISTS "ResultLock" ( "id" TEXT NOT NULL, "competitionId" TEXT NOT NULL, "roundId" TEXT NOT NULL, "category" "CompetitionCategory" NOT NULL, "lockedById" TEXT NOT NULL, "resultSnapshot" JSONB NOT NULL, "lockedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "ResultLock_pkey" PRIMARY KEY ("id") ); -- ResultUnlockEvent CREATE TABLE IF NOT EXISTS "ResultUnlockEvent" ( "id" TEXT NOT NULL, "resultLockId" TEXT NOT NULL, "unlockedById" TEXT NOT NULL, "reason" TEXT NOT NULL, "unlockedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "ResultUnlockEvent_pkey" PRIMARY KEY ("id") ); -- --- Add Columns to Existing Tables --- -- Assignment: add juryGroupId DO $$ BEGIN ALTER TABLE "Assignment" ADD COLUMN "juryGroupId" TEXT; EXCEPTION WHEN duplicate_column THEN NULL; END $$; -- SpecialAward: add competition/round architecture fields DO $$ BEGIN ALTER TABLE "SpecialAward" ADD COLUMN "competitionId" TEXT; EXCEPTION WHEN duplicate_column THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SpecialAward" ADD COLUMN "evaluationRoundId" TEXT; EXCEPTION WHEN duplicate_column THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SpecialAward" ADD COLUMN "juryGroupId" TEXT; EXCEPTION WHEN duplicate_column THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SpecialAward" ADD COLUMN "eligibilityMode" "AwardEligibilityMode" NOT NULL DEFAULT 'STAY_IN_MAIN'; EXCEPTION WHEN duplicate_column THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SpecialAward" ADD COLUMN "decisionMode" TEXT; EXCEPTION WHEN duplicate_column THEN NULL; END $$; -- MentorAssignment: add workspace fields DO $$ BEGIN ALTER TABLE "MentorAssignment" ADD COLUMN "workspaceEnabled" BOOLEAN NOT NULL DEFAULT false; EXCEPTION WHEN duplicate_column THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "MentorAssignment" ADD COLUMN "workspaceOpenAt" TIMESTAMP(3); EXCEPTION WHEN duplicate_column THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "MentorAssignment" ADD COLUMN "workspaceCloseAt" TIMESTAMP(3); EXCEPTION WHEN duplicate_column THEN NULL; END $$; -- MentorMessage: add workspace fields DO $$ BEGIN ALTER TABLE "MentorMessage" ADD COLUMN "workspaceId" TEXT; EXCEPTION WHEN duplicate_column THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "MentorMessage" ADD COLUMN "senderRole" "MentorMessageRole"; EXCEPTION WHEN duplicate_column THEN NULL; END $$; -- ProjectFile: add submission window link DO $$ BEGIN ALTER TABLE "ProjectFile" ADD COLUMN "submissionWindowId" TEXT; EXCEPTION WHEN duplicate_column THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "ProjectFile" ADD COLUMN "submissionFileRequirementId" TEXT; EXCEPTION WHEN duplicate_column THEN NULL; END $$; -- --- Unique Constraints --- CREATE UNIQUE INDEX IF NOT EXISTS "Competition_slug_key" ON "Competition"("slug"); CREATE UNIQUE INDEX IF NOT EXISTS "Round_competitionId_slug_key" ON "Round"("competitionId", "slug"); CREATE UNIQUE INDEX IF NOT EXISTS "Round_competitionId_sortOrder_key" ON "Round"("competitionId", "sortOrder"); CREATE UNIQUE INDEX IF NOT EXISTS "ProjectRoundState_projectId_roundId_key" ON "ProjectRoundState"("projectId", "roundId"); CREATE UNIQUE INDEX IF NOT EXISTS "JuryGroup_competitionId_slug_key" ON "JuryGroup"("competitionId", "slug"); CREATE UNIQUE INDEX IF NOT EXISTS "JuryGroupMember_juryGroupId_userId_key" ON "JuryGroupMember"("juryGroupId", "userId"); CREATE UNIQUE INDEX IF NOT EXISTS "SubmissionWindow_competitionId_slug_key" ON "SubmissionWindow"("competitionId", "slug"); CREATE UNIQUE INDEX IF NOT EXISTS "SubmissionWindow_competitionId_roundNumber_key" ON "SubmissionWindow"("competitionId", "roundNumber"); CREATE UNIQUE INDEX IF NOT EXISTS "RoundSubmissionVisibility_roundId_submissionWindowId_key" ON "RoundSubmissionVisibility"("roundId", "submissionWindowId"); CREATE UNIQUE INDEX IF NOT EXISTS "AssignmentIntent_juryGroupMemberId_roundId_projectId_key" ON "AssignmentIntent"("juryGroupMemberId", "roundId", "projectId"); CREATE UNIQUE INDEX IF NOT EXISTS "MentorFile_promotedToFileId_key" ON "MentorFile"("promotedToFileId"); CREATE UNIQUE INDEX IF NOT EXISTS "DeliberationVote_sessionId_juryMemberId_projectId_runoffRo_key" ON "DeliberationVote"("sessionId", "juryMemberId", "projectId", "runoffRound"); CREATE UNIQUE INDEX IF NOT EXISTS "DeliberationResult_sessionId_projectId_key" ON "DeliberationResult"("sessionId", "projectId"); CREATE UNIQUE INDEX IF NOT EXISTS "DeliberationParticipant_sessionId_userId_key" ON "DeliberationParticipant"("sessionId", "userId"); CREATE UNIQUE INDEX IF NOT EXISTS "SubmissionFileRequirement_submissionWindowId_slug_key" ON "SubmissionFileRequirement"("submissionWindowId", "slug"); CREATE UNIQUE INDEX IF NOT EXISTS "AdvancementRule_roundId_sortOrder_key" ON "AdvancementRule"("roundId", "sortOrder"); -- --- Indexes --- -- Competition CREATE INDEX IF NOT EXISTS "Competition_programId_idx" ON "Competition"("programId"); CREATE INDEX IF NOT EXISTS "Competition_status_idx" ON "Competition"("status"); -- Round CREATE INDEX IF NOT EXISTS "Round_competitionId_idx" ON "Round"("competitionId"); CREATE INDEX IF NOT EXISTS "Round_roundType_idx" ON "Round"("roundType"); CREATE INDEX IF NOT EXISTS "Round_status_idx" ON "Round"("status"); -- ProjectRoundState CREATE INDEX IF NOT EXISTS "ProjectRoundState_projectId_idx" ON "ProjectRoundState"("projectId"); CREATE INDEX IF NOT EXISTS "ProjectRoundState_roundId_idx" ON "ProjectRoundState"("roundId"); CREATE INDEX IF NOT EXISTS "ProjectRoundState_state_idx" ON "ProjectRoundState"("state"); -- AdvancementRule CREATE INDEX IF NOT EXISTS "AdvancementRule_roundId_idx" ON "AdvancementRule"("roundId"); -- JuryGroup CREATE INDEX IF NOT EXISTS "JuryGroup_competitionId_idx" ON "JuryGroup"("competitionId"); -- JuryGroupMember CREATE INDEX IF NOT EXISTS "JuryGroupMember_juryGroupId_idx" ON "JuryGroupMember"("juryGroupId"); CREATE INDEX IF NOT EXISTS "JuryGroupMember_userId_idx" ON "JuryGroupMember"("userId"); -- SubmissionWindow CREATE INDEX IF NOT EXISTS "SubmissionWindow_competitionId_idx" ON "SubmissionWindow"("competitionId"); -- SubmissionFileRequirement CREATE INDEX IF NOT EXISTS "SubmissionFileRequirement_submissionWindowId_idx" ON "SubmissionFileRequirement"("submissionWindowId"); -- RoundSubmissionVisibility CREATE INDEX IF NOT EXISTS "RoundSubmissionVisibility_roundId_idx" ON "RoundSubmissionVisibility"("roundId"); -- AssignmentIntent CREATE INDEX IF NOT EXISTS "AssignmentIntent_roundId_idx" ON "AssignmentIntent"("roundId"); CREATE INDEX IF NOT EXISTS "AssignmentIntent_projectId_idx" ON "AssignmentIntent"("projectId"); CREATE INDEX IF NOT EXISTS "AssignmentIntent_status_idx" ON "AssignmentIntent"("status"); -- AssignmentException CREATE INDEX IF NOT EXISTS "AssignmentException_assignmentId_idx" ON "AssignmentException"("assignmentId"); CREATE INDEX IF NOT EXISTS "AssignmentException_approvedById_idx" ON "AssignmentException"("approvedById"); -- MentorFile CREATE INDEX IF NOT EXISTS "MentorFile_mentorAssignmentId_idx" ON "MentorFile"("mentorAssignmentId"); CREATE INDEX IF NOT EXISTS "MentorFile_uploadedByUserId_idx" ON "MentorFile"("uploadedByUserId"); -- MentorFileComment CREATE INDEX IF NOT EXISTS "MentorFileComment_mentorFileId_idx" ON "MentorFileComment"("mentorFileId"); CREATE INDEX IF NOT EXISTS "MentorFileComment_authorId_idx" ON "MentorFileComment"("authorId"); CREATE INDEX IF NOT EXISTS "MentorFileComment_parentCommentId_idx" ON "MentorFileComment"("parentCommentId"); -- SubmissionPromotionEvent CREATE INDEX IF NOT EXISTS "SubmissionPromotionEvent_projectId_idx" ON "SubmissionPromotionEvent"("projectId"); CREATE INDEX IF NOT EXISTS "SubmissionPromotionEvent_roundId_idx" ON "SubmissionPromotionEvent"("roundId"); CREATE INDEX IF NOT EXISTS "SubmissionPromotionEvent_sourceFileId_idx" ON "SubmissionPromotionEvent"("sourceFileId"); -- DeliberationSession CREATE INDEX IF NOT EXISTS "DeliberationSession_competitionId_idx" ON "DeliberationSession"("competitionId"); CREATE INDEX IF NOT EXISTS "DeliberationSession_roundId_idx" ON "DeliberationSession"("roundId"); CREATE INDEX IF NOT EXISTS "DeliberationSession_status_idx" ON "DeliberationSession"("status"); -- DeliberationVote CREATE INDEX IF NOT EXISTS "DeliberationVote_sessionId_idx" ON "DeliberationVote"("sessionId"); CREATE INDEX IF NOT EXISTS "DeliberationVote_juryMemberId_idx" ON "DeliberationVote"("juryMemberId"); CREATE INDEX IF NOT EXISTS "DeliberationVote_projectId_idx" ON "DeliberationVote"("projectId"); -- DeliberationResult CREATE INDEX IF NOT EXISTS "DeliberationResult_sessionId_idx" ON "DeliberationResult"("sessionId"); CREATE INDEX IF NOT EXISTS "DeliberationResult_projectId_idx" ON "DeliberationResult"("projectId"); -- DeliberationParticipant CREATE INDEX IF NOT EXISTS "DeliberationParticipant_sessionId_idx" ON "DeliberationParticipant"("sessionId"); CREATE INDEX IF NOT EXISTS "DeliberationParticipant_userId_idx" ON "DeliberationParticipant"("userId"); -- ResultLock CREATE INDEX IF NOT EXISTS "ResultLock_competitionId_idx" ON "ResultLock"("competitionId"); CREATE INDEX IF NOT EXISTS "ResultLock_roundId_idx" ON "ResultLock"("roundId"); CREATE INDEX IF NOT EXISTS "ResultLock_category_idx" ON "ResultLock"("category"); -- ResultUnlockEvent CREATE INDEX IF NOT EXISTS "ResultUnlockEvent_resultLockId_idx" ON "ResultUnlockEvent"("resultLockId"); CREATE INDEX IF NOT EXISTS "ResultUnlockEvent_unlockedById_idx" ON "ResultUnlockEvent"("unlockedById"); -- Indexes on modified existing tables CREATE INDEX IF NOT EXISTS "Assignment_juryGroupId_idx" ON "Assignment"("juryGroupId"); CREATE INDEX IF NOT EXISTS "SpecialAward_competitionId_idx" ON "SpecialAward"("competitionId"); CREATE INDEX IF NOT EXISTS "SpecialAward_evaluationRoundId_idx" ON "SpecialAward"("evaluationRoundId"); CREATE INDEX IF NOT EXISTS "MentorMessage_workspaceId_idx" ON "MentorMessage"("workspaceId"); CREATE INDEX IF NOT EXISTS "ProjectFile_submissionWindowId_idx" ON "ProjectFile"("submissionWindowId"); CREATE INDEX IF NOT EXISTS "ProjectFile_submissionFileRequirementId_idx" ON "ProjectFile"("submissionFileRequirementId"); -- --- Foreign Keys --- -- Competition DO $$ BEGIN ALTER TABLE "Competition" ADD CONSTRAINT "Competition_programId_fkey" FOREIGN KEY ("programId") REFERENCES "Program"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- Round DO $$ BEGIN ALTER TABLE "Round" ADD CONSTRAINT "Round_competitionId_fkey" FOREIGN KEY ("competitionId") REFERENCES "Competition"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "Round" ADD CONSTRAINT "Round_juryGroupId_fkey" FOREIGN KEY ("juryGroupId") REFERENCES "JuryGroup"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "Round" ADD CONSTRAINT "Round_submissionWindowId_fkey" FOREIGN KEY ("submissionWindowId") REFERENCES "SubmissionWindow"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- ProjectRoundState DO $$ BEGIN ALTER TABLE "ProjectRoundState" ADD CONSTRAINT "ProjectRoundState_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "ProjectRoundState" ADD CONSTRAINT "ProjectRoundState_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "Round"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- AdvancementRule DO $$ BEGIN ALTER TABLE "AdvancementRule" ADD CONSTRAINT "AdvancementRule_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "Round"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- JuryGroup DO $$ BEGIN ALTER TABLE "JuryGroup" ADD CONSTRAINT "JuryGroup_competitionId_fkey" FOREIGN KEY ("competitionId") REFERENCES "Competition"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- JuryGroupMember DO $$ BEGIN ALTER TABLE "JuryGroupMember" ADD CONSTRAINT "JuryGroupMember_juryGroupId_fkey" FOREIGN KEY ("juryGroupId") REFERENCES "JuryGroup"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "JuryGroupMember" ADD CONSTRAINT "JuryGroupMember_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- SubmissionWindow DO $$ BEGIN ALTER TABLE "SubmissionWindow" ADD CONSTRAINT "SubmissionWindow_competitionId_fkey" FOREIGN KEY ("competitionId") REFERENCES "Competition"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- SubmissionFileRequirement DO $$ BEGIN ALTER TABLE "SubmissionFileRequirement" ADD CONSTRAINT "SubmissionFileRequirement_submissionWindowId_fkey" FOREIGN KEY ("submissionWindowId") REFERENCES "SubmissionWindow"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- RoundSubmissionVisibility DO $$ BEGIN ALTER TABLE "RoundSubmissionVisibility" ADD CONSTRAINT "RoundSubmissionVisibility_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "Round"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "RoundSubmissionVisibility" ADD CONSTRAINT "RoundSubmissionVisibility_submissionWindowId_fkey" FOREIGN KEY ("submissionWindowId") REFERENCES "SubmissionWindow"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- AssignmentIntent DO $$ BEGIN ALTER TABLE "AssignmentIntent" ADD CONSTRAINT "AssignmentIntent_juryGroupMemberId_fkey" FOREIGN KEY ("juryGroupMemberId") REFERENCES "JuryGroupMember"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "AssignmentIntent" ADD CONSTRAINT "AssignmentIntent_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "Round"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "AssignmentIntent" ADD CONSTRAINT "AssignmentIntent_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- AssignmentException DO $$ BEGIN ALTER TABLE "AssignmentException" ADD CONSTRAINT "AssignmentException_assignmentId_fkey" FOREIGN KEY ("assignmentId") REFERENCES "Assignment"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "AssignmentException" ADD CONSTRAINT "AssignmentException_approvedById_fkey" FOREIGN KEY ("approvedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- MentorFile DO $$ BEGIN ALTER TABLE "MentorFile" ADD CONSTRAINT "MentorFile_mentorAssignmentId_fkey" FOREIGN KEY ("mentorAssignmentId") REFERENCES "MentorAssignment"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "MentorFile" ADD CONSTRAINT "MentorFile_uploadedByUserId_fkey" FOREIGN KEY ("uploadedByUserId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "MentorFile" ADD CONSTRAINT "MentorFile_promotedByUserId_fkey" FOREIGN KEY ("promotedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "MentorFile" ADD CONSTRAINT "MentorFile_promotedToFileId_fkey" FOREIGN KEY ("promotedToFileId") REFERENCES "ProjectFile"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- MentorFileComment DO $$ BEGIN ALTER TABLE "MentorFileComment" ADD CONSTRAINT "MentorFileComment_mentorFileId_fkey" FOREIGN KEY ("mentorFileId") REFERENCES "MentorFile"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "MentorFileComment" ADD CONSTRAINT "MentorFileComment_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "MentorFileComment" ADD CONSTRAINT "MentorFileComment_parentCommentId_fkey" FOREIGN KEY ("parentCommentId") REFERENCES "MentorFileComment"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- SubmissionPromotionEvent DO $$ BEGIN ALTER TABLE "SubmissionPromotionEvent" ADD CONSTRAINT "SubmissionPromotionEvent_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SubmissionPromotionEvent" ADD CONSTRAINT "SubmissionPromotionEvent_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "Round"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SubmissionPromotionEvent" ADD CONSTRAINT "SubmissionPromotionEvent_sourceFileId_fkey" FOREIGN KEY ("sourceFileId") REFERENCES "MentorFile"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SubmissionPromotionEvent" ADD CONSTRAINT "SubmissionPromotionEvent_promotedById_fkey" FOREIGN KEY ("promotedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- DeliberationSession DO $$ BEGIN ALTER TABLE "DeliberationSession" ADD CONSTRAINT "DeliberationSession_competitionId_fkey" FOREIGN KEY ("competitionId") REFERENCES "Competition"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "DeliberationSession" ADD CONSTRAINT "DeliberationSession_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "Round"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- DeliberationVote DO $$ BEGIN ALTER TABLE "DeliberationVote" ADD CONSTRAINT "DeliberationVote_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "DeliberationSession"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "DeliberationVote" ADD CONSTRAINT "DeliberationVote_juryMemberId_fkey" FOREIGN KEY ("juryMemberId") REFERENCES "JuryGroupMember"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "DeliberationVote" ADD CONSTRAINT "DeliberationVote_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- DeliberationResult DO $$ BEGIN ALTER TABLE "DeliberationResult" ADD CONSTRAINT "DeliberationResult_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "DeliberationSession"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "DeliberationResult" ADD CONSTRAINT "DeliberationResult_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- DeliberationParticipant DO $$ BEGIN ALTER TABLE "DeliberationParticipant" ADD CONSTRAINT "DeliberationParticipant_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "DeliberationSession"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "DeliberationParticipant" ADD CONSTRAINT "DeliberationParticipant_userId_fkey" FOREIGN KEY ("userId") REFERENCES "JuryGroupMember"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "DeliberationParticipant" ADD CONSTRAINT "DeliberationParticipant_replacedById_fkey" FOREIGN KEY ("replacedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- ResultLock DO $$ BEGIN ALTER TABLE "ResultLock" ADD CONSTRAINT "ResultLock_competitionId_fkey" FOREIGN KEY ("competitionId") REFERENCES "Competition"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "ResultLock" ADD CONSTRAINT "ResultLock_roundId_fkey" FOREIGN KEY ("roundId") REFERENCES "Round"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "ResultLock" ADD CONSTRAINT "ResultLock_lockedById_fkey" FOREIGN KEY ("lockedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- ResultUnlockEvent DO $$ BEGIN ALTER TABLE "ResultUnlockEvent" ADD CONSTRAINT "ResultUnlockEvent_resultLockId_fkey" FOREIGN KEY ("resultLockId") REFERENCES "ResultLock"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "ResultUnlockEvent" ADD CONSTRAINT "ResultUnlockEvent_unlockedById_fkey" FOREIGN KEY ("unlockedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; -- FKs on modified existing tables DO $$ BEGIN ALTER TABLE "Assignment" ADD CONSTRAINT "Assignment_juryGroupId_fkey" FOREIGN KEY ("juryGroupId") REFERENCES "JuryGroup"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SpecialAward" ADD CONSTRAINT "SpecialAward_competitionId_fkey" FOREIGN KEY ("competitionId") REFERENCES "Competition"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SpecialAward" ADD CONSTRAINT "SpecialAward_evaluationRoundId_fkey" FOREIGN KEY ("evaluationRoundId") REFERENCES "Round"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "SpecialAward" ADD CONSTRAINT "SpecialAward_juryGroupId_fkey" FOREIGN KEY ("juryGroupId") REFERENCES "JuryGroup"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "MentorMessage" ADD CONSTRAINT "MentorMessage_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "MentorAssignment"("id") ON DELETE CASCADE ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "ProjectFile" ADD CONSTRAINT "ProjectFile_submissionWindowId_fkey" FOREIGN KEY ("submissionWindowId") REFERENCES "SubmissionWindow"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE "ProjectFile" ADD CONSTRAINT "ProjectFile_submissionFileRequirementId_fkey" FOREIGN KEY ("submissionFileRequirementId") REFERENCES "SubmissionFileRequirement"("id") ON DELETE SET NULL ON UPDATE CASCADE; EXCEPTION WHEN duplicate_object THEN NULL; END $$;