Montify stores integration: multi-store connections, customer/order/transaction sync, webhooks

This commit is contained in:
2026-10-10 15:59:12 +03:30
parent fa3fe0d364
commit e82bd2b2df
18 changed files with 3712 additions and 0 deletions
+142
View File
@@ -201,6 +201,7 @@ model Organization {
webhookEndpoints WebhookEndpoint[]
smsCampaigns SmsCampaign[]
wooCommerceConnections WooCommerceConnection[]
montifyConnections MontifyConnection[]
voipConnections VoipConnection[]
reservationServices ReservationService[]
reservationAppointments ReservationAppointment[]
@@ -2080,6 +2081,147 @@ model WooCommerceOrderLink {
@@index([invoiceId])
}
/// اتصال فروشگاه Montify (هر فروشگاه: Base URL + توکن اختصاصی)
model MontifyConnection {
id String @id @default(cuid())
organizationId String
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
label String
baseUrl String
storeId String @default("")
tokenCiphertext String
tokenIv String
tokenTag String
tokenLast4 String @default("")
enabled Boolean @default(true)
webhookRemoteId String?
webhookSecretCiphertext String?
webhookSecretIv String?
webhookSecretTag String?
/// بیشترین updated_at مشتریان دریافت‌شده (برای updated_after)
customersCursor DateTime?
/// idle | running | ok | error
syncStatus String @default("idle")
syncStartedAt DateTime?
lastSyncAt DateTime?
lastSyncResult Json?
lastHealthAt DateTime?
lastHealthOk Boolean?
lastError String?
lastWebhookAt DateTime?
links MontifyLink[]
orders MontifyOrder[]
transactions MontifyTransaction[]
deliveries MontifyWebhookDelivery[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([organizationId, enabled])
}
/// پیوند مشتری فروشگاه با شخص CRM (entityType = customer، entityId = Person.id)
model MontifyLink {
id String @id @default(cuid())
organizationId String
connectionId String
connection MontifyConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
entityType String
externalId String
entityId String
externalUpdatedAt DateTime?
/// آخرین زمان دریافت سفارش‌های این مشتری (updated_after سفارش‌ها)
ordersSyncedAt DateTime?
/// پروفایل فروشگاهی مشتری: wallet_balance، gold_wallet_balance، summary، engagement، …
data Json?
syncedAt DateTime @default(now())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([connectionId, entityType, externalId])
@@index([organizationId, entityType, entityId])
}
/// سفارش فروشگاه (فقط‌خواندنی، نگاشت مستند: code → order_reference، sts → order_status)
model MontifyOrder {
id String @id @default(cuid())
organizationId String
connectionId String
connection MontifyConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
externalId String
customerExternalId String?
personId String?
orderReference String?
orderStatus String?
paymentStatus String?
paymentType String?
totalPrice Decimal? @db.Decimal(20, 2)
discountTotalPrice Decimal? @db.Decimal(20, 2)
totalDiscounts Decimal? @db.Decimal(20, 2)
totalTax Decimal? @db.Decimal(20, 2)
totalQty Decimal? @db.Decimal(14, 3)
profit Decimal? @db.Decimal(20, 2)
percentProfit Decimal? @db.Decimal(10, 3)
sumGold Decimal? @db.Decimal(14, 3)
sumSilver Decimal? @db.Decimal(14, 3)
address Json?
note String?
cancelReason String?
cancelledAt DateTime?
closedAt DateTime?
codeDiscount String?
items Json @default("[]")
externalCreatedAt DateTime?
externalUpdatedAt DateTime?
deletedAt DateTime?
raw Json?
syncedAt DateTime @default(now())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([connectionId, externalId])
@@index([organizationId, personId])
@@index([organizationId, externalCreatedAt])
}
/// تراکنش مالی مشتری در فروشگاه (واریز/برداشت ریالی یا گرم طلا)
model MontifyTransaction {
id String @id @default(cuid())
organizationId String
connectionId String
connection MontifyConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
externalId String
customerExternalId String?
personId String?
type String?
amount Decimal? @db.Decimal(24, 4)
currency String?
status String?
referenceCode String?
externalCreatedAt DateTime?
raw Json?
syncedAt DateTime @default(now())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([connectionId, externalId])
@@index([organizationId, personId])
}
model MontifyWebhookDelivery {
id String @id @default(cuid())
connectionId String
connection MontifyConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
deliveryId String
event String
/// received | processed | failed
status String @default("received")
error String?
createdAt DateTime @default(now())
@@unique([connectionId, deliveryId])
@@index([connectionId, createdAt])
}
/// اتصال تلفن سازمانی / سانترال (وب‌هوک عمومی)
model VoipConnection {
id String @id @default(cuid())