add review and booking policies

This commit is contained in:
root
2026-05-25 18:29:05 -04:00
parent 8ed572b3bd
commit 0d969ab095
37 changed files with 3775 additions and 113 deletions
@@ -0,0 +1,19 @@
-- CreateEnum
CREATE TYPE "ReservationPhotoType" AS ENUM ('PICKUP', 'DROPOFF');
-- CreateTable
CREATE TABLE "reservation_photos" (
"id" TEXT NOT NULL,
"reservationId" TEXT NOT NULL,
"type" "ReservationPhotoType" NOT NULL,
"url" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "reservation_photos_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "reservation_photos_reservationId_idx" ON "reservation_photos"("reservationId");
-- AddForeignKey
ALTER TABLE "reservation_photos" ADD CONSTRAINT "reservation_photos_reservationId_fkey" FOREIGN KEY ("reservationId") REFERENCES "reservations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,6 @@
-- AlterEnum (PostgreSQL enum values must be added outside a transaction)
ALTER TYPE "VehicleStatus" ADD VALUE 'RESERVED';
ALTER TYPE "VehicleStatus" ADD VALUE 'READY';
ALTER TYPE "VehicleStatus" ADD VALUE 'RETURNED';
ALTER TYPE "VehicleStatus" ADD VALUE 'NEEDS_CLEANING';
ALTER TYPE "VehicleStatus" ADD VALUE 'DAMAGE_REVIEW';
@@ -0,0 +1,83 @@
-- CreateEnum: FeedbackCategory
CREATE TYPE "FeedbackCategory" AS ENUM (
'BOOKING',
'PICKUP',
'VEHICLE_CLEANLINESS',
'VEHICLE_CONDITION',
'STAFF_SERVICE',
'PRICING',
'DEPOSIT',
'INSURANCE',
'DAMAGE_CLAIM',
'RETURN_PROCESS',
'COMMUNICATION',
'ROADSIDE_ASSISTANCE',
'BILLING',
'OTHER'
);
-- CreateEnum: ComplaintSeverity
CREATE TYPE "ComplaintSeverity" AS ENUM ('LEVEL_1', 'LEVEL_2', 'LEVEL_3');
-- CreateEnum: ComplaintStatus
CREATE TYPE "ComplaintStatus" AS ENUM ('OPEN', 'INVESTIGATING', 'RESOLVED', 'CLOSED');
-- AlterTable: reviews — add category column
ALTER TABLE "reviews" ADD COLUMN "category" "FeedbackCategory";
-- AlterTable: reservations — add review tracking columns
ALTER TABLE "reservations"
ADD COLUMN "reviewRequestSentAt" TIMESTAMP(3),
ADD COLUMN "reviewReminderSentAt" TIMESTAMP(3),
ADD COLUMN "reviewFinalReminderSentAt" TIMESTAMP(3),
ADD COLUMN "reviewPaused" BOOLEAN NOT NULL DEFAULT false;
-- AlterTable: customers — add reviewOptOut column
ALTER TABLE "customers" ADD COLUMN "reviewOptOut" BOOLEAN NOT NULL DEFAULT false;
-- CreateTable: complaints
CREATE TABLE "complaints" (
"id" TEXT NOT NULL,
"companyId" TEXT NOT NULL,
"reservationId" TEXT,
"reviewId" TEXT,
"customerId" TEXT,
"severity" "ComplaintSeverity" NOT NULL DEFAULT 'LEVEL_1',
"status" "ComplaintStatus" NOT NULL DEFAULT 'OPEN',
"category" "FeedbackCategory" NOT NULL,
"subject" TEXT NOT NULL,
"description" TEXT,
"resolution" TEXT,
"notes" TEXT,
"assignedTo" TEXT,
"resolvedAt" TIMESTAMP(3),
"resolvedBy" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "complaints_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "complaints_companyId_idx" ON "complaints"("companyId");
CREATE INDEX "complaints_reservationId_idx" ON "complaints"("reservationId");
-- AddForeignKey: complaints → companies
ALTER TABLE "complaints"
ADD CONSTRAINT "complaints_companyId_fkey"
FOREIGN KEY ("companyId") REFERENCES "companies"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey: complaints → reservations
ALTER TABLE "complaints"
ADD CONSTRAINT "complaints_reservationId_fkey"
FOREIGN KEY ("reservationId") REFERENCES "reservations"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey: complaints → reviews
ALTER TABLE "complaints"
ADD CONSTRAINT "complaints_reviewId_fkey"
FOREIGN KEY ("reviewId") REFERENCES "reviews"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey: complaints → customers
ALTER TABLE "complaints"
ADD CONSTRAINT "complaints_customerId_fkey"
FOREIGN KEY ("customerId") REFERENCES "customers"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+100 -6
View File
@@ -172,8 +172,13 @@ enum EmployeeRole {
enum VehicleStatus {
AVAILABLE
RESERVED
READY
RENTED
RETURNED
NEEDS_CLEANING
MAINTENANCE
DAMAGE_REVIEW
OUT_OF_SERVICE
}
@@ -223,6 +228,11 @@ enum BookingSource {
API
}
enum ReservationPhotoType {
PICKUP
DROPOFF
}
enum CancelledBy {
COMPANY
RENTER
@@ -398,6 +408,36 @@ enum NotificationType {
REVIEW_REQUEST
}
enum FeedbackCategory {
BOOKING
PICKUP
VEHICLE_CLEANLINESS
VEHICLE_CONDITION
STAFF_SERVICE
PRICING
DEPOSIT
INSURANCE
DAMAGE_CLAIM
RETURN_PROCESS
COMMUNICATION
ROADSIDE_ASSISTANCE
BILLING
OTHER
}
enum ComplaintSeverity {
LEVEL_1
LEVEL_2
LEVEL_3
}
enum ComplaintStatus {
OPEN
INVESTIGATING
RESOLVED
CLOSED
}
enum NotificationChannel {
EMAIL
SMS
@@ -450,6 +490,7 @@ model Company {
insurancePolicies InsurancePolicy[]
pricingRules PricingRule[]
notifications Notification[] @relation("CompanyNotifications")
complaints Complaint[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -1083,7 +1124,9 @@ model Customer {
licenseApprovedAt DateTime?
licenseApprovalNote String?
reservations Reservation[]
reservations Reservation[]
complaints Complaint[]
reviewOptOut Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -1134,6 +1177,11 @@ model Reservation {
checkInFuelLevel String?
checkOutFuelLevel String?
reviewRequestSentAt DateTime?
reviewReminderSentAt DateTime?
reviewFinalReminderSentAt DateTime?
reviewPaused Boolean @default(false)
insurances ReservationInsurance[]
insuranceTotal Int @default(0)
additionalDrivers AdditionalDriver[]
@@ -1143,7 +1191,9 @@ model Reservation {
damageReports DamageReport[]
rentalPayments RentalPayment[]
inspections DamageInspection[]
photos ReservationPhoto[]
review Review?
complaints Complaint[]
damageChargeAmount Int?
damageChargeNote String?
extras Json?
@@ -1183,19 +1233,21 @@ model RentalPayment {
}
model Review {
id String @id @default(cuid())
reservationId String @unique
reservation Reservation @relation(fields: [reservationId], references: [id])
id String @id @default(cuid())
reservationId String @unique
reservation Reservation @relation(fields: [reservationId], references: [id])
renterId String?
renter Renter? @relation(fields: [renterId], references: [id])
renter Renter? @relation(fields: [renterId], references: [id])
companyId String
overallRating Int
vehicleRating Int?
serviceRating Int?
comment String?
isPublished Boolean @default(true)
isPublished Boolean @default(true)
companyReply String?
companyRepliedAt DateTime?
category FeedbackCategory?
complaints Complaint[]
createdAt DateTime @default(now())
@@ -1203,6 +1255,36 @@ model Review {
@@map("reviews")
}
model Complaint {
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
reservationId String?
reservation Reservation? @relation(fields: [reservationId], references: [id])
reviewId String?
review Review? @relation(fields: [reviewId], references: [id])
customerId String?
customer Customer? @relation(fields: [customerId], references: [id])
severity ComplaintSeverity @default(LEVEL_1)
status ComplaintStatus @default(OPEN)
category FeedbackCategory
subject String
description String?
resolution String?
notes String?
assignedTo String?
resolvedAt DateTime?
resolvedBy String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([companyId])
@@index([reservationId])
@@map("complaints")
}
// ═══════════════════════════════════════════════════════════════
// NOTIFICATIONS
// ═══════════════════════════════════════════════════════════════
@@ -1645,3 +1727,15 @@ model PricingPromotion {
@@index([isActive])
@@map("pricing_promotions")
}
model ReservationPhoto {
id String @id @default(cuid())
reservationId String
reservation Reservation @relation(fields: [reservationId], references: [id], onDelete: Cascade)
type ReservationPhotoType
url String
createdAt DateTime @default(now())
@@index([reservationId])
@@map("reservation_photos")
}