generator client { provider = "prisma-client-js" } datasource db { // Local scaffold default: SQLite. For MySQL set provider = "mysql" and DATABASE_URL accordingly. provider = "sqlite" url = env("DATABASE_URL") } enum ProductType { hamkar khanegi } enum UserRole { super_admin viewer } enum SmsLedgerType { charge debit adjust } model User { id String @id @default(cuid()) email String @unique passwordHash String @map("password_hash") name String role UserRole @default(super_admin) isActive Boolean @default(true) @map("is_active") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") auditLogs AuditLog[] @@map("users") } model Tenant { id String @id @default(cuid()) product ProductType slug String @unique nameFa String @map("name_fa") nameEn String? @map("name_en") domain String @unique domains Json? avatarUrl String? @map("avatar_url") primaryColor String? @map("primary_color") secondaryColor String? @map("secondary_color") backgroundColor String? @map("background_color") nodeServer String @map("node_server") nodeWs String? @map("node_ws") appUrl String? @map("app_url") adminUrl String? @map("admin_url") remoteApiToken String? @map("remote_api_token") /// Legacy cache from older sync attempts — SuperAdmin SMS account is now source of truth smsSettingsCache Json? @map("sms_settings_cache") smsSyncedAt DateTime? @map("sms_synced_at") /// Full Khanegi UI JSON (theme, navigation, pages). Hamkar: unused for now. appUiConfig Json? @map("app_ui_config") isActive Boolean @default(true) @map("is_active") notes String? createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") auditLogs AuditLog[] smsAccount SmsAccount? @@index([product]) @@index([isActive]) @@map("tenants") } /// SuperAdmin-owned SMS wallet + gateway config per sold version. /// Does NOT replace Hamkar/Khanegi internal SMS panels yet. model SmsAccount { id String @id @default(cuid()) tenantId String @unique @map("tenant_id") balanceRials Int @default(0) @map("balance_rials") pricePerPartRials Int @default(2500) @map("price_per_part_rials") isBlocked Boolean @default(false) @map("is_blocked") /// below this => red/critical alertCriticalRials Int @default(10000) @map("alert_critical_rials") /// at/below this (and above critical) => yellow; above => green alertWarningRials Int @default(100000) @map("alert_warning_rials") gatewayProvider String? @map("gateway_provider") melipayamakUser String? @map("melipayamak_user") melipayamakPassword String? @map("melipayamak_password") melipayamakFrom String? @map("melipayamak_from") panelUsername String? @map("panel_username") panelPassword String? @map("panel_password") panelFrom String? @map("panel_from") extraSettings Json? @map("extra_settings") todayMessages Int @default(0) @map("today_messages") todayParts Int @default(0) @map("today_parts") todayCostRials Int @default(0) @map("today_cost_rials") monthMessages Int @default(0) @map("month_messages") monthParts Int @default(0) @map("month_parts") monthCostRials Int @default(0) @map("month_cost_rials") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade) ledgers SmsLedger[] @@map("sms_accounts") } model SmsLedger { id String @id @default(cuid()) smsAccountId String @map("sms_account_id") type SmsLedgerType amountRials Int @map("amount_rials") parts Int? note String? createdById String? @map("created_by_id") createdAt DateTime @default(now()) @map("created_at") smsAccount SmsAccount @relation(fields: [smsAccountId], references: [id], onDelete: Cascade) @@index([smsAccountId]) @@index([createdAt]) @@map("sms_ledgers") } model AuditLog { id String @id @default(cuid()) action String entityType String @map("entity_type") entityId String? @map("entity_id") tenantId String? @map("tenant_id") userId String? @map("user_id") before Json? after Json? meta Json? createdAt DateTime @default(now()) @map("created_at") tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: SetNull) user User? @relation(fields: [userId], references: [id], onDelete: SetNull) @@index([tenantId]) @@index([userId]) @@index([createdAt]) @@map("audit_logs") }