Add SMS OTP auth, discounts, customer orders, and category slugs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-05 15:15:10 +03:30
co-authored by Cursor
parent 58380ab81d
commit d09eca8702
48 changed files with 1719 additions and 38 deletions
+51 -2
View File
@@ -49,6 +49,8 @@ model User {
refreshTokens RefreshToken[]
addresses UserAddress[]
orders Order[]
discounts Discount[] @relation("DiscountAssignee")
discountsCreated Discount[] @relation("DiscountCreatedBy")
@@index([role])
@@index([disabled])
@@ -80,6 +82,27 @@ model RefreshToken {
@@index([tokenHash])
}
enum SmsOtpPurpose {
register
login
resetPassword
}
model SmsOtp {
id String @id @default(cuid())
cellNumber String
purpose SmsOtpPurpose
codeHash String
/// Pending registration fields (firstName, lastName, title, passwordHash)
payload Json?
attempts Int @default(0)
expiresAt DateTime
createdAt DateTime @default(now())
@@index([cellNumber, purpose])
@@index([expiresAt])
}
model Flavor {
id String @id @default(cuid())
nameFa String
@@ -94,6 +117,7 @@ model Category {
id String @id @default(cuid())
nameFa String
nameEn String
slug String @unique
parentId String?
parent Category? @relation("CategoryTree", fields: [parentId], references: [id], onDelete: Restrict)
children Category[] @relation("CategoryTree")
@@ -102,6 +126,7 @@ model Category {
updatedAt DateTime @updatedAt
optionBlocks CategoryOptionBlock[]
products Product[]
discounts Discount[]
@@index([parentId])
}
@@ -215,7 +240,9 @@ model Order {
shippingAddressLine String?
shippingLandline String?
note String @default("")
itemCount Int
discountCode String?
discountAmount Int @default(0)
itemCount Float
totalPrice Int
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -234,7 +261,7 @@ model OrderItem {
productId String?
product Product? @relation(fields: [productId], references: [id], onDelete: SetNull)
nameFa String
quantity Int
quantity Float
unitPrice Int
sellUnit SellUnit
sortOrder Int @default(0)
@@ -254,3 +281,25 @@ model OrderItemOption {
@@index([orderItemId])
}
model Discount {
id String @id @default(cuid())
code String @unique
categoryId String?
category Category? @relation(fields: [categoryId], references: [id], onDelete: SetNull)
userId String?
user User? @relation("DiscountAssignee", fields: [userId], references: [id], onDelete: Cascade)
minOrderAmount Int @default(0)
expiresAt DateTime
percent Int
maxValue Int
active Boolean @default(true)
createdByAdminId String?
createdByAdmin User? @relation("DiscountCreatedBy", fields: [createdByAdminId], references: [id], onDelete: SetNull)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId])
@@index([categoryId])
@@index([active, expiresAt])
}