Files
eCommerce-backend/prisma/schema.prisma
2026-02-19 17:25:38 +05:30

384 lines
8.0 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"
}
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
}