feat: order revision, rial wage from variant, product tags; drop user-app-v2
Admin order edit with category chips and timeline; customer checkout charges variant rialWage; product tags; retire the unused user-app-v2 tree. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
-- Product labels from Setting `__list__tags`, assigned per product in admin.
|
||||
ALTER TABLE "Product" ADD COLUMN IF NOT EXISTS "tags" TEXT[] DEFAULT ARRAY[]::TEXT[];
|
||||
@@ -0,0 +1,29 @@
|
||||
-- Admin order edit + customer confirm (Order.revisionStatus / OrderRevision).
|
||||
|
||||
CREATE TYPE "OrderRevisionStatus" AS ENUM ('NONE', 'AWAITING_CUSTOMER');
|
||||
|
||||
ALTER TABLE "Order" ADD COLUMN "revisionStatus" "OrderRevisionStatus" NOT NULL DEFAULT 'NONE';
|
||||
|
||||
CREATE TABLE "OrderRevision" (
|
||||
"id" TEXT NOT NULL,
|
||||
"orderId" TEXT NOT NULL,
|
||||
"items" JSONB NOT NULL,
|
||||
"totalGoldWeightGrams" DECIMAL(14,4) NOT NULL,
|
||||
"wageWeightGrams" DECIMAL(14,4) NOT NULL,
|
||||
"flatRialCharge" DECIMAL(20,2) NOT NULL DEFAULT 0,
|
||||
"proposedByAdminUserId" TEXT,
|
||||
"note" TEXT,
|
||||
"customerDecision" TEXT,
|
||||
"customerDecidedAt" TIMESTAMP(3),
|
||||
"appliedAt" TIMESTAMP(3),
|
||||
"discardedAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "OrderRevision_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE INDEX "Order_revisionStatus_idx" ON "Order"("revisionStatus");
|
||||
CREATE INDEX "OrderRevision_orderId_idx" ON "OrderRevision"("orderId");
|
||||
CREATE INDEX "OrderRevision_createdAt_idx" ON "OrderRevision"("createdAt");
|
||||
|
||||
ALTER TABLE "OrderRevision" ADD CONSTRAINT "OrderRevision_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "Order"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -693,6 +693,9 @@ model Product {
|
||||
/// Legacy Product.show_type: 1 site, 2 mobile, 3 both.
|
||||
showType Int @default(3)
|
||||
isActive Boolean @default(true)
|
||||
/// Labels from Setting `__list__tags`, assigned on the product form. The
|
||||
/// storefront shows them on list cards only (not the product detail page).
|
||||
tags String[] @default([])
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
/// Stock of the linked کارساخته as last read from the accounting software
|
||||
@@ -800,6 +803,12 @@ model ProductVariant {
|
||||
// Orders — stock orders (debt-bearing)
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// Customer-confirm state for an admin-proposed order edit (not a pipeline status).
|
||||
enum OrderRevisionStatus {
|
||||
NONE
|
||||
AWAITING_CUSTOMER
|
||||
}
|
||||
|
||||
model Order {
|
||||
id String @id @default(cuid())
|
||||
orderNumber String @unique
|
||||
@@ -811,6 +820,9 @@ model Order {
|
||||
channel OrderChannel @default(RETAIL)
|
||||
status OrderStatus @default(PLACED)
|
||||
|
||||
/// Pending admin edit awaiting customer confirm (or admin force/discard).
|
||||
revisionStatus OrderRevisionStatus @default(NONE)
|
||||
|
||||
/// Total gold weight incl. wage across all items ("allGram" / order.w).
|
||||
totalGoldWeightGrams Decimal @db.Decimal(14, 4)
|
||||
/// Pure making-charge weight component (totalGoldWeightGrams minus raw weight sum).
|
||||
@@ -843,14 +855,48 @@ model Order {
|
||||
items OrderItem[]
|
||||
statusEvents OrderStatusEvent[]
|
||||
ledgerEntries LedgerEntry[]
|
||||
revisions OrderRevision[]
|
||||
convertedFromPreOrder PreOrder?
|
||||
|
||||
@@index([customerId])
|
||||
@@index([status])
|
||||
@@index([revisionStatus])
|
||||
@@index([salesAgentId])
|
||||
@@index([referrerCustomerId])
|
||||
}
|
||||
|
||||
/// Proposed line-item edit for an Order. Live until applied or discarded.
|
||||
/// While pending, Order.revisionStatus = AWAITING_CUSTOMER and charged figures
|
||||
/// stay on the current Order until the customer confirms (or admin force-applies).
|
||||
model OrderRevision {
|
||||
id String @id @default(cuid())
|
||||
orderId String
|
||||
order Order @relation(fields: [orderId], references: [id], onDelete: Cascade)
|
||||
|
||||
/// Proposed lines: [{ productVariantId, quantity, rashWeightGramsSnapshot,
|
||||
/// wagePercentSnapshot, discountPercentSnapshot, computedWeightGrams, flatRialCharge }]
|
||||
items Json
|
||||
|
||||
totalGoldWeightGrams Decimal @db.Decimal(14, 4)
|
||||
wageWeightGrams Decimal @db.Decimal(14, 4)
|
||||
flatRialCharge Decimal @default(0) @db.Decimal(20, 2)
|
||||
|
||||
proposedByAdminId String? @map("proposedByAdminUserId")
|
||||
note String?
|
||||
|
||||
/// null | ACCEPTED | REJECTED — reject leaves AWAITING_CUSTOMER for admin decision.
|
||||
customerDecision String?
|
||||
customerDecidedAt DateTime?
|
||||
|
||||
appliedAt DateTime?
|
||||
discardedAt DateTime?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([orderId])
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
model OrderItem {
|
||||
id String @id @default(cuid())
|
||||
orderId String
|
||||
|
||||
Reference in New Issue
Block a user