// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" output = "../generated/prisma" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } enum OperatorCode { ORANGE MTN AIRTEL VODACOM MOOV } enum PaymentStatus { PENDING SUCCESS FAILED REFUNDED } enum SubscriptionStatus { PENDING TRIAL ACTIVE SUSPENDED CANCELLED EXPIRED FAILED } model Operator { id String @id @default(cuid()) code OperatorCode name String country String config Json active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt users User[] } model User { id String @id @default(cuid()) msisdn String @unique userToken String @unique userAlias String operatorId String partnerId String country String metadata Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt operator Operator @relation(fields: [operatorId], references: [id]) partner Partner @relation(fields: [partnerId], references: [id]) subscriptions Subscription[] payments Payment[] invoices Invoice[] // Added relation } model Plan { id String @id @default(cuid()) partnerId String code String name String description String? amount Float currency String interval String // DAILY, WEEKLY, MONTHLY, YEARLY intervalCount Int @default(1) trialDays Int @default(0) features Json? // Array of features limits Json? // Object with usage limits metadata Json? active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt partner Partner @relation(fields: [partnerId], references: [id]) subscriptions Subscription[] @@unique([partnerId, code]) @@index([partnerId, active]) } model Invoice { id String @id @default(cuid()) number String @unique subscriptionId String userId String partnerId String paymentId String? @unique amount Float currency String status String // PENDING, PAID, FAILED, CANCELLED billingPeriodStart DateTime billingPeriodEnd DateTime dueDate DateTime paidAt DateTime? items Json // Array of line items attempts Int @default(0) failureReason String? metadata Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt subscription Subscription @relation(fields: [subscriptionId], references: [id]) user User @relation(fields: [userId], references: [id]) partner Partner @relation(fields: [partnerId], references: [id]) payment Payment? @relation(fields: [paymentId], references: [id]) @@index([subscriptionId]) @@index([partnerId, status]) } model Subscription { id String @id @default(cuid()) userId String planId String partnerId String status SubscriptionStatus currentPeriodStart DateTime currentPeriodEnd DateTime nextBillingDate DateTime? trialEndsAt DateTime? cancelledAt DateTime? suspendedAt DateTime? failureCount Int @default(0) renewalCount Int @default(0) lastPaymentId String? metadata Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id]) plan Plan @relation(fields: [planId], references: [id]) partner Partner @relation(fields: [partnerId], references: [id]) payments Payment[] invoices Invoice[] // Added relation } model Payment { id String @id @default(cuid()) userId String partnerId String subscriptionId String? amount Float currency String description String reference String @unique operatorReference String? status PaymentStatus failureReason String? metadata Json? completedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id]) partner Partner @relation(fields: [partnerId], references: [id]) subscription Subscription? @relation(fields: [subscriptionId], references: [id]) refunds Refund[] invoice Invoice? // Added relation } model Refund { id String @id @default(cuid()) paymentId String amount Float reason String? status String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt payment Payment @relation(fields: [paymentId], references: [id]) } model Webhook { id String @id @default(cuid()) url String event String payload Json response Json? status String attempts Int @default(0) lastAttempt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Partner { id String @id @default(cuid()) name String email String @unique passwordHash String apiKey String @unique secretKey String status String @default("PENDING") companyInfo Json? callbacks Json? country String metadata Json? keysRotatedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt users User[] subscriptions Subscription[] payments Payment[] authSessions AuthSession[] plans Plan[] // Added relation invoices Invoice[] // Added relation } model AuthSession { id String @id @default(cuid()) sessionId String @unique partnerId String userId String? msisdn String operator String country String authMethod String challengeId String? status String expiresAt DateTime createdAt DateTime @default(now()) updatedAt DateTime @updatedAt partner Partner @relation(fields: [partnerId], references: [id]) } model Notification { id String @id @default(cuid()) partnerId String userId String? type String // PAYMENT, SUBSCRIPTION, ALERT, MARKETING channel String // SMS, EMAIL, WEBHOOK recipient String subject String? content String templateId String? status String // PENDING, SENT, FAILED batchId String? scheduledFor DateTime? sentAt DateTime? failedAt DateTime? failureReason String? response Json? metadata Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt partner Partner @relation(fields: [partnerId], references: [id]) user User? @relation(fields: [userId], references: [id]) }