@varaos/db 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@varaos/db",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "private": false,
5
5
  "main": "index.js",
6
6
  "files": [
@@ -0,0 +1,273 @@
1
+ /*
2
+ Warnings:
3
+
4
+ - You are about to drop the column `processed` on the `BillingEvent` table. All the data in the column will be lost.
5
+ - You are about to drop the column `razorpayInvoiceId` on the `Invoice` table. All the data in the column will be lost.
6
+ - The `status` column on the `Job` table would be dropped and recreated. This will lead to data loss if there is data in the column.
7
+ - You are about to drop the column `razorpayCustomerId` on the `Subscription` table. All the data in the column will be lost.
8
+ - You are about to drop the column `razorpayPlanId` on the `Subscription` table. All the data in the column will be lost.
9
+ - You are about to drop the column `razorpaySubscriptionId` on the `Subscription` table. All the data in the column will be lost.
10
+ - A unique constraint covering the columns `[provider,eventId]` on the table `BillingEvent` will be added. If there are existing duplicate values, this will fail.
11
+ - A unique constraint covering the columns `[provider,providerInvoiceId]` on the table `Invoice` will be added. If there are existing duplicate values, this will fail.
12
+ - A unique constraint covering the columns `[provider,providerPaymentMethodId]` on the table `PaymentMethod` will be added. If there are existing duplicate values, this will fail.
13
+ - A unique constraint covering the columns `[providerSubscriptionId]` on the table `Subscription` will be added. If there are existing duplicate values, this will fail.
14
+ - Changed the type of `provider` on the `BillingEvent` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
15
+ - Added the required column `billingCustomerId` to the `Invoice` table without a default value. This is not possible if the table is not empty.
16
+ - Added the required column `provider` to the `Invoice` table without a default value. This is not possible if the table is not empty.
17
+ - Added the required column `providerInvoiceId` to the `Invoice` table without a default value. This is not possible if the table is not empty.
18
+ - Changed the type of `status` on the `Invoice` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
19
+ - Added the required column `billingCustomerId` to the `PaymentMethod` table without a default value. This is not possible if the table is not empty.
20
+ - Added the required column `providerPaymentMethodId` to the `PaymentMethod` table without a default value. This is not possible if the table is not empty.
21
+ - Changed the type of `provider` on the `PaymentMethod` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
22
+ - Changed the type of `type` on the `PaymentMethod` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
23
+ - Added the required column `billingCustomerId` to the `Subscription` table without a default value. This is not possible if the table is not empty.
24
+ - Added the required column `provider` to the `Subscription` table without a default value. This is not possible if the table is not empty.
25
+ - Added the required column `providerSubscriptionId` to the `Subscription` table without a default value. This is not possible if the table is not empty.
26
+
27
+ */
28
+ -- CreateEnum
29
+ CREATE TYPE "public"."BillingProvider" AS ENUM ('razorpay', 'stripe', 'juspay');
30
+
31
+ -- CreateEnum
32
+ CREATE TYPE "public"."SubscriptionEventType" AS ENUM ('created', 'activated', 'trial_started', 'trial_ended', 'charged', 'payment_failed', 'payment_recovered', 'paused', 'resumed', 'plan_changed', 'quantity_changed', 'canceled', 'completed', 'expired', 'refunded');
33
+
34
+ -- CreateEnum
35
+ CREATE TYPE "public"."InvoiceStatus" AS ENUM ('draft', 'open', 'paid', 'partially_paid', 'failed', 'void', 'refunded');
36
+
37
+ -- CreateEnum
38
+ CREATE TYPE "public"."PaymentMethodType" AS ENUM ('card', 'upi', 'bank', 'wallet');
39
+
40
+ -- CreateEnum
41
+ CREATE TYPE "public"."PaymentMethodStatus" AS ENUM ('active', 'inactive', 'expired', 'revoked');
42
+
43
+ -- CreateEnum
44
+ CREATE TYPE "public"."BillingEventStatus" AS ENUM ('received', 'processing', 'processed', 'failed');
45
+
46
+ -- CreateEnum
47
+ CREATE TYPE "public"."BillingLedgerEntryType" AS ENUM ('charge', 'refund', 'credit', 'debit', 'adjustment');
48
+
49
+ -- CreateEnum
50
+ CREATE TYPE "public"."BillingLedgerDirection" AS ENUM ('debit', 'credit');
51
+
52
+ -- CreateEnum
53
+ CREATE TYPE "public"."JobStatus" AS ENUM ('pending', 'scheduled', 'running', 'completed', 'failed', 'dead');
54
+
55
+ -- CreateEnum
56
+ CREATE TYPE "public"."CouponDiscountType" AS ENUM ('percentage', 'flat');
57
+
58
+ -- CreateEnum
59
+ CREATE TYPE "public"."CouponRedemptionScope" AS ENUM ('subscription', 'invoice', 'one_time');
60
+
61
+ -- DropIndex
62
+ DROP INDEX "public"."BillingEvent_eventId_key";
63
+
64
+ -- DropIndex
65
+ DROP INDEX "public"."Subscription_razorpayCustomerId_idx";
66
+
67
+ -- DropIndex
68
+ DROP INDEX "public"."Subscription_razorpaySubscriptionId_idx";
69
+
70
+ -- DropIndex
71
+ DROP INDEX "public"."Subscription_razorpaySubscriptionId_key";
72
+
73
+ -- AlterTable
74
+ ALTER TABLE "public"."BillingEvent" DROP COLUMN "processed",
75
+ ADD COLUMN "status" "public"."BillingEventStatus" NOT NULL DEFAULT 'received',
76
+ DROP COLUMN "provider",
77
+ ADD COLUMN "provider" "public"."BillingProvider" NOT NULL;
78
+
79
+ -- AlterTable
80
+ ALTER TABLE "public"."Invoice" DROP COLUMN "razorpayInvoiceId",
81
+ ADD COLUMN "billingCustomerId" TEXT NOT NULL,
82
+ ADD COLUMN "hostedInvoiceUrl" TEXT,
83
+ ADD COLUMN "provider" "public"."BillingProvider" NOT NULL,
84
+ ADD COLUMN "providerInvoiceId" TEXT NOT NULL,
85
+ DROP COLUMN "status",
86
+ ADD COLUMN "status" "public"."InvoiceStatus" NOT NULL,
87
+ ALTER COLUMN "periodStart" DROP NOT NULL,
88
+ ALTER COLUMN "periodEnd" DROP NOT NULL;
89
+
90
+ -- AlterTable
91
+ ALTER TABLE "public"."Job" DROP COLUMN "status",
92
+ ADD COLUMN "status" "public"."JobStatus" NOT NULL DEFAULT 'pending';
93
+
94
+ -- AlterTable
95
+ ALTER TABLE "public"."PaymentMethod" ADD COLUMN "billingCustomerId" TEXT NOT NULL,
96
+ ADD COLUMN "providerPaymentMethodId" TEXT NOT NULL,
97
+ ADD COLUMN "status" "public"."PaymentMethodStatus" NOT NULL DEFAULT 'active',
98
+ DROP COLUMN "provider",
99
+ ADD COLUMN "provider" "public"."BillingProvider" NOT NULL,
100
+ DROP COLUMN "type",
101
+ ADD COLUMN "type" "public"."PaymentMethodType" NOT NULL,
102
+ ALTER COLUMN "isDefault" SET DEFAULT false;
103
+
104
+ -- AlterTable
105
+ ALTER TABLE "public"."Subscription" DROP COLUMN "razorpayCustomerId",
106
+ DROP COLUMN "razorpayPlanId",
107
+ DROP COLUMN "razorpaySubscriptionId",
108
+ ADD COLUMN "billingCustomerId" TEXT NOT NULL,
109
+ ADD COLUMN "provider" "public"."BillingProvider" NOT NULL,
110
+ ADD COLUMN "providerPlanId" TEXT,
111
+ ADD COLUMN "providerSubscriptionId" TEXT NOT NULL;
112
+
113
+ -- CreateTable
114
+ CREATE TABLE "public"."BillingCustomer" (
115
+ "id" TEXT NOT NULL,
116
+ "userId" TEXT NOT NULL,
117
+ "provider" "public"."BillingProvider" NOT NULL,
118
+ "providerCustomerId" TEXT NOT NULL,
119
+ "email" TEXT,
120
+ "metadata" JSONB,
121
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
122
+ "updatedAt" TIMESTAMP(3) NOT NULL,
123
+
124
+ CONSTRAINT "BillingCustomer_pkey" PRIMARY KEY ("id")
125
+ );
126
+
127
+ -- CreateTable
128
+ CREATE TABLE "public"."SubscriptionEvent" (
129
+ "id" TEXT NOT NULL,
130
+ "subscriptionId" TEXT NOT NULL,
131
+ "provider" "public"."BillingProvider" NOT NULL,
132
+ "eventType" "public"."SubscriptionEventType" NOT NULL,
133
+ "payload" JSONB NOT NULL,
134
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
135
+
136
+ CONSTRAINT "SubscriptionEvent_pkey" PRIMARY KEY ("id")
137
+ );
138
+
139
+ -- CreateTable
140
+ CREATE TABLE "public"."BillingLedger" (
141
+ "id" TEXT NOT NULL,
142
+ "userId" TEXT NOT NULL,
143
+ "billingCustomerId" TEXT NOT NULL,
144
+ "provider" "public"."BillingProvider" NOT NULL,
145
+ "entryType" "public"."BillingLedgerEntryType" NOT NULL,
146
+ "direction" "public"."BillingLedgerDirection" NOT NULL,
147
+ "amount" INTEGER NOT NULL,
148
+ "currency" TEXT NOT NULL,
149
+ "referenceType" TEXT NOT NULL,
150
+ "referenceId" TEXT NOT NULL,
151
+ "description" TEXT,
152
+ "metadata" JSONB,
153
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
154
+
155
+ CONSTRAINT "BillingLedger_pkey" PRIMARY KEY ("id")
156
+ );
157
+
158
+ -- CreateTable
159
+ CREATE TABLE "public"."Coupon" (
160
+ "id" TEXT NOT NULL,
161
+ "code" TEXT NOT NULL,
162
+ "discountType" "public"."CouponDiscountType" NOT NULL,
163
+ "discountValue" INTEGER NOT NULL,
164
+ "currency" TEXT,
165
+ "maxRedemptions" INTEGER,
166
+ "redeemedCount" INTEGER NOT NULL DEFAULT 0,
167
+ "validFrom" TIMESTAMP(3),
168
+ "validUntil" TIMESTAMP(3),
169
+ "applicablePlans" "public"."Plan"[],
170
+ "redemptionScope" "public"."CouponRedemptionScope" NOT NULL,
171
+ "active" BOOLEAN NOT NULL DEFAULT true,
172
+ "metadata" JSONB,
173
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
174
+ "updatedAt" TIMESTAMP(3) NOT NULL,
175
+
176
+ CONSTRAINT "Coupon_pkey" PRIMARY KEY ("id")
177
+ );
178
+
179
+ -- CreateTable
180
+ CREATE TABLE "public"."RevenueAggregate" (
181
+ "id" TEXT NOT NULL,
182
+ "period" TEXT NOT NULL,
183
+ "provider" "public"."BillingProvider" NOT NULL,
184
+ "grossRevenue" INTEGER NOT NULL,
185
+ "refunds" INTEGER NOT NULL,
186
+ "credits" INTEGER NOT NULL,
187
+ "netRevenue" INTEGER NOT NULL,
188
+ "currency" TEXT NOT NULL,
189
+ "updatedAt" TIMESTAMP(3) NOT NULL,
190
+
191
+ CONSTRAINT "RevenueAggregate_pkey" PRIMARY KEY ("id")
192
+ );
193
+
194
+ -- CreateIndex
195
+ CREATE INDEX "BillingCustomer_providerCustomerId_idx" ON "public"."BillingCustomer"("providerCustomerId");
196
+
197
+ -- CreateIndex
198
+ CREATE UNIQUE INDEX "BillingCustomer_provider_providerCustomerId_key" ON "public"."BillingCustomer"("provider", "providerCustomerId");
199
+
200
+ -- CreateIndex
201
+ CREATE UNIQUE INDEX "BillingCustomer_userId_provider_key" ON "public"."BillingCustomer"("userId", "provider");
202
+
203
+ -- CreateIndex
204
+ CREATE INDEX "SubscriptionEvent_subscriptionId_createdAt_idx" ON "public"."SubscriptionEvent"("subscriptionId", "createdAt");
205
+
206
+ -- CreateIndex
207
+ CREATE INDEX "BillingLedger_userId_createdAt_idx" ON "public"."BillingLedger"("userId", "createdAt");
208
+
209
+ -- CreateIndex
210
+ CREATE INDEX "BillingLedger_billingCustomerId_createdAt_idx" ON "public"."BillingLedger"("billingCustomerId", "createdAt");
211
+
212
+ -- CreateIndex
213
+ CREATE INDEX "BillingLedger_provider_createdAt_idx" ON "public"."BillingLedger"("provider", "createdAt");
214
+
215
+ -- CreateIndex
216
+ CREATE UNIQUE INDEX "Coupon_code_key" ON "public"."Coupon"("code");
217
+
218
+ -- CreateIndex
219
+ CREATE INDEX "RevenueAggregate_period_idx" ON "public"."RevenueAggregate"("period");
220
+
221
+ -- CreateIndex
222
+ CREATE UNIQUE INDEX "RevenueAggregate_period_provider_currency_key" ON "public"."RevenueAggregate"("period", "provider", "currency");
223
+
224
+ -- CreateIndex
225
+ CREATE INDEX "BillingEvent_provider_eventType_idx" ON "public"."BillingEvent"("provider", "eventType");
226
+
227
+ -- CreateIndex
228
+ CREATE UNIQUE INDEX "BillingEvent_provider_eventId_key" ON "public"."BillingEvent"("provider", "eventId");
229
+
230
+ -- CreateIndex
231
+ CREATE INDEX "Invoice_billingCustomerId_idx" ON "public"."Invoice"("billingCustomerId");
232
+
233
+ -- CreateIndex
234
+ CREATE UNIQUE INDEX "Invoice_provider_providerInvoiceId_key" ON "public"."Invoice"("provider", "providerInvoiceId");
235
+
236
+ -- CreateIndex
237
+ CREATE INDEX "PaymentMethod_billingCustomerId_idx" ON "public"."PaymentMethod"("billingCustomerId");
238
+
239
+ -- CreateIndex
240
+ CREATE UNIQUE INDEX "PaymentMethod_provider_providerPaymentMethodId_key" ON "public"."PaymentMethod"("provider", "providerPaymentMethodId");
241
+
242
+ -- CreateIndex
243
+ CREATE UNIQUE INDEX "Subscription_providerSubscriptionId_key" ON "public"."Subscription"("providerSubscriptionId");
244
+
245
+ -- CreateIndex
246
+ CREATE INDEX "Subscription_provider_providerSubscriptionId_idx" ON "public"."Subscription"("provider", "providerSubscriptionId");
247
+
248
+ -- CreateIndex
249
+ CREATE INDEX "Subscription_billingCustomerId_idx" ON "public"."Subscription"("billingCustomerId");
250
+
251
+ -- AddForeignKey
252
+ ALTER TABLE "public"."Subscription" ADD CONSTRAINT "Subscription_billingCustomerId_fkey" FOREIGN KEY ("billingCustomerId") REFERENCES "public"."BillingCustomer"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
253
+
254
+ -- AddForeignKey
255
+ ALTER TABLE "public"."Invoice" ADD CONSTRAINT "Invoice_subscriptionId_fkey" FOREIGN KEY ("subscriptionId") REFERENCES "public"."Subscription"("id") ON DELETE SET NULL ON UPDATE CASCADE;
256
+
257
+ -- AddForeignKey
258
+ ALTER TABLE "public"."Invoice" ADD CONSTRAINT "Invoice_billingCustomerId_fkey" FOREIGN KEY ("billingCustomerId") REFERENCES "public"."BillingCustomer"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
259
+
260
+ -- AddForeignKey
261
+ ALTER TABLE "public"."PaymentMethod" ADD CONSTRAINT "PaymentMethod_billingCustomerId_fkey" FOREIGN KEY ("billingCustomerId") REFERENCES "public"."BillingCustomer"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
262
+
263
+ -- AddForeignKey
264
+ ALTER TABLE "public"."BillingCustomer" ADD CONSTRAINT "BillingCustomer_userId_fkey" FOREIGN KEY ("userId") REFERENCES "public"."User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
265
+
266
+ -- AddForeignKey
267
+ ALTER TABLE "public"."SubscriptionEvent" ADD CONSTRAINT "SubscriptionEvent_subscriptionId_fkey" FOREIGN KEY ("subscriptionId") REFERENCES "public"."Subscription"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
268
+
269
+ -- AddForeignKey
270
+ ALTER TABLE "public"."BillingLedger" ADD CONSTRAINT "BillingLedger_userId_fkey" FOREIGN KEY ("userId") REFERENCES "public"."User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
271
+
272
+ -- AddForeignKey
273
+ ALTER TABLE "public"."BillingLedger" ADD CONSTRAINT "BillingLedger_billingCustomerId_fkey" FOREIGN KEY ("billingCustomerId") REFERENCES "public"."BillingCustomer"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@@ -0,0 +1,2 @@
1
+ -- AlterEnum
2
+ ALTER TYPE "public"."SubscriptionStatus" ADD VALUE 'created';
@@ -83,6 +83,7 @@ enum TwoFactorMethod {
83
83
  }
84
84
 
85
85
  enum SubscriptionStatus {
86
+ created // intent created, payment pending
86
87
  active
87
88
  trialing
88
89
  past_due
@@ -90,6 +91,7 @@ enum SubscriptionStatus {
90
91
  paused
91
92
  }
92
93
 
94
+
93
95
  enum WorkflowStatus {
94
96
  draft
95
97
  active
@@ -119,6 +121,99 @@ enum WorkflowStepRunStatus {
119
121
  skipped
120
122
  }
121
123
 
124
+ enum BillingProvider {
125
+ razorpay
126
+ stripe
127
+ juspay
128
+ }
129
+
130
+ enum SubscriptionEventType {
131
+ created // Subscription object created (before activation)
132
+ activated // First successful activation
133
+ trial_started // Trial period started
134
+ trial_ended // Trial expired or converted
135
+
136
+ charged // Successful recurring or first charge
137
+ payment_failed // Charge attempt failed
138
+ payment_recovered // Previously failed payment later succeeded
139
+
140
+ paused // Subscription paused (manual or system)
141
+ resumed // Subscription resumed after pause
142
+
143
+ plan_changed // Upgrade / downgrade
144
+ quantity_changed // Seats / units changed (enterprise)
145
+
146
+ canceled // User or system initiated cancellation
147
+ completed // Subscription ran its full course
148
+ expired // Ended due to non-payment / mandate expiry
149
+
150
+ refunded // Full or partial refund issued
151
+ }
152
+
153
+ enum InvoiceStatus {
154
+ draft
155
+ open
156
+ paid
157
+ partially_paid
158
+ failed
159
+ void
160
+ refunded
161
+ }
162
+
163
+ enum PaymentMethodType {
164
+ card
165
+ upi
166
+ bank
167
+ wallet
168
+ }
169
+
170
+ enum PaymentMethodStatus {
171
+ active
172
+ inactive
173
+ expired
174
+ revoked
175
+ }
176
+
177
+ enum BillingEventStatus {
178
+ received
179
+ processing
180
+ processed
181
+ failed
182
+ }
183
+
184
+ enum BillingLedgerEntryType {
185
+ charge
186
+ refund
187
+ credit
188
+ debit
189
+ adjustment
190
+ }
191
+
192
+ enum BillingLedgerDirection {
193
+ debit
194
+ credit
195
+ }
196
+
197
+ enum JobStatus {
198
+ pending
199
+ scheduled
200
+ running
201
+ completed
202
+ failed
203
+ dead
204
+ }
205
+
206
+ enum CouponDiscountType {
207
+ percentage
208
+ flat
209
+ }
210
+
211
+ enum CouponRedemptionScope {
212
+ subscription
213
+ invoice
214
+ one_time
215
+ }
216
+
122
217
  /// ─────────────────────────────────────────────
123
218
  /// USERS & AUTH
124
219
  /// ─────────────────────────────────────────────
@@ -176,14 +271,16 @@ model User {
176
271
  Onboarding Onboarding?
177
272
  ChatSession ChatSession[]
178
273
 
179
- createdAt DateTime @default(now())
180
- updatedAt DateTime @updatedAt
181
- posts Post[]
182
- userSessions UserSession[]
183
- paymentMethods PaymentMethod[]
184
- userEmails UserEmail[]
185
- invoices Invoice[]
186
- userFiles UserFile[]
274
+ createdAt DateTime @default(now())
275
+ updatedAt DateTime @updatedAt
276
+ posts Post[]
277
+ userSessions UserSession[]
278
+ paymentMethods PaymentMethod[]
279
+ userEmails UserEmail[]
280
+ invoices Invoice[]
281
+ userFiles UserFile[]
282
+ billingCustomers BillingCustomer[]
283
+ billingLedgers BillingLedger[]
187
284
 
188
285
  @@index([status])
189
286
  }
@@ -725,85 +822,232 @@ model SecurityEvent {
725
822
  /// ─────────────────────────────────────────────
726
823
 
727
824
  model Subscription {
728
- id String @id @default(uuid())
825
+ id String @id @default(uuid())
826
+
729
827
  userId String
730
828
  plan Plan
731
- status SubscriptionStatus // active | trialing | past_due | canceled
829
+ status SubscriptionStatus
732
830
 
733
- // ── Lifecycle (rarely changes)
831
+ provider BillingProvider // razorpay | stripe | juspay
832
+ providerSubscriptionId String @unique
833
+ providerPlanId String?
834
+
835
+ billingCustomerId String
836
+
837
+ // Lifecycle
734
838
  startedAt DateTime
735
839
  endedAt DateTime?
736
840
 
737
- // ── Billing cycle (changes every invoice)
841
+ // Billing cycle
738
842
  currentPeriodStart DateTime?
739
843
  currentPeriodEnd DateTime?
740
-
741
- // ── Provider scheduling (informational only)
742
- nextPayment DateTime?
743
-
744
- razorpayCustomerId String?
745
- razorpaySubscriptionId String? @unique
746
- razorpayPlanId String?
844
+ nextPayment DateTime?
747
845
 
748
846
  metadata Json?
749
847
 
750
- user User @relation(fields: [userId], references: [id])
848
+ user User @relation(fields: [userId], references: [id])
849
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
850
+ invoices Invoice[]
851
+ subscriptionEvents SubscriptionEvent[]
751
852
 
752
- @@index([razorpayCustomerId])
753
- @@index([razorpaySubscriptionId])
853
+ @@index([provider, providerSubscriptionId])
854
+ @@index([billingCustomerId])
754
855
  }
755
856
 
756
857
  model Invoice {
757
- id String @id @default(uuid())
858
+ id String @id @default(uuid())
859
+
758
860
  userId String
759
861
  subscriptionId String?
760
- razorpayInvoiceId String
761
- amount Int
762
- currency String
763
- status String // paid | open | failed | refunded
764
- periodStart DateTime
765
- periodEnd DateTime
766
- pdfUrl String?
767
- metadata Json?
862
+ billingCustomerId String
863
+
864
+ provider BillingProvider // razorpay | stripe | juspay
865
+ providerInvoiceId String
866
+
867
+ amount Int
868
+ currency String
869
+ status InvoiceStatus
870
+
871
+ periodStart DateTime?
872
+ periodEnd DateTime?
873
+
874
+ hostedInvoiceUrl String?
875
+ pdfUrl String?
876
+
877
+ metadata Json?
768
878
 
769
879
  createdAt DateTime @default(now())
770
880
 
771
- user User @relation(fields: [userId], references: [id])
881
+ user User @relation(fields: [userId], references: [id])
882
+ subscription Subscription? @relation(fields: [subscriptionId], references: [id])
883
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
884
+
885
+ @@unique([provider, providerInvoiceId])
886
+ @@index([billingCustomerId])
772
887
  }
773
888
 
774
889
  model BillingEvent {
775
- id String @id @default(uuid())
776
- provider String // razorpay
890
+ id String @id @default(uuid())
777
891
 
892
+ provider BillingProvider // razorpay | stripe | juspay
778
893
  eventType String
779
- eventId String @unique // razorpay event ID
894
+ eventId String
780
895
 
781
- payload Json
782
- processed Boolean @default(false)
896
+ payload Json
897
+
898
+ status BillingEventStatus @default(received)
783
899
  processedAt DateTime?
784
900
  error String?
785
901
 
786
902
  createdAt DateTime @default(now())
787
903
 
904
+ @@unique([provider, eventId])
788
905
  @@index([provider, eventType])
789
906
  }
790
907
 
791
908
  model PaymentMethod {
792
- id String @id @default(uuid())
793
- userId String
794
- provider String // razorpay | stripe | paypal
795
- type String // card
796
- brand String?
797
- last4 String?
798
- expMonth Int?
799
- expYear Int?
800
- isDefault Boolean @default(true)
801
- metadata Json?
909
+ id String @id @default(uuid())
910
+
911
+ userId String
912
+ billingCustomerId String
913
+
914
+ provider BillingProvider // razorpay | stripe | juspay
915
+ providerPaymentMethodId String // token_xxx, pm_xxx
916
+
917
+ type PaymentMethodType // card | upi | bank
918
+ brand String?
919
+ last4 String?
920
+ expMonth Int?
921
+ expYear Int?
922
+
923
+ isDefault Boolean @default(false)
924
+ status PaymentMethodStatus @default(active)
925
+
926
+ metadata Json?
802
927
 
803
928
  createdAt DateTime @default(now())
804
929
  updatedAt DateTime @updatedAt
805
930
 
806
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
931
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
932
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
933
+
934
+ @@unique([provider, providerPaymentMethodId])
935
+ @@index([billingCustomerId])
936
+ }
937
+
938
+ model BillingCustomer {
939
+ id String @id @default(uuid())
940
+
941
+ userId String
942
+ provider BillingProvider // razorpay | stripe | juspay
943
+ providerCustomerId String // cust_xxx, cus_xxx
944
+
945
+ email String?
946
+ metadata Json?
947
+
948
+ createdAt DateTime @default(now())
949
+ updatedAt DateTime @updatedAt
950
+
951
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
952
+ subscriptions Subscription[]
953
+ invoices Invoice[]
954
+ paymentMethods PaymentMethod[]
955
+ billingLedgers BillingLedger[]
956
+
957
+ @@unique([provider, providerCustomerId])
958
+ @@unique([userId, provider])
959
+ @@index([providerCustomerId])
960
+ }
961
+
962
+ model SubscriptionEvent {
963
+ id String @id @default(uuid())
964
+
965
+ subscriptionId String
966
+ provider BillingProvider
967
+ eventType SubscriptionEventType
968
+ payload Json
969
+
970
+ createdAt DateTime @default(now())
971
+
972
+ subscription Subscription @relation(fields: [subscriptionId], references: [id])
973
+
974
+ @@index([subscriptionId, createdAt])
975
+ }
976
+
977
+ model BillingLedger {
978
+ id String @id @default(uuid())
979
+
980
+ userId String
981
+ billingCustomerId String
982
+
983
+ provider BillingProvider
984
+
985
+ entryType BillingLedgerEntryType // charge | refund | credit | debit | adjustment
986
+ direction BillingLedgerDirection // debit | credit
987
+
988
+ amount Int
989
+ currency String
990
+
991
+ referenceType String // invoice | subscription | payment | coupon | reward
992
+ referenceId String
993
+
994
+ description String?
995
+ metadata Json?
996
+
997
+ createdAt DateTime @default(now())
998
+
999
+ user User @relation(fields: [userId], references: [id])
1000
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
1001
+
1002
+ @@index([userId, createdAt])
1003
+ @@index([billingCustomerId, createdAt])
1004
+ @@index([provider, createdAt])
1005
+ }
1006
+
1007
+ model Coupon {
1008
+ id String @id @default(uuid())
1009
+
1010
+ code String @unique
1011
+
1012
+ discountType CouponDiscountType
1013
+ discountValue Int // % or flat amount (minor units)
1014
+
1015
+ currency String? // required for flat discounts
1016
+
1017
+ maxRedemptions Int?
1018
+ redeemedCount Int @default(0)
1019
+
1020
+ validFrom DateTime?
1021
+ validUntil DateTime?
1022
+
1023
+ applicablePlans Plan[]
1024
+ redemptionScope CouponRedemptionScope
1025
+
1026
+ active Boolean @default(true)
1027
+
1028
+ metadata Json?
1029
+
1030
+ createdAt DateTime @default(now())
1031
+ updatedAt DateTime @updatedAt
1032
+ }
1033
+
1034
+ model RevenueAggregate {
1035
+ id String @id @default(uuid())
1036
+
1037
+ period String // YYYY-MM (e.g. 2026-02)
1038
+ provider BillingProvider
1039
+
1040
+ grossRevenue Int
1041
+ refunds Int
1042
+ credits Int
1043
+ netRevenue Int
1044
+
1045
+ currency String
1046
+
1047
+ updatedAt DateTime @updatedAt
1048
+
1049
+ @@unique([period, provider, currency])
1050
+ @@index([period])
807
1051
  }
808
1052
 
809
1053
  model WaitList {
@@ -825,7 +1069,7 @@ model WaitList {
825
1069
  model Job {
826
1070
  id String @id @default(uuid())
827
1071
  type String
828
- status String @default("pending")
1072
+ status JobStatus @default(pending)
829
1073
  payload Json
830
1074
  retries Int @default(0)
831
1075
  maxRetries Int @default(3)