@varaos/db 1.3.1 → 1.3.2

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.2",
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;
@@ -119,6 +119,99 @@ enum WorkflowStepRunStatus {
119
119
  skipped
120
120
  }
121
121
 
122
+ enum BillingProvider {
123
+ razorpay
124
+ stripe
125
+ juspay
126
+ }
127
+
128
+ enum SubscriptionEventType {
129
+ created // Subscription object created (before activation)
130
+ activated // First successful activation
131
+ trial_started // Trial period started
132
+ trial_ended // Trial expired or converted
133
+
134
+ charged // Successful recurring or first charge
135
+ payment_failed // Charge attempt failed
136
+ payment_recovered // Previously failed payment later succeeded
137
+
138
+ paused // Subscription paused (manual or system)
139
+ resumed // Subscription resumed after pause
140
+
141
+ plan_changed // Upgrade / downgrade
142
+ quantity_changed // Seats / units changed (enterprise)
143
+
144
+ canceled // User or system initiated cancellation
145
+ completed // Subscription ran its full course
146
+ expired // Ended due to non-payment / mandate expiry
147
+
148
+ refunded // Full or partial refund issued
149
+ }
150
+
151
+ enum InvoiceStatus {
152
+ draft
153
+ open
154
+ paid
155
+ partially_paid
156
+ failed
157
+ void
158
+ refunded
159
+ }
160
+
161
+ enum PaymentMethodType {
162
+ card
163
+ upi
164
+ bank
165
+ wallet
166
+ }
167
+
168
+ enum PaymentMethodStatus {
169
+ active
170
+ inactive
171
+ expired
172
+ revoked
173
+ }
174
+
175
+ enum BillingEventStatus {
176
+ received
177
+ processing
178
+ processed
179
+ failed
180
+ }
181
+
182
+ enum BillingLedgerEntryType {
183
+ charge
184
+ refund
185
+ credit
186
+ debit
187
+ adjustment
188
+ }
189
+
190
+ enum BillingLedgerDirection {
191
+ debit
192
+ credit
193
+ }
194
+
195
+ enum JobStatus {
196
+ pending
197
+ scheduled
198
+ running
199
+ completed
200
+ failed
201
+ dead
202
+ }
203
+
204
+ enum CouponDiscountType {
205
+ percentage
206
+ flat
207
+ }
208
+
209
+ enum CouponRedemptionScope {
210
+ subscription
211
+ invoice
212
+ one_time
213
+ }
214
+
122
215
  /// ─────────────────────────────────────────────
123
216
  /// USERS & AUTH
124
217
  /// ─────────────────────────────────────────────
@@ -176,14 +269,16 @@ model User {
176
269
  Onboarding Onboarding?
177
270
  ChatSession ChatSession[]
178
271
 
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[]
272
+ createdAt DateTime @default(now())
273
+ updatedAt DateTime @updatedAt
274
+ posts Post[]
275
+ userSessions UserSession[]
276
+ paymentMethods PaymentMethod[]
277
+ userEmails UserEmail[]
278
+ invoices Invoice[]
279
+ userFiles UserFile[]
280
+ billingCustomers BillingCustomer[]
281
+ billingLedgers BillingLedger[]
187
282
 
188
283
  @@index([status])
189
284
  }
