This commit is contained in:
commit
59bb5a38a3
132 files changed
+19435
No files matched your search
@@ -0,0 +1,528 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PricePhase" AS ENUM ('PREVIEW', 'EARLY_BIRD', 'REGULAR');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "BookingStatus" AS ENUM ('PENDING', 'CONFIRMED', 'CANCELED', 'EXPIRED', 'NEEDS_REVIEW');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PaymentStatus" AS ENUM ('UNPAID', 'PROCESSING', 'PARTIALLY_PAID', 'PAID', 'FAILED', 'PARTIALLY_REFUNDED', 'REFUNDED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "PlanType" AS ENUM ('FULL', 'TWO_INSTALLMENTS', 'THREE_INSTALLMENTS');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "InstallmentStatus" AS ENUM ('PENDING', 'PROCESSING', 'PAID', 'FAILED', 'REQUIRES_ACTION', 'CANCELED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ReservationStatus" AS ENUM ('ACTIVE', 'HELD', 'CONVERTED', 'RELEASED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "RedemptionStatus" AS ENUM ('RESERVED', 'COMPLETED', 'RELEASED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "StripeEventStatus" AS ENUM ('PROCESSING', 'PROCESSED', 'IGNORED', 'FAILED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "EmailStatus" AS ENUM ('PENDING', 'SENT', 'FAILED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ActorType" AS ENUM ('ADMIN', 'CUSTOMER', 'STRIPE', 'WORKER', 'SYSTEM');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Camp" (
|
||||
"id" TEXT NOT NULL,
|
||||
"salesEnabled" BOOLEAN NOT NULL DEFAULT false,
|
||||
"capacity" INTEGER NOT NULL DEFAULT 10,
|
||||
"capacityConfirmed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"stammmodelQuota" INTEGER NOT NULL DEFAULT 4,
|
||||
"stammmodelQuotaConfirmed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"campStartDate" DATE,
|
||||
"campEndDate" DATE,
|
||||
"dateConfirmed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"locationName" TEXT,
|
||||
"locationRegion" TEXT,
|
||||
"locationConfirmed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"accommodationText" TEXT,
|
||||
"accommodationConfirmed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"servicesConfirmed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"organizerName" TEXT,
|
||||
"organizerAddress" TEXT,
|
||||
"organizerEmail" TEXT,
|
||||
"organizerPhone" TEXT,
|
||||
"organizerConfirmed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"taxNote" TEXT,
|
||||
"taxConfirmed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"termsVersion" TEXT,
|
||||
"termsUrl" TEXT,
|
||||
"termsApproved" BOOLEAN NOT NULL DEFAULT false,
|
||||
"travelLawChecked" BOOLEAN NOT NULL DEFAULT false,
|
||||
"installmentsApproved" BOOLEAN NOT NULL DEFAULT false,
|
||||
"installmentRuleApproved" BOOLEAN NOT NULL DEFAULT false,
|
||||
"reservationMinutes" INTEGER NOT NULL DEFAULT 30,
|
||||
"finalInstallmentLeadDays" INTEGER NOT NULL DEFAULT 30,
|
||||
"minInstallmentGapDays" INTEGER NOT NULL DEFAULT 14,
|
||||
"testPhaseOverride" "PricePhase",
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"updatedBy" TEXT,
|
||||
|
||||
CONSTRAINT "Camp_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Booking" (
|
||||
"id" TEXT NOT NULL,
|
||||
"reference" TEXT NOT NULL,
|
||||
"campId" TEXT NOT NULL,
|
||||
"status" "BookingStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"paymentStatus" "PaymentStatus" NOT NULL DEFAULT 'UNPAID',
|
||||
"livemode" BOOLEAN NOT NULL,
|
||||
"idempotencyKey" TEXT NOT NULL,
|
||||
"statusTokenHash" TEXT NOT NULL,
|
||||
"firstName" TEXT NOT NULL,
|
||||
"lastName" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"phone" TEXT NOT NULL,
|
||||
"country" TEXT NOT NULL,
|
||||
"notes" TEXT,
|
||||
"adultConfirmedAt" TIMESTAMP(3) NOT NULL,
|
||||
"termsAcceptedAt" TIMESTAMP(3) NOT NULL,
|
||||
"termsVersion" TEXT NOT NULL,
|
||||
"accommodationAcknowledgedAt" TIMESTAMP(3) NOT NULL,
|
||||
"privacyAcknowledgedAt" TIMESTAMP(3) NOT NULL,
|
||||
"installmentMandateAt" TIMESTAMP(3),
|
||||
"pricePhase" "PricePhase" NOT NULL,
|
||||
"basePriceCents" INTEGER NOT NULL,
|
||||
"phaseDiscountCents" INTEGER NOT NULL,
|
||||
"voucherDiscountCents" INTEGER NOT NULL,
|
||||
"totalCents" INTEGER NOT NULL,
|
||||
"planType" "PlanType" NOT NULL,
|
||||
"priceSnapshot" JSONB NOT NULL,
|
||||
"priceLockedUntil" TIMESTAMP(3) NOT NULL,
|
||||
"voucherId" TEXT,
|
||||
"stripeCustomerId" TEXT,
|
||||
"stripeCheckoutSessionId" TEXT,
|
||||
"stripeCheckoutUrl" TEXT,
|
||||
"stripePaymentMethodId" TEXT,
|
||||
"paymentMethodDetachedAt" TIMESTAMP(3),
|
||||
"paidCents" INTEGER NOT NULL DEFAULT 0,
|
||||
"refundedCents" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"confirmedAt" TIMESTAMP(3),
|
||||
"canceledAt" TIMESTAMP(3),
|
||||
"cancelReason" TEXT,
|
||||
"reviewReason" TEXT,
|
||||
|
||||
CONSTRAINT "Booking_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Installment" (
|
||||
"id" TEXT NOT NULL,
|
||||
"bookingId" TEXT NOT NULL,
|
||||
"seq" INTEGER NOT NULL,
|
||||
"amountCents" INTEGER NOT NULL,
|
||||
"dueAt" TIMESTAMP(3),
|
||||
"status" "InstallmentStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"attemptCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"lastAttemptAt" TIMESTAMP(3),
|
||||
"nextAttemptAt" TIMESTAMP(3),
|
||||
"failureCode" TEXT,
|
||||
"paidAt" TIMESTAMP(3),
|
||||
"refundedCents" INTEGER NOT NULL DEFAULT 0,
|
||||
"stripePaymentIntentId" TEXT,
|
||||
"stripeChargeId" TEXT,
|
||||
"checkoutSessionId" TEXT,
|
||||
"checkoutExpiresAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Installment_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Refund" (
|
||||
"id" TEXT NOT NULL,
|
||||
"bookingId" TEXT NOT NULL,
|
||||
"installmentId" TEXT,
|
||||
"stripeRefundId" TEXT NOT NULL,
|
||||
"amountCents" INTEGER NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"reason" TEXT,
|
||||
"createdBy" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Refund_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "SeatReservation" (
|
||||
"id" TEXT NOT NULL,
|
||||
"bookingId" TEXT NOT NULL,
|
||||
"campId" TEXT NOT NULL,
|
||||
"livemode" BOOLEAN NOT NULL,
|
||||
"status" "ReservationStatus" NOT NULL DEFAULT 'ACTIVE',
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"releasedAt" TIMESTAMP(3),
|
||||
"releaseReason" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "SeatReservation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Voucher" (
|
||||
"id" TEXT NOT NULL,
|
||||
"code" TEXT NOT NULL,
|
||||
"active" BOOLEAN NOT NULL DEFAULT true,
|
||||
"validFrom" TIMESTAMP(3),
|
||||
"validUntil" TIMESTAMP(3),
|
||||
"maxRedemptions" INTEGER NOT NULL DEFAULT 1,
|
||||
"boundEmail" TEXT,
|
||||
"internalNote" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Voucher_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "VoucherRedemption" (
|
||||
"id" TEXT NOT NULL,
|
||||
"voucherId" TEXT NOT NULL,
|
||||
"bookingId" TEXT NOT NULL,
|
||||
"livemode" BOOLEAN NOT NULL,
|
||||
"status" "RedemptionStatus" NOT NULL DEFAULT 'RESERVED',
|
||||
"releasedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "VoucherRedemption_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "StripeEvent" (
|
||||
"id" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"livemode" BOOLEAN NOT NULL,
|
||||
"status" "StripeEventStatus" NOT NULL DEFAULT 'PROCESSING',
|
||||
"error" TEXT,
|
||||
"attempts" INTEGER NOT NULL DEFAULT 1,
|
||||
"receivedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"processedAt" TIMESTAMP(3),
|
||||
|
||||
CONSTRAINT "StripeEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "EmailMessage" (
|
||||
"id" TEXT NOT NULL,
|
||||
"dedupeKey" TEXT NOT NULL,
|
||||
"bookingId" TEXT,
|
||||
"toAddress" TEXT NOT NULL,
|
||||
"subject" TEXT NOT NULL,
|
||||
"textBody" TEXT NOT NULL,
|
||||
"htmlBody" TEXT NOT NULL,
|
||||
"status" "EmailStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"attempts" INTEGER NOT NULL DEFAULT 0,
|
||||
"lastError" TEXT,
|
||||
"sentAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "EmailMessage_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AuditLog" (
|
||||
"id" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"actorType" "ActorType" NOT NULL,
|
||||
"actorId" TEXT,
|
||||
"action" TEXT NOT NULL,
|
||||
"entityType" TEXT NOT NULL,
|
||||
"entityId" TEXT NOT NULL,
|
||||
"details" JSONB,
|
||||
|
||||
CONSTRAINT "AuditLog_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "RateLimitBucket" (
|
||||
"key" TEXT NOT NULL,
|
||||
"windowStart" TIMESTAMP(3) NOT NULL,
|
||||
"count" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "RateLimitBucket_pkey" PRIMARY KEY ("key")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"emailVerified" BOOLEAN NOT NULL DEFAULT false,
|
||||
"image" TEXT,
|
||||
"twoFactorEnabled" BOOLEAN DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "user_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "session" (
|
||||
"id" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"ipAddress" TEXT,
|
||||
"userAgent" TEXT,
|
||||
"userId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "session_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "account" (
|
||||
"id" TEXT NOT NULL,
|
||||
"accountId" TEXT NOT NULL,
|
||||
"providerId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"accessToken" TEXT,
|
||||
"refreshToken" TEXT,
|
||||
"idToken" TEXT,
|
||||
"accessTokenExpiresAt" TIMESTAMP(3),
|
||||
"refreshTokenExpiresAt" TIMESTAMP(3),
|
||||
"scope" TEXT,
|
||||
"password" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "account_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "verification" (
|
||||
"id" TEXT NOT NULL,
|
||||
"identifier" TEXT NOT NULL,
|
||||
"value" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "verification_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "twoFactor" (
|
||||
"id" TEXT NOT NULL,
|
||||
"secret" TEXT NOT NULL,
|
||||
"backupCodes" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "twoFactor_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "rateLimit" (
|
||||
"id" TEXT NOT NULL,
|
||||
"key" TEXT NOT NULL,
|
||||
"count" INTEGER NOT NULL,
|
||||
"lastRequest" BIGINT NOT NULL,
|
||||
|
||||
CONSTRAINT "rateLimit_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Booking_reference_key" ON "Booking"("reference");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Booking_idempotencyKey_key" ON "Booking"("idempotencyKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Booking_statusTokenHash_key" ON "Booking"("statusTokenHash");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Booking_stripeCheckoutSessionId_key" ON "Booking"("stripeCheckoutSessionId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Booking_livemode_status_idx" ON "Booking"("livemode", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Booking_email_idx" ON "Booking"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Booking_createdAt_idx" ON "Booking"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Installment_stripePaymentIntentId_key" ON "Installment"("stripePaymentIntentId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Installment_stripeChargeId_key" ON "Installment"("stripeChargeId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Installment_checkoutSessionId_key" ON "Installment"("checkoutSessionId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Installment_status_dueAt_idx" ON "Installment"("status", "dueAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Installment_bookingId_seq_key" ON "Installment"("bookingId", "seq");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Refund_stripeRefundId_key" ON "Refund"("stripeRefundId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "SeatReservation_bookingId_key" ON "SeatReservation"("bookingId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "SeatReservation_campId_livemode_status_expiresAt_idx" ON "SeatReservation"("campId", "livemode", "status", "expiresAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Voucher_code_key" ON "Voucher"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "VoucherRedemption_bookingId_key" ON "VoucherRedemption"("bookingId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "VoucherRedemption_voucherId_livemode_status_idx" ON "VoucherRedemption"("voucherId", "livemode", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "EmailMessage_dedupeKey_key" ON "EmailMessage"("dedupeKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EmailMessage_status_createdAt_idx" ON "EmailMessage"("status", "createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AuditLog_entityType_entityId_idx" ON "AuditLog"("entityType", "entityId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AuditLog_createdAt_idx" ON "AuditLog"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_email_key" ON "user"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "session_token_key" ON "session"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "session_userId_idx" ON "session"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "account_userId_idx" ON "account"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "verification_identifier_idx" ON "verification"("identifier");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "twoFactor_secret_idx" ON "twoFactor"("secret");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "twoFactor_userId_idx" ON "twoFactor"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "rateLimit_key_key" ON "rateLimit"("key");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_campId_fkey" FOREIGN KEY ("campId") REFERENCES "Camp"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_voucherId_fkey" FOREIGN KEY ("voucherId") REFERENCES "Voucher"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Installment" ADD CONSTRAINT "Installment_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Refund" ADD CONSTRAINT "Refund_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Refund" ADD CONSTRAINT "Refund_installmentId_fkey" FOREIGN KEY ("installmentId") REFERENCES "Installment"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SeatReservation" ADD CONSTRAINT "SeatReservation_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "SeatReservation" ADD CONSTRAINT "SeatReservation_campId_fkey" FOREIGN KEY ("campId") REFERENCES "Camp"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "VoucherRedemption" ADD CONSTRAINT "VoucherRedemption_voucherId_fkey" FOREIGN KEY ("voucherId") REFERENCES "Voucher"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "VoucherRedemption" ADD CONSTRAINT "VoucherRedemption_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EmailMessage" ADD CONSTRAINT "EmailMessage_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "session" ADD CONSTRAINT "session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "account" ADD CONSTRAINT "account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "twoFactor" ADD CONSTRAINT "twoFactor_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Unveraenderlicher Preis-Snapshot und Zahlungsplan (Briefing Abschnitt 9).
|
||||
-- Der bei Buchung vereinbarte Preis darf auch durch einen Programmfehler oder
|
||||
-- einen direkten Datenbankzugriff nicht nachtraeglich veraendert werden.
|
||||
-- Eine Vertragsaenderung heisst: stornieren und neu buchen.
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE OR REPLACE FUNCTION booking_snapshot_immutable() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF NEW."reference" IS DISTINCT FROM OLD."reference"
|
||||
OR NEW."livemode" IS DISTINCT FROM OLD."livemode"
|
||||
OR NEW."idempotencyKey" IS DISTINCT FROM OLD."idempotencyKey"
|
||||
OR NEW."pricePhase" IS DISTINCT FROM OLD."pricePhase"
|
||||
OR NEW."basePriceCents" IS DISTINCT FROM OLD."basePriceCents"
|
||||
OR NEW."phaseDiscountCents" IS DISTINCT FROM OLD."phaseDiscountCents"
|
||||
OR NEW."voucherDiscountCents" IS DISTINCT FROM OLD."voucherDiscountCents"
|
||||
OR NEW."totalCents" IS DISTINCT FROM OLD."totalCents"
|
||||
OR NEW."planType" IS DISTINCT FROM OLD."planType"
|
||||
OR NEW."priceSnapshot" IS DISTINCT FROM OLD."priceSnapshot"
|
||||
OR NEW."priceLockedUntil" IS DISTINCT FROM OLD."priceLockedUntil"
|
||||
OR NEW."voucherId" IS DISTINCT FROM OLD."voucherId"
|
||||
THEN
|
||||
RAISE EXCEPTION 'Preis-Snapshot der Buchung % ist unveraenderlich', OLD."id";
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER booking_snapshot_immutable
|
||||
BEFORE UPDATE ON "Booking"
|
||||
FOR EACH ROW EXECUTE FUNCTION booking_snapshot_immutable();
|
||||
|
||||
CREATE OR REPLACE FUNCTION installment_plan_immutable() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
IF NEW."bookingId" IS DISTINCT FROM OLD."bookingId"
|
||||
OR NEW."seq" IS DISTINCT FROM OLD."seq"
|
||||
OR NEW."amountCents" IS DISTINCT FROM OLD."amountCents"
|
||||
OR NEW."dueAt" IS DISTINCT FROM OLD."dueAt"
|
||||
THEN
|
||||
RAISE EXCEPTION 'Rate % ist Teil des vereinbarten Zahlungsplans und unveraenderlich', OLD."id";
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER installment_plan_immutable
|
||||
BEFORE UPDATE ON "Installment"
|
||||
FOR EACH ROW EXECUTE FUNCTION installment_plan_immutable();
|
||||
|
||||
-- Plausibilitaet auf Datenbankebene.
|
||||
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_amounts_check"
|
||||
CHECK ("totalCents" > 0 AND "basePriceCents" > 0 AND "phaseDiscountCents" >= 0
|
||||
AND "voucherDiscountCents" >= 0 AND "paidCents" >= 0 AND "refundedCents" >= 0
|
||||
AND "totalCents" = "basePriceCents" - "phaseDiscountCents" - "voucherDiscountCents");
|
||||
ALTER TABLE "Installment" ADD CONSTRAINT "Installment_amount_check"
|
||||
CHECK ("amountCents" > 0 AND "seq" BETWEEN 1 AND 3 AND "refundedCents" >= 0);
|
||||
ALTER TABLE "Camp" ADD CONSTRAINT "Camp_limits_check"
|
||||
CHECK ("capacity" >= 0 AND "stammmodelQuota" >= 0 AND "reservationMinutes" BETWEEN 30 AND 1440
|
||||
AND "finalInstallmentLeadDays" >= 0 AND "minInstallmentGapDays" >= 1);
|
||||
ALTER TABLE "Voucher" ADD CONSTRAINT "Voucher_limits_check"
|
||||
CHECK ("maxRedemptions" >= 1 AND "code" = upper("code"));
|
||||
@@ -0,0 +1,4 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "twoFactor" ADD COLUMN "failedVerificationCount" INTEGER DEFAULT 0,
|
||||
ADD COLUMN "lockedUntil" TIMESTAMP(3),
|
||||
ADD COLUMN "verified" BOOLEAN DEFAULT true;
|
||||
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
Reference in new issue
Block a user