generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

enum UserStatus {
  invited
  active
  inactive
  suspended
}

model User {
  id                 String      @id @default(uuid())
  name               String
  email              String      @unique
  passwordHash       String?     @map("password_hash")
  refreshTokenHash   String?     @map("refresh_token_hash")
  refreshTokenExpiresAt DateTime? @map("refresh_token_expires_at")
  sessionVersion     Int         @default(0) @map("session_version")
  status             UserStatus  @default(invited)
  roleId             String?     @map("role_id")
  inviteTokenHash    String?     @map("invite_token_hash")
  inviteTokenExpiresAt DateTime? @map("invite_token_expires_at")
  passwordResetTokenHash String? @map("password_reset_token_hash")
  passwordResetTokenExpiresAt DateTime? @map("password_reset_token_expires_at")
  twoFactorEnabled   Boolean     @default(false) @map("two_factor_enabled")
  twoFactorSecretEncrypted String? @map("two_factor_secret_encrypted")
  twoFactorPendingSecretEncrypted String? @map("two_factor_pending_secret_encrypted")
  twoFactorRecoveryCodesHashJson Json? @map("two_factor_recovery_codes_hash_json")
  twoFactorConfirmedAt DateTime? @map("two_factor_confirmed_at")
  emailVerifiedAt    DateTime?   @map("email_verified_at")
  lastLoginAt        DateTime?   @map("last_login_at")
  createdAt          DateTime    @default(now()) @map("created_at")
  updatedAt          DateTime    @updatedAt @map("updated_at")
  role               Role?       @relation(fields: [roleId], references: [id])

  @@index([passwordResetTokenHash])
  @@map("users")
}

model Role {
  id              String   @id @default(uuid())
  key             String   @unique
  name            String
  summary         String
  badge           String
  tone            String
  icon            String
  permissionsJson Json     @map("permissions_json")
  createdAt       DateTime @default(now()) @map("created_at")
  updatedAt       DateTime @updatedAt @map("updated_at")
  users           User[]

  @@map("roles")
}

model Contact {
  id            String   @id @default(uuid())
  name          String
  phoneNumber   String   @unique @map("phone_number")
  email         String?
  company       String?
  notes         String?
  isBlacklisted Boolean  @default(false) @map("is_blacklisted")
  assignedUserId String? @map("assigned_user_id")
  assignedUserName String? @map("assigned_user_name")
  assignedAt    DateTime? @map("assigned_at")
  createdAt     DateTime @default(now()) @map("created_at")
  updatedAt     DateTime @updatedAt @map("updated_at")
  conversationMessages ConversationMessage[]

  @@map("contacts")
}

model ConversationMessage {
  id                String   @id @default(uuid())
  contactId         String   @map("contact_id")
  direction         String
  messageType       String   @default("text") @map("message_type")
  source            String   @default("agent")
  body              String
  status            String   @default("sent")
  senderUserId      String?  @map("sender_user_id")
  senderName        String?  @map("sender_name")
  externalMessageId String?  @map("external_message_id")
  webhookEventId    String?  @unique @map("webhook_event_id")
  occurredAt        DateTime @default(now()) @map("occurred_at")
  readAt            DateTime? @map("read_at")
  createdAt         DateTime @default(now()) @map("created_at")
  updatedAt         DateTime @updatedAt @map("updated_at")
  contact           Contact  @relation(fields: [contactId], references: [id], onDelete: Cascade)

  @@index([contactId, occurredAt])
  @@map("conversation_messages")
}

model WebhookEvent {
  id                String   @id @default(uuid())
  provider          String
  eventId           String   @unique @map("event_id")
  eventType         String   @map("event_type")
  senderPhone       String?  @map("sender_phone")
  recipientPhone    String?  @map("recipient_phone")
  externalMessageId String?  @map("external_message_id")
  eventTimestamp    DateTime @map("event_timestamp")
  payloadJson       Json     @map("payload_json")
  verified          Boolean  @default(false)
  processingStatus  String   @default("received") @map("processing_status")
  processingNotes   String?  @map("processing_notes")
  createdAt         DateTime @default(now()) @map("created_at")
  updatedAt         DateTime @updatedAt @map("updated_at")

  @@map("webhook_events")
}

model IntegrationConfig {
  id         String   @id @default(uuid())
  configKey  String   @unique @map("config_key")
  provider   String
  isEnabled  Boolean  @default(true) @map("is_enabled")
  configJson Json     @map("config_json")
  createdAt  DateTime @default(now()) @map("created_at")
  updatedAt  DateTime @updatedAt @map("updated_at")

  @@map("integration_configs")
}

model Job {
  id           String    @id @default(uuid())
  queueName    String    @map("queue_name")
  jobType      String    @map("job_type")
  status       String    @default("queued")
  payloadJson  Json      @map("payload_json")
  attempts     Int       @default(0)
  maxAttempts  Int       @default(3) @map("max_attempts")
  availableAt  DateTime  @default(now()) @map("available_at")
  processedAt  DateTime? @map("processed_at")
  failedAt     DateTime? @map("failed_at")
  errorMessage String?   @map("error_message")
  createdAt    DateTime  @default(now()) @map("created_at")
  updatedAt    DateTime  @updatedAt @map("updated_at")

  @@index([queueName, status, availableAt])
  @@map("jobs")
}

