Commit design approval workflow and related features

- Add design approval workflow components and API routes
- Update checkout process for design approval integration
- Add admin navigation for design management
- Update mail utilities for design notifications
- Update types for design approval system
- Update Prisma schema for design approval database

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Andymick
2026-07-18 15:42:30 +01:00
co-authored by Claude Haiku 4.5
parent 14fa3acc7a
commit 313943aeaa
8 changed files with 158 additions and 30 deletions
+51 -9
View File
@@ -39,6 +39,8 @@ model Product {
printAreaBack String? // same shape, for the back print area — only used when imageUrlBack is set
printAreaWidthMm Int @default(200) // width of the printable area in millimeters
printAreaHeightMm Int @default(280) // height of the printable area in millimeters
referenceWidthCm Int? // width of garment/object for ruler reference (cm)
referenceHeightCm Int? // height of garment/object for ruler reference (cm)
imageUrl String? // optional real product photo — shown instead of the illustration when set
imageUrlBack String? // optional back-view photo, toggled alongside the front photo
photoRecolorable Boolean @default(false) // if true, the photo is treated as a grayscale
@@ -53,15 +55,16 @@ model Product {
saleStartsAt DateTime? // leave null to start the sale immediately
saleEndsAt DateTime? // leave null for an open-ended sale
orderItems OrderItem[]
proofs DesignProof[]
customRequests CustomRequest[]
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[]
stockLevels StockLevel[]
purchaseItems PurchaseItem[]
productImages ProductImage[]
orderItems OrderItem[]
proofs DesignProof[]
customRequests CustomRequest[]
designApprovals DesignApproval[]
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[]
stockLevels StockLevel[]
purchaseItems PurchaseItem[]
productImages ProductImage[]
}
// Bulk-uploaded product images with auto-detected colors. Supports any product type
@@ -174,6 +177,41 @@ model Message {
createdAt DateTime @default(now())
}
// Customer-submitted designs pending admin approval before checkout
model DesignApproval {
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])
designJson String // serialized {front:[...], back:[...]} design elements
designPreviewUrl String // base64 PNG data URL — front design, transparent, print-ready
designPreviewUrlBack String? // same, for the back design if there is one
placementPreviewUrl String? // front design on product photo
placementPreviewUrlBack String? // back design on product photo
designWidthCm Float? // width of design in centimeters (legacy, for backward compatibility)
designHeightCm Float? // height of design in centimeters (legacy, for backward compatibility)
designImageDimensions String? // JSON array of {imageId, widthCm, heightCm} for each uploaded image
color String
size String?
status String @default("PENDING") // PENDING | APPROVED | REJECTED
messages DesignApprovalMessage[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// Chat messages for design approval discussions
model DesignApprovalMessage {
id String @id @default(cuid())
designId String
design DesignApproval @relation(fields: [designId], references: [id], onDelete: Cascade)
sender String // "ADMIN" | "CUSTOMER"
body String
createdAt DateTime @default(now())
}
model Order {
id String @id @default(cuid())
stripeSessionId String? @unique
@@ -207,6 +245,7 @@ model Customer {
passwordResetToken PasswordResetToken?
customRequests CustomRequest[]
manualSales ManualSale[]
designApprovals DesignApproval[]
}
// A sale that didn't go through the website checkout — cash at a fair, a bank
@@ -383,6 +422,9 @@ model OrderItem {
designPreviewUrlBack String? // same, for the back design if there is one
placementPreviewUrl String? // front design shown composited on the actual product photo, for reference — where does this go when printing
placementPreviewUrlBack String? // same, for the back
designWidthCm Float? // width of design in centimeters (legacy)
designHeightCm Float? // height of design in centimeters (legacy)
designImageDimensions String? // JSON array of {imageId, widthCm, heightCm} for each uploaded image
}
// Audit log for admin logins — tracks when the admin panel is accessed