Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions prisma/migrations/20251120085659_security_updates/migration.sql
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
-- DropIndex
DROP INDEX "Problem_state_visibility_difficultyId_createdAt_idx";
-- Guarded drop to avoid failures on fresh databases where the index was never created
DROP INDEX IF EXISTS "Problem_state_visibility_difficultyId_createdAt_idx";

-- CreateIndex
CREATE INDEX "Problem_state_visibility_difficultyId_createdAt_idx" ON "Problem"("state", "visibility", "difficultyId", "createdAt" DESC);

-- CreateIndex
CREATE INDEX "ProblemTag_tagId_problemId_idx" ON "ProblemTag"("tagId", "problemId");
DO $$
BEGIN
IF EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'Problem'
AND column_name = 'state'
) THEN
CREATE INDEX IF NOT EXISTS "Problem_state_visibility_difficultyId_createdAt_idx" ON "Problem"("state", "visibility", "difficultyId", "createdAt" DESC);
END IF;

-- CreateIndex
CREATE INDEX "Submission_contestId_userId_idx" ON "Submission"("contestId", "userId");
IF EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'Submission'
AND column_name = 'contestId'
) THEN
CREATE INDEX IF NOT EXISTS "Submission_contestId_userId_idx" ON "Submission"("contestId", "userId");
CREATE INDEX IF NOT EXISTS "Submission_contestId_problemId_userId_idx" ON "Submission"("contestId", "problemId", "userId");
END IF;
END
$$;

-- CreateIndex
CREATE INDEX "Submission_contestId_problemId_userId_idx" ON "Submission"("contestId", "problemId", "userId");
CREATE INDEX "ProblemTag_tagId_problemId_idx" ON "ProblemTag"("tagId", "problemId");
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,8 @@ CREATE INDEX "User_status_role_idx" ON "User"("status", "role");
CREATE UNIQUE INDEX "Problem_currentVersionId_key" ON "Problem"("currentVersionId");

-- CreateIndex
CREATE INDEX "Problem_state_visibility_difficultyId_createdAt_idx" ON "Problem"("state", "visibility", "difficultyId", "createdAt");
-- Ensure the Problem composite index exists without colliding when earlier migrations already created it
CREATE INDEX IF NOT EXISTS "Problem_state_visibility_difficultyId_createdAt_idx" ON "Problem"("state", "visibility", "difficultyId", "createdAt" DESC);

-- CreateIndex
CREATE INDEX "Tag_category_isFeatured_idx" ON "Tag"("category", "isFeatured");
Expand All @@ -595,6 +596,12 @@ CREATE INDEX "Submission_userId_problemId_createdAt_idx" ON "Submission"("userId
-- CreateIndex
CREATE INDEX "Submission_problemId_verdictCode_createdAt_idx" ON "Submission"("problemId", "verdictCode", "createdAt");

-- CreateIndex
CREATE INDEX IF NOT EXISTS "Submission_contestId_userId_idx" ON "Submission"("contestId", "userId");

-- CreateIndex
CREATE INDEX IF NOT EXISTS "Submission_contestId_problemId_userId_idx" ON "Submission"("contestId", "problemId", "userId");

-- CreateIndex
CREATE INDEX "Submission_codeHash_idx" ON "Submission"("codeHash");

Expand Down
153 changes: 125 additions & 28 deletions prisma/migrations/20260224090000_contest_type_field/migration.sql
Original file line number Diff line number Diff line change
@@ -1,31 +1,59 @@
-- Add the missing contest enums and columns to keep schema and DB aligned
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'ContestType') THEN
CREATE TYPE "ContestType" AS ENUM ('COMPETITIVE', 'EDUCATIONAL', 'PRIVATE', 'CUSTOM');
IF NOT EXISTS (
SELECT 1
FROM pg_type t
JOIN pg_namespace n ON n.oid = t.typnamespace
WHERE t.typname = 'ContestType'
AND n.nspname = 'public'
) THEN
CREATE TYPE public."ContestType" AS ENUM ('COMPETITIVE', 'EDUCATIONAL', 'PRIVATE', 'CUSTOM');
END IF;
END$$;
END
$$;

DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'ContestRegistrationStatus') THEN
CREATE TYPE "ContestRegistrationStatus" AS ENUM ('REGISTERED', 'INVITED', 'WAITLISTED', 'DECLINED', 'REMOVED');
IF NOT EXISTS (
SELECT 1
FROM pg_type t
JOIN pg_namespace n ON n.oid = t.typnamespace
WHERE t.typname = 'ContestRegistrationStatus'
AND n.nspname = 'public'
) THEN
CREATE TYPE public."ContestRegistrationStatus" AS ENUM ('REGISTERED', 'INVITED', 'WAITLISTED', 'DECLINED', 'REMOVED');
END IF;
END$$;
END
$$;

DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'ClarificationVisibility') THEN
CREATE TYPE "ClarificationVisibility" AS ENUM ('PRIVATE', 'PUBLIC');
IF NOT EXISTS (
SELECT 1
FROM pg_type t
JOIN pg_namespace n ON n.oid = t.typnamespace
WHERE t.typname = 'ClarificationVisibility'
AND n.nspname = 'public'
) THEN
CREATE TYPE public."ClarificationVisibility" AS ENUM ('PRIVATE', 'PUBLIC');
END IF;
END$$;
END
$$;

DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'ClarificationStatus') THEN
CREATE TYPE "ClarificationStatus" AS ENUM ('OPEN', 'ANSWERED', 'ANNOUNCED', 'CLOSED');
IF NOT EXISTS (
SELECT 1
FROM pg_type t
JOIN pg_namespace n ON n.oid = t.typnamespace
WHERE t.typname = 'ClarificationStatus'
AND n.nspname = 'public'
) THEN
CREATE TYPE public."ClarificationStatus" AS ENUM ('OPEN', 'ANSWERED', 'ANNOUNCED', 'CLOSED');
END IF;
END$$;
END
$$;

