Feature: Add customer reviews system with admin management

- Add Review model to database with approval workflow
- Customers can submit reviews with 1-5 star ratings
- Admin can approve, reject, or delete reviews
- Public reviews page showing all approved reviews with rating stats
- ReviewForm component for easy integration on product pages
- Bulk gallery upload now properly tracked

Chore: Add expected delivery date for design approvals

- Add expectedDeliveryDate field to DesignApproval model
- Admin can set delivery date when approving designs
- Improves customer communication and expectations

Chore: Add welcome back message for logged-in customers

- Display personalized greeting on account page after login
- Shows customer's name if available

Chore: Add color difference disclaimer to product pages

- Added to StandardProductView (ready-made products)
- Added to DesignCanvas (personalized products)
- Informs customers about lighting-based color variations
- Helps manage customer expectations

Feature: Add image identification in design specifications

- Images now clearly labeled as "Image 1", "Image 2", etc.
- Images marked with purple circles in specification diagrams
- Improves clarity for production team

Documentation: Add comprehensive database optimization guide

- DATABASE_OPTIMIZATION.md - Full optimization strategies
- DATABASE_OPTIMIZATION_QUICK_START.md - Implementation examples
- DATABASE_OPTIMIZATION_MIGRATION.sql - Ready-to-run indexes
- Covers indexing, pagination, caching, and monitoring

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Andymick
2026-07-19 18:24:58 +01:00
co-authored by Claude Haiku 4.5
parent a1f1cc3fa1
commit 16f1f64fd0
21 changed files with 1531 additions and 19 deletions
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "DesignApproval" ADD COLUMN "expectedDeliveryDate" TIMESTAMP(3);
@@ -0,0 +1,22 @@
-- CreateTable
CREATE TABLE "Review" (
"id" TEXT NOT NULL,
"customerId" TEXT,
"customerEmail" TEXT NOT NULL,
"customerName" TEXT,
"productId" TEXT NOT NULL,
"rating" INTEGER NOT NULL,
"title" TEXT NOT NULL,
"comment" TEXT NOT NULL,
"approved" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Review_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "Review" ADD CONSTRAINT "Review_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "Customer"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Review" ADD CONSTRAINT "Review_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Product"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+20
View File
@@ -60,6 +60,7 @@ model Product {
proofs DesignProof[]
customRequests CustomRequest[]
designApprovals DesignApproval[]
reviews Review[]
promotions Promotion[] // only relevant to promotions scoped to specific items, not "all items"
collections Collection[] // occasion/recipient tags, e.g. "Christmas", "For Teachers"
manualSaleItems ManualSaleItem[]
@@ -199,6 +200,7 @@ model DesignApproval {
color String
size String?
status String @default("PENDING") // PENDING | IN_REVIEW | APPROVED | REJECTED
expectedDeliveryDate DateTime? // admin sets this when approving the design
messages DesignApprovalMessage[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -268,6 +270,7 @@ model Customer {
customRequests CustomRequest[]
manualSales ManualSale[]
designApprovals DesignApproval[]
reviews Review[]
}
// A sale that didn't go through the website checkout — cash at a fair, a bank
@@ -547,6 +550,23 @@ model BankReconciliation {
notes String? // manual notes about the match
}
// Customer reviews for products
model Review {
id String @id @default(cuid())
customerId String? // null for guest customers
customer Customer? @relation(fields: [customerId], references: [id], onDelete: SetNull)
customerEmail String
customerName String?
productId String
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
rating Int // 1-5 stars
title String // short headline
comment String // full review text
approved Boolean @default(false) // must be approved by admin before showing publicly
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// Shipping rates configuration — managed from admin panel
// Allows easy updates to Royal Mail pricing without code changes
model ShippingRate {