szabadpalya/api/internal/store/migrations/0001_init.sql

155 lines
6.5 KiB
SQL

-- Squashed from the two Prisma migrations this schema replaces. Identical
-- shape, so an existing database can be adopted by inserting the version row
-- into schema_migrations by hand instead of re-running this.
--
-- Identifiers stay quoted and camelCase: renaming them would have been a
-- second migration to review on top of a rewrite, and the SQL is generated
-- by nobody now, so the cost of keeping them is zero.
CREATE TYPE "TierType" AS ENUM ('DONATION', 'DIGITAL', 'PHYSICAL');
CREATE TYPE "CampaignStatus" AS ENUM ('DRAFT', 'BEADVA', 'AKTIV', 'FINANSZIROZOTT', 'LEZART', 'ELUTASITVA');
CREATE TYPE "PledgeStatus" AS ENUM ('AUTHORIZED', 'CAPTURED', 'RELEASED', 'REFUNDED');
CREATE TYPE "PhysicalTierPolicy" AS ENUM ('GUARD', 'IMMEDIATE');
CREATE TABLE "Organization" (
"id" TEXT NOT NULL PRIMARY KEY,
"slug" TEXT NOT NULL,
"name" TEXT NOT NULL,
"initials" TEXT NOT NULL,
"location" TEXT NOT NULL,
"blurb" TEXT NOT NULL,
"stripeAccountId" TEXT,
"approved" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE "User" (
"id" TEXT NOT NULL PRIMARY KEY,
"email" TEXT NOT NULL,
"name" TEXT NOT NULL DEFAULT '',
"emailVerified" BOOLEAN NOT NULL DEFAULT false,
"image" TEXT,
"isAdmin" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"updatedAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- Sessions and magic-link tokens are stored hashed, so a database dump does
-- not hand out live credentials. See internal/auth.
CREATE TABLE "Session" (
"id" TEXT NOT NULL PRIMARY KEY,
"token" TEXT NOT NULL,
"expiresAt" TIMESTAMPTZ NOT NULL,
"ipAddress" TEXT,
"userAgent" TEXT,
"userId" TEXT NOT NULL REFERENCES "User"("id") ON DELETE CASCADE,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"updatedAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE "Verification" (
"id" TEXT NOT NULL PRIMARY KEY,
"identifier" TEXT NOT NULL,
"value" TEXT NOT NULL,
"expiresAt" TIMESTAMPTZ NOT NULL,
"consumedAt" TIMESTAMPTZ,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"updatedAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE "Campaign" (
"id" TEXT NOT NULL PRIMARY KEY,
"slug" TEXT NOT NULL,
"title" TEXT NOT NULL,
"category" TEXT NOT NULL,
"summary" TEXT NOT NULL,
"art" TEXT NOT NULL,
"goalAmount" INTEGER NOT NULL,
"currency" TEXT NOT NULL DEFAULT 'HUF',
"startsAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"endsAt" TIMESTAMPTZ NOT NULL,
"status" "CampaignStatus" NOT NULL DEFAULT 'DRAFT',
"physicalTierPolicy" "PhysicalTierPolicy" NOT NULL DEFAULT 'GUARD',
"organizationId" TEXT NOT NULL REFERENCES "Organization"("id") ON DELETE RESTRICT,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"updatedAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE "StorySection" (
"id" TEXT NOT NULL PRIMARY KEY,
"campaignId" TEXT NOT NULL REFERENCES "Campaign"("id") ON DELETE CASCADE,
"heading" TEXT NOT NULL,
"body" TEXT[] NOT NULL,
"position" INTEGER NOT NULL
);
CREATE TABLE "RewardTier" (
"id" TEXT NOT NULL PRIMARY KEY,
"campaignId" TEXT NOT NULL REFERENCES "Campaign"("id") ON DELETE CASCADE,
"type" "TierType" NOT NULL,
"price" INTEGER NOT NULL,
"listPrice" INTEGER,
"title" TEXT NOT NULL,
"includes" TEXT[] NOT NULL,
"inventoryLimit" INTEGER,
"estimatedDelivery" TIMESTAMPTZ,
"featured" BOOLEAN NOT NULL DEFAULT false,
"position" INTEGER NOT NULL
);
CREATE TABLE "Pledge" (
"id" TEXT NOT NULL PRIMARY KEY,
"campaignId" TEXT NOT NULL REFERENCES "Campaign"("id") ON DELETE CASCADE,
"tierId" TEXT NOT NULL REFERENCES "RewardTier"("id") ON DELETE RESTRICT,
"userId" TEXT REFERENCES "User"("id") ON DELETE SET NULL,
"backerEmail" TEXT NOT NULL,
"quantity" INTEGER NOT NULL DEFAULT 1,
"amount" INTEGER NOT NULL,
"status" "PledgeStatus" NOT NULL DEFAULT 'AUTHORIZED',
"stripePaymentIntentId" TEXT,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now(),
"capturedAt" TIMESTAMPTZ
);
CREATE TABLE "ShippingAddress" (
"id" TEXT NOT NULL PRIMARY KEY,
"pledgeId" TEXT NOT NULL REFERENCES "Pledge"("id") ON DELETE CASCADE,
"recipient" TEXT NOT NULL,
"postalCode" TEXT NOT NULL,
"city" TEXT NOT NULL,
"street" TEXT NOT NULL,
"note" TEXT
);
CREATE TABLE "CampaignUpdate" (
"id" TEXT NOT NULL PRIMARY KEY,
"campaignId" TEXT NOT NULL REFERENCES "Campaign"("id") ON DELETE CASCADE,
"title" TEXT NOT NULL,
"body" TEXT NOT NULL,
"publishedAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE "Comment" (
"id" TEXT NOT NULL PRIMARY KEY,
"campaignId" TEXT NOT NULL REFERENCES "Campaign"("id") ON DELETE CASCADE,
"authorName" TEXT NOT NULL,
"body" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE UNIQUE INDEX "Organization_slug_key" ON "Organization"("slug");
CREATE UNIQUE INDEX "Organization_stripeAccountId_key" ON "Organization"("stripeAccountId");
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
CREATE UNIQUE INDEX "Session_token_key" ON "Session"("token");
CREATE INDEX "Session_userId_idx" ON "Session"("userId");
CREATE INDEX "Verification_identifier_idx" ON "Verification"("identifier");
CREATE UNIQUE INDEX "Verification_value_key" ON "Verification"("value");
CREATE UNIQUE INDEX "Campaign_slug_key" ON "Campaign"("slug");
CREATE INDEX "Campaign_status_endsAt_idx" ON "Campaign"("status", "endsAt");
CREATE UNIQUE INDEX "StorySection_campaignId_position_key" ON "StorySection"("campaignId", "position");
CREATE UNIQUE INDEX "RewardTier_campaignId_position_key" ON "RewardTier"("campaignId", "position");
CREATE UNIQUE INDEX "Pledge_stripePaymentIntentId_key" ON "Pledge"("stripePaymentIntentId");
CREATE INDEX "Pledge_campaignId_status_idx" ON "Pledge"("campaignId", "status");
CREATE INDEX "Pledge_tierId_idx" ON "Pledge"("tierId");
CREATE UNIQUE INDEX "ShippingAddress_pledgeId_key" ON "ShippingAddress"("pledgeId");