model AuditLog {
  id          String   @id @default(uuid())
  actorUserId String?  @map("actor_user_id")
  actorName   String   @map("actor_name")
  actorEmail  String?  @map("actor_email")
  actionType  String   @map("action_type")
  module      String
  ipAddress   String?  @map("ip_address")
  severity    String   @default("default")
  details     String
  metadataJson Json?   @map("metadata_json")
  createdAt   DateTime @default(now()) @map("created_at")

  @@index([createdAt])
  @@index([actorName])
  @@index([actionType])
  @@index([module])
  @@map("audit_logs")
}

model MessageTemplate {
  id          String   @id @default(uuid())
  name        String   @unique
  category    String
  status      String
  language    String
  headerText  String?  @map("header_text")
  bodyText    String   @map("body_text")
  footerText  String?  @map("footer_text")
  buttonsJson Json?    @map("buttons_json")
  createdAt   DateTime @default(now()) @map("created_at")
  updatedAt   DateTime @updatedAt @map("updated_at")

  @@index([status, category, language])
  @@map("message_templates")
}

model Campaign {
  id              String              @id @default(uuid())
  code            String              @unique
  name            String
  audienceLabel   String              @map("audience_label")
  audienceGroup   String              @map("audience_group")
  status          String
  totalRecipients Int                 @default(0) @map("total_recipients")
  deliveredCount  Int                 @default(0) @map("delivered_count")
  readCount       Int                 @default(0) @map("read_count")
  failedCount     Int                 @default(0) @map("failed_count")
  deliveryRate    Float?              @map("delivery_rate")
  readRate        Float?              @map("read_rate")
  sentAt          DateTime?           @map("sent_at")
  scheduledAt     DateTime?           @map("scheduled_at")
  templateName    String?             @map("template_name")
  language        String?
  messageTitle    String?             @map("message_title")
  messageBody     String?             @map("message_body")
  primaryButton   String?             @map("primary_button")
  secondaryButton String?             @map("secondary_button")
  bannerImageUrl  String?             @map("banner_image_url")
  createdAt       DateTime            @default(now()) @map("created_at")
  updatedAt       DateTime            @updatedAt @map("updated_at")
  recipients      CampaignRecipient[]

  @@map("campaigns")
}

model CampaignRecipient {
  id          String    @id @default(uuid())
  campaignId  String    @map("campaign_id")
  phoneNumber String    @map("phone_number")
  status      String
  sentAt      DateTime? @map("sent_at")
  errorReason String?   @map("error_reason")
  deviceOs    String?   @map("device_os")
  createdAt   DateTime  @default(now()) @map("created_at")
  updatedAt   DateTime  @updatedAt @map("updated_at")
  campaign    Campaign  @relation(fields: [campaignId], references: [id], onDelete: Cascade)

  @@index([campaignId, status])
  @@index([campaignId, sentAt])
  @@map("campaign_recipients")
}

model Wallet {
  id           String              @id @default(uuid())
  ownerKey     String              @unique @map("owner_key")
  currency     String              @default("IDR")
  balanceMinor Int                 @default(0) @map("balance_minor")
  heldMinor    Int                 @default(0) @map("held_minor")
  status       String              @default("active")
  createdAt    DateTime            @default(now()) @map("created_at")
  updatedAt    DateTime            @updatedAt @map("updated_at")
  transactions WalletTransaction[]
  paymentOrders PaymentOrder[]

  @@map("wallets")
}

model WalletTransaction {
  id                 String   @id @default(uuid())
  walletId           String   @map("wallet_id")
  type               String
  direction          String
  amountMinor        Int      @map("amount_minor")
  balanceBeforeMinor Int      @map("balance_before_minor")
  balanceAfterMinor  Int      @map("balance_after_minor")
  status             String   @default("posted")
  referenceType      String?  @map("reference_type")
  referenceId        String?  @map("reference_id")
  description        String?
  metadataJson       Json?    @map("metadata_json")
  createdAt          DateTime @default(now()) @map("created_at")
  wallet             Wallet   @relation(fields: [walletId], references: [id], onDelete: Cascade)

  @@index([walletId, createdAt])
  @@index([referenceType, referenceId])
  @@map("wallet_transactions")
}

model PaymentOrder {
  id              String    @id @default(uuid())
  walletId        String    @map("wallet_id")
  provider        String    @default("midtrans")
  providerOrderId String    @unique @map("provider_order_id")
  amountMinor     Int       @map("amount_minor")
  currency        String    @default("IDR")
  status          String    @default("pending")
  snapToken       String?   @map("snap_token")
  redirectUrl     String?   @map("redirect_url")
  paidAt          DateTime? @map("paid_at")
  expiredAt       DateTime? @map("expired_at")
  metadataJson    Json?     @map("metadata_json")
  createdAt       DateTime  @default(now()) @map("created_at")
  updatedAt       DateTime  @updatedAt @map("updated_at")
  wallet          Wallet    @relation(fields: [walletId], references: [id], onDelete: Cascade)

  @@index([walletId, status])
  @@map("payment_orders")
}
