Initial PHP rebuild of the app
This commit is contained in:
690 files changed
+33944
-12046
No files matched your search
@@ -0,0 +1,729 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Weekday" AS ENUM ('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Permission" AS ENUM ('MANAGE_BUSINESS_PROFILE', 'MANAGE_BOOKING_RULES', 'MANAGE_SERVICES', 'MANAGE_STAFF', 'MANAGE_LOYALTY_PROGRAMME', 'MANAGE_NOTIFICATION_SETTINGS', 'VIEW_ALL_STAFF_APPOINTMENTS', 'MANAGE_OWN_APPOINTMENTS', 'CHECK_IN_CUSTOMERS', 'MANAGE_LOYALTY_STAMPS', 'MANAGE_OWN_AVAILABILITY', 'VIEW_CUSTOMER_DIRECTORY', 'BOOK_ON_BEHALF_OF_CUSTOMER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "StaffStatus" AS ENUM ('ACTIVE', 'ON_BREAK', 'INACTIVE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "AppointmentStatus" AS ENUM ('PENDING_APPROVAL', 'CONFIRMED', 'ARRIVED', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED', 'NO_SHOW');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "TimeOffStatus" AS ENUM ('PENDING', 'APPROVED', 'DECLINED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "RewardType" AS ENUM ('PERCENTAGE', 'FIXED_AMOUNT', 'FREE_SERVICE');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "RewardStatus" AS ENUM ('AVAILABLE', 'REDEEMED', 'EXPIRED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "LoyaltyTransactionType" AS ENUM ('STAMP_ADDED', 'STAMP_REMOVED', 'STAMP_EXPIRED', 'REWARD_REDEEMED');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NotificationCategory" AS ENUM ('BOOKING_CONFIRMATION', 'BOOKING_REMINDER', 'BOOKING_CHANGED', 'BOOKING_CANCELLED', 'LOYALTY_REWARD_EARNED', 'LOYALTY_REWARD_AVAILABLE', 'MARKETING');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NotificationChannel" AS ENUM ('EMAIL', 'SMS', 'PUSH');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "NotificationStatus" AS ENUM ('PENDING', 'SENT', 'FAILED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Business" (
|
||||
"id" TEXT NOT NULL,
|
||||
"slug" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"logoUrl" TEXT,
|
||||
"phone" TEXT,
|
||||
"email" TEXT,
|
||||
"website" TEXT,
|
||||
"instagramUrl" TEXT,
|
||||
"facebookUrl" TEXT,
|
||||
"timezone" TEXT NOT NULL DEFAULT 'Europe/London',
|
||||
"currency" TEXT NOT NULL DEFAULT 'GBP',
|
||||
"locale" TEXT NOT NULL DEFAULT 'en-GB',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Business_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "BusinessLocation" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL DEFAULT 'Main Location',
|
||||
"addressLine1" TEXT NOT NULL,
|
||||
"addressLine2" TEXT,
|
||||
"city" TEXT NOT NULL,
|
||||
"region" TEXT,
|
||||
"postalCode" TEXT NOT NULL,
|
||||
"country" TEXT NOT NULL DEFAULT 'GB',
|
||||
"latitude" DECIMAL(9,6),
|
||||
"longitude" DECIMAL(9,6),
|
||||
"isPrimary" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "BusinessLocation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "BusinessHours" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"dayOfWeek" "Weekday" NOT NULL,
|
||||
"isClosed" BOOLEAN NOT NULL DEFAULT false,
|
||||
"opensAtMinutes" INTEGER,
|
||||
"closesAtMinutes" INTEGER,
|
||||
|
||||
CONSTRAINT "BusinessHours_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "BusinessSettings" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"cancellationPolicy" TEXT,
|
||||
"lateArrivalPolicy" TEXT,
|
||||
"bookingTerms" TEXT,
|
||||
"privacyPolicyUrl" TEXT,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "BusinessSettings_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "BookingRule" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"minNoticeMinutes" INTEGER NOT NULL DEFAULT 120,
|
||||
"maxAdvanceDays" INTEGER NOT NULL DEFAULT 60,
|
||||
"cancellationWindowHours" INTEGER NOT NULL DEFAULT 24,
|
||||
"rescheduleWindowHours" INTEGER NOT NULL DEFAULT 24,
|
||||
"slotIntervalMinutes" INTEGER NOT NULL DEFAULT 30,
|
||||
"bufferBeforeMinutes" INTEGER NOT NULL DEFAULT 0,
|
||||
"bufferAfterMinutes" INTEGER NOT NULL DEFAULT 5,
|
||||
"maxAppointmentsPerDay" INTEGER,
|
||||
"customerCanChooseStaff" BOOLEAN NOT NULL DEFAULT true,
|
||||
"allowGuestBooking" BOOLEAN NOT NULL DEFAULT true,
|
||||
"requireApproval" BOOLEAN NOT NULL DEFAULT false,
|
||||
"requireDeposit" BOOLEAN NOT NULL DEFAULT false,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "BookingRule_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT,
|
||||
"email" TEXT,
|
||||
"emailVerified" TIMESTAMP(3),
|
||||
"phone" TEXT,
|
||||
"phoneVerified" TIMESTAMP(3),
|
||||
"image" TEXT,
|
||||
"passwordHash" TEXT,
|
||||
"isSuperAdmin" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Account" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"provider" TEXT NOT NULL,
|
||||
"providerAccountId" TEXT NOT NULL,
|
||||
"refresh_token" TEXT,
|
||||
"access_token" TEXT,
|
||||
"expires_at" INTEGER,
|
||||
"token_type" TEXT,
|
||||
"scope" TEXT,
|
||||
"id_token" TEXT,
|
||||
"session_state" TEXT,
|
||||
|
||||
CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Session" (
|
||||
"id" TEXT NOT NULL,
|
||||
"sessionToken" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"expires" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "VerificationToken" (
|
||||
"identifier" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expires" TIMESTAMP(3) NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CustomerProfile" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT,
|
||||
"firstName" TEXT NOT NULL,
|
||||
"lastName" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"phone" TEXT,
|
||||
"isGuest" BOOLEAN NOT NULL DEFAULT true,
|
||||
"preferredBarberId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CustomerProfile_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "StaffProfile" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"roleId" TEXT NOT NULL,
|
||||
"bio" TEXT,
|
||||
"status" "StaffStatus" NOT NULL DEFAULT 'ACTIVE',
|
||||
"isBookableOnline" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "StaffProfile_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Role" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"isSystem" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Role_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "RolePermission" (
|
||||
"id" TEXT NOT NULL,
|
||||
"roleId" TEXT NOT NULL,
|
||||
"permission" "Permission" NOT NULL,
|
||||
|
||||
CONSTRAINT "RolePermission_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ServiceCategory" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"displayOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ServiceCategory_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Service" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"categoryId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"durationMinutes" INTEGER NOT NULL,
|
||||
"price" DECIMAL(10,2) NOT NULL,
|
||||
"bufferBeforeMinutes" INTEGER NOT NULL DEFAULT 0,
|
||||
"bufferAfterMinutes" INTEGER NOT NULL DEFAULT 0,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"allowOnlineBooking" BOOLEAN NOT NULL DEFAULT true,
|
||||
"displayOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Service_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "StaffService" (
|
||||
"id" TEXT NOT NULL,
|
||||
"staffId" TEXT NOT NULL,
|
||||
"serviceId" TEXT NOT NULL,
|
||||
"priceOverride" DECIMAL(10,2),
|
||||
"durationOverrideMinutes" INTEGER,
|
||||
|
||||
CONSTRAINT "StaffService_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "WorkingHours" (
|
||||
"id" TEXT NOT NULL,
|
||||
"staffId" TEXT NOT NULL,
|
||||
"dayOfWeek" "Weekday" NOT NULL,
|
||||
"isOff" BOOLEAN NOT NULL DEFAULT false,
|
||||
"startMinutes" INTEGER,
|
||||
"endMinutes" INTEGER,
|
||||
|
||||
CONSTRAINT "WorkingHours_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Break" (
|
||||
"id" TEXT NOT NULL,
|
||||
"staffId" TEXT NOT NULL,
|
||||
"label" TEXT NOT NULL,
|
||||
"startMinutes" INTEGER NOT NULL,
|
||||
"endMinutes" INTEGER NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Break_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "BreakDay" (
|
||||
"id" TEXT NOT NULL,
|
||||
"breakId" TEXT NOT NULL,
|
||||
"dayOfWeek" "Weekday" NOT NULL,
|
||||
|
||||
CONSTRAINT "BreakDay_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "TimeOff" (
|
||||
"id" TEXT NOT NULL,
|
||||
"staffId" TEXT NOT NULL,
|
||||
"startDate" DATE NOT NULL,
|
||||
"endDate" DATE NOT NULL,
|
||||
"reason" TEXT,
|
||||
"status" "TimeOffStatus" NOT NULL DEFAULT 'APPROVED',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "TimeOff_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Appointment" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"customerId" TEXT NOT NULL,
|
||||
"staffId" TEXT NOT NULL,
|
||||
"status" "AppointmentStatus" NOT NULL DEFAULT 'CONFIRMED',
|
||||
"startAt" TIMESTAMP(3) NOT NULL,
|
||||
"endAt" TIMESTAMP(3) NOT NULL,
|
||||
"notes" TEXT,
|
||||
"cancellationReason" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Appointment_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AppointmentService" (
|
||||
"id" TEXT NOT NULL,
|
||||
"appointmentId" TEXT NOT NULL,
|
||||
"serviceId" TEXT NOT NULL,
|
||||
"priceAtBooking" DECIMAL(10,2) NOT NULL,
|
||||
"durationAtBookingMinutes" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "AppointmentService_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LoyaltyProgramme" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"isEnabled" BOOLEAN NOT NULL DEFAULT false,
|
||||
"stampsRequired" INTEGER NOT NULL DEFAULT 10,
|
||||
"rewardType" "RewardType" NOT NULL DEFAULT 'PERCENTAGE',
|
||||
"rewardValue" DECIMAL(10,2),
|
||||
"rewardLabel" TEXT,
|
||||
"maxRewardValue" DECIMAL(10,2),
|
||||
"autoApplyReward" BOOLEAN NOT NULL DEFAULT true,
|
||||
"requiresStaffApproval" BOOLEAN NOT NULL DEFAULT false,
|
||||
"stampsExpireAfterDays" INTEGER,
|
||||
"rewardExpiresAfterDays" INTEGER,
|
||||
"earnOnCancelled" BOOLEAN NOT NULL DEFAULT false,
|
||||
"earnOnNoShow" BOOLEAN NOT NULL DEFAULT false,
|
||||
"cardBackgroundColor" TEXT,
|
||||
"cardBackgroundImageUrl" TEXT,
|
||||
"stampIcon" TEXT,
|
||||
"termsLine" TEXT,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "LoyaltyProgramme_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LoyaltyEligibleService" (
|
||||
"id" TEXT NOT NULL,
|
||||
"loyaltyProgrammeId" TEXT NOT NULL,
|
||||
"serviceId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "LoyaltyEligibleService_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LoyaltyEligibleStaff" (
|
||||
"id" TEXT NOT NULL,
|
||||
"loyaltyProgrammeId" TEXT NOT NULL,
|
||||
"staffId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "LoyaltyEligibleStaff_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LoyaltyAccount" (
|
||||
"id" TEXT NOT NULL,
|
||||
"customerId" TEXT NOT NULL,
|
||||
"loyaltyProgrammeId" TEXT NOT NULL,
|
||||
"currentStamps" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "LoyaltyAccount_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LoyaltyTransaction" (
|
||||
"id" TEXT NOT NULL,
|
||||
"loyaltyAccountId" TEXT NOT NULL,
|
||||
"type" "LoyaltyTransactionType" NOT NULL,
|
||||
"amount" INTEGER NOT NULL,
|
||||
"reason" TEXT,
|
||||
"appointmentId" TEXT,
|
||||
"authoredByStaffId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "LoyaltyTransaction_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "LoyaltyReward" (
|
||||
"id" TEXT NOT NULL,
|
||||
"loyaltyAccountId" TEXT NOT NULL,
|
||||
"rewardType" "RewardType" NOT NULL,
|
||||
"value" DECIMAL(10,2),
|
||||
"label" TEXT NOT NULL,
|
||||
"status" "RewardStatus" NOT NULL DEFAULT 'AVAILABLE',
|
||||
"appliedToAppointmentId" TEXT,
|
||||
"redeemedAt" TIMESTAMP(3),
|
||||
"expiresAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "LoyaltyReward_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Notification" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT,
|
||||
"appointmentId" TEXT,
|
||||
"category" "NotificationCategory" NOT NULL,
|
||||
"channel" "NotificationChannel" NOT NULL,
|
||||
"status" "NotificationStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"subject" TEXT,
|
||||
"body" TEXT NOT NULL,
|
||||
"sentAt" TIMESTAMP(3),
|
||||
"failureReason" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Notification_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "NotificationPreference" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"category" "NotificationCategory" NOT NULL,
|
||||
"channel" "NotificationChannel" NOT NULL,
|
||||
"isEnabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
|
||||
CONSTRAINT "NotificationPreference_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CustomerNote" (
|
||||
"id" TEXT NOT NULL,
|
||||
"customerId" TEXT NOT NULL,
|
||||
"authorStaffId" TEXT NOT NULL,
|
||||
"body" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "CustomerNote_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "AuditLog" (
|
||||
"id" TEXT NOT NULL,
|
||||
"actorUserId" TEXT,
|
||||
"action" TEXT NOT NULL,
|
||||
"entityType" TEXT NOT NULL,
|
||||
"entityId" TEXT NOT NULL,
|
||||
"metadata" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "AuditLog_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Business_slug_key" ON "Business"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "BusinessLocation_businessId_idx" ON "BusinessLocation"("businessId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BusinessHours_businessId_dayOfWeek_key" ON "BusinessHours"("businessId", "dayOfWeek");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BusinessSettings_businessId_key" ON "BusinessSettings"("businessId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BookingRule_businessId_key" ON "BookingRule"("businessId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_phone_key" ON "User"("phone");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "VerificationToken_token_key" ON "VerificationToken"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "VerificationToken_identifier_token_key" ON "VerificationToken"("identifier", "token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "CustomerProfile_userId_key" ON "CustomerProfile"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CustomerProfile_email_idx" ON "CustomerProfile"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CustomerProfile_phone_idx" ON "CustomerProfile"("phone");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CustomerProfile_preferredBarberId_idx" ON "CustomerProfile"("preferredBarberId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "StaffProfile_userId_key" ON "StaffProfile"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "StaffProfile_businessId_idx" ON "StaffProfile"("businessId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Role_businessId_name_key" ON "Role"("businessId", "name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "RolePermission_roleId_permission_key" ON "RolePermission"("roleId", "permission");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ServiceCategory_businessId_idx" ON "ServiceCategory"("businessId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Service_businessId_idx" ON "Service"("businessId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Service_categoryId_idx" ON "Service"("categoryId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "StaffService_staffId_serviceId_key" ON "StaffService"("staffId", "serviceId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "WorkingHours_staffId_dayOfWeek_key" ON "WorkingHours"("staffId", "dayOfWeek");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BreakDay_breakId_dayOfWeek_key" ON "BreakDay"("breakId", "dayOfWeek");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TimeOff_staffId_startDate_endDate_idx" ON "TimeOff"("staffId", "startDate", "endDate");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Appointment_staffId_startAt_idx" ON "Appointment"("staffId", "startAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Appointment_businessId_startAt_idx" ON "Appointment"("businessId", "startAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Appointment_customerId_idx" ON "Appointment"("customerId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AppointmentService_appointmentId_idx" ON "AppointmentService"("appointmentId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "LoyaltyProgramme_businessId_key" ON "LoyaltyProgramme"("businessId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "LoyaltyEligibleService_loyaltyProgrammeId_serviceId_key" ON "LoyaltyEligibleService"("loyaltyProgrammeId", "serviceId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "LoyaltyEligibleStaff_loyaltyProgrammeId_staffId_key" ON "LoyaltyEligibleStaff"("loyaltyProgrammeId", "staffId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "LoyaltyAccount_customerId_loyaltyProgrammeId_key" ON "LoyaltyAccount"("customerId", "loyaltyProgrammeId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LoyaltyTransaction_loyaltyAccountId_idx" ON "LoyaltyTransaction"("loyaltyAccountId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "LoyaltyReward_loyaltyAccountId_idx" ON "LoyaltyReward"("loyaltyAccountId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Notification_userId_idx" ON "Notification"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Notification_appointmentId_idx" ON "Notification"("appointmentId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "NotificationPreference_userId_category_channel_key" ON "NotificationPreference"("userId", "category", "channel");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CustomerNote_customerId_idx" ON "CustomerNote"("customerId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AuditLog_entityType_entityId_idx" ON "AuditLog"("entityType", "entityId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AuditLog_actorUserId_idx" ON "AuditLog"("actorUserId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BusinessLocation" ADD CONSTRAINT "BusinessLocation_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BusinessHours" ADD CONSTRAINT "BusinessHours_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BusinessSettings" ADD CONSTRAINT "BusinessSettings_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BookingRule" ADD CONSTRAINT "BookingRule_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("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 "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerProfile" ADD CONSTRAINT "CustomerProfile_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerProfile" ADD CONSTRAINT "CustomerProfile_preferredBarberId_fkey" FOREIGN KEY ("preferredBarberId") REFERENCES "StaffProfile"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "StaffProfile" ADD CONSTRAINT "StaffProfile_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "StaffProfile" ADD CONSTRAINT "StaffProfile_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "StaffProfile" ADD CONSTRAINT "StaffProfile_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "Role"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Role" ADD CONSTRAINT "Role_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "RolePermission" ADD CONSTRAINT "RolePermission_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "Role"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ServiceCategory" ADD CONSTRAINT "ServiceCategory_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Service" ADD CONSTRAINT "Service_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Service" ADD CONSTRAINT "Service_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "ServiceCategory"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "StaffService" ADD CONSTRAINT "StaffService_staffId_fkey" FOREIGN KEY ("staffId") REFERENCES "StaffProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "StaffService" ADD CONSTRAINT "StaffService_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "WorkingHours" ADD CONSTRAINT "WorkingHours_staffId_fkey" FOREIGN KEY ("staffId") REFERENCES "StaffProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Break" ADD CONSTRAINT "Break_staffId_fkey" FOREIGN KEY ("staffId") REFERENCES "StaffProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BreakDay" ADD CONSTRAINT "BreakDay_breakId_fkey" FOREIGN KEY ("breakId") REFERENCES "Break"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TimeOff" ADD CONSTRAINT "TimeOff_staffId_fkey" FOREIGN KEY ("staffId") REFERENCES "StaffProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Appointment" ADD CONSTRAINT "Appointment_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Appointment" ADD CONSTRAINT "Appointment_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "CustomerProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Appointment" ADD CONSTRAINT "Appointment_staffId_fkey" FOREIGN KEY ("staffId") REFERENCES "StaffProfile"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "AppointmentService" ADD CONSTRAINT "AppointmentService_appointmentId_fkey" FOREIGN KEY ("appointmentId") REFERENCES "Appointment"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "AppointmentService" ADD CONSTRAINT "AppointmentService_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyProgramme" ADD CONSTRAINT "LoyaltyProgramme_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyEligibleService" ADD CONSTRAINT "LoyaltyEligibleService_loyaltyProgrammeId_fkey" FOREIGN KEY ("loyaltyProgrammeId") REFERENCES "LoyaltyProgramme"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyEligibleService" ADD CONSTRAINT "LoyaltyEligibleService_serviceId_fkey" FOREIGN KEY ("serviceId") REFERENCES "Service"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyEligibleStaff" ADD CONSTRAINT "LoyaltyEligibleStaff_loyaltyProgrammeId_fkey" FOREIGN KEY ("loyaltyProgrammeId") REFERENCES "LoyaltyProgramme"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyAccount" ADD CONSTRAINT "LoyaltyAccount_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "CustomerProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyAccount" ADD CONSTRAINT "LoyaltyAccount_loyaltyProgrammeId_fkey" FOREIGN KEY ("loyaltyProgrammeId") REFERENCES "LoyaltyProgramme"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyTransaction" ADD CONSTRAINT "LoyaltyTransaction_loyaltyAccountId_fkey" FOREIGN KEY ("loyaltyAccountId") REFERENCES "LoyaltyAccount"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyTransaction" ADD CONSTRAINT "LoyaltyTransaction_appointmentId_fkey" FOREIGN KEY ("appointmentId") REFERENCES "Appointment"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyTransaction" ADD CONSTRAINT "LoyaltyTransaction_authoredByStaffId_fkey" FOREIGN KEY ("authoredByStaffId") REFERENCES "StaffProfile"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyReward" ADD CONSTRAINT "LoyaltyReward_loyaltyAccountId_fkey" FOREIGN KEY ("loyaltyAccountId") REFERENCES "LoyaltyAccount"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Notification" ADD CONSTRAINT "Notification_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Notification" ADD CONSTRAINT "Notification_appointmentId_fkey" FOREIGN KEY ("appointmentId") REFERENCES "Appointment"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "NotificationPreference" ADD CONSTRAINT "NotificationPreference_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerNote" ADD CONSTRAINT "CustomerNote_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "CustomerProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CustomerNote" ADD CONSTRAINT "CustomerNote_authorStaffId_fkey" FOREIGN KEY ("authorStaffId") REFERENCES "StaffProfile"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
-- AlterEnum
|
||||
BEGIN;
|
||||
CREATE TYPE "AppointmentStatus_new" AS ENUM ('PENDING', 'CONFIRMED', 'CHECKED_IN', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED', 'NO_SHOW');
|
||||
ALTER TABLE "public"."Appointment" ALTER COLUMN "status" DROP DEFAULT;
|
||||
ALTER TABLE "Appointment" ALTER COLUMN "status" TYPE "AppointmentStatus_new" USING ("status"::text::"AppointmentStatus_new");
|
||||
ALTER TYPE "AppointmentStatus" RENAME TO "AppointmentStatus_old";
|
||||
ALTER TYPE "AppointmentStatus_new" RENAME TO "AppointmentStatus";
|
||||
DROP TYPE "public"."AppointmentStatus_old";
|
||||
ALTER TABLE "Appointment" ALTER COLUMN "status" SET DEFAULT 'CONFIRMED';
|
||||
COMMIT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Appointment" ADD COLUMN "cancelledAt" TIMESTAMP(3),
|
||||
ADD COLUMN "cancelledByUserId" TEXT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "BookingRule" ADD COLUMN "maxAppointmentsPerStaffPerDay" INTEGER;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Appointment" ADD CONSTRAINT "Appointment_cancelledByUserId_fkey" FOREIGN KEY ("cancelledByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Appointment" ADD COLUMN "createdByUserId" TEXT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "CustomerNote" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "TimeOff" ADD COLUMN "endMinutes" INTEGER,
|
||||
ADD COLUMN "startMinutes" INTEGER;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Appointment" ADD CONSTRAINT "Appointment_createdByUserId_fkey" FOREIGN KEY ("createdByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
-- AlterEnum
|
||||
-- This migration adds more than one value to an enum.
|
||||
-- With PostgreSQL versions 11 and earlier, this is not possible
|
||||
-- in a single migration. This can be worked around by creating
|
||||
-- multiple migrations, each migration adding only one value to
|
||||
-- the enum.
|
||||
|
||||
|
||||
ALTER TYPE "Permission" ADD VALUE 'MANAGE_ALL_APPOINTMENTS';
|
||||
ALTER TYPE "Permission" ADD VALUE 'VIEW_REPORTING';
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Appointment" ADD COLUMN "discountAmount" DECIMAL(10,2);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "LoyaltyReward" ADD COLUMN "redeemedByStaffId" TEXT;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "StaffInvitation" (
|
||||
"id" TEXT NOT NULL,
|
||||
"businessId" TEXT NOT NULL,
|
||||
"staffId" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"invitedByUserId" TEXT,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"acceptedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "StaffInvitation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "StaffInvitation_staffId_key" ON "StaffInvitation"("staffId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "StaffInvitation_token_key" ON "StaffInvitation"("token");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "StaffInvitation_businessId_idx" ON "StaffInvitation"("businessId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "StaffInvitation" ADD CONSTRAINT "StaffInvitation_businessId_fkey" FOREIGN KEY ("businessId") REFERENCES "Business"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "StaffInvitation" ADD CONSTRAINT "StaffInvitation_staffId_fkey" FOREIGN KEY ("staffId") REFERENCES "StaffProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "StaffInvitation" ADD CONSTRAINT "StaffInvitation_invitedByUserId_fkey" FOREIGN KEY ("invitedByUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyReward" ADD CONSTRAINT "LoyaltyReward_appliedToAppointmentId_fkey" FOREIGN KEY ("appliedToAppointmentId") REFERENCES "Appointment"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyReward" ADD CONSTRAINT "LoyaltyReward_redeemedByStaffId_fkey" FOREIGN KEY ("redeemedByStaffId") REFERENCES "StaffProfile"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "LoyaltyProgramme" ADD COLUMN "freeServiceId" TEXT;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LoyaltyProgramme" ADD CONSTRAINT "LoyaltyProgramme_freeServiceId_fkey" FOREIGN KEY ("freeServiceId") REFERENCES "Service"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -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"
|
||||
@@ -0,0 +1,665 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `Business` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`slug` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`logoUrl` VARCHAR(191) NULL,
|
||||
`phone` VARCHAR(191) NULL,
|
||||
`email` VARCHAR(191) NULL,
|
||||
`website` VARCHAR(191) NULL,
|
||||
`instagramUrl` VARCHAR(191) NULL,
|
||||
`facebookUrl` VARCHAR(191) NULL,
|
||||
`timezone` VARCHAR(191) NOT NULL DEFAULT 'Europe/London',
|
||||
`currency` VARCHAR(191) NOT NULL DEFAULT 'GBP',
|
||||
`locale` VARCHAR(191) NOT NULL DEFAULT 'en-GB',
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Business_slug_key`(`slug`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `BusinessLocation` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL DEFAULT 'Main Location',
|
||||
`addressLine1` VARCHAR(191) NOT NULL,
|
||||
`addressLine2` VARCHAR(191) NULL,
|
||||
`city` VARCHAR(191) NOT NULL,
|
||||
`region` VARCHAR(191) NULL,
|
||||
`postalCode` VARCHAR(191) NOT NULL,
|
||||
`country` VARCHAR(191) NOT NULL DEFAULT 'GB',
|
||||
`latitude` DECIMAL(9, 6) NULL,
|
||||
`longitude` DECIMAL(9, 6) NULL,
|
||||
`isPrimary` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `BusinessLocation_businessId_idx`(`businessId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `BusinessHours` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`dayOfWeek` ENUM('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY') NOT NULL,
|
||||
`isClosed` BOOLEAN NOT NULL DEFAULT false,
|
||||
`opensAtMinutes` INTEGER NULL,
|
||||
`closesAtMinutes` INTEGER NULL,
|
||||
|
||||
UNIQUE INDEX `BusinessHours_businessId_dayOfWeek_key`(`businessId`, `dayOfWeek`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `BusinessSettings` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`cancellationPolicy` TEXT NULL,
|
||||
`lateArrivalPolicy` TEXT NULL,
|
||||
`bookingTerms` TEXT NULL,
|
||||
`privacyPolicyUrl` VARCHAR(191) NULL,
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `BusinessSettings_businessId_key`(`businessId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `BookingRule` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`minNoticeMinutes` INTEGER NOT NULL DEFAULT 120,
|
||||
`maxAdvanceDays` INTEGER NOT NULL DEFAULT 60,
|
||||
`cancellationWindowHours` INTEGER NOT NULL DEFAULT 24,
|
||||
`rescheduleWindowHours` INTEGER NOT NULL DEFAULT 24,
|
||||
`slotIntervalMinutes` INTEGER NOT NULL DEFAULT 30,
|
||||
`bufferBeforeMinutes` INTEGER NOT NULL DEFAULT 0,
|
||||
`bufferAfterMinutes` INTEGER NOT NULL DEFAULT 5,
|
||||
`maxAppointmentsPerDay` INTEGER NULL,
|
||||
`maxAppointmentsPerStaffPerDay` INTEGER NULL,
|
||||
`customerCanChooseStaff` BOOLEAN NOT NULL DEFAULT true,
|
||||
`allowGuestBooking` BOOLEAN NOT NULL DEFAULT true,
|
||||
`requireApproval` BOOLEAN NOT NULL DEFAULT false,
|
||||
`requireDeposit` BOOLEAN NOT NULL DEFAULT false,
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `BookingRule_businessId_key`(`businessId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `User` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NULL,
|
||||
`email` VARCHAR(191) NULL,
|
||||
`emailVerified` DATETIME(3) NULL,
|
||||
`phone` VARCHAR(191) NULL,
|
||||
`phoneVerified` DATETIME(3) NULL,
|
||||
`image` VARCHAR(191) NULL,
|
||||
`passwordHash` VARCHAR(191) NULL,
|
||||
`isSuperAdmin` BOOLEAN NOT NULL DEFAULT false,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `User_email_key`(`email`),
|
||||
UNIQUE INDEX `User_phone_key`(`phone`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Account` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`userId` VARCHAR(191) NOT NULL,
|
||||
`type` VARCHAR(191) NOT NULL,
|
||||
`provider` VARCHAR(191) NOT NULL,
|
||||
`providerAccountId` VARCHAR(191) NOT NULL,
|
||||
`refresh_token` TEXT NULL,
|
||||
`access_token` TEXT NULL,
|
||||
`expires_at` INTEGER NULL,
|
||||
`token_type` VARCHAR(191) NULL,
|
||||
`scope` VARCHAR(191) NULL,
|
||||
`id_token` TEXT NULL,
|
||||
`session_state` VARCHAR(191) NULL,
|
||||
|
||||
UNIQUE INDEX `Account_provider_providerAccountId_key`(`provider`, `providerAccountId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Session` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`sessionToken` VARCHAR(191) NOT NULL,
|
||||
`userId` VARCHAR(191) NOT NULL,
|
||||
`expires` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Session_sessionToken_key`(`sessionToken`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `VerificationToken` (
|
||||
`identifier` VARCHAR(191) NOT NULL,
|
||||
`token` VARCHAR(191) NOT NULL,
|
||||
`expires` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `VerificationToken_token_key`(`token`),
|
||||
UNIQUE INDEX `VerificationToken_identifier_token_key`(`identifier`, `token`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `CustomerProfile` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`userId` VARCHAR(191) NULL,
|
||||
`firstName` VARCHAR(191) NOT NULL,
|
||||
`lastName` VARCHAR(191) NOT NULL,
|
||||
`email` VARCHAR(191) NOT NULL,
|
||||
`phone` VARCHAR(191) NULL,
|
||||
`isGuest` BOOLEAN NOT NULL DEFAULT true,
|
||||
`preferredBarberId` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `CustomerProfile_userId_key`(`userId`),
|
||||
INDEX `CustomerProfile_email_idx`(`email`),
|
||||
INDEX `CustomerProfile_phone_idx`(`phone`),
|
||||
INDEX `CustomerProfile_preferredBarberId_idx`(`preferredBarberId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `StaffProfile` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`userId` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`roleId` VARCHAR(191) NOT NULL,
|
||||
`bio` TEXT NULL,
|
||||
`status` ENUM('ACTIVE', 'ON_BREAK', 'INACTIVE') NOT NULL DEFAULT 'ACTIVE',
|
||||
`isBookableOnline` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `StaffProfile_userId_key`(`userId`),
|
||||
INDEX `StaffProfile_businessId_idx`(`businessId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Role` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`isSystem` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `Role_businessId_name_key`(`businessId`, `name`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `RolePermission` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`roleId` VARCHAR(191) NOT NULL,
|
||||
`permission` ENUM('MANAGE_BUSINESS_PROFILE', 'MANAGE_BOOKING_RULES', 'MANAGE_SERVICES', 'MANAGE_STAFF', 'MANAGE_LOYALTY_PROGRAMME', 'MANAGE_NOTIFICATION_SETTINGS', 'VIEW_ALL_STAFF_APPOINTMENTS', 'MANAGE_ALL_APPOINTMENTS', 'MANAGE_OWN_APPOINTMENTS', 'CHECK_IN_CUSTOMERS', 'MANAGE_LOYALTY_STAMPS', 'MANAGE_OWN_AVAILABILITY', 'VIEW_CUSTOMER_DIRECTORY', 'BOOK_ON_BEHALF_OF_CUSTOMER', 'VIEW_REPORTING') NOT NULL,
|
||||
|
||||
UNIQUE INDEX `RolePermission_roleId_permission_key`(`roleId`, `permission`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `StaffInvitation` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`staffId` VARCHAR(191) NOT NULL,
|
||||
`email` VARCHAR(191) NOT NULL,
|
||||
`token` VARCHAR(191) NOT NULL,
|
||||
`invitedByUserId` VARCHAR(191) NULL,
|
||||
`expiresAt` DATETIME(3) NOT NULL,
|
||||
`acceptedAt` DATETIME(3) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `StaffInvitation_staffId_key`(`staffId`),
|
||||
UNIQUE INDEX `StaffInvitation_token_key`(`token`),
|
||||
INDEX `StaffInvitation_businessId_idx`(`businessId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `ServiceCategory` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`displayOrder` INTEGER NOT NULL DEFAULT 0,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `ServiceCategory_businessId_idx`(`businessId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Service` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`categoryId` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`durationMinutes` INTEGER NOT NULL,
|
||||
`price` DECIMAL(10, 2) NOT NULL,
|
||||
`bufferBeforeMinutes` INTEGER NOT NULL DEFAULT 0,
|
||||
`bufferAfterMinutes` INTEGER NOT NULL DEFAULT 0,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`allowOnlineBooking` BOOLEAN NOT NULL DEFAULT true,
|
||||
`displayOrder` INTEGER NOT NULL DEFAULT 0,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `Service_businessId_idx`(`businessId`),
|
||||
INDEX `Service_categoryId_idx`(`categoryId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `StaffService` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`staffId` VARCHAR(191) NOT NULL,
|
||||
`serviceId` VARCHAR(191) NOT NULL,
|
||||
`priceOverride` DECIMAL(10, 2) NULL,
|
||||
`durationOverrideMinutes` INTEGER NULL,
|
||||
|
||||
UNIQUE INDEX `StaffService_staffId_serviceId_key`(`staffId`, `serviceId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `WorkingHours` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`staffId` VARCHAR(191) NOT NULL,
|
||||
`dayOfWeek` ENUM('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY') NOT NULL,
|
||||
`isOff` BOOLEAN NOT NULL DEFAULT false,
|
||||
`startMinutes` INTEGER NULL,
|
||||
`endMinutes` INTEGER NULL,
|
||||
|
||||
UNIQUE INDEX `WorkingHours_staffId_dayOfWeek_key`(`staffId`, `dayOfWeek`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Break` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`staffId` VARCHAR(191) NOT NULL,
|
||||
`label` VARCHAR(191) NOT NULL,
|
||||
`startMinutes` INTEGER NOT NULL,
|
||||
`endMinutes` INTEGER NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `BreakDay` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`breakId` VARCHAR(191) NOT NULL,
|
||||
`dayOfWeek` ENUM('MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY') NOT NULL,
|
||||
|
||||
UNIQUE INDEX `BreakDay_breakId_dayOfWeek_key`(`breakId`, `dayOfWeek`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `TimeOff` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`staffId` VARCHAR(191) NOT NULL,
|
||||
`startDate` DATE NOT NULL,
|
||||
`endDate` DATE NOT NULL,
|
||||
`reason` VARCHAR(191) NULL,
|
||||
`status` ENUM('PENDING', 'APPROVED', 'DECLINED') NOT NULL DEFAULT 'APPROVED',
|
||||
`startMinutes` INTEGER NULL,
|
||||
`endMinutes` INTEGER NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `TimeOff_staffId_startDate_endDate_idx`(`staffId`, `startDate`, `endDate`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Appointment` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`customerId` VARCHAR(191) NOT NULL,
|
||||
`staffId` VARCHAR(191) NOT NULL,
|
||||
`status` ENUM('PENDING', 'CONFIRMED', 'CHECKED_IN', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED', 'NO_SHOW') NOT NULL DEFAULT 'CONFIRMED',
|
||||
`startAt` DATETIME(3) NOT NULL,
|
||||
`endAt` DATETIME(3) NOT NULL,
|
||||
`notes` TEXT NULL,
|
||||
`discountAmount` DECIMAL(10, 2) NULL,
|
||||
`cancellationReason` VARCHAR(191) NULL,
|
||||
`cancelledAt` DATETIME(3) NULL,
|
||||
`cancelledByUserId` VARCHAR(191) NULL,
|
||||
`createdByUserId` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `Appointment_staffId_startAt_idx`(`staffId`, `startAt`),
|
||||
INDEX `Appointment_businessId_startAt_idx`(`businessId`, `startAt`),
|
||||
INDEX `Appointment_customerId_idx`(`customerId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `AppointmentService` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`appointmentId` VARCHAR(191) NOT NULL,
|
||||
`serviceId` VARCHAR(191) NOT NULL,
|
||||
`priceAtBooking` DECIMAL(10, 2) NOT NULL,
|
||||
`durationAtBookingMinutes` INTEGER NOT NULL,
|
||||
|
||||
INDEX `AppointmentService_appointmentId_idx`(`appointmentId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `LoyaltyProgramme` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`isEnabled` BOOLEAN NOT NULL DEFAULT false,
|
||||
`stampsRequired` INTEGER NOT NULL DEFAULT 10,
|
||||
`rewardType` ENUM('PERCENTAGE', 'FIXED_AMOUNT', 'FREE_SERVICE') NOT NULL DEFAULT 'PERCENTAGE',
|
||||
`rewardValue` DECIMAL(10, 2) NULL,
|
||||
`rewardLabel` VARCHAR(191) NULL,
|
||||
`maxRewardValue` DECIMAL(10, 2) NULL,
|
||||
`freeServiceId` VARCHAR(191) NULL,
|
||||
`autoApplyReward` BOOLEAN NOT NULL DEFAULT true,
|
||||
`requiresStaffApproval` BOOLEAN NOT NULL DEFAULT false,
|
||||
`stampsExpireAfterDays` INTEGER NULL,
|
||||
`rewardExpiresAfterDays` INTEGER NULL,
|
||||
`earnOnCancelled` BOOLEAN NOT NULL DEFAULT false,
|
||||
`earnOnNoShow` BOOLEAN NOT NULL DEFAULT false,
|
||||
`cardBackgroundColor` VARCHAR(191) NULL,
|
||||
`cardBackgroundImageUrl` VARCHAR(191) NULL,
|
||||
`stampIcon` VARCHAR(191) NULL,
|
||||
`termsLine` VARCHAR(191) NULL,
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `LoyaltyProgramme_businessId_key`(`businessId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `LoyaltyEligibleService` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`loyaltyProgrammeId` VARCHAR(191) NOT NULL,
|
||||
`serviceId` VARCHAR(191) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `LoyaltyEligibleService_loyaltyProgrammeId_serviceId_key`(`loyaltyProgrammeId`, `serviceId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `LoyaltyEligibleStaff` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`loyaltyProgrammeId` VARCHAR(191) NOT NULL,
|
||||
`staffId` VARCHAR(191) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `LoyaltyEligibleStaff_loyaltyProgrammeId_staffId_key`(`loyaltyProgrammeId`, `staffId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `LoyaltyAccount` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`customerId` VARCHAR(191) NOT NULL,
|
||||
`loyaltyProgrammeId` VARCHAR(191) NOT NULL,
|
||||
`currentStamps` INTEGER NOT NULL DEFAULT 0,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `LoyaltyAccount_customerId_loyaltyProgrammeId_key`(`customerId`, `loyaltyProgrammeId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `LoyaltyTransaction` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`loyaltyAccountId` VARCHAR(191) NOT NULL,
|
||||
`type` ENUM('STAMP_ADDED', 'STAMP_REMOVED', 'STAMP_EXPIRED', 'REWARD_REDEEMED') NOT NULL,
|
||||
`amount` INTEGER NOT NULL,
|
||||
`reason` VARCHAR(191) NULL,
|
||||
`appointmentId` VARCHAR(191) NULL,
|
||||
`authoredByStaffId` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `LoyaltyTransaction_loyaltyAccountId_idx`(`loyaltyAccountId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `LoyaltyReward` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`loyaltyAccountId` VARCHAR(191) NOT NULL,
|
||||
`rewardType` ENUM('PERCENTAGE', 'FIXED_AMOUNT', 'FREE_SERVICE') NOT NULL,
|
||||
`value` DECIMAL(10, 2) NULL,
|
||||
`label` VARCHAR(191) NOT NULL,
|
||||
`status` ENUM('AVAILABLE', 'REDEEMED', 'EXPIRED') NOT NULL DEFAULT 'AVAILABLE',
|
||||
`appliedToAppointmentId` VARCHAR(191) NULL,
|
||||
`redeemedAt` DATETIME(3) NULL,
|
||||
`redeemedByStaffId` VARCHAR(191) NULL,
|
||||
`expiresAt` DATETIME(3) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `LoyaltyReward_loyaltyAccountId_idx`(`loyaltyAccountId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Notification` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`userId` VARCHAR(191) NULL,
|
||||
`appointmentId` VARCHAR(191) NULL,
|
||||
`category` ENUM('BOOKING_CONFIRMATION', 'BOOKING_REMINDER', 'BOOKING_CHANGED', 'BOOKING_CANCELLED', 'LOYALTY_REWARD_EARNED', 'LOYALTY_REWARD_AVAILABLE', 'MARKETING') NOT NULL,
|
||||
`channel` ENUM('EMAIL', 'SMS', 'PUSH') NOT NULL,
|
||||
`status` ENUM('PENDING', 'SENT', 'FAILED') NOT NULL DEFAULT 'PENDING',
|
||||
`subject` VARCHAR(191) NULL,
|
||||
`body` TEXT NOT NULL,
|
||||
`sentAt` DATETIME(3) NULL,
|
||||
`failureReason` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `Notification_userId_idx`(`userId`),
|
||||
INDEX `Notification_appointmentId_idx`(`appointmentId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `NotificationPreference` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`userId` VARCHAR(191) NOT NULL,
|
||||
`category` ENUM('BOOKING_CONFIRMATION', 'BOOKING_REMINDER', 'BOOKING_CHANGED', 'BOOKING_CANCELLED', 'LOYALTY_REWARD_EARNED', 'LOYALTY_REWARD_AVAILABLE', 'MARKETING') NOT NULL,
|
||||
`channel` ENUM('EMAIL', 'SMS', 'PUSH') NOT NULL,
|
||||
`isEnabled` BOOLEAN NOT NULL DEFAULT true,
|
||||
|
||||
UNIQUE INDEX `NotificationPreference_userId_category_channel_key`(`userId`, `category`, `channel`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `CustomerNote` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`customerId` VARCHAR(191) NOT NULL,
|
||||
`authorStaffId` VARCHAR(191) NOT NULL,
|
||||
`body` TEXT NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `CustomerNote_customerId_idx`(`customerId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `AuditLog` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`actorUserId` VARCHAR(191) NULL,
|
||||
`action` VARCHAR(191) NOT NULL,
|
||||
`entityType` VARCHAR(191) NOT NULL,
|
||||
`entityId` VARCHAR(191) NOT NULL,
|
||||
`metadata` JSON NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `AuditLog_entityType_entityId_idx`(`entityType`, `entityId`),
|
||||
INDEX `AuditLog_actorUserId_idx`(`actorUserId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `BusinessLocation` ADD CONSTRAINT `BusinessLocation_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `BusinessHours` ADD CONSTRAINT `BusinessHours_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `BusinessSettings` ADD CONSTRAINT `BusinessSettings_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `BookingRule` ADD CONSTRAINT `BookingRule_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`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 `Session` ADD CONSTRAINT `Session_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CustomerProfile` ADD CONSTRAINT `CustomerProfile_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CustomerProfile` ADD CONSTRAINT `CustomerProfile_preferredBarberId_fkey` FOREIGN KEY (`preferredBarberId`) REFERENCES `StaffProfile`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `StaffProfile` ADD CONSTRAINT `StaffProfile_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `StaffProfile` ADD CONSTRAINT `StaffProfile_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `StaffProfile` ADD CONSTRAINT `StaffProfile_roleId_fkey` FOREIGN KEY (`roleId`) REFERENCES `Role`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Role` ADD CONSTRAINT `Role_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `RolePermission` ADD CONSTRAINT `RolePermission_roleId_fkey` FOREIGN KEY (`roleId`) REFERENCES `Role`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `StaffInvitation` ADD CONSTRAINT `StaffInvitation_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `StaffInvitation` ADD CONSTRAINT `StaffInvitation_staffId_fkey` FOREIGN KEY (`staffId`) REFERENCES `StaffProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `StaffInvitation` ADD CONSTRAINT `StaffInvitation_invitedByUserId_fkey` FOREIGN KEY (`invitedByUserId`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `ServiceCategory` ADD CONSTRAINT `ServiceCategory_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Service` ADD CONSTRAINT `Service_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Service` ADD CONSTRAINT `Service_categoryId_fkey` FOREIGN KEY (`categoryId`) REFERENCES `ServiceCategory`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `StaffService` ADD CONSTRAINT `StaffService_staffId_fkey` FOREIGN KEY (`staffId`) REFERENCES `StaffProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `StaffService` ADD CONSTRAINT `StaffService_serviceId_fkey` FOREIGN KEY (`serviceId`) REFERENCES `Service`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `WorkingHours` ADD CONSTRAINT `WorkingHours_staffId_fkey` FOREIGN KEY (`staffId`) REFERENCES `StaffProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Break` ADD CONSTRAINT `Break_staffId_fkey` FOREIGN KEY (`staffId`) REFERENCES `StaffProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `BreakDay` ADD CONSTRAINT `BreakDay_breakId_fkey` FOREIGN KEY (`breakId`) REFERENCES `Break`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `TimeOff` ADD CONSTRAINT `TimeOff_staffId_fkey` FOREIGN KEY (`staffId`) REFERENCES `StaffProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Appointment` ADD CONSTRAINT `Appointment_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Appointment` ADD CONSTRAINT `Appointment_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `CustomerProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Appointment` ADD CONSTRAINT `Appointment_staffId_fkey` FOREIGN KEY (`staffId`) REFERENCES `StaffProfile`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Appointment` ADD CONSTRAINT `Appointment_cancelledByUserId_fkey` FOREIGN KEY (`cancelledByUserId`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Appointment` ADD CONSTRAINT `Appointment_createdByUserId_fkey` FOREIGN KEY (`createdByUserId`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `AppointmentService` ADD CONSTRAINT `AppointmentService_appointmentId_fkey` FOREIGN KEY (`appointmentId`) REFERENCES `Appointment`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `AppointmentService` ADD CONSTRAINT `AppointmentService_serviceId_fkey` FOREIGN KEY (`serviceId`) REFERENCES `Service`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyProgramme` ADD CONSTRAINT `LoyaltyProgramme_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyProgramme` ADD CONSTRAINT `LoyaltyProgramme_freeServiceId_fkey` FOREIGN KEY (`freeServiceId`) REFERENCES `Service`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyEligibleService` ADD CONSTRAINT `LoyaltyEligibleService_loyaltyProgrammeId_fkey` FOREIGN KEY (`loyaltyProgrammeId`) REFERENCES `LoyaltyProgramme`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyEligibleService` ADD CONSTRAINT `LoyaltyEligibleService_serviceId_fkey` FOREIGN KEY (`serviceId`) REFERENCES `Service`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyEligibleStaff` ADD CONSTRAINT `LoyaltyEligibleStaff_loyaltyProgrammeId_fkey` FOREIGN KEY (`loyaltyProgrammeId`) REFERENCES `LoyaltyProgramme`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyAccount` ADD CONSTRAINT `LoyaltyAccount_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `CustomerProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyAccount` ADD CONSTRAINT `LoyaltyAccount_loyaltyProgrammeId_fkey` FOREIGN KEY (`loyaltyProgrammeId`) REFERENCES `LoyaltyProgramme`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyTransaction` ADD CONSTRAINT `LoyaltyTransaction_loyaltyAccountId_fkey` FOREIGN KEY (`loyaltyAccountId`) REFERENCES `LoyaltyAccount`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyTransaction` ADD CONSTRAINT `LoyaltyTransaction_appointmentId_fkey` FOREIGN KEY (`appointmentId`) REFERENCES `Appointment`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyTransaction` ADD CONSTRAINT `LoyaltyTransaction_authoredByStaffId_fkey` FOREIGN KEY (`authoredByStaffId`) REFERENCES `StaffProfile`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyReward` ADD CONSTRAINT `LoyaltyReward_loyaltyAccountId_fkey` FOREIGN KEY (`loyaltyAccountId`) REFERENCES `LoyaltyAccount`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyReward` ADD CONSTRAINT `LoyaltyReward_appliedToAppointmentId_fkey` FOREIGN KEY (`appliedToAppointmentId`) REFERENCES `Appointment`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `LoyaltyReward` ADD CONSTRAINT `LoyaltyReward_redeemedByStaffId_fkey` FOREIGN KEY (`redeemedByStaffId`) REFERENCES `StaffProfile`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Notification` ADD CONSTRAINT `Notification_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Notification` ADD CONSTRAINT `Notification_appointmentId_fkey` FOREIGN KEY (`appointmentId`) REFERENCES `Appointment`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `NotificationPreference` ADD CONSTRAINT `NotificationPreference_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CustomerNote` ADD CONSTRAINT `CustomerNote_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `CustomerProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CustomerNote` ADD CONSTRAINT `CustomerNote_authorStaffId_fkey` FOREIGN KEY (`authorStaffId`) REFERENCES `StaffProfile`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `GuestAppointmentAccessToken` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`appointmentId` VARCHAR(191) NOT NULL,
|
||||
`tokenHash` VARCHAR(191) NOT NULL,
|
||||
`expiresAt` DATETIME(3) NOT NULL,
|
||||
`revokedAt` DATETIME(3) NULL,
|
||||
`lastUsedAt` DATETIME(3) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `GuestAppointmentAccessToken_appointmentId_key`(`appointmentId`),
|
||||
UNIQUE INDEX `GuestAppointmentAccessToken_tokenHash_key`(`tokenHash`),
|
||||
INDEX `GuestAppointmentAccessToken_expiresAt_idx`(`expiresAt`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `GuestAppointmentAccessToken` ADD CONSTRAINT `GuestAppointmentAccessToken_appointmentId_fkey` FOREIGN KEY (`appointmentId`) REFERENCES `Appointment`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,101 @@
|
||||
-- Phase 7: redesign Notification/NotificationPreference around the
|
||||
-- Notification (message) / NotificationDelivery (one attempt per channel)
|
||||
-- split — see prisma/schema.prisma for the full rationale. Both tables
|
||||
-- were unused scaffolding from Phase 2 (confirmed via a repo-wide grep for
|
||||
-- `prisma.notification`/`prisma.notificationPreference` before writing
|
||||
-- this migration — zero call sites), so these are safe destructive
|
||||
-- ALTERs, not a real data migration.
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `Notification` DROP FOREIGN KEY `Notification_userId_fkey`;
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE `NotificationPreference` DROP FOREIGN KEY `NotificationPreference_userId_fkey`;
|
||||
|
||||
-- DropIndex
|
||||
DROP INDEX `Notification_userId_idx` ON `Notification`;
|
||||
|
||||
-- DropIndex
|
||||
DROP INDEX `NotificationPreference_userId_category_channel_key` ON `NotificationPreference`;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Notification` DROP COLUMN `body`,
|
||||
DROP COLUMN `category`,
|
||||
DROP COLUMN `channel`,
|
||||
DROP COLUMN `failureReason`,
|
||||
DROP COLUMN `sentAt`,
|
||||
DROP COLUMN `status`,
|
||||
DROP COLUMN `userId`,
|
||||
ADD COLUMN `bodyText` TEXT NOT NULL,
|
||||
ADD COLUMN `businessId` VARCHAR(191) NOT NULL,
|
||||
ADD COLUMN `deepLinkPath` VARCHAR(191) NULL,
|
||||
ADD COLUMN `idempotencyKey` VARCHAR(191) NOT NULL,
|
||||
ADD COLUMN `loyaltyRewardId` VARCHAR(191) NULL,
|
||||
ADD COLUMN `readAt` DATETIME(3) NULL,
|
||||
ADD COLUMN `recipientCustomerId` VARCHAR(191) NULL,
|
||||
ADD COLUMN `recipientUserId` VARCHAR(191) NULL,
|
||||
ADD COLUMN `type` ENUM('BOOKING_CONFIRMED', 'BOOKING_PENDING_APPROVAL', 'BOOKING_APPROVED', 'BOOKING_REMINDER', 'BOOKING_RESCHEDULED', 'BOOKING_CANCELLED', 'BOOKING_BARBER_CHANGED', 'BOOKING_COMPLETED', 'LOYALTY_STAMP_ADDED', 'LOYALTY_REWARD_EARNED', 'LOYALTY_REWARD_REDEEMED', 'LOYALTY_REWARD_EXPIRING', 'STAFF_NEW_APPOINTMENT', 'STAFF_APPOINTMENT_RESCHEDULED', 'STAFF_APPOINTMENT_CANCELLED', 'STAFF_APPOINTMENT_CHECKED_IN', 'STAFF_APPOINTMENT_REMINDER', 'STAFF_SCHEDULE_CHANGED', 'OWNER_NEW_BOOKING', 'OWNER_BOOKING_CANCELLED', 'OWNER_NO_SHOW', 'OWNER_STAFF_INVITATION_ACCEPTED', 'OWNER_REPEATED_DELIVERY_FAILURE') NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `NotificationPreference` DROP COLUMN `category`,
|
||||
ADD COLUMN `type` ENUM('BOOKING_CONFIRMED', 'BOOKING_PENDING_APPROVAL', 'BOOKING_APPROVED', 'BOOKING_REMINDER', 'BOOKING_RESCHEDULED', 'BOOKING_CANCELLED', 'BOOKING_BARBER_CHANGED', 'BOOKING_COMPLETED', 'LOYALTY_STAMP_ADDED', 'LOYALTY_REWARD_EARNED', 'LOYALTY_REWARD_REDEEMED', 'LOYALTY_REWARD_EXPIRING', 'STAFF_NEW_APPOINTMENT', 'STAFF_APPOINTMENT_RESCHEDULED', 'STAFF_APPOINTMENT_CANCELLED', 'STAFF_APPOINTMENT_CHECKED_IN', 'STAFF_APPOINTMENT_REMINDER', 'STAFF_SCHEDULE_CHANGED', 'OWNER_NEW_BOOKING', 'OWNER_BOOKING_CANCELLED', 'OWNER_NO_SHOW', 'OWNER_STAFF_INVITATION_ACCEPTED', 'OWNER_REPEATED_DELIVERY_FAILURE') NOT NULL,
|
||||
MODIFY `channel` ENUM('EMAIL', 'PUSH', 'IN_APP') NOT NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `NotificationDelivery` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`notificationId` VARCHAR(191) NOT NULL,
|
||||
`channel` ENUM('EMAIL', 'PUSH', 'IN_APP') NOT NULL,
|
||||
`status` ENUM('PENDING', 'SCHEDULED', 'PROCESSING', 'SENT', 'FAILED', 'CANCELLED', 'SKIPPED') NOT NULL DEFAULT 'PENDING',
|
||||
`scheduledFor` DATETIME(3) NULL,
|
||||
`attemptCount` INTEGER NOT NULL DEFAULT 0,
|
||||
`lastAttemptedAt` DATETIME(3) NULL,
|
||||
`providerName` VARCHAR(191) NULL,
|
||||
`providerMessageId` VARCHAR(191) NULL,
|
||||
`failureReason` VARCHAR(191) NULL,
|
||||
`sentAt` DATETIME(3) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `NotificationDelivery_status_scheduledFor_idx`(`status`, `scheduledFor`),
|
||||
UNIQUE INDEX `NotificationDelivery_notificationId_channel_key`(`notificationId`, `channel`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX `Notification_idempotencyKey_key` ON `Notification`(`idempotencyKey`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `Notification_businessId_createdAt_idx` ON `Notification`(`businessId`, `createdAt`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `Notification_recipientUserId_readAt_idx` ON `Notification`(`recipientUserId`, `readAt`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX `Notification_recipientCustomerId_idx` ON `Notification`(`recipientCustomerId`);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX `NotificationPreference_userId_type_channel_key` ON `NotificationPreference`(`userId`, `type`, `channel`);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Notification` ADD CONSTRAINT `Notification_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Notification` ADD CONSTRAINT `Notification_recipientUserId_fkey` FOREIGN KEY (`recipientUserId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Notification` ADD CONSTRAINT `Notification_recipientCustomerId_fkey` FOREIGN KEY (`recipientCustomerId`) REFERENCES `CustomerProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Notification` ADD CONSTRAINT `Notification_loyaltyRewardId_fkey` FOREIGN KEY (`loyaltyRewardId`) REFERENCES `LoyaltyReward`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `NotificationDelivery` ADD CONSTRAINT `NotificationDelivery_notificationId_fkey` FOREIGN KEY (`notificationId`) REFERENCES `Notification`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
-- Re-adds the FK this migration dropped above (to accommodate the
|
||||
-- category->type column rename) but never restored — caught while writing
|
||||
-- a later migration and diffing against the live dev DB, which showed
|
||||
-- NotificationPreference.userId with no FK at all. Fixed here, in the
|
||||
-- original migration, rather than a separate patch: this migration had
|
||||
-- only ever been applied to this local dev database, never shared.
|
||||
ALTER TABLE `NotificationPreference` ADD CONSTRAINT `NotificationPreference_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
-- Adds STAFF_INVITATION_RECEIVED to NotificationType — the invite email
|
||||
-- itself, sent to the person being invited (see StaffInvitationService and
|
||||
-- templates/staff-emails.ts renderStaffInvitationEmail). Distinct from the
|
||||
-- existing OWNER_STAFF_INVITATION_ACCEPTED, which notifies the owner once
|
||||
-- accepted.
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Notification` MODIFY `type` ENUM('BOOKING_CONFIRMED', 'BOOKING_PENDING_APPROVAL', 'BOOKING_APPROVED', 'BOOKING_REMINDER', 'BOOKING_RESCHEDULED', 'BOOKING_CANCELLED', 'BOOKING_BARBER_CHANGED', 'BOOKING_COMPLETED', 'LOYALTY_STAMP_ADDED', 'LOYALTY_REWARD_EARNED', 'LOYALTY_REWARD_REDEEMED', 'LOYALTY_REWARD_EXPIRING', 'STAFF_NEW_APPOINTMENT', 'STAFF_APPOINTMENT_RESCHEDULED', 'STAFF_APPOINTMENT_CANCELLED', 'STAFF_APPOINTMENT_CHECKED_IN', 'STAFF_APPOINTMENT_REMINDER', 'STAFF_SCHEDULE_CHANGED', 'STAFF_INVITATION_RECEIVED', 'OWNER_NEW_BOOKING', 'OWNER_BOOKING_CANCELLED', 'OWNER_NO_SHOW', 'OWNER_STAFF_INVITATION_ACCEPTED', 'OWNER_REPEATED_DELIVERY_FAILURE') NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `NotificationPreference` MODIFY `type` ENUM('BOOKING_CONFIRMED', 'BOOKING_PENDING_APPROVAL', 'BOOKING_APPROVED', 'BOOKING_REMINDER', 'BOOKING_RESCHEDULED', 'BOOKING_CANCELLED', 'BOOKING_BARBER_CHANGED', 'BOOKING_COMPLETED', 'LOYALTY_STAMP_ADDED', 'LOYALTY_REWARD_EARNED', 'LOYALTY_REWARD_REDEEMED', 'LOYALTY_REWARD_EXPIRING', 'STAFF_NEW_APPOINTMENT', 'STAFF_APPOINTMENT_RESCHEDULED', 'STAFF_APPOINTMENT_CANCELLED', 'STAFF_APPOINTMENT_CHECKED_IN', 'STAFF_APPOINTMENT_REMINDER', 'STAFF_SCHEDULE_CHANGED', 'STAFF_INVITATION_RECEIVED', 'OWNER_NEW_BOOKING', 'OWNER_BOOKING_CANCELLED', 'OWNER_NO_SHOW', 'OWNER_STAFF_INVITATION_ACCEPTED', 'OWNER_REPEATED_DELIVERY_FAILURE') NOT NULL;
|
||||
@@ -0,0 +1,28 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `PushSubscription` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`userId` VARCHAR(191) NULL,
|
||||
`customerId` VARCHAR(191) NULL,
|
||||
`endpoint` VARCHAR(500) NOT NULL,
|
||||
`p256dhKey` VARCHAR(191) NOT NULL,
|
||||
`authKey` VARCHAR(191) NOT NULL,
|
||||
`deviceLabel` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`lastUsedAt` DATETIME(3) NULL,
|
||||
`revokedAt` DATETIME(3) NULL,
|
||||
|
||||
UNIQUE INDEX `PushSubscription_endpoint_key`(`endpoint`),
|
||||
INDEX `PushSubscription_userId_idx`(`userId`),
|
||||
INDEX `PushSubscription_customerId_idx`(`customerId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `PushSubscription` ADD CONSTRAINT `PushSubscription_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `PushSubscription` ADD CONSTRAINT `PushSubscription_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `PushSubscription` ADD CONSTRAINT `PushSubscription_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `CustomerProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- RenameIndex
|
||||
ALTER TABLE `Break` RENAME INDEX `Break_staffId_fkey` TO `Break_staffId_idx`;
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `BookingRule` MODIFY `allowGuestBooking` BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Business` ADD COLUMN `appIconUrl` VARCHAR(191) NULL,
|
||||
ADD COLUMN `backgroundColor` VARCHAR(191) NULL,
|
||||
ADD COLUMN `coverImageUrl` VARCHAR(191) NULL,
|
||||
ADD COLUMN `faviconUrl` VARCHAR(191) NULL,
|
||||
ADD COLUMN `shortName` VARCHAR(191) NULL,
|
||||
ADD COLUMN `themeColor` VARCHAR(191) NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `ApplicationInstallation` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`status` ENUM('NOT_INSTALLED', 'INSTALLING', 'INSTALLED', 'FAILED') NOT NULL DEFAULT 'NOT_INSTALLED',
|
||||
`installedAt` DATETIME(3) NULL,
|
||||
`installedVersion` VARCHAR(191) NULL,
|
||||
`initialAdminUserId` VARCHAR(191) NULL,
|
||||
`primaryBusinessId` VARCHAR(191) NULL,
|
||||
`metadata` JSON NULL,
|
||||
`failureReason` TEXT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `StaffCalendarConnection` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`staffId` VARCHAR(191) NOT NULL,
|
||||
`provider` ENUM('GOOGLE') NOT NULL DEFAULT 'GOOGLE',
|
||||
`externalAccountId` VARCHAR(191) NOT NULL,
|
||||
`accountEmail` VARCHAR(191) NOT NULL,
|
||||
`encryptedAccessToken` TEXT NULL,
|
||||
`encryptedRefreshToken` TEXT NOT NULL,
|
||||
`tokenExpiresAt` DATETIME(3) NULL,
|
||||
`selectedCalendarId` VARCHAR(191) NOT NULL,
|
||||
`selectedCalendarName` VARCHAR(191) NOT NULL,
|
||||
`connectedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`lastSyncAt` DATETIME(3) NULL,
|
||||
`lastSyncError` TEXT NULL,
|
||||
`revokedAt` DATETIME(3) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `StaffCalendarConnection_staffId_key`(`staffId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `AppointmentCalendarEvent` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`appointmentId` VARCHAR(191) NOT NULL,
|
||||
`connectionId` VARCHAR(191) NOT NULL,
|
||||
`providerEventId` VARCHAR(191) NOT NULL,
|
||||
`providerCalendarId` VARCHAR(191) NOT NULL,
|
||||
`status` ENUM('SYNCED', 'PENDING', 'FAILED', 'CANCELLED') NOT NULL DEFAULT 'SYNCED',
|
||||
`lastSyncedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`lastSyncError` TEXT NULL,
|
||||
`sourceVersion` INTEGER NOT NULL DEFAULT 1,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `AppointmentCalendarEvent_connectionId_idx`(`connectionId`),
|
||||
UNIQUE INDEX `AppointmentCalendarEvent_appointmentId_connectionId_key`(`appointmentId`, `connectionId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `StaffCalendarConnection` ADD CONSTRAINT `StaffCalendarConnection_staffId_fkey` FOREIGN KEY (`staffId`) REFERENCES `StaffProfile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `AppointmentCalendarEvent` ADD CONSTRAINT `AppointmentCalendarEvent_appointmentId_fkey` FOREIGN KEY (`appointmentId`) REFERENCES `Appointment`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `AppointmentCalendarEvent` ADD CONSTRAINT `AppointmentCalendarEvent_connectionId_fkey` FOREIGN KEY (`connectionId`) REFERENCES `StaffCalendarConnection`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Business` ADD COLUMN `googlePlaceId` VARCHAR(191) NULL,
|
||||
ADD COLUMN `googleRating` DECIMAL(2, 1) NULL,
|
||||
ADD COLUMN `googleRatingCount` INTEGER NULL,
|
||||
ADD COLUMN `welcomeBackgroundDesktopUrl` VARCHAR(191) NULL,
|
||||
ADD COLUMN `welcomeBackgroundMobileUrl` VARCHAR(191) NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `BusinessSettings` ADD COLUMN `reviewsExcludeRatingOnly` BOOLEAN NOT NULL DEFAULT false,
|
||||
ADD COLUMN `reviewsMinRating` INTEGER NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `RolePermission` MODIFY `permission` ENUM('MANAGE_BUSINESS_PROFILE', 'MANAGE_BOOKING_RULES', 'MANAGE_SERVICES', 'MANAGE_STAFF', 'MANAGE_LOYALTY_PROGRAMME', 'MANAGE_NOTIFICATION_SETTINGS', 'VIEW_ALL_STAFF_APPOINTMENTS', 'MANAGE_ALL_APPOINTMENTS', 'MANAGE_OWN_APPOINTMENTS', 'CHECK_IN_CUSTOMERS', 'MANAGE_LOYALTY_STAMPS', 'MANAGE_OWN_AVAILABILITY', 'VIEW_CUSTOMER_DIRECTORY', 'BOOK_ON_BEHALF_OF_CUSTOMER', 'VIEW_REPORTING', 'MANAGE_MEDIA_LIBRARY', 'MANAGE_REVIEWS') NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Service` ADD COLUMN `imageUrl` VARCHAR(191) NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `MediaAsset` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`url` VARCHAR(500) NOT NULL,
|
||||
`originalFilename` VARCHAR(191) NULL,
|
||||
`mimeType` VARCHAR(191) NOT NULL,
|
||||
`sizeBytes` INTEGER NOT NULL,
|
||||
`width` INTEGER NULL,
|
||||
`height` INTEGER NULL,
|
||||
`category` VARCHAR(191) NULL,
|
||||
`uploadedByUserId` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `MediaAsset_businessId_category_idx`(`businessId`, `category`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `BusinessGalleryImage` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`placement` ENUM('HERO', 'PORTFOLIO') NOT NULL,
|
||||
`mediaAssetId` VARCHAR(191) NULL,
|
||||
`imageUrl` VARCHAR(500) NOT NULL,
|
||||
`category` VARCHAR(191) NULL,
|
||||
`caption` VARCHAR(191) NULL,
|
||||
`displayOrder` INTEGER NOT NULL DEFAULT 0,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `BusinessGalleryImage_businessId_placement_displayOrder_idx`(`businessId`, `placement`, `displayOrder`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Review` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`businessId` VARCHAR(191) NOT NULL,
|
||||
`externalId` VARCHAR(191) NOT NULL,
|
||||
`authorName` VARCHAR(191) NOT NULL,
|
||||
`authorPhotoUrl` VARCHAR(191) NULL,
|
||||
`rating` INTEGER NOT NULL,
|
||||
`text` TEXT NULL,
|
||||
`relativeTimeDescription` VARCHAR(191) NULL,
|
||||
`publishedAt` DATETIME(3) NULL,
|
||||
`isHidden` BOOLEAN NOT NULL DEFAULT false,
|
||||
`fetchedAt` DATETIME(3) NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `Review_businessId_isHidden_idx`(`businessId`, `isHidden`),
|
||||
UNIQUE INDEX `Review_businessId_externalId_key`(`businessId`, `externalId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `MediaAsset` ADD CONSTRAINT `MediaAsset_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `MediaAsset` ADD CONSTRAINT `MediaAsset_uploadedByUserId_fkey` FOREIGN KEY (`uploadedByUserId`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `BusinessGalleryImage` ADD CONSTRAINT `BusinessGalleryImage_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `BusinessGalleryImage` ADD CONSTRAINT `BusinessGalleryImage_mediaAssetId_fkey` FOREIGN KEY (`mediaAssetId`) REFERENCES `MediaAsset`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Review` ADD CONSTRAINT `Review_businessId_fkey` FOREIGN KEY (`businessId`) REFERENCES `Business`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `LoyaltyProgramme` ADD COLUMN `cardBorderColor` VARCHAR(191) NULL,
|
||||
ADD COLUMN `cardFont` ENUM('SANS', 'SERIF', 'MONO') NOT NULL DEFAULT 'SANS',
|
||||
ADD COLUMN `cardMemberNumberColor` VARCHAR(191) NULL,
|
||||
ADD COLUMN `cardTopRightText` VARCHAR(191) NULL,
|
||||
ADD COLUMN `cardTopRightTextColor` VARCHAR(191) NULL,
|
||||
ADD COLUMN `cardTopRightTextSize` ENUM('SM', 'MD', 'LG') NOT NULL DEFAULT 'MD',
|
||||
ADD COLUMN `rewardPosition` ENUM('AFTER_ALL_STAMPS', 'FINAL_SLOT_IS_REWARD') NOT NULL DEFAULT 'AFTER_ALL_STAMPS';
|
||||
|
||||
-- Stamp-limit enforcement (Phase 10 follow-up brief: "Valid range: 1–10").
|
||||
-- Confirmed via a direct read of the live database before writing this
|
||||
-- migration that no existing LoyaltyProgramme row has stampsRequired > 10
|
||||
-- and no LoyaltyAccount has currentStamps > 10 — safe to add directly,
|
||||
-- no data migration needed. Defense-in-depth alongside the identical
|
||||
-- 1-10 check in validateProgrammeConfig() and the owner form's client
|
||||
-- validation; MySQL 8.0.16+ enforces CHECK constraints (this app's
|
||||
-- documented target, see schema.prisma's own header).
|
||||
ALTER TABLE `LoyaltyProgramme` ADD CONSTRAINT `LoyaltyProgramme_stampsRequired_range`
|
||||
CHECK (`stampsRequired` BETWEEN 1 AND 10);
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
-- Backfill MANAGE_MEDIA_LIBRARY and MANAGE_REVIEWS (added in Phase 9)
|
||||
-- onto every role that already holds MANAGE_STAFF — the app's existing
|
||||
-- definition of "owner" (see src/services/staff/staff.service.ts's
|
||||
-- countOtherActiveManagers, "A role holding MANAGE_STAFF is this app's
|
||||
-- definition of 'an owner'"). syncRolePermissions() only ever runs at
|
||||
-- install/seed time, so any business installed before Phase 9 has its
|
||||
-- Owner role stuck on the old 15-permission set — confirmed by reading
|
||||
-- the actual RolePermission rows on a real installed business before
|
||||
-- writing this migration.
|
||||
--
|
||||
-- This is what silently made /owner/settings/reviews redirect away
|
||||
-- (hasPermission(..., MANAGE_REVIEWS) failing, redirecting to /staff,
|
||||
-- which then renders the barber calendar — looking exactly like
|
||||
-- "Reviews opens Calendar") and made Media Manager deletes silently fail
|
||||
-- (MANAGE_MEDIA_LIBRARY). Not a routing bug — a missing data backfill.
|
||||
--
|
||||
-- Idempotent: a fresh install's Owner role already has both permissions
|
||||
-- from syncRolePermissions() at install time, and INSERT IGNORE plus the
|
||||
-- existing @@unique([roleId, permission]) constraint make re-running
|
||||
-- this migration (or running it against an already-correct database)
|
||||
-- a safe no-op.
|
||||
|
||||
INSERT IGNORE INTO `RolePermission` (`id`, `roleId`, `permission`)
|
||||
SELECT UUID(), owner.`roleId`, 'MANAGE_MEDIA_LIBRARY'
|
||||
FROM `RolePermission` owner
|
||||
WHERE owner.`permission` = 'MANAGE_STAFF';
|
||||
|
||||
INSERT IGNORE INTO `RolePermission` (`id`, `roleId`, `permission`)
|
||||
SELECT UUID(), owner.`roleId`, 'MANAGE_REVIEWS'
|
||||
FROM `RolePermission` owner
|
||||
WHERE owner.`permission` = 'MANAGE_STAFF';
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
-- Rewrite any already-stored `/media/...` URLs (the pre-Phase-10 upload
|
||||
-- path, which never actually worked in production — Next.js 16's
|
||||
-- `next start` does not dynamically serve files added to public/ after
|
||||
-- the build; see src/lib/media/media-storage.ts's header for the full
|
||||
-- account) to the new `/api/media/...` prefix served by
|
||||
-- src/app/api/media/[...path]/route.ts.
|
||||
--
|
||||
-- Confirmed via a direct read of the live database before writing this
|
||||
-- migration: exactly one MediaAsset row and its matching
|
||||
-- BusinessGalleryImage row use the old prefix; every other image field
|
||||
-- currently stores a full external URL (Business.logoUrl/coverImageUrl,
|
||||
-- etc.) and is untouched by this. Every statement below is still
|
||||
-- included for completeness/safety, covers every image column that can
|
||||
-- receive a MediaPicker-sourced URL, and is a no-op wherever nothing
|
||||
-- matches.
|
||||
--
|
||||
-- Idempotent: re-running finds nothing left matching `/media/%` (rows
|
||||
-- already rewritten now start with `/api/media/%`), so this is safe to
|
||||
-- apply more than once.
|
||||
|
||||
UPDATE `MediaAsset` SET `url` = CONCAT('/api', `url`) WHERE `url` LIKE '/media/%';
|
||||
UPDATE `BusinessGalleryImage` SET `imageUrl` = CONCAT('/api', `imageUrl`) WHERE `imageUrl` LIKE '/media/%';
|
||||
UPDATE `Business` SET `logoUrl` = CONCAT('/api', `logoUrl`) WHERE `logoUrl` LIKE '/media/%';
|
||||
UPDATE `Business` SET `coverImageUrl` = CONCAT('/api', `coverImageUrl`) WHERE `coverImageUrl` LIKE '/media/%';
|
||||
UPDATE `Business` SET `faviconUrl` = CONCAT('/api', `faviconUrl`) WHERE `faviconUrl` LIKE '/media/%';
|
||||
UPDATE `Business` SET `appIconUrl` = CONCAT('/api', `appIconUrl`) WHERE `appIconUrl` LIKE '/media/%';
|
||||
UPDATE `Business` SET `welcomeBackgroundDesktopUrl` = CONCAT('/api', `welcomeBackgroundDesktopUrl`) WHERE `welcomeBackgroundDesktopUrl` LIKE '/media/%';
|
||||
UPDATE `Business` SET `welcomeBackgroundMobileUrl` = CONCAT('/api', `welcomeBackgroundMobileUrl`) WHERE `welcomeBackgroundMobileUrl` LIKE '/media/%';
|
||||
UPDATE `LoyaltyProgramme` SET `cardBackgroundImageUrl` = CONCAT('/api', `cardBackgroundImageUrl`) WHERE `cardBackgroundImageUrl` LIKE '/media/%';
|
||||
UPDATE `Service` SET `imageUrl` = CONCAT('/api', `imageUrl`) WHERE `imageUrl` LIKE '/media/%';
|
||||
UPDATE `User` SET `image` = CONCAT('/api', `image`) WHERE `image` LIKE '/media/%';
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
-- Phase 11: the loyalty card's owner-configurable text now replaces the
|
||||
-- hardcoded "Loyalty Card" title (top-left), not a secondary badge next to
|
||||
-- the member number (top-right) — renamed to match, using CHANGE COLUMN so
|
||||
-- any value an owner already configured (e.g. a custom title) survives the
|
||||
-- rename instead of being dropped.
|
||||
ALTER TABLE `LoyaltyProgramme`
|
||||
CHANGE COLUMN `cardTopRightText` `cardTitleText` VARCHAR(191) NULL,
|
||||
CHANGE COLUMN `cardTopRightTextSize` `cardTitleTextSize` ENUM('SM', 'MD', 'LG') NOT NULL DEFAULT 'MD',
|
||||
CHANGE COLUMN `cardTopRightTextColor` `cardTitleTextColor` VARCHAR(191) NULL;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Business` ADD COLUMN `icon192Url` VARCHAR(191) NULL,
|
||||
ADD COLUMN `icon512Url` VARCHAR(191) NULL,
|
||||
ADD COLUMN `maskableIcon192Url` VARCHAR(191) NULL,
|
||||
ADD COLUMN `maskableIcon512Url` VARCHAR(191) NULL,
|
||||
ADD COLUMN `splashScreenLandscapeUrl` VARCHAR(191) NULL,
|
||||
ADD COLUMN `splashScreenPortraitUrl` VARCHAR(191) NULL;
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `splashScreenLandscapeUrl` on the `Business` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `splashScreenPortraitUrl` on the `Business` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `Business` DROP COLUMN `splashScreenLandscapeUrl`,
|
||||
DROP COLUMN `splashScreenPortraitUrl`,
|
||||
ADD COLUMN `splashScreens` JSON NULL;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Business` ADD COLUMN `bottomNavShowLabels` BOOLEAN NOT NULL 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 = "mysql"
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user