@@ -725,85 +820,232 @@ model SecurityEvent {
725
820
  /// ─────────────────────────────────────────────
726
821
 
727
822
  model Subscription {
728
- id String @id @default(uuid())
823
+ id String @id @default(uuid())
824
+
729
825
  userId String
730
826
  plan Plan
731
- status SubscriptionStatus // active | trialing | past_due | canceled
827
+ status SubscriptionStatus
828
+
829
+ provider BillingProvider // razorpay | stripe | juspay
830
+ providerSubscriptionId String @unique
831
+ providerPlanId String?
732
832
 
733
- // ── Lifecycle (rarely changes)
833
+ billingCustomerId String
834
+
835
+ // Lifecycle
734
836
  startedAt DateTime
735
837
  endedAt DateTime?
736
838
 
737
- // ── Billing cycle (changes every invoice)
839
+ // Billing cycle
738
840
  currentPeriodStart DateTime?
739
841
  currentPeriodEnd DateTime?
740
-
741
- // ── Provider scheduling (informational only)
742
- nextPayment DateTime?
743
-
744
- razorpayCustomerId String?
745
- razorpaySubscriptionId String? @unique
746
- razorpayPlanId String?
842
+ nextPayment DateTime?
747
843
 
748
844
  metadata Json?
749
845
 
750
- user User @relation(fields: [userId], references: [id])
846
+ user User @relation(fields: [userId], references: [id])
847
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
848
+ invoices Invoice[]
849
+ subscriptionEvents SubscriptionEvent[]
751
850
 
752
- @@index([razorpayCustomerId])
753
- @@index([razorpaySubscriptionId])
851
+ @@index([provider, providerSubscriptionId])
852
+ @@index([billingCustomerId])
754
853
  }
755
854
 
756
855
  model Invoice {
757
- id String @id @default(uuid())
856
+ id String @id @default(uuid())
857
+
758
858
  userId String
759
859
  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?
860
+ billingCustomerId String
861
+
862
+ provider BillingProvider // razorpay | stripe | juspay
863
+ providerInvoiceId String
864
+
865
+ amount Int
866
+ currency String
867
+ status InvoiceStatus
868
+
869
+ periodStart DateTime?
870
+ periodEnd DateTime?
871
+
872
+ hostedInvoiceUrl String?
873
+ pdfUrl String?
874
+
875
+ metadata Json?
768
876
 
769
877
  createdAt DateTime @default(now())
770
878
 
771
- user User @relation(fields: [userId], references: [id])
879
+ user User @relation(fields: [userId], references: [id])
880
+ subscription Subscription? @relation(fields: [subscriptionId], references: [id])
881
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
882
+
883
+ @@unique([provider, providerInvoiceId])
884
+ @@index([billingCustomerId])
772
885
  }
773
886
 
774
887
  model BillingEvent {
775
- id String @id @default(uuid())
776
- provider String // razorpay
888
+ id String @id @default(uuid())
777
889
 
890
+ provider BillingProvider // razorpay | stripe | juspay
778
891
  eventType String
779
- eventId String @unique // razorpay event ID
892
+ eventId String
780
893
 
781
- payload Json
782
- processed Boolean @default(false)
894
+ payload Json
895
+
896
+ status BillingEventStatus @default(received)
783
897
  processedAt DateTime?
784
898
  error String?
785
899
 
786
900
  createdAt DateTime @default(now())
787
901
 
902
+ @@unique([provider, eventId])
788
903
  @@index([provider, eventType])
789
904
  }
790
905
 
791
906
  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?
907
+ id String @id @default(uuid())
908
+
909
+ userId String
910
+ billingCustomerId String
911
+
912
+ provider BillingProvider // razorpay | stripe | juspay
913
+ providerPaymentMethodId String // token_xxx, pm_xxx
914
+
915
+ type PaymentMethodType // card | upi | bank
916
+ brand String?
917
+ last4 String?
918
+ expMonth Int?
919
+ expYear Int?
920
+
921
+ isDefault Boolean @default(false)
922
+ status PaymentMethodStatus @default(active)
923
+
924
+ metadata Json?
802
925
 
803
926
  createdAt DateTime @default(now())
804
927
  updatedAt DateTime @updatedAt
805
928
 
806
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
929
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
930
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
931
+
932
+ @@unique([provider, providerPaymentMethodId])
933
+ @@index([billingCustomerId])
934
+ }
935
+
936
+ model BillingCustomer {
937
+ id String @id @default(uuid())
938
+
939
+ userId String
940
+ provider BillingProvider // razorpay | stripe | juspay
941
+ providerCustomerId String // cust_xxx, cus_xxx
942
+
943
+ email String?
944
+ metadata Json?
945
+
946
+ createdAt DateTime @default(now())
947
+ updatedAt DateTime @updatedAt
948
+
949
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
950
+ subscriptions Subscription[]
951
+ invoices Invoice[]
952
+ paymentMethods PaymentMethod[]
953
+ billingLedgers BillingLedger[]
954
+
955
+ @@unique([provider, providerCustomerId])
956
+ @@unique([userId, provider])
957
+ @@index([providerCustomerId])
958
+ }
959
+
960
+ model SubscriptionEvent {
961
+ id String @id @default(uuid())
962
+
963
+ subscriptionId String
964
+ provider BillingProvider
965
+ eventType SubscriptionEventType
966
+ payload Json
967
+
968
+ createdAt DateTime @default(now())
969
+
970
+ subscription Subscription @relation(fields: [subscriptionId], references: [id])
971
+
972
+ @@index([subscriptionId, createdAt])
973
+ }
974
+
975
+ model BillingLedger {
976
+ id String @id @default(uuid())
977
+
978
+ userId String
979
+ billingCustomerId String
980
+
981
+ provider BillingProvider
982
+
983
+ entryType BillingLedgerEntryType // charge | refund | credit | debit | adjustment
984
+ direction BillingLedgerDirection // debit | credit
985
+
986
+ amount Int
987
+ currency String
988
+
989
+ referenceType String // invoice | subscription | payment | coupon | reward
990
+ referenceId String
991
+
992
+ description String?
993
+ metadata Json?
994
+
995
+ createdAt DateTime @default(now())
996
+
997
+ user User @relation(fields: [userId], references: [id])
998
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
999
+
1000
+ @@index([userId, createdAt])
1001
+ @@index([billingCustomerId, createdAt])
1002
+ @@index([provider, createdAt])
1003
+ }
1004
+
1005
+ model Coupon {
1006
+ id String @id @default(uuid())
1007
+
1008
+ code String @unique
1009
+
1010
+ discountType CouponDiscountType
1011
+ discountValue Int // % or flat amount (minor units)
1012
+
1013
+ currency String? // required for flat discounts
1014
+
1015
+ maxRedemptions Int?
1016
+ redeemedCount Int @default(0)
1017
+
1018
+ validFrom DateTime?
1019
+ validUntil DateTime?
1020
+
1021
+ applicablePlans Plan[]
1022
+ redemptionScope CouponRedemptionScope
1023
+
1024
+ active Boolean @default(true)
1025
+
1026
+ metadata Json?
1027
+
1028
+ createdAt DateTime @default(now())
1029
+ updatedAt DateTime @updatedAt
1030
+ }
1031
+
1032
+ model RevenueAggregate {
1033
+ id String @id @default(uuid())
1034
+
1035
+ period String // YYYY-MM (e.g. 2026-02)
1036
+ provider BillingProvider
1037
+
1038
+ grossRevenue Int
1039
+ refunds Int
1040
+ credits Int
1041
+ netRevenue Int
1042
+
1043
+ currency String
1044
+
1045
+ updatedAt DateTime @updatedAt
1046
+
1047
+ @@unique([period, provider, currency])
1048
+ @@index([period])
807
1049
  }
808
1050
 
809
1051
  model WaitList {
@@ -825,7 +1067,7 @@ model WaitList {
825
1067
  model Job {
826
1068
  id String @id @default(uuid())
827
1069
  type String
828
- status String @default("pending")
1070
+ status JobStatus @default(pending)
829
1071
  payload Json
830
1072
  retries Int @default(0)
831
1073
  maxRetries Int @default(3)