292 lines
9.3 KiB
SQL
292 lines
9.3 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "Role" AS ENUM ('CUSTOMER', 'THERAPIST', 'ADMIN');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "OverrideKind" AS ENUM ('BLOCK', 'EXTRA_HOURS');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "PaymentStatus" AS ENUM ('NONE', 'PENDING', 'AUTHORIZED', 'CAPTURED', 'REFUNDED', 'FAILED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "PaymentKind" AS ENUM ('DEPOSIT', 'BALANCE', 'REFUND');
|
|
|
|
-- AlterTable
|
|
ALTER TABLE "Booking" ADD COLUMN "cancelReason" TEXT,
|
|
ADD COLUMN "cancelledAt" TIMESTAMPTZ(3),
|
|
ADD COLUMN "cancelledBy" TEXT,
|
|
ADD COLUMN "notes" TEXT,
|
|
ADD COLUMN "paymentStatus" "PaymentStatus" NOT NULL DEFAULT 'NONE',
|
|
ADD COLUMN "stripePaymentIntentId" TEXT;
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "User" (
|
|
"id" TEXT NOT NULL,
|
|
"email" TEXT NOT NULL,
|
|
"emailVerified" TIMESTAMPTZ(3),
|
|
"name" TEXT NOT NULL,
|
|
"phone" TEXT,
|
|
"role" "Role" NOT NULL DEFAULT 'CUSTOMER',
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
|
|
"deletedAt" TIMESTAMPTZ(3),
|
|
|
|
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Customer" (
|
|
"userId" TEXT NOT NULL,
|
|
"notes" TEXT,
|
|
"stripeCustomerId" TEXT,
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
|
|
|
|
CONSTRAINT "Customer_pkey" PRIMARY KEY ("userId")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Therapist" (
|
|
"userId" TEXT NOT NULL,
|
|
"bio" TEXT,
|
|
"active" BOOLEAN NOT NULL DEFAULT true,
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
|
|
|
|
CONSTRAINT "Therapist_pkey" PRIMARY KEY ("userId")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "TherapistTag" (
|
|
"therapistId" TEXT NOT NULL,
|
|
"tag" TEXT NOT NULL,
|
|
|
|
CONSTRAINT "TherapistTag_pkey" PRIMARY KEY ("therapistId","tag")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Room" (
|
|
"id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"active" BOOLEAN NOT NULL DEFAULT true,
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
|
|
|
|
CONSTRAINT "Room_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "RoomTag" (
|
|
"roomId" TEXT NOT NULL,
|
|
"tag" TEXT NOT NULL,
|
|
|
|
CONSTRAINT "RoomTag_pkey" PRIMARY KEY ("roomId","tag")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "RoomBlock" (
|
|
"id" TEXT NOT NULL,
|
|
"roomId" TEXT NOT NULL,
|
|
"startsAt" TIMESTAMPTZ(3) NOT NULL,
|
|
"endsAt" TIMESTAMPTZ(3) NOT NULL,
|
|
"reason" TEXT,
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "RoomBlock_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Service" (
|
|
"id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"durationMin" INTEGER NOT NULL,
|
|
"bufferAfterMin" INTEGER NOT NULL DEFAULT 15,
|
|
"priceCents" INTEGER NOT NULL,
|
|
"depositCents" INTEGER NOT NULL DEFAULT 0,
|
|
"active" BOOLEAN NOT NULL DEFAULT true,
|
|
"requiredTherapistTags" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
|
"requiredRoomTags" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
|
|
|
|
CONSTRAINT "Service_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "ServiceTherapist" (
|
|
"serviceId" TEXT NOT NULL,
|
|
"therapistId" TEXT NOT NULL,
|
|
|
|
CONSTRAINT "ServiceTherapist_pkey" PRIMARY KEY ("serviceId","therapistId")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "WorkingHours" (
|
|
"id" TEXT NOT NULL,
|
|
"therapistId" TEXT NOT NULL,
|
|
"weekday" INTEGER NOT NULL,
|
|
"startMin" INTEGER NOT NULL,
|
|
"endMin" INTEGER NOT NULL,
|
|
"effectiveFrom" TIMESTAMPTZ(3),
|
|
"effectiveTo" TIMESTAMPTZ(3),
|
|
|
|
CONSTRAINT "WorkingHours_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "AvailabilityOverride" (
|
|
"id" TEXT NOT NULL,
|
|
"therapistId" TEXT NOT NULL,
|
|
"startsAt" TIMESTAMPTZ(3) NOT NULL,
|
|
"endsAt" TIMESTAMPTZ(3) NOT NULL,
|
|
"kind" "OverrideKind" NOT NULL,
|
|
"reason" TEXT,
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "AvailabilityOverride_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Payment" (
|
|
"id" TEXT NOT NULL,
|
|
"bookingId" TEXT NOT NULL,
|
|
"kind" "PaymentKind" NOT NULL,
|
|
"amountCents" INTEGER NOT NULL,
|
|
"currency" TEXT NOT NULL DEFAULT 'usd',
|
|
"stripePaymentIntentId" TEXT,
|
|
"status" "PaymentStatus" NOT NULL,
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
|
|
|
|
CONSTRAINT "Payment_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Notification" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT,
|
|
"bookingId" TEXT,
|
|
"channel" TEXT NOT NULL,
|
|
"template" TEXT NOT NULL,
|
|
"to" TEXT NOT NULL,
|
|
"subject" TEXT NOT NULL,
|
|
"bodyHash" TEXT NOT NULL,
|
|
"status" TEXT NOT NULL,
|
|
"providerId" TEXT,
|
|
"sentAt" TIMESTAMPTZ(3),
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "Notification_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "AuditLog" (
|
|
"id" TEXT NOT NULL,
|
|
"actorId" TEXT,
|
|
"action" TEXT NOT NULL,
|
|
"entityType" TEXT NOT NULL,
|
|
"entityId" TEXT NOT NULL,
|
|
"meta" JSONB,
|
|
"ip" TEXT,
|
|
"ua" TEXT,
|
|
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "AuditLog_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "User_role_idx" ON "User"("role");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "User_deletedAt_idx" ON "User"("deletedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Customer_stripeCustomerId_key" ON "Customer"("stripeCustomerId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "TherapistTag_tag_idx" ON "TherapistTag"("tag");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "RoomTag_tag_idx" ON "RoomTag"("tag");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "RoomBlock_roomId_startsAt_idx" ON "RoomBlock"("roomId", "startsAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "ServiceTherapist_therapistId_idx" ON "ServiceTherapist"("therapistId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "WorkingHours_therapistId_weekday_idx" ON "WorkingHours"("therapistId", "weekday");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "AvailabilityOverride_therapistId_startsAt_idx" ON "AvailabilityOverride"("therapistId", "startsAt");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Payment_stripePaymentIntentId_key" ON "Payment"("stripePaymentIntentId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Payment_bookingId_idx" ON "Payment"("bookingId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Notification_bookingId_idx" ON "Notification"("bookingId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Notification_userId_idx" ON "Notification"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Notification_status_idx" ON "Notification"("status");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "AuditLog_entityType_entityId_idx" ON "AuditLog"("entityType", "entityId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "AuditLog_actorId_createdAt_idx" ON "AuditLog"("actorId", "createdAt");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Customer" ADD CONSTRAINT "Customer_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Therapist" ADD CONSTRAINT "Therapist_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "TherapistTag" ADD CONSTRAINT "TherapistTag_therapistId_fkey" FOREIGN KEY ("therapistId") REFERENCES "Therapist"("userId") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "RoomTag" ADD CONSTRAINT "RoomTag_roomId_fkey" FOREIGN KEY ("roomId") REFERENCES "Room"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "RoomBlock" ADD CONSTRAINT "RoomBlock_roomId_fkey" FOREIGN KEY ("roomId") REFERENCES "Room"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "ServiceTherapist" ADD CONSTRAINT "ServiceTherapist_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "ServiceTherapist" ADD CONSTRAINT "ServiceTherapist_therapistId_fkey" FOREIGN KEY ("therapistId") REFERENCES "Therapist"("userId") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "WorkingHours" ADD CONSTRAINT "WorkingHours_therapistId_fkey" FOREIGN KEY ("therapistId") REFERENCES "Therapist"("userId") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "AvailabilityOverride" ADD CONSTRAINT "AvailabilityOverride_therapistId_fkey" FOREIGN KEY ("therapistId") REFERENCES "Therapist"("userId") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_therapistId_fkey" FOREIGN KEY ("therapistId") REFERENCES "Therapist"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_roomId_fkey" FOREIGN KEY ("roomId") REFERENCES "Room"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Payment" ADD CONSTRAINT "Payment_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "AuditLog" ADD CONSTRAINT "AuditLog_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|