385 lines
7.7 KiB
Plaintext
385 lines
7.7 KiB
Plaintext
// This is your Prisma schema file,
|
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
|
|
generator client {
|
|
provider = "prisma-client-js"
|
|
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
// User Management & Authentication
|
|
model User {
|
|
id String @id @default(cuid())
|
|
email String @unique
|
|
username String? @unique
|
|
firstName String?
|
|
lastName String?
|
|
phone String?
|
|
avatar String?
|
|
|
|
// Authentication
|
|
passwordHash String
|
|
isVerified Boolean @default(false)
|
|
isActive Boolean @default(true)
|
|
|
|
// Roles & Permissions
|
|
role UserRole @default(CUSTOMER)
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
lastLoginAt DateTime?
|
|
|
|
// Relations
|
|
addresses Address[]
|
|
orders Order[]
|
|
reviews Review[]
|
|
wishlist WishlistItem[]
|
|
cart CartItem[]
|
|
|
|
orderStatusChanges OrderStatusHistory[]
|
|
|
|
|
|
|
|
@@map("users")
|
|
}
|
|
|
|
enum UserRole {
|
|
CUSTOMER
|
|
ADMIN
|
|
SUPER_ADMIN
|
|
EDITOR
|
|
MODERATOR
|
|
SELLER
|
|
}
|
|
|
|
// Address Management
|
|
model Address {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
type AddressType @default(SHIPPING)
|
|
isDefault Boolean @default(false)
|
|
|
|
// Address Details
|
|
firstName String
|
|
lastName String
|
|
company String?
|
|
addressLine1 String
|
|
addressLine2 String?
|
|
city String
|
|
state String
|
|
postalCode String
|
|
country String
|
|
phone String?
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
orders Order[]
|
|
|
|
@@map("addresses")
|
|
}
|
|
|
|
enum AddressType {
|
|
SHIPPING
|
|
BILLING
|
|
}
|
|
|
|
// Order Management
|
|
model Order {
|
|
id String @id @default(cuid())
|
|
orderNumber String @unique
|
|
userId String
|
|
status OrderStatus @default(PENDING)
|
|
|
|
// Pricing
|
|
subtotal Decimal @db.Decimal(10, 2)
|
|
taxAmount Decimal @db.Decimal(10, 2)
|
|
shippingAmount Decimal @db.Decimal(10, 2)
|
|
discountAmount Decimal @db.Decimal(10, 2) @default(0)
|
|
totalAmount Decimal @db.Decimal(10, 2)
|
|
|
|
// Payment
|
|
paymentStatus PaymentStatus @default(PENDING)
|
|
paymentMethod String?
|
|
paymentId String?
|
|
|
|
// Shipping
|
|
shippingAddressId String
|
|
trackingNumber String?
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
shippedAt DateTime?
|
|
deliveredAt DateTime?
|
|
|
|
// ✅ Add this field
|
|
returnRequestedAt DateTime?
|
|
returnStatus ReturnStatus @default(NONE)
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id])
|
|
address Address @relation(fields: [shippingAddressId], references: [id])
|
|
items OrderItem[]
|
|
|
|
statusHistory OrderStatusHistory[]
|
|
|
|
|
|
|
|
@@map("orders")
|
|
}
|
|
|
|
|
|
model OrderStatusHistory {
|
|
id String @id @default(cuid())
|
|
orderId String
|
|
|
|
fromStatus OrderStatus?
|
|
toStatus OrderStatus
|
|
changedBy String?
|
|
|
|
trackingNumber String?
|
|
notes String?
|
|
ipAddress String?
|
|
userAgent String?
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relations
|
|
order Order @relation(fields: [orderId], references: [id], onDelete: Cascade)
|
|
admin User? @relation(fields: [changedBy], references: [id])
|
|
|
|
@@index([orderId])
|
|
@@index([createdAt])
|
|
@@map("order_status_history")
|
|
}
|
|
|
|
|
|
enum OrderStatus {
|
|
PENDING
|
|
CONFIRMED
|
|
PROCESSING
|
|
SHIPPED
|
|
DELIVERED
|
|
CANCELLED
|
|
REFUNDED
|
|
RETURN_REQUESTED
|
|
}
|
|
|
|
enum PaymentStatus {
|
|
PENDING
|
|
PAID
|
|
FAILED
|
|
REFUNDED
|
|
PARTIALLY_REFUNDED
|
|
}
|
|
|
|
enum ReturnStatus {
|
|
NONE
|
|
REQUESTED
|
|
APPROVED
|
|
REJECTED
|
|
COMPLETED
|
|
}
|
|
|
|
|
|
// Order Items
|
|
model OrderItem {
|
|
id String @id @default(cuid())
|
|
orderId String
|
|
productId String // Reference to MongoDB product
|
|
|
|
// Product Details (snapshot at time of order)
|
|
productName String
|
|
productSku String
|
|
price Decimal @db.Decimal(10, 2)
|
|
quantity Int
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
order Order @relation(fields: [orderId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("order_items")
|
|
}
|
|
|
|
// Reviews & Ratings
|
|
model Review {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
productId String // Reference to MongoDB product
|
|
orderId String? // Optional reference to order
|
|
|
|
rating Int // 1-5 stars
|
|
title String?
|
|
comment String?
|
|
isVerified Boolean @default(false)
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id])
|
|
|
|
@@unique([userId, productId])
|
|
@@map("reviews")
|
|
}
|
|
|
|
// Wishlist Management
|
|
model WishlistItem {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
productId String // Reference to MongoDB product
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, productId])
|
|
@@map("wishlist_items")
|
|
}
|
|
|
|
// Shopping Cart
|
|
model CartItem {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
productId String // Reference to MongoDB product
|
|
quantity Int @default(1)
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, productId])
|
|
@@map("cart_items")
|
|
}
|
|
|
|
// Categories (Reference data)
|
|
// Categories (Reference data)
|
|
model Category {
|
|
id String @id @default(cuid())
|
|
name String // Removed @unique - same name can exist under different parents
|
|
slug String // Removed @unique - will use composite unique instead
|
|
description String?
|
|
image String?
|
|
parentId String?
|
|
isActive Boolean @default(true)
|
|
sequence Int @default(0)
|
|
|
|
// SEO
|
|
metaTitle String?
|
|
metaDescription String?
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
parent Category? @relation("CategoryHierarchy", fields: [parentId], references: [id])
|
|
children Category[] @relation("CategoryHierarchy")
|
|
|
|
// Composite unique constraint: same slug allowed if different parent
|
|
@@unique([slug, parentId], name: "unique_slug_per_parent")
|
|
|
|
@@map("categories")
|
|
}
|
|
|
|
// Coupons & Discounts
|
|
model Coupon {
|
|
id String @id @default(cuid())
|
|
code String @unique
|
|
description String?
|
|
type CouponType
|
|
value Decimal @db.Decimal(10, 2)
|
|
|
|
// Conditions
|
|
minOrderAmount Decimal? @db.Decimal(10, 2)
|
|
maxUses Int?
|
|
usedCount Int @default(0)
|
|
|
|
// Validity
|
|
validFrom DateTime
|
|
validUntil DateTime
|
|
isActive Boolean @default(true)
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@map("coupons")
|
|
}
|
|
|
|
enum CouponType {
|
|
PERCENTAGE
|
|
FIXED_AMOUNT
|
|
FREE_SHIPPING
|
|
}
|
|
|
|
// System Configuration
|
|
model SystemConfig {
|
|
id String @id @default(cuid())
|
|
key String @unique
|
|
value String
|
|
type ConfigType @default(STRING)
|
|
|
|
// Timestamps
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@map("system_config")
|
|
}
|
|
|
|
enum ConfigType {
|
|
STRING
|
|
NUMBER
|
|
BOOLEAN
|
|
JSON
|
|
}
|
|
|
|
|
|
model InventoryLog {
|
|
id String @id @default(cuid())
|
|
|
|
productId String
|
|
productName String
|
|
|
|
type InventoryLogType
|
|
quantityChange Int
|
|
previousStock Int
|
|
newStock Int
|
|
|
|
orderId String?
|
|
adjustedBy String?
|
|
notes String?
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([productId])
|
|
@@index([orderId])
|
|
@@index([type])
|
|
@@map("inventory_logs")
|
|
}
|
|
|
|
enum InventoryLogType {
|
|
SOLD
|
|
RESTOCK
|
|
ADJUSTMENT
|
|
RETURN
|
|
DAMAGED
|
|
} |