Ship loyalty club and form builder so production pull gets the new screens.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-06 13:50:05 +03:30
co-authored by Cursor
parent 175f1fa440
commit 820c0780d8
21 changed files with 3658 additions and 893 deletions
+93 -10
View File
@@ -161,7 +161,11 @@ model Organization {
portalOtps PortalOtp[]
projectBoards ProjectBoard[]
projectCards ProjectCard[]
loyaltyTiers LoyaltyTier[]
loyaltyTiers LoyaltyTier[]
loyaltySettings LoyaltySettings?
loyaltyLedgers LoyaltyLedger[]
loyaltyRewards LoyaltyReward[]
loyaltyRedemptions LoyaltyRedemption[]
automationRules AutomationRule[]
memoryItems MemoryItem[]
noteAiSuggestions NoteAiSuggestion[]
@@ -256,6 +260,8 @@ model Person {
loyaltyPoints Int @default(0)
loyaltyTierId String?
loyaltyTier LoyaltyTier? @relation(fields: [loyaltyTierId], references: [id], onDelete: SetNull)
loyaltyLedgers LoyaltyLedger[]
loyaltyRedemptions LoyaltyRedemption[]
deals Deal[]
activities Activity[]
smartNotes Note[]
@@ -581,6 +587,7 @@ model LeadForm {
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
name String
description String?
publicToken String @unique @default(cuid())
isActive Boolean @default(true)
createPerson Boolean @default(true)
@@ -591,7 +598,11 @@ model LeadForm {
redirectUrl String?
assigneeIds String[] @default([])
roundRobinIndex Int @default(0)
submitLabel String @default("ارسال درخواست")
submitColor String @default("#14b8a6")
coverStorageKey String?
fields LeadFormField[]
submissions LeadFormSubmission[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -599,20 +610,33 @@ model LeadForm {
}
model LeadFormField {
id String @id @default(cuid())
formId String
form LeadForm @relation(fields: [formId], references: [id], onDelete: Cascade)
key String
label String
fieldType String @default("text")
required Boolean @default(false)
mapTo String
position Int @default(0)
id String @id @default(cuid())
formId String
form LeadForm @relation(fields: [formId], references: [id], onDelete: Cascade)
key String
label String
fieldType String @default("text")
required Boolean @default(false)
mapTo String
position Int @default(0)
placeholder String?
options Json?
@@unique([formId, key])
@@index([formId, position])
}
model LeadFormSubmission {
id String @id @default(cuid())
formId String
form LeadForm @relation(fields: [formId], references: [id], onDelete: Cascade)
values Json
personId String?
createdAt DateTime @default(now())
@@index([formId, createdAt])
}
model Quote {
id String @id @default(cuid())
organizationId String
@@ -958,6 +982,65 @@ model LoyaltyTier {
@@index([organizationId, minPoints])
}
model LoyaltySettings {
id String @id @default(cuid())
organizationId String @unique
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
enabled Boolean @default(true)
welcomePoints Int @default(0)
notifyOnAdjust Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model LoyaltyLedger {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
personId String
person Person @relation(fields: [personId], references: [id], onDelete: Cascade)
delta Int
reason String?
source String @default("manual")
createdAt DateTime @default(now())
@@index([organizationId, createdAt])
@@index([personId, createdAt])
}
model LoyaltyReward {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
name String
description String?
pointsCost Int
isActive Boolean @default(true)
position Int @default(0)
color String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
redemptions LoyaltyRedemption[]
@@index([organizationId, position])
}
model LoyaltyRedemption {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
personId String
person Person @relation(fields: [personId], references: [id], onDelete: Cascade)
rewardId String
reward LoyaltyReward @relation(fields: [rewardId], references: [id], onDelete: Restrict)
pointsSpent Int
createdAt DateTime @default(now())
@@index([organizationId, createdAt])
@@index([personId])
@@index([rewardId])
}
model AutomationRule {
id String @id @default(cuid())
organizationId String