DO $$
BEGIN
Expand All @@ -39,20 +67,89 @@ BEGIN
END;
END$$;

ALTER TABLE "Contest" ADD COLUMN "type" "ContestType" NOT NULL DEFAULT 'COMPETITIVE';
ALTER TABLE "Contest" ADD COLUMN "settings" JSONB NOT NULL DEFAULT '{}';
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'Contest' AND column_name = 'type'
) THEN
ALTER TABLE "Contest" ADD COLUMN "type" public."ContestType" NOT NULL DEFAULT 'COMPETITIVE';
END IF;

IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'Contest' AND column_name = 'settings'
) THEN
ALTER TABLE "Contest" ADD COLUMN "settings" JSONB NOT NULL DEFAULT '{}';
END IF;
END
$$;

ALTER TABLE "ContestProblem" ADD COLUMN "settings" JSONB NOT NULL DEFAULT '{}';
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ContestProblem' AND column_name = 'settings'
) THEN
ALTER TABLE "ContestProblem" ADD COLUMN "settings" JSONB NOT NULL DEFAULT '{}';
END IF;
END
$$;

ALTER TABLE "ContestRegistration" ADD COLUMN "status" "ContestRegistrationStatus" NOT NULL DEFAULT 'REGISTERED';
ALTER TABLE "ContestRegistration" ADD COLUMN "isDisqualified" BOOLEAN NOT NULL DEFAULT false;
ALTER TABLE "ContestRegistration" ADD COLUMN "disqualifiedAt" TIMESTAMP(3);
ALTER TABLE "ContestRegistration" ADD COLUMN "dqReason" TEXT;
ALTER TABLE "ContestRegistration" ADD COLUMN "deviceFingerprint" TEXT;
ALTER TABLE "ContestRegistration" ADD COLUMN "ipHash" TEXT;
ALTER TABLE "ContestRegistration" ADD COLUMN "inviteCode" TEXT;
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ContestRegistration' AND column_name = 'status'
) THEN
ALTER TABLE "ContestRegistration" ADD COLUMN "status" public."ContestRegistrationStatus" NOT NULL DEFAULT 'REGISTERED';
END IF;

IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ContestRegistration' AND column_name = 'isDisqualified'
) THEN
ALTER TABLE "ContestRegistration" ADD COLUMN "isDisqualified" BOOLEAN NOT NULL DEFAULT false;
END IF;

IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ContestRegistration' AND column_name = 'disqualifiedAt'
) THEN
ALTER TABLE "ContestRegistration" ADD COLUMN "disqualifiedAt" TIMESTAMP(3);
END IF;

IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ContestRegistration' AND column_name = 'dqReason'
) THEN
ALTER TABLE "ContestRegistration" ADD COLUMN "dqReason" TEXT;
END IF;

IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ContestRegistration' AND column_name = 'deviceFingerprint'
) THEN
ALTER TABLE "ContestRegistration" ADD COLUMN "deviceFingerprint" TEXT;
END IF;

IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ContestRegistration' AND column_name = 'ipHash'
) THEN
ALTER TABLE "ContestRegistration" ADD COLUMN "ipHash" TEXT;
END IF;

IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ContestRegistration' AND column_name = 'inviteCode'
) THEN
ALTER TABLE "ContestRegistration" ADD COLUMN "inviteCode" TEXT;
END IF;
END
$$;

CREATE TABLE "ContestSnapshot" (
CREATE TABLE IF NOT EXISTS "ContestSnapshot" (
"id" TEXT NOT NULL,
"contestId" TEXT NOT NULL,
"frozenAt" TIMESTAMP(3) NOT NULL,
Expand All @@ -63,9 +160,9 @@ CREATE TABLE "ContestSnapshot" (
CONSTRAINT "ContestSnapshot_contestId_fkey" FOREIGN KEY ("contestId") REFERENCES "Contest"("id") ON DELETE CASCADE ON UPDATE CASCADE
);

CREATE INDEX "ContestSnapshot_contestId_frozenAt_idx" ON "ContestSnapshot"("contestId", "frozenAt");
CREATE INDEX IF NOT EXISTS "ContestSnapshot_contestId_frozenAt_idx" ON "ContestSnapshot"("contestId", "frozenAt");

CREATE TABLE "ContestClarification" (
CREATE TABLE IF NOT EXISTS "ContestClarification" (
"id" TEXT NOT NULL,
"contestId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
Expand All @@ -87,7 +184,7 @@ CREATE TABLE "ContestClarification" (
CONSTRAINT "ContestClarification_answeredById_fkey" FOREIGN KEY ("answeredById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE
);

CREATE INDEX "ContestClarification_contestId_status_idx" ON "ContestClarification"("contestId", "status");
CREATE INDEX "ContestClarification_userId_createdAt_idx" ON "ContestClarification"("userId", "createdAt");
CREATE INDEX IF NOT EXISTS "ContestClarification_contestId_status_idx" ON "ContestClarification"("contestId", "status");
CREATE INDEX IF NOT EXISTS "ContestClarification_userId_createdAt_idx" ON "ContestClarification"("userId", "createdAt");

ALTER TABLE "Submission" ADD COLUMN "isFrozen" BOOLEAN NOT NULL DEFAULT false;
ALTER TABLE "Submission" ADD COLUMN IF NOT EXISTS "isFrozen" BOOLEAN NOT NULL DEFAULT false;