@varaos/db 1.3.5 → 1.4.0

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.
@@ -1,1394 +1,1980 @@
1
- generator client {
2
- provider = "prisma-client-js"
3
- }
4
-
5
- datasource db {
6
- provider = "postgresql"
7
- url = env("DATABASE_URL")
8
- directUrl = env("DIRECT_URL")
9
- }
10
-
11
- /// ─────────────────────────────────────────────
12
- /// ENUMS
13
- /// ─────────────────────────────────────────────
14
-
15
- enum Role {
16
- user
17
- support
18
- business
19
- superadmin
20
- moderator
21
- admin
22
- }
23
-
24
- enum Status {
25
- active // Visible and usable in production
26
- suspended // Temporarily disabled but can be restored
27
- deleted // Soft-deleted or removed from UI
28
- draft // Being worked on but not yet published
29
- pending_review // Awaiting manual or automated approval
30
- deprecated // Old but still accessible for legacy users
31
- archived // Hidden from new users, preserved for history
32
- disconnected
33
- }
34
-
35
- enum Plan {
36
- free
37
- starter
38
- pro
39
- business
40
- enterprise
41
- }
42
-
43
- enum AuthType {
44
- credentials
45
- oauth
46
- hybrid
47
- }
48
-
49
- enum MessageRole {
50
- user
51
- assistant
52
- system
53
- tool
54
- moderator
55
- }
56
-
57
- enum PostType {
58
- BLOG
59
- ANNOUNCEMENT
60
- SESSION
61
- }
62
-
63
- enum ReactionType {
64
- LIKE
65
- LOVE
66
- CLAP
67
- FIRE
68
- WOW
69
- }
70
-
71
- enum FileCategory {
72
- avatar
73
- media
74
- attachment
75
- memory
76
- export
77
- }
78
-
79
- enum TwoFactorMethod {
80
- totp
81
- email
82
- webauthn
83
- }
84
-
85
- enum SubscriptionStatus {
86
- created // intent created, payment pending
87
- active
88
- trialing
89
- past_due
90
- canceled
91
- paused
92
- }
93
-
94
- enum WorkflowStatus {
95
- draft
96
- active
97
- paused
98
- archived
99
- }
100
-
101
- enum WorkflowRunStatus {
102
- running
103
- completed
104
- failed
105
- canceled
106
- }
107
-
108
- enum WorkflowStepStatus {
109
- draft
110
- active
111
- paused
112
- deprecated
113
- }
114
-
115
- enum WorkflowStepRunStatus {
116
- pending
117
- running
118
- completed
119
- failed
120
- skipped
121
- }
122
-
123
- enum BillingProvider {
124
- razorpay
125
- stripe
126
- juspay
127
- }
128
-
129
- enum SubscriptionEventType {
130
- created // Subscription object created (before activation)
131
- activated // First successful activation
132
- trial_started // Trial period started
133
- trial_ended // Trial expired or converted
134
-
135
- charged // Successful recurring or first charge
136
- payment_failed // Charge attempt failed
137
- payment_recovered // Previously failed payment later succeeded
138
-
139
- paused // Subscription paused (manual or system)
140
- resumed // Subscription resumed after pause
141
-
142
- plan_changed // Upgrade / downgrade
143
- quantity_changed // Seats / units changed (enterprise)
144
-
145
- canceled // User or system initiated cancellation
146
- completed // Subscription ran its full course
147
- expired // Ended due to non-payment / mandate expiry
148
-
149
- refunded // Full or partial refund issued
150
- }
151
-
152
- enum InvoiceStatus {
153
- draft
154
- open
155
- paid
156
- partially_paid
157
- failed
158
- void
159
- refunded
160
- }
161
-
162
- enum PaymentMethodType {
163
- card
164
- upi
165
- bank
166
- wallet
167
- }
168
-
169
- enum PaymentMethodStatus {
170
- active
171
- inactive
172
- expired
173
- revoked
174
- }
175
-
176
- enum BillingEventStatus {
177
- received
178
- processing
179
- processed
180
- failed
181
- }
182
-
183
- enum BillingLedgerEntryType {
184
- charge
185
- refund
186
- credit
187
- debit
188
- adjustment
189
- }
190
-
191
- enum BillingLedgerDirection {
192
- debit
193
- credit
194
- }
195
-
196
- enum JobStatus {
197
- pending
198
- scheduled
199
- running
200
- completed
201
- failed
202
- dead
203
- }
204
-
205
- enum CouponDiscountType {
206
- percentage
207
- flat
208
- }
209
-
210
- enum CouponRedemptionScope {
211
- subscription
212
- invoice
213
- one_time
214
- }
215
-
216
- enum CreditPurchaseStatus {
217
- pending
218
- paid
219
- failed
220
- refunded
221
- partially_refunded
222
- }
223
-
224
- /// ─────────────────────────────────────────────
225
- /// USERS & AUTH
226
- /// ─────────────────────────────────────────────
227
-
228
- model User {
229
- id String @id @default(uuid())
230
- name String
231
-
232
- image String? // provider image
233
- avatarOverrideUrl String?
234
-
235
- email String @unique
236
- password String?
237
- emailVerified DateTime?
238
- onboarding DateTime?
239
- role Role @default(user)
240
- timezone String?
241
- language String?
242
- status Status @default(active)
243
- lastLogin DateTime?
244
- lastPasswordChange DateTime?
245
- twoFactorEnabled Boolean @default(false)
246
-
247
- userTwoFactor UserTwoFactor?
248
-
249
- metadata Json?
250
- deletedAt DateTime?
251
- plan Plan @default(free)
252
- tokenBalance Int @default(0)
253
- creditsUsed Int @default(0)
254
-
255
- chatCount Int @default(0)
256
- workflowCount Int @default(0)
257
- integrationCount Int @default(0)
258
-
259
- lastActiveAt DateTime?
260
-
261
- authType AuthType @default(oauth)
262
-
263
- passwordStrength String? // weak | medium | strong
264
-
265
- storageUsed BigInt @default(0) // bytes
266
- storageLimit BigInt @default(524288000) // 500 MB (beta)
267
-
268
- accounts Account[]
269
- integrations Integration[]
270
- tokenTransactions TokenTransaction[]
271
- auditLogs AuditLog[]
272
- subscriptions Subscription[]
273
- workspaces Workspace[] @relation("UserWorkspaces")
274
- defaultWorkspaceId String? @unique
275
- defaultWorkspace Workspace? @relation("UserDefaultWorkspace", fields: [defaultWorkspaceId], references: [id])
276
- Workflow Workflow[]
277
- Notification Notification[]
278
- Onboarding Onboarding?
279
- ChatSession ChatSession[]
280
-
281
- createdAt DateTime @default(now())
282
- updatedAt DateTime @updatedAt
283
- posts Post[]
284
- userSessions UserSession[]
285
- paymentMethods PaymentMethod[]
286
- userEmails UserEmail[]
287
- invoices Invoice[]
288
- userFiles UserFile[]
289
- billingCustomers BillingCustomer[]
290
- billingLedgers BillingLedger[]
291
- creditPurchases CreditPurchase[]
292
- refunds Refund[]
293
-
294
- @@index([status])
295
- }
296
-
297
- model UserFile {
298
- id String @id @default(uuid())
299
- userId String
300
-
301
- path String // Spaces object key (users/{userId}/{category}/{fileId}.ext)
302
- size BigInt // bytes
303
- mimeType String
304
- category FileCategory
305
-
306
- checksum String? // sha256 or md5 for integrity verification
307
- metadata Json?
308
-
309
- createdAt DateTime @default(now())
310
-
311
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
312
-
313
- @@index([userId])
314
- @@index([category])
315
- @@index([userId, category])
316
- }
317
-
318
- model UserSession {
319
- id String @id @default(uuid())
320
- userId String
321
- ip String?
322
- userAgent String?
323
- lastUsed DateTime
324
-
325
- revoked Boolean @default(false)
326
- revokedAt DateTime?
327
-
328
- expiresAt DateTime
329
- createdAt DateTime @default(now())
330
-
331
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
332
-
333
- @@index([userId, revoked])
334
- }
335
-
336
- model UploadIntent {
337
- id String @id
338
- userId String
339
- category FileCategory
340
- size BigInt
341
- objectKey String
342
- createdAt DateTime @default(now())
343
-
344
- @@index([userId])
345
- @@index([userId, category])
346
- }
347
-
348
- model UserEmail {
349
- id String @id @default(uuid())
350
- userId String
351
- email String @unique
352
- verified Boolean @default(false)
353
- primary Boolean @default(false)
354
- type String? // billing | security | notifications
355
- createdAt DateTime @default(now())
356
-
357
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
358
- }
359
-
360
- model UserTwoFactor {
361
- id String @id @default(uuid())
362
- userId String @unique
363
-
364
- method TwoFactorMethod @default(totp)
365
- secret String? // null when disabled or method != totp
366
- enabled Boolean @default(false)
367
-
368
- lastVerifiedAt DateTime?
369
- enabledAt DateTime?
370
-
371
- recoveryEmailVerifiedAt DateTime?
372
-
373
- backupCodes Json? // [{ hash, used, usedAt }]
374
-
375
- createdAt DateTime @default(now())
376
- updatedAt DateTime @updatedAt
377
-
378
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
379
-
380
- @@index([userId])
381
- }
382
-
383
- model Account {
384
- id String @id @default(uuid())
385
- userId String
386
- type String
387
- provider String
388
- providerAccountId String
389
- refresh_token String? @db.Text
390
- access_token String? @db.Text
391
- expires_at Int?
392
- token_type String?
393
- scope String?
394
- id_token String? @db.Text
395
- session_state String?
396
-
397
- createdAt DateTime @default(now())
398
- updatedAt DateTime @updatedAt
399
-
400
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
401
-
402
- @@unique([provider, providerAccountId])
403
- }
404
-
405
- model VerificationToken {
406
- id String @id @default(uuid())
407
- email String
408
- token String @unique
409
- expiresAt DateTime
410
-
411
- @@unique([email, token])
412
- }
413
-
414
- model PasswordResetToken {
415
- id String @id @default(uuid())
416
- email String
417
- token String @unique
418
- expiresAt DateTime
419
-
420
- @@unique([email, token])
421
- }
422
-
423
- /// ─────────────────────────────────────────────
424
- /// WORKSPACES & INTEGRATIONS
425
- /// ─────────────────────────────────────────────
426
-
427
- model Workspace {
428
- id String @id @default(uuid())
429
- name String
430
- description String?
431
- ownerId String
432
- status Status @default(active)
433
- deletedAt DateTime?
434
-
435
- createdAt DateTime @default(now())
436
- updatedAt DateTime @updatedAt
437
-
438
- owner User @relation("UserWorkspaces", fields: [ownerId], references: [id])
439
- defaultFor User? @relation("UserDefaultWorkspace")
440
-
441
- integrations Integration[]
442
- aiAgents AIAgent[]
443
- Workflow Workflow[]
444
- ChatSession ChatSession[]
445
-
446
- @@index([status])
447
- @@index([ownerId])
448
- }
449
-
450
- model Integration {
451
- id String @id @default(cuid())
452
- userId String
453
- workspaceId String?
454
- provider String
455
- providerAccountId String
456
- integration String
457
- accessToken String
458
- refreshToken String?
459
- expiresAt DateTime?
460
- scopes Json
461
- profile Json
462
- status Status @default(active)
463
- metadata Json?
464
- deletedAt DateTime?
465
-
466
- catalogId String?
467
- catalog IntegrationCatalog? @relation(fields: [catalogId], references: [id])
468
-
469
- createdAt DateTime @default(now())
470
- updatedAt DateTime @updatedAt
471
-
472
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
473
- workspace Workspace? @relation(fields: [workspaceId], references: [id])
474
- integrationSyncLog IntegrationSyncLog[]
475
-
476
- @@unique([userId, provider, integration, workspaceId], name: "user_provider_integration_workspace")
477
- @@index([workspaceId])
478
- @@index([status])
479
- @@map("integrations")
480
- }
481
-
482
- model IntegrationCatalog {
483
- id String @id @default(uuid())
484
- provider String
485
- integration String
486
- name String
487
- category String?
488
- showDuringOnboarding Boolean @default(true)
489
- default Boolean @default(false)
490
- premium Boolean @default(false)
491
- iconUrl String?
492
- description String?
493
- docsUrl String?
494
- oauthType String?
495
- setupInstructions Json?
496
- status Status @default(draft)
497
-
498
- // ✅ NEW
499
- capabilities Json?
500
- examplePrompts String[]
501
-
502
- createdAt DateTime @default(now())
503
- updatedAt DateTime @updatedAt
504
- Integration Integration[]
505
-
506
- @@unique([provider, integration])
507
- @@index([status])
508
- @@map("integration_catalog")
509
- }
510
-
511
- model IntegrationSyncLog {
512
- id String @id @default(uuid())
513
- integrationId String
514
- syncStatus String
515
- errorMessage String?
516
- timestamp DateTime @default(now())
517
-
518
- integration Integration @relation(fields: [integrationId], references: [id])
519
- }
520
-
521
- /// ─────────────────────────────────────────────
522
- /// AUTOMATIONS / AI / WORKFLOWS
523
- /// ─────────────────────────────────────────────
524
-
525
- model AIAgent {
526
- id String @id @default(uuid())
527
- name String
528
- key String @unique
529
- description String?
530
- active Boolean @default(true)
531
- config Json?
532
- workspaceId String?
533
- workspace Workspace? @relation(fields: [workspaceId], references: [id])
534
-
535
- createdAt DateTime @default(now())
536
- updatedAt DateTime @updatedAt
537
-
538
- tokenTransactions TokenTransaction[]
539
- ChatSession ChatSession[]
540
- }
541
-
542
- model UsageAggregate {
543
- id String @id @default(uuid())
544
- userId String
545
- workspaceId String?
546
- billingPeriod String
547
- source String // chat | automation | api
548
- tokensUsed Int
549
- requestCount Int
550
- updatedAt DateTime @updatedAt
551
-
552
- @@unique([userId, workspaceId, billingPeriod, source])
553
- }
554
-
555
- model TokenTransaction {
556
- id String @id @default(uuid())
557
- userId String
558
- agentId String?
559
- tokensUsed Int
560
- action String
561
-
562
- source String? // chat | automation | api
563
- workspaceId String?
564
- integration String?
565
-
566
- billingPeriod String? // e.g. "2025-01" (YYYY-MM)
567
-
568
- metadata Json?
569
- createdAt DateTime @default(now())
570
-
571
- user User @relation(fields: [userId], references: [id])
572
- agent AIAgent? @relation(fields: [agentId], references: [id])
573
- }
574
-
575
- model Workflow {
576
- id String @id @default(uuid())
577
- name String
578
- description String?
579
- status WorkflowStatus @default(active)
580
- userId String
581
- workspaceId String?
582
-
583
- user User @relation(fields: [userId], references: [id])
584
- workspace Workspace? @relation(fields: [workspaceId], references: [id])
585
- steps WorkflowStep[]
586
-
587
- createdAt DateTime @default(now())
588
- updatedAt DateTime @updatedAt
589
- WorkflowRun WorkflowRun[]
590
- }
591
-
592
- model WorkflowStep {
593
- id String @id @default(uuid())
594
- workflowId String
595
- type String
596
- config Json
597
- order Int
598
- status WorkflowStepStatus @default(active)
599
-
600
- workflow Workflow @relation(fields: [workflowId], references: [id])
601
-
602
- createdAt DateTime @default(now())
603
- updatedAt DateTime @updatedAt
604
- WorkflowStepRun WorkflowStepRun[]
605
- }
606
-
607
- model WorkflowRun {
608
- id String @id @default(uuid())
609
- workflowId String
610
- status WorkflowRunStatus @default(running)
611
- input Json?
612
- output Json?
613
- error String?
614
-
615
- startedAt DateTime @default(now())
616
- finishedAt DateTime?
617
-
618
- workflow Workflow @relation(fields: [workflowId], references: [id])
619
- steps WorkflowStepRun[]
620
-
621
- @@index([workflowId, startedAt])
622
- }
623
-
624
- model WorkflowStepRun {
625
- id String @id @default(uuid())
626
- workflowRunId String
627
- workflowStepId String
628
- status WorkflowStepRunStatus @default(pending)
629
- input Json?
630
- output Json?
631
- error String?
632
-
633
- startedAt DateTime?
634
- finishedAt DateTime?
635
-
636
- workflowRun WorkflowRun @relation(fields: [workflowRunId], references: [id])
637
- workflowStep WorkflowStep @relation(fields: [workflowStepId], references: [id])
638
- }
639
-
640
- /// ─────────────────────────────────────────────
641
- /// COMMUNICATION / CHAT / EMAIL
642
- /// ─────────────────────────────────────────────
643
-
644
- model Notification {
645
- id String @id @default(uuid())
646
- userId String?
647
- type String
648
- title String
649
- body String?
650
- read Boolean @default(false)
651
-
652
- createdAt DateTime @default(now())
653
-
654
- user User? @relation(fields: [userId], references: [id])
655
- }
656
-
657
- model ChatSession {
658
- id String @id @default(uuid())
659
- title String?
660
- userId String?
661
- workspaceId String?
662
- aiAgentId String?
663
- status String @default("active")
664
- metadata Json?
665
- deletedAt DateTime?
666
-
667
- user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
668
- workspace Workspace? @relation(fields: [workspaceId], references: [id])
669
- aiAgent AIAgent? @relation(fields: [aiAgentId], references: [id])
670
- messages ChatMessage[]
671
-
672
- createdAt DateTime @default(now())
673
- updatedAt DateTime @updatedAt
674
-
675
- @@index([userId, createdAt])
676
- @@index([workspaceId, createdAt])
677
- @@index([status])
678
- }
679
-
680
- model ChatMessage {
681
- id String @id @default(uuid())
682
- chatSessionId String
683
- sender MessageRole
684
- content String
685
- style String?
686
- tokensUsed Int?
687
- metadata Json?
688
- deletedAt DateTime?
689
-
690
- chatSession ChatSession @relation(fields: [chatSessionId], references: [id])
691
-
692
- createdAt DateTime @default(now())
693
-
694
- @@index([chatSessionId, createdAt])
695
- }
696
-
697
- model EmailLog {
698
- id String @id @default(uuid())
699
- to String
700
- subject String
701
- type String // verification, marketing, notification, etc.
702
- status String @default("sent")
703
- metadata Json?
704
- sentAt DateTime @default(now())
705
- error String?
706
- }
707
-
708
- /// ─────────────────────────────────────────────
709
- /// WORKFLOW TEMPLATES & ONBOARDING PERSONAS
710
- /// ─────────────────────────────────────────────
711
-
712
- model WorkflowTemplate {
713
- id String @id @default(uuid())
714
- name String
715
- description String?
716
- category String?
717
- recommended Boolean @default(false)
718
- iconUrl String?
719
- estimatedSetupTime Int?
720
- status Status @default(active)
721
-
722
- createdAt DateTime @default(now())
723
- updatedAt DateTime @updatedAt
724
-
725
- steps WorkflowStepTemplate[]
726
- }
727
-
728
- model WorkflowStepTemplate {
729
- id String @id @default(uuid())
730
- templateId String
731
- type String
732
- config Json
733
- order Int
734
- status String @default("active")
735
-
736
- template WorkflowTemplate @relation(fields: [templateId], references: [id])
737
- }
738
-
739
- model OnboardingPersona {
740
- id String @id @default(uuid())
741
- key String @unique
742
- title String
743
- description String?
744
- iconUrl String?
745
- recommended Boolean @default(false)
746
- status Status @default(active)
747
-
748
- createdAt DateTime @default(now())
749
- updatedAt DateTime @updatedAt
750
- }
751
-
752
- /// ─────────────────────────────────────────────
753
- /// MONITORING / ADMIN / SYSTEM CONFIG
754
- /// ─────────────────────────────────────────────
755
-
756
- model Service {
757
- id String @id @default(uuid())
758
- name String
759
- description String?
760
- endpoint String
761
- status String @default("healthy")
762
- lastPing DateTime?
763
- uptime Float?
764
- region String?
765
- metadata Json?
766
- createdAt DateTime @default(now())
767
- updatedAt DateTime @updatedAt
768
-
769
- logs ServiceLog[]
770
- errors ErrorLog[]
771
- }
772
-
773
- model ServiceLog {
774
- id String @id @default(uuid())
775
- serviceId String
776
- level String
777
- message String
778
- metadata Json?
779
- createdAt DateTime @default(now())
780
-
781
- service Service @relation(fields: [serviceId], references: [id])
782
- }
783
-
784
- model ErrorLog {
785
- id String @id @default(uuid())
786
- serviceId String?
787
- errorType String?
788
- message String
789
- stackTrace String?
790
- context Json?
791
- createdAt DateTime @default(now())
792
-
793
- service Service? @relation(fields: [serviceId], references: [id])
794
- }
795
-
796
- model SystemConfig {
797
- id String @id @default(uuid())
798
- key String @unique
799
- value Json
800
- category String?
801
- updatedAt DateTime @updatedAt
802
- }
803
-
804
- model AuditLog {
805
- id String @id @default(uuid())
806
- userId String?
807
- actorRole Role?
808
- eventType String
809
- targetType String?
810
- targetId String?
811
- description String?
812
- metadata Json?
813
- createdAt DateTime @default(now())
814
-
815
- user User? @relation(fields: [userId], references: [id])
816
-
817
- @@index([userId, createdAt])
818
- }
819
-
820
- model SecurityEvent {
821
- id String @id @default(uuid())
822
- userId String?
823
- type String // login | logout | password_change | session_revoked
824
- ip String?
825
- userAgent String?
826
- success Boolean
827
- metadata Json?
828
- createdAt DateTime @default(now())
829
-
830
- @@index([userId, createdAt])
831
- }
832
-
833
- /// ─────────────────────────────────────────────
834
- /// BILLING / WAITLIST / JOBS / ONBOARDING
835
- /// ─────────────────────────────────────────────
836
-
837
- model Subscription {
838
- id String @id @default(uuid())
839
-
840
- userId String
841
- plan Plan
842
- status SubscriptionStatus
843
-
844
- provider BillingProvider // razorpay | stripe | juspay
845
- providerSubscriptionId String @unique
846
- providerPlanId String?
847
-
848
- billingCustomerId String
849
-
850
- // Lifecycle
851
- startedAt DateTime
852
- endedAt DateTime?
853
-
854
- // Billing cycle
855
- currentPeriodStart DateTime?
856
- currentPeriodEnd DateTime?
857
- nextPayment DateTime?
858
-
859
- metadata Json?
860
-
861
- user User @relation(fields: [userId], references: [id])
862
- billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
863
- invoices Invoice[]
864
- subscriptionEvents SubscriptionEvent[]
865
-
866
- @@index([provider, providerSubscriptionId])
867
- @@index([billingCustomerId])
868
- }
869
-
870
- model Invoice {
871
- id String @id @default(uuid())
872
-
873
- userId String
874
- subscriptionId String?
875
- billingCustomerId String
876
-
877
- provider BillingProvider // razorpay | stripe | juspay
878
- providerInvoiceId String
879
-
880
- amount Int
881
- currency String
882
- status InvoiceStatus
883
-
884
- periodStart DateTime?
885
- periodEnd DateTime?
886
-
887
- hostedInvoiceUrl String?
888
- pdfUrl String?
889
-
890
- metadata Json?
891
-
892
- createdAt DateTime @default(now())
893
-
894
- user User @relation(fields: [userId], references: [id])
895
- subscription Subscription? @relation(fields: [subscriptionId], references: [id])
896
- billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
897
-
898
- @@unique([provider, providerInvoiceId])
899
- @@index([billingCustomerId])
900
- }
901
-
902
- model BillingEvent {
903
- id String @id @default(uuid())
904
-
905
- provider BillingProvider // razorpay | stripe | juspay
906
- eventType String
907
- eventId String
908
-
909
- payload Json
910
-
911
- status BillingEventStatus @default(received)
912
- processedAt DateTime?
913
- error String?
914
-
915
- createdAt DateTime @default(now())
916
-
917
- @@unique([provider, eventId])
918
- @@index([provider, eventType])
919
- }
920
-
921
- model PaymentMethod {
922
- id String @id @default(uuid())
923
-
924
- userId String
925
- billingCustomerId String
926
-
927
- provider BillingProvider // razorpay | stripe | juspay
928
- providerPaymentMethodId String // token_xxx, pm_xxx
929
-
930
- type PaymentMethodType // card | upi | bank
931
- brand String?
932
- last4 String?
933
- expMonth Int?
934
- expYear Int?
935
-
936
- isDefault Boolean @default(false)
937
- status PaymentMethodStatus @default(active)
938
-
939
- metadata Json?
940
-
941
- createdAt DateTime @default(now())
942
- updatedAt DateTime @updatedAt
943
-
944
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
945
- billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
946
-
947
- @@unique([provider, providerPaymentMethodId])
948
- @@index([billingCustomerId])
949
- }
950
-
951
- model BillingCustomer {
952
- id String @id @default(uuid())
953
-
954
- userId String
955
- provider BillingProvider // razorpay | stripe | juspay
956
- providerCustomerId String // cust_xxx, cus_xxx
957
-
958
- email String?
959
- metadata Json?
960
-
961
- createdAt DateTime @default(now())
962
- updatedAt DateTime @updatedAt
963
-
964
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
965
- subscriptions Subscription[]
966
- invoices Invoice[]
967
- paymentMethods PaymentMethod[]
968
- billingLedgers BillingLedger[]
969
- creditPurchases CreditPurchase[]
970
- refunds Refund[]
971
-
972
- @@unique([provider, providerCustomerId])
973
- @@unique([userId, provider])
974
- @@index([providerCustomerId])
975
- }
976
-
977
- model SubscriptionEvent {
978
- id String @id @default(uuid())
979
-
980
- subscriptionId String
981
- provider BillingProvider
982
- eventType SubscriptionEventType
983
- payload Json
984
-
985
- createdAt DateTime @default(now())
986
-
987
- subscription Subscription @relation(fields: [subscriptionId], references: [id])
988
-
989
- @@index([subscriptionId, createdAt])
990
- }
991
-
992
- model BillingLedger {
993
- id String @id @default(uuid())
994
-
995
- userId String
996
- billingCustomerId String
997
-
998
- provider BillingProvider
999
-
1000
- entryType BillingLedgerEntryType // charge | refund | credit | debit | adjustment
1001
- direction BillingLedgerDirection // debit | credit
1002
-
1003
- amount Int
1004
- currency String
1005
-
1006
- referenceType String // invoice | subscription | payment | coupon | reward
1007
- referenceId String
1008
-
1009
- description String?
1010
- metadata Json?
1011
-
1012
- createdAt DateTime @default(now())
1013
-
1014
- user User @relation(fields: [userId], references: [id])
1015
- billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
1016
-
1017
- @@index([userId, createdAt])
1018
- @@index([billingCustomerId, createdAt])
1019
- @@index([provider, createdAt])
1020
- }
1021
-
1022
- model Coupon {
1023
- id String @id @default(uuid())
1024
-
1025
- code String @unique
1026
-
1027
- discountType CouponDiscountType
1028
- discountValue Int // % or flat amount (minor units)
1029
-
1030
- currency String? // required for flat discounts
1031
-
1032
- maxRedemptions Int?
1033
- redeemedCount Int @default(0)
1034
-
1035
- validFrom DateTime?
1036
- validUntil DateTime?
1037
-
1038
- applicablePlans Plan[]
1039
- redemptionScope CouponRedemptionScope
1040
-
1041
- active Boolean @default(true)
1042
-
1043
- metadata Json?
1044
-
1045
- createdAt DateTime @default(now())
1046
- updatedAt DateTime @updatedAt
1047
- creditPurchases CreditPurchase[]
1048
- }
1049
-
1050
- model RevenueAggregate {
1051
- id String @id @default(uuid())
1052
-
1053
- period String // YYYY-MM (e.g. 2026-02)
1054
- provider BillingProvider
1055
-
1056
- grossRevenue Int
1057
- refunds Int
1058
- credits Int
1059
- netRevenue Int
1060
-
1061
- currency String
1062
-
1063
- updatedAt DateTime @updatedAt
1064
-
1065
- @@unique([period, provider, currency])
1066
- @@index([period])
1067
- }
1068
-
1069
- model WaitList {
1070
- id String @id @default(uuid())
1071
- email String @unique
1072
- name String?
1073
- company String?
1074
- role String?
1075
- teamSize String?
1076
- useCase String?
1077
- consentToUpdates Boolean
1078
- referralCode String? @unique
1079
- referredBy String?
1080
-
1081
- createdAt DateTime @default(now())
1082
- updatedAt DateTime @updatedAt
1083
- }
1084
-
1085
- model Job {
1086
- id String @id @default(uuid())
1087
- type String
1088
- status JobStatus @default(pending)
1089
- payload Json
1090
- retries Int @default(0)
1091
- maxRetries Int @default(3)
1092
- error String?
1093
- scheduledAt DateTime?
1094
- startedAt DateTime?
1095
- finishedAt DateTime?
1096
-
1097
- createdAt DateTime @default(now())
1098
- updatedAt DateTime @updatedAt
1099
- }
1100
-
1101
- model Onboarding {
1102
- id String @id @default(uuid())
1103
- userId String @unique
1104
- persona String?
1105
- setupType String?
1106
- progress Json?
1107
- completed Boolean @default(false)
1108
-
1109
- createdAt DateTime @default(now())
1110
- updatedAt DateTime @updatedAt
1111
-
1112
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1113
- }
1114
-
1115
- /////////////////////
1116
- // Unique Visitors
1117
- //////////////////////
1118
- model Visitor {
1119
- id String @id @default(uuid())
1120
- visitorId String @unique // cookie or fingerprint ID
1121
- ipAddress String?
1122
- userAgent String?
1123
- country String? // optional if you plan to use GeoIP later
1124
- referrer String?
1125
- firstVisit DateTime @default(now())
1126
- lastVisit DateTime @updatedAt
1127
- visitCount Int @default(1)
1128
-
1129
- createdAt DateTime @default(now())
1130
- updatedAt DateTime @updatedAt
1131
- postReactions PostReaction[]
1132
- postShares PostShare[]
1133
-
1134
- @@index([createdAt])
1135
- }
1136
-
1137
- model EmailCampaign {
1138
- id String @id @default(uuid())
1139
- name String
1140
- templateId String
1141
- subject String
1142
- audience String // e.g. "waitlist", "users", "custom"
1143
- segmentFilter Json? // optional query/filter metadata
1144
- sentCount Int @default(0)
1145
- status String @default("draft") // draft | sending | sent | failed
1146
- metadata Json?
1147
- createdById String?
1148
- createdAt DateTime @default(now())
1149
- updatedAt DateTime @updatedAt
1150
-
1151
- logs EmailSendLog[]
1152
- }
1153
-
1154
- model EmailSendLog {
1155
- id String @id @default(uuid())
1156
- campaignId String
1157
- recipient String
1158
- status String
1159
- messageId String?
1160
- error String?
1161
- metadata Json?
1162
- sentAt DateTime @default(now())
1163
- openCount Int @default(0)
1164
- clickCount Int @default(0)
1165
- lastEventAt DateTime?
1166
-
1167
- campaign EmailCampaign @relation(fields: [campaignId], references: [id])
1168
- }
1169
-
1170
- model Post {
1171
- id String @id @default(uuid())
1172
- title String
1173
- slug String @unique
1174
- excerpt String?
1175
- type PostType @default(BLOG)
1176
- status Status @default(draft)
1177
-
1178
- content Json
1179
- contentHtml String?
1180
-
1181
- featuredImage String?
1182
-
1183
- // many-to-many pivot
1184
- tags PostTag[] @relation("PostTags")
1185
-
1186
- authorId String?
1187
- author User? @relation(fields: [authorId], references: [id])
1188
-
1189
- publishedAt DateTime?
1190
- createdAt DateTime @default(now())
1191
- updatedAt DateTime @updatedAt
1192
- postComments PostComment[]
1193
- postReactions PostReaction[]
1194
- postShares PostShare[]
1195
-
1196
- @@index([type])
1197
- @@index([status])
1198
- @@index([publishedAt])
1199
- }
1200
-
1201
- model Tag {
1202
- id String @id @default(uuid())
1203
- name String @unique
1204
- color String @default("blue")
1205
- // inverse many-to-many pivot
1206
- posts PostTag[] @relation("PostTags")
1207
- }
1208
-
1209
- model PostTag {
1210
- postId String
1211
- tagId String
1212
-
1213
- // Add relation names
1214
- post Post @relation("PostTags", fields: [postId], references: [id], onDelete: Cascade)
1215
- tag Tag @relation("PostTags", fields: [tagId], references: [id], onDelete: Cascade)
1216
-
1217
- @@id([postId, tagId])
1218
- @@index([tagId])
1219
- }
1220
-
1221
- /// ─────────────────────────────────────────────
1222
- /// COMMENT IDENTITIES (Name + Email Login-less System)
1223
- /// ─────────────────────────────────────────────
1224
-
1225
- model CommentIdentity {
1226
- id String @id @default(uuid())
1227
- name String
1228
- email String @unique
1229
- verified Boolean @default(false)
1230
- metadata Json?
1231
-
1232
- createdAt DateTime @default(now())
1233
- updatedAt DateTime @updatedAt
1234
-
1235
- comments PostComment[]
1236
- postReactions PostReaction[]
1237
- postShares PostShare[]
1238
-
1239
- @@index([email])
1240
- }
1241
-
1242
- /// ─────────────────────────────────────────────
1243
- /// POST COMMENTS (Revised to use CommentIdentity)
1244
- /// ─────────────────────────────────────────────
1245
-
1246
- model PostComment {
1247
- id String @id @default(uuid())
1248
- postId String
1249
- identityId String? // Instead of userId (for public commenters)
1250
- parentId String? // Threaded comments
1251
-
1252
- content String
1253
- status Status @default(active)
1254
- deletedAt DateTime?
1255
-
1256
- // Relations
1257
- post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
1258
- identity CommentIdentity? @relation(fields: [identityId], references: [id])
1259
- parent PostComment? @relation("CommentReplies", fields: [parentId], references: [id])
1260
- replies PostComment[] @relation("CommentReplies")
1261
-
1262
- createdAt DateTime @default(now())
1263
- updatedAt DateTime @updatedAt
1264
-
1265
- @@index([postId])
1266
- @@index([identityId])
1267
- @@index([parentId])
1268
- @@index([status])
1269
- }
1270
-
1271
- /// ─────────────────────────────────────────────
1272
- /// POST REACTIONS (LIKE, LOVE, CLAP, FIRE, WOW)
1273
- /// ─────────────────────────────────────────────
1274
-
1275
- model PostReaction {
1276
- id String @id @default(uuid())
1277
- postId String
1278
- visitorId String? // Could be Visitor.visitorId
1279
- identityId String? // If commenter also reacts
1280
- type ReactionType
1281
-
1282
- status Status @default(active)
1283
- deletedAt DateTime?
1284
-
1285
- post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
1286
- visitor Visitor? @relation(fields: [visitorId], references: [visitorId])
1287
- identity CommentIdentity? @relation(fields: [identityId], references: [id])
1288
-
1289
- createdAt DateTime @default(now())
1290
- updatedAt DateTime @updatedAt
1291
-
1292
- @@unique([postId, visitorId, type])
1293
- @@unique([postId, identityId, type])
1294
- @@index([postId])
1295
- @@index([visitorId])
1296
- @@index([identityId])
1297
- @@index([type])
1298
- }
1299
-
1300
- /// ─────────────────────────────────────────────
1301
- /// POST SHARES (Analytics + Share Platform Info)
1302
- /// ─────────────────────────────────────────────
1303
-
1304
- model PostShare {
1305
- id String @id @default(uuid())
1306
- postId String
1307
- visitorId String?
1308
- identityId String?
1309
- platform String? // twitter | whatsapp | copy | linkedin | etc.
1310
- metadata Json?
1311
-
1312
- post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
1313
- visitor Visitor? @relation(fields: [visitorId], references: [visitorId])
1314
- identity CommentIdentity? @relation(fields: [identityId], references: [id])
1315
-
1316
- createdAt DateTime @default(now())
1317
-
1318
- @@index([postId])
1319
- @@index([visitorId])
1320
- @@index([identityId])
1321
- @@index([platform])
1322
- }
1323
-
1324
- //// _________________________________________________________________
1325
- //// CREDITS PURCHASES & REFUNDS
1326
- //// _________________________________________________________________
1327
-
1328
- model CreditPurchase {
1329
- id String @id @default(uuid())
1330
-
1331
- userId String
1332
- billingCustomerId String?
1333
-
1334
- provider BillingProvider
1335
- providerOrderId String @unique // Razorpay order_xxx
1336
- providerPaymentId String? // Razorpay pay_xxx
1337
-
1338
- creditAmount Int // Number of credits purchased
1339
- pricePaid Int // Amount in paise/cents
1340
- currency String @default("INR")
1341
-
1342
- status CreditPurchaseStatus @default(pending)
1343
-
1344
- couponId String?
1345
- discountAmount Int?
1346
-
1347
- metadata Json?
1348
-
1349
- paidAt DateTime?
1350
- refundedAt DateTime?
1351
-
1352
- createdAt DateTime @default(now())
1353
- updatedAt DateTime @updatedAt
1354
-
1355
- user User @relation(fields: [userId], references: [id])
1356
- billingCustomer BillingCustomer? @relation(fields: [billingCustomerId], references: [id])
1357
- coupon Coupon? @relation(fields: [couponId], references: [id])
1358
-
1359
- @@index([userId])
1360
- @@index([provider, providerOrderId])
1361
- @@index([status])
1362
- }
1363
-
1364
- model Refund {
1365
- id String @id @default(uuid())
1366
-
1367
- userId String
1368
- billingCustomerId String?
1369
-
1370
- provider BillingProvider
1371
- providerRefundId String @unique // Razorpay rfnd_xxx
1372
- providerPaymentId String // Original payment
1373
-
1374
- amount Int
1375
- currency String
1376
-
1377
- reason String?
1378
- status String @default("pending") // pending | processed | failed
1379
-
1380
- // Link to original purchase
1381
- invoiceId String?
1382
- creditPurchaseId String?
1383
-
1384
- metadata Json?
1385
-
1386
- processedAt DateTime?
1387
- createdAt DateTime @default(now())
1388
-
1389
- user User @relation(fields: [userId], references: [id])
1390
- billingCustomer BillingCustomer? @relation(fields: [billingCustomerId], references: [id])
1391
-
1392
- @@index([userId])
1393
- @@index([provider, providerRefundId])
1394
- }
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ datasource db {
6
+ provider = "postgresql"
7
+ url = env("DATABASE_URL")
8
+ directUrl = env("DIRECT_URL")
9
+ }
10
+
11
+ /// ─────────────────────────────────────────────
12
+ /// ENUMS
13
+ /// ─────────────────────────────────────────────
14
+
15
+ enum Role {
16
+ user
17
+ support
18
+ business
19
+ superadmin
20
+ moderator
21
+ admin
22
+ }
23
+
24
+ enum Status {
25
+ active // Visible and usable in production
26
+ suspended // Temporarily disabled but can be restored
27
+ deleted // Soft-deleted or removed from UI
28
+ draft // Being worked on but not yet published
29
+ pending_review // Awaiting manual or automated approval
30
+ deprecated // Old but still accessible for legacy users
31
+ archived // Hidden from new users, preserved for history
32
+ disconnected
33
+ }
34
+
35
+ enum Plan {
36
+ free
37
+ starter
38
+ pro
39
+ business
40
+ enterprise
41
+ }
42
+
43
+ enum AuthType {
44
+ credentials
45
+ oauth
46
+ hybrid
47
+ }
48
+
49
+ enum MessageRole {
50
+ user
51
+ assistant
52
+ system
53
+ tool
54
+ moderator
55
+ }
56
+
57
+ enum PostType {
58
+ BLOG
59
+ ANNOUNCEMENT
60
+ SESSION
61
+ }
62
+
63
+ enum ReactionType {
64
+ LIKE
65
+ LOVE
66
+ CLAP
67
+ FIRE
68
+ WOW
69
+ }
70
+
71
+ enum FileCategory {
72
+ avatar
73
+ media
74
+ attachment
75
+ memory
76
+ export
77
+ }
78
+
79
+ enum TwoFactorMethod {
80
+ totp
81
+ email
82
+ webauthn
83
+ }
84
+
85
+ enum SubscriptionStatus {
86
+ created // intent created, payment pending
87
+ active
88
+ trialing
89
+ past_due
90
+ canceled
91
+ paused
92
+ }
93
+
94
+ enum WorkflowStatus {
95
+ draft
96
+ pending_review // NEW: Awaiting user approval
97
+ active
98
+ paused
99
+ archived
100
+ failed // NEW: Execution failures
101
+ }
102
+
103
+ /// NEW: Trigger type enum for workflow automation
104
+ enum TriggerType {
105
+ manual // User-initiated
106
+ scheduled // Cron/time-based
107
+ event // External event
108
+ webhook // Incoming webhook
109
+ condition // When condition met
110
+ }
111
+
112
+ enum WorkflowRunStatus {
113
+ pending // NEW: Queued for execution
114
+ running
115
+ completed
116
+ failed
117
+ canceled
118
+ timeout // NEW: Execution timed out
119
+ }
120
+
121
+ enum WorkflowStepStatus {
122
+ draft
123
+ active
124
+ paused
125
+ deprecated
126
+ }
127
+
128
+ enum WorkflowStepRunStatus {
129
+ pending
130
+ running
131
+ completed
132
+ failed
133
+ skipped
134
+ timeout // NEW: Step timed out
135
+ }
136
+
137
+ enum BillingProvider {
138
+ razorpay
139
+ stripe
140
+ juspay
141
+ }
142
+
143
+ enum SubscriptionEventType {
144
+ created // Subscription object created (before activation)
145
+ activated // First successful activation
146
+ trial_started // Trial period started
147
+ trial_ended // Trial expired or converted
148
+
149
+ charged // Successful recurring or first charge
150
+ payment_failed // Charge attempt failed
151
+ payment_recovered // Previously failed payment later succeeded
152
+
153
+ paused // Subscription paused (manual or system)
154
+ resumed // Subscription resumed after pause
155
+
156
+ plan_changed // Upgrade / downgrade
157
+ quantity_changed // Seats / units changed (enterprise)
158
+
159
+ canceled // User or system initiated cancellation
160
+ completed // Subscription ran its full course
161
+ expired // Ended due to non-payment / mandate expiry
162
+
163
+ refunded // Full or partial refund issued
164
+ }
165
+
166
+ enum InvoiceStatus {
167
+ draft
168
+ open
169
+ paid
170
+ partially_paid
171
+ failed
172
+ void
173
+ refunded
174
+ }
175
+
176
+ enum PaymentMethodType {
177
+ card
178
+ upi
179
+ bank
180
+ wallet
181
+ }
182
+
183
+ enum PaymentMethodStatus {
184
+ active
185
+ inactive
186
+ expired
187
+ revoked
188
+ }
189
+
190
+ enum BillingEventStatus {
191
+ received
192
+ processing
193
+ processed
194
+ failed
195
+ }
196
+
197
+ enum BillingLedgerEntryType {
198
+ charge
199
+ refund
200
+ credit
201
+ debit
202
+ adjustment
203
+ }
204
+
205
+ enum BillingLedgerDirection {
206
+ debit
207
+ credit
208
+ }
209
+
210
+ enum JobStatus {
211
+ pending
212
+ scheduled
213
+ running
214
+ completed
215
+ failed
216
+ dead
217
+ }
218
+
219
+ enum CouponDiscountType {
220
+ percentage
221
+ flat
222
+ }
223
+
224
+ enum CouponRedemptionScope {
225
+ subscription
226
+ invoice
227
+ one_time
228
+ }
229
+
230
+ enum CreditPurchaseStatus {
231
+ pending
232
+ paid
233
+ failed
234
+ refunded
235
+ partially_refunded
236
+ }
237
+
238
+ /// ─────────────────────────────────────────────────────────────
239
+ /// ENUMS FOR MEMORY & RAG SYSTEM
240
+ /// ─────────────────────────────────────────────────────────────
241
+
242
+ enum MemoryType {
243
+ preference // "User prefers formal emails"
244
+ fact // "CEO is John Smith"
245
+ context // "Currently working on Q1 report"
246
+ instruction // "Always CC manager on reports"
247
+ relationship // "John is user's manager"
248
+ }
249
+
250
+ enum MemorySource {
251
+ chat // Extracted from conversation
252
+ document // Extracted from uploaded doc
253
+ integration // Synced from connected service
254
+ explicit // User explicitly told us
255
+ inferred // AI inferred from behavior
256
+ }
257
+
258
+ enum DocumentStatus {
259
+ pending // Queued for processing
260
+ processing // Being chunked/embedded
261
+ completed // Ready for RAG
262
+ failed // Processing error
263
+ archived // No longer active
264
+ }
265
+
266
+ enum DocumentSourceType {
267
+ user_file // From UserFile upload
268
+ integration // From Gmail, Drive, etc
269
+ url // Fetched from URL
270
+ paste // Direct text paste
271
+ chat // Extracted from chat
272
+ }
273
+
274
+ /// ─────────────────────────────────────────────────────────────
275
+ /// ENUMS FOR TOOL SYSTEM
276
+ /// ─────────────────────────────────────────────────────────────
277
+
278
+ enum ToolStatus {
279
+ active
280
+ deprecated
281
+ disabled
282
+ beta
283
+ }
284
+
285
+ /// ─────────────────────────────────────────────
286
+ /// USERS & AUTH
287
+ /// ─────────────────────────────────────────────
288
+
289
+ model User {
290
+ id String @id @default(uuid())
291
+ name String
292
+
293
+ image String? // provider image
294
+ avatarOverrideUrl String?
295
+
296
+ email String @unique
297
+ password String?
298
+ emailVerified DateTime?
299
+ onboarding DateTime?
300
+ role Role @default(user)
301
+ timezone String?
302
+ language String?
303
+ status Status @default(active)
304
+ lastLogin DateTime?
305
+ lastPasswordChange DateTime?
306
+ twoFactorEnabled Boolean @default(false)
307
+
308
+ userTwoFactor UserTwoFactor?
309
+
310
+ metadata Json?
311
+ deletedAt DateTime?
312
+ plan Plan @default(free)
313
+ tokenBalance Int @default(0)
314
+ creditsUsed Int @default(0)
315
+
316
+ chatCount Int @default(0)
317
+ workflowCount Int @default(0)
318
+ integrationCount Int @default(0)
319
+
320
+ lastActiveAt DateTime?
321
+
322
+ authType AuthType @default(oauth)
323
+
324
+ passwordStrength String? // weak | medium | strong
325
+
326
+ storageUsed BigInt @default(0) // bytes
327
+ storageLimit BigInt @default(524288000) // 500 MB (beta)
328
+
329
+ accounts Account[]
330
+ integrations Integration[]
331
+ tokenTransactions TokenTransaction[]
332
+ auditLogs AuditLog[]
333
+ subscriptions Subscription[]
334
+ workspaces Workspace[] @relation("UserWorkspaces")
335
+ defaultWorkspaceId String? @unique
336
+ defaultWorkspace Workspace? @relation("UserDefaultWorkspace", fields: [defaultWorkspaceId], references: [id])
337
+ Workflow Workflow[]
338
+ Notification Notification[]
339
+ Onboarding Onboarding?
340
+ ChatSession ChatSession[]
341
+
342
+ createdAt DateTime @default(now())
343
+ updatedAt DateTime @updatedAt
344
+ posts Post[]
345
+ userSessions UserSession[]
346
+ paymentMethods PaymentMethod[]
347
+ userEmails UserEmail[]
348
+ invoices Invoice[]
349
+ userFiles UserFile[]
350
+ billingCustomers BillingCustomer[]
351
+ billingLedgers BillingLedger[]
352
+ creditPurchases CreditPurchase[]
353
+ refunds Refund[]
354
+
355
+ /// Memory & RAG system relations
356
+ memories Memory[]
357
+ documents Document[]
358
+
359
+ @@index([status])
360
+ }
361
+
362
+ model UserFile {
363
+ id String @id @default(uuid())
364
+ userId String
365
+
366
+ path String // Spaces object key (users/{userId}/{category}/{fileId}.ext)
367
+ size BigInt // bytes
368
+ mimeType String
369
+ category FileCategory
370
+
371
+ /// Link to Document if this file has been ingested for RAG
372
+ documentId String? @unique
373
+
374
+ checksum String? // sha256 or md5 for integrity verification
375
+ metadata Json?
376
+
377
+ createdAt DateTime @default(now())
378
+
379
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
380
+ document Document? @relation(fields: [documentId], references: [id])
381
+
382
+ @@index([userId])
383
+ @@index([category])
384
+ @@index([userId, category])
385
+ }
386
+
387
+ model UserSession {
388
+ id String @id @default(uuid())
389
+ userId String
390
+ ip String?
391
+ userAgent String?
392
+ lastUsed DateTime
393
+
394
+ revoked Boolean @default(false)
395
+ revokedAt DateTime?
396
+
397
+ expiresAt DateTime
398
+ createdAt DateTime @default(now())
399
+
400
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
401
+
402
+ @@index([userId, revoked])
403
+ }
404
+
405
+ model UploadIntent {
406
+ id String @id
407
+ userId String
408
+ category FileCategory
409
+ size BigInt
410
+ objectKey String
411
+ createdAt DateTime @default(now())
412
+
413
+ @@index([userId])
414
+ @@index([userId, category])
415
+ }
416
+
417
+ model UserEmail {
418
+ id String @id @default(uuid())
419
+ userId String
420
+ email String @unique
421
+ verified Boolean @default(false)
422
+ primary Boolean @default(false)
423
+ type String? // billing | security | notifications
424
+ createdAt DateTime @default(now())
425
+
426
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
427
+ }
428
+
429
+ model UserTwoFactor {
430
+ id String @id @default(uuid())
431
+ userId String @unique
432
+
433
+ method TwoFactorMethod @default(totp)
434
+ secret String? // null when disabled or method != totp
435
+ enabled Boolean @default(false)
436
+
437
+ lastVerifiedAt DateTime?
438
+ enabledAt DateTime?
439
+
440
+ recoveryEmailVerifiedAt DateTime?
441
+
442
+ backupCodes Json? // [{ hash, used, usedAt }]
443
+
444
+ createdAt DateTime @default(now())
445
+ updatedAt DateTime @updatedAt
446
+
447
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
448
+
449
+ @@index([userId])
450
+ }
451
+
452
+ model Account {
453
+ id String @id @default(uuid())
454
+ userId String
455
+ type String
456
+ provider String
457
+ providerAccountId String
458
+ refresh_token String? @db.Text
459
+ access_token String? @db.Text
460
+ expires_at Int?
461
+ token_type String?
462
+ scope String?
463
+ id_token String? @db.Text
464
+ session_state String?
465
+
466
+ createdAt DateTime @default(now())
467
+ updatedAt DateTime @updatedAt
468
+
469
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
470
+
471
+ @@unique([provider, providerAccountId])
472
+ }
473
+
474
+ model VerificationToken {
475
+ id String @id @default(uuid())
476
+ email String
477
+ token String @unique
478
+ expiresAt DateTime
479
+
480
+ @@unique([email, token])
481
+ }
482
+
483
+ model PasswordResetToken {
484
+ id String @id @default(uuid())
485
+ email String
486
+ token String @unique
487
+ expiresAt DateTime
488
+
489
+ @@unique([email, token])
490
+ }
491
+
492
+ /// ─────────────────────────────────────────────
493
+ /// WORKSPACES & INTEGRATIONS
494
+ /// ─────────────────────────────────────────────
495
+
496
+ model Workspace {
497
+ id String @id @default(uuid())
498
+ name String
499
+ description String?
500
+ ownerId String
501
+ status Status @default(active)
502
+ deletedAt DateTime?
503
+
504
+ createdAt DateTime @default(now())
505
+ updatedAt DateTime @updatedAt
506
+
507
+ owner User @relation("UserWorkspaces", fields: [ownerId], references: [id])
508
+ defaultFor User? @relation("UserDefaultWorkspace")
509
+
510
+ integrations Integration[]
511
+ aiAgents AIAgent[]
512
+ Workflow Workflow[]
513
+ ChatSession ChatSession[]
514
+
515
+ /// Memory & RAG system relations
516
+ memories Memory[]
517
+ documents Document[]
518
+
519
+ @@index([status])
520
+ @@index([ownerId])
521
+ }
522
+
523
+ model Integration {
524
+ id String @id @default(cuid())
525
+ userId String
526
+ workspaceId String?
527
+ provider String
528
+ providerAccountId String
529
+ integration String
530
+ accessToken String
531
+ refreshToken String?
532
+ expiresAt DateTime?
533
+ scopes Json
534
+ profile Json
535
+ status Status @default(active)
536
+ metadata Json?
537
+ deletedAt DateTime?
538
+
539
+ catalogId String?
540
+ catalog IntegrationCatalog? @relation(fields: [catalogId], references: [id])
541
+
542
+ createdAt DateTime @default(now())
543
+ updatedAt DateTime @updatedAt
544
+
545
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
546
+ workspace Workspace? @relation(fields: [workspaceId], references: [id])
547
+ integrationSyncLog IntegrationSyncLog[]
548
+
549
+ @@unique([userId, provider, integration, workspaceId], name: "user_provider_integration_workspace")
550
+ @@index([workspaceId])
551
+ @@index([status])
552
+ @@map("integrations")
553
+ }
554
+
555
+ model IntegrationCatalog {
556
+ id String @id @default(uuid())
557
+ provider String
558
+ integration String
559
+ name String
560
+ category String?
561
+ showDuringOnboarding Boolean @default(true)
562
+ default Boolean @default(false)
563
+ premium Boolean @default(false)
564
+ iconUrl String?
565
+ description String?
566
+ docsUrl String?
567
+ oauthType String?
568
+ setupInstructions Json?
569
+ status Status @default(draft)
570
+
571
+ // NEW
572
+ capabilities Json?
573
+ examplePrompts String[]
574
+
575
+ createdAt DateTime @default(now())
576
+ updatedAt DateTime @updatedAt
577
+ Integration Integration[]
578
+
579
+ @@unique([provider, integration])
580
+ @@index([status])
581
+ @@map("integration_catalog")
582
+ }
583
+
584
+ model IntegrationSyncLog {
585
+ id String @id @default(uuid())
586
+ integrationId String
587
+ syncStatus String
588
+ errorMessage String?
589
+ timestamp DateTime @default(now())
590
+
591
+ integration Integration @relation(fields: [integrationId], references: [id])
592
+ }
593
+
594
+ /// ─────────────────────────────────────────────
595
+ /// AUTOMATIONS / AI / WORKFLOWS
596
+ /// ─────────────────────────────────────────────
597
+
598
+ model AIAgent {
599
+ id String @id @default(uuid())
600
+ name String
601
+ key String @unique
602
+ description String?
603
+ active Boolean @default(true)
604
+ config Json?
605
+ workspaceId String?
606
+ workspace Workspace? @relation(fields: [workspaceId], references: [id])
607
+
608
+ createdAt DateTime @default(now())
609
+ updatedAt DateTime @updatedAt
610
+
611
+ tokenTransactions TokenTransaction[]
612
+ ChatSession ChatSession[]
613
+ }
614
+
615
+ model UsageAggregate {
616
+ id String @id @default(uuid())
617
+ userId String
618
+ workspaceId String?
619
+ billingPeriod String
620
+ source String // chat | automation | api
621
+ tokensUsed Int
622
+ requestCount Int
623
+ updatedAt DateTime @updatedAt
624
+
625
+ @@unique([userId, workspaceId, billingPeriod, source])
626
+ }
627
+
628
+ model TokenTransaction {
629
+ id String @id @default(uuid())
630
+ userId String
631
+ agentId String?
632
+ tokensUsed Int
633
+ action String
634
+
635
+ source String? // chat | automation | api
636
+ workspaceId String?
637
+ integration String?
638
+
639
+ billingPeriod String? // e.g. "2025-01" (YYYY-MM)
640
+
641
+ metadata Json?
642
+ createdAt DateTime @default(now())
643
+
644
+ user User @relation(fields: [userId], references: [id])
645
+ agent AIAgent? @relation(fields: [agentId], references: [id])
646
+ }
647
+
648
+ model Workflow {
649
+ id String @id @default(uuid())
650
+ name String
651
+ description String?
652
+ status WorkflowStatus @default(active)
653
+ userId String
654
+ workspaceId String?
655
+
656
+ /// Full workflow spec from AI service (for AI-generated workflows)
657
+ /// Includes: trigger, conditions, actions, etc.
658
+ spec Json?
659
+
660
+ /// How this workflow is triggered
661
+ triggerType TriggerType?
662
+
663
+ /// Trigger configuration (e.g., cron schedule)
664
+ triggerConfig Json?
665
+
666
+ /// Which integrations this workflow needs
667
+ /// e.g., ["gmail", "calendar", "slack"]
668
+ requiredIntegrations String[] @default([])
669
+
670
+ /// Execution stats
671
+ runCount Int @default(0)
672
+ lastRunAt DateTime?
673
+ lastRunStatus String?
674
+
675
+ /// For scheduled workflows
676
+ nextScheduledAt DateTime?
677
+
678
+ /// Soft delete support
679
+ deletedAt DateTime?
680
+
681
+ metadata Json?
682
+
683
+ createdAt DateTime @default(now())
684
+ updatedAt DateTime @updatedAt
685
+
686
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
687
+ workspace Workspace? @relation(fields: [workspaceId], references: [id])
688
+ steps WorkflowStep[]
689
+ runs WorkflowRun[]
690
+
691
+ @@index([userId, status])
692
+ @@index([triggerType])
693
+ @@index([nextScheduledAt])
694
+ }
695
+
696
+ model WorkflowStep {
697
+ id String @id @default(uuid())
698
+ workflowId String
699
+ type String
700
+ config Json
701
+ order Int
702
+ status WorkflowStepStatus @default(active)
703
+
704
+ /// What action this step performs (for AI-generated)
705
+ /// e.g., "email.send", "calendar.create", "slack.post"
706
+ actionTarget String?
707
+
708
+ /// Which integration is required for this step
709
+ integrationId String?
710
+
711
+ /// Whether this step requires user confirmation before executing
712
+ requiresConfirmation Boolean @default(false)
713
+
714
+ workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
715
+
716
+ createdAt DateTime @default(now())
717
+ updatedAt DateTime @updatedAt
718
+ stepRuns WorkflowStepRun[]
719
+
720
+ @@index([workflowId, order])
721
+ @@index([actionTarget])
722
+ }
723
+
724
+ model WorkflowRun {
725
+ id String @id @default(uuid())
726
+ workflowId String
727
+
728
+ /// Link to Job table for background execution tracking
729
+ jobId String? @unique
730
+
731
+ status WorkflowRunStatus @default(pending)
732
+
733
+ /// What triggered this run
734
+ triggeredBy String? // user_id, scheduler, event_id
735
+ triggerType String? // manual, scheduled, event
736
+
737
+ /// Input to this run (trigger payload)
738
+ input Json?
739
+
740
+ /// Final output
741
+ output Json?
742
+
743
+ /// Error message if failed
744
+ error String?
745
+
746
+ startedAt DateTime?
747
+ finishedAt DateTime?
748
+
749
+ /// How long execution took
750
+ durationMs Int?
751
+
752
+ /// Tokens used for this run (for AI workflows)
753
+ tokensUsed Int?
754
+
755
+ metadata Json?
756
+
757
+ createdAt DateTime @default(now())
758
+
759
+ workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
760
+
761
+ /// Link to Job for background execution
762
+ job Job? @relation(fields: [jobId], references: [id])
763
+
764
+ steps WorkflowStepRun[]
765
+
766
+ @@index([workflowId, startedAt])
767
+ @@index([status])
768
+ }
769
+
770
+ model WorkflowStepRun {
771
+ id String @id @default(uuid())
772
+ workflowRunId String
773
+ workflowStepId String
774
+
775
+ /// Step index for ordering (useful for AI-generated dynamic steps)
776
+ stepIndex Int?
777
+
778
+ status WorkflowStepRunStatus @default(pending)
779
+
780
+ /// Input to this step
781
+ input Json?
782
+
783
+ /// Output from this step
784
+ output Json?
785
+
786
+ /// Error if step failed
787
+ error String?
788
+
789
+ /// Which integration was used for this step
790
+ integrationId String?
791
+
792
+ /// External request/order ID (for tracking in external system)
793
+ externalRequestId String?
794
+
795
+ startedAt DateTime?
796
+ finishedAt DateTime?
797
+
798
+ /// Step execution time
799
+ durationMs Int?
800
+
801
+ /// How many times this step was retried
802
+ retryCount Int @default(0)
803
+
804
+ metadata Json?
805
+
806
+ createdAt DateTime @default(now())
807
+
808
+ workflowRun WorkflowRun @relation(fields: [workflowRunId], references: [id], onDelete: Cascade)
809
+ workflowStep WorkflowStep @relation(fields: [workflowStepId], references: [id])
810
+
811
+ @@index([workflowRunId, stepIndex])
812
+ @@index([workflowStepId])
813
+ }
814
+
815
+ /// ─────────────────────────────────────────────────────────────
816
+ /// MEMORY SYSTEM (USER CONTEXT PERSISTENCE)
817
+ /// ─────────────────────────────────────────────────────────────
818
+
819
+ /// Lightweight facts about user learned over time
820
+ /// Examples:
821
+ /// - "Prefers formal email tone"
822
+ /// - "CEO is Jane Smith"
823
+ /// - "Current project is Q1 launch"
824
+ model Memory {
825
+ id String @id @default(uuid())
826
+ userId String
827
+ workspaceId String?
828
+
829
+ /// Type of memory: preference, fact, context, instruction, relationship
830
+ type MemoryType
831
+
832
+ /// Where this memory came from: chat, document, integration, explicit, inferred
833
+ source MemorySource
834
+
835
+ /// The actual memory content
836
+ content String @db.Text
837
+
838
+ /// Optional condensed version for quick retrieval
839
+ summary String?
840
+
841
+ /// Importance scoring (0-1 scale)
842
+ /// Decays over time for less relevant memories
843
+ importance Float @default(0.5)
844
+
845
+ /// How many times this memory was accessed/recalled
846
+ accessCount Int @default(0)
847
+
848
+ /// Last time this memory was used in response
849
+ lastAccessed DateTime?
850
+
851
+ /// Source tracking - where this memory came from
852
+ sourceId String? // chatSessionId, documentId, workflowRunId
853
+ sourceType String? // chat, document, workflow, integration
854
+
855
+ /// TTL for temporary memories
856
+ expiresAt DateTime?
857
+
858
+ /// Soft delete
859
+ active Boolean @default(true)
860
+
861
+ metadata Json?
862
+
863
+ createdAt DateTime @default(now())
864
+ updatedAt DateTime @updatedAt
865
+
866
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
867
+ workspace Workspace? @relation(fields: [workspaceId], references: [id])
868
+
869
+ @@index([userId, type, active])
870
+ @@index([userId, importance])
871
+ @@index([expiresAt])
872
+ }
873
+
874
+ /// ─────────────────────────────────────────────────────────────
875
+ /// DOCUMENT SYSTEM (RAG - RETRIEVAL AUGMENTED GENERATION)
876
+ /// ─────────────────────────────────────────────────────────────
877
+
878
+ /// Tracks document ingestion progress
879
+ /// When user uploads a file, Document record created
880
+ /// Workers then chunk, embed, and store DocumentChunks
881
+ model Document {
882
+ id String @id @default(uuid())
883
+ userId String
884
+ workspaceId String?
885
+
886
+ /// Where document came from
887
+ sourceType DocumentSourceType
888
+
889
+ /// ID of the source (e.g., UserFile.id, Integration.id)
890
+ sourceId String?
891
+
892
+ /// Original name/title
893
+ sourceName String?
894
+
895
+ /// Original URL (for web sources)
896
+ sourceUrl String?
897
+
898
+ /// Raw content stored temporarily during processing
899
+ rawContent String? @db.Text
900
+
901
+ /// MIME type (application/pdf, text/plain, etc.)
902
+ mimeType String?
903
+
904
+ /// Ingestion status
905
+ status DocumentStatus @default(pending)
906
+
907
+ /// How many chunks were created
908
+ chunkCount Int @default(0)
909
+
910
+ /// Error message if ingestion failed
911
+ error String?
912
+
913
+ /// AI-generated summary of document
914
+ summary String?
915
+
916
+ /// Extracted topics/tags from content
917
+ topics String[] @default([])
918
+
919
+ metadata Json?
920
+
921
+ processedAt DateTime?
922
+ createdAt DateTime @default(now())
923
+ updatedAt DateTime @updatedAt
924
+
925
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
926
+ workspace Workspace? @relation(fields: [workspaceId], references: [id])
927
+
928
+ /// Chunks of this document
929
+ chunks DocumentChunk[]
930
+
931
+ /// If this document came from UserFile, link it
932
+ userFile UserFile?
933
+
934
+ @@index([userId, status])
935
+ @@index([sourceType, sourceId])
936
+ @@index([status])
937
+ }
938
+
939
+ /// Chunks of documents for semantic search
940
+ /// Created by ingestion worker
941
+ /// Examples: paragraphs from PDF, sections from doc, etc.
942
+ model DocumentChunk {
943
+ id String @id @default(uuid())
944
+ documentId String
945
+
946
+ /// Order within document (for context)
947
+ chunkIndex Int
948
+
949
+ /// The actual text content
950
+ content String @db.Text
951
+
952
+ /// Tokens in this chunk (for context window management)
953
+ tokenCount Int?
954
+
955
+ /// Position in original document (for citation)
956
+ startChar Int?
957
+ endChar Int?
958
+
959
+ /// Metadata from original
960
+ sectionTitle String?
961
+ pageNumber Int?
962
+
963
+ metadata Json?
964
+
965
+ createdAt DateTime @default(now())
966
+
967
+ document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
968
+
969
+ /// Note: Vector index needs to be added via raw SQL:
970
+ /// CREATE INDEX ON "DocumentChunk" USING ivfflat (embedding vector_cosine_ops)
971
+
972
+ @@index([documentId, chunkIndex])
973
+ }
974
+
975
+ /// Summaries of conversations for context window management
976
+ /// When conversation gets long, summarize earlier parts
977
+ /// Keep summary in context instead of full messages
978
+ model ConversationSummary {
979
+ id String @id @default(uuid())
980
+ chatSessionId String
981
+
982
+ /// Which messages are summarized
983
+ fromMessageId String?
984
+ toMessageId String?
985
+ messageCount Int
986
+
987
+ /// Summary text
988
+ summary String @db.Text
989
+
990
+ /// Key points extracted (for quick reference)
991
+ keyPoints Json?
992
+
993
+ createdAt DateTime @default(now())
994
+
995
+ chatSession ChatSession @relation(fields: [chatSessionId], references: [id], onDelete: Cascade)
996
+
997
+ @@index([chatSessionId, createdAt])
998
+ }
999
+
1000
+ /// ─────────────────────────────────────────────
1001
+ /// COMMUNICATION / CHAT / EMAIL
1002
+ /// ─────────────────────────────────────────────
1003
+
1004
+ model Notification {
1005
+ id String @id @default(uuid())
1006
+ userId String?
1007
+ type String
1008
+ title String
1009
+ body String?
1010
+ read Boolean @default(false)
1011
+
1012
+ createdAt DateTime @default(now())
1013
+
1014
+ user User? @relation(fields: [userId], references: [id])
1015
+ }
1016
+
1017
+ model ChatSession {
1018
+ id String @id @default(uuid())
1019
+ title String?
1020
+ userId String?
1021
+ workspaceId String?
1022
+ aiAgentId String?
1023
+ status String @default("active")
1024
+
1025
+ /// Memory and RAG context management
1026
+ contextMode String? @default("standard") // standard | deep | rag
1027
+ memoryEnabled Boolean @default(true)
1028
+
1029
+ /// Track summarization for long conversations
1030
+ lastSummaryAt DateTime?
1031
+ summaryCount Int @default(0)
1032
+
1033
+ metadata Json?
1034
+ deletedAt DateTime?
1035
+
1036
+ user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
1037
+ workspace Workspace? @relation(fields: [workspaceId], references: [id])
1038
+ aiAgent AIAgent? @relation(fields: [aiAgentId], references: [id])
1039
+ messages ChatMessage[]
1040
+ summaries ConversationSummary[]
1041
+
1042
+ createdAt DateTime @default(now())
1043
+ updatedAt DateTime @updatedAt
1044
+
1045
+ @@index([userId, createdAt])
1046
+ @@index([workspaceId, createdAt])
1047
+ @@index([status])
1048
+ }
1049
+
1050
+ model ChatMessage {
1051
+ id String @id @default(uuid())
1052
+ chatSessionId String
1053
+ sender MessageRole
1054
+ content String
1055
+ style String?
1056
+ tokensUsed Int?
1057
+
1058
+ /// Track which memories/documents/tools were used to generate this message
1059
+ memoriesUsed String[] @default([]) // IDs of Memory records used
1060
+ documentsUsed String[] @default([]) // IDs of DocumentChunk records used
1061
+ toolsUsed String[] @default([]) // IDs of Tool records used
1062
+
1063
+ /// Mark important messages for memory extraction
1064
+ isKeyMessage Boolean @default(false)
1065
+
1066
+ metadata Json?
1067
+ deletedAt DateTime?
1068
+
1069
+ chatSession ChatSession @relation(fields: [chatSessionId], references: [id])
1070
+
1071
+ createdAt DateTime @default(now())
1072
+
1073
+ @@index([chatSessionId, createdAt])
1074
+ @@index([isKeyMessage])
1075
+ }
1076
+
1077
+ model EmailLog {
1078
+ id String @id @default(uuid())
1079
+ to String
1080
+ subject String
1081
+ type String // verification, marketing, notification, etc.
1082
+ status String @default("sent")
1083
+ metadata Json?
1084
+ sentAt DateTime @default(now())
1085
+ error String?
1086
+ }
1087
+
1088
+ /// ─────────────────────────────────────────────
1089
+ /// WORKFLOW TEMPLATES & ONBOARDING PERSONAS
1090
+ /// ─────────────────────────────────────────────
1091
+
1092
+ model WorkflowTemplate {
1093
+ id String @id @default(uuid())
1094
+ name String
1095
+ description String?
1096
+ category String?
1097
+ recommended Boolean @default(false)
1098
+ iconUrl String?
1099
+ estimatedSetupTime Int?
1100
+ status Status @default(active)
1101
+
1102
+ createdAt DateTime @default(now())
1103
+ updatedAt DateTime @updatedAt
1104
+
1105
+ steps WorkflowStepTemplate[]
1106
+ }
1107
+
1108
+ model WorkflowStepTemplate {
1109
+ id String @id @default(uuid())
1110
+ templateId String
1111
+ type String
1112
+ config Json
1113
+ order Int
1114
+ status String @default("active")
1115
+
1116
+ template WorkflowTemplate @relation(fields: [templateId], references: [id])
1117
+ }
1118
+
1119
+ model OnboardingPersona {
1120
+ id String @id @default(uuid())
1121
+ key String @unique
1122
+ title String
1123
+ description String?
1124
+ iconUrl String?
1125
+ recommended Boolean @default(false)
1126
+ status Status @default(active)
1127
+
1128
+ createdAt DateTime @default(now())
1129
+ updatedAt DateTime @updatedAt
1130
+ }
1131
+
1132
+ /// ─────────────────────────────────────────────
1133
+ /// MONITORING / ADMIN / SYSTEM CONFIG
1134
+ /// ─────────────────────────────────────────────
1135
+
1136
+ model Service {
1137
+ id String @id @default(uuid())
1138
+ name String
1139
+ description String?
1140
+ endpoint String
1141
+ status String @default("healthy")
1142
+ lastPing DateTime?
1143
+ uptime Float?
1144
+ region String?
1145
+ metadata Json?
1146
+ createdAt DateTime @default(now())
1147
+ updatedAt DateTime @updatedAt
1148
+
1149
+ logs ServiceLog[]
1150
+ errors ErrorLog[]
1151
+ }
1152
+
1153
+ model ServiceLog {
1154
+ id String @id @default(uuid())
1155
+ serviceId String
1156
+ level String
1157
+ message String
1158
+ metadata Json?
1159
+ createdAt DateTime @default(now())
1160
+
1161
+ service Service @relation(fields: [serviceId], references: [id])
1162
+ }
1163
+
1164
+ model ErrorLog {
1165
+ id String @id @default(uuid())
1166
+ serviceId String?
1167
+ errorType String?
1168
+ message String
1169
+ stackTrace String?
1170
+ context Json?
1171
+ createdAt DateTime @default(now())
1172
+
1173
+ service Service? @relation(fields: [serviceId], references: [id])
1174
+ }
1175
+
1176
+ model SystemConfig {
1177
+ id String @id @default(uuid())
1178
+ key String @unique
1179
+ value Json
1180
+ category String?
1181
+ updatedAt DateTime @updatedAt
1182
+ }
1183
+
1184
+ model AuditLog {
1185
+ id String @id @default(uuid())
1186
+ userId String?
1187
+ actorRole Role?
1188
+ eventType String
1189
+ targetType String?
1190
+ targetId String?
1191
+ description String?
1192
+ metadata Json?
1193
+ createdAt DateTime @default(now())
1194
+
1195
+ user User? @relation(fields: [userId], references: [id])
1196
+
1197
+ @@index([userId, createdAt])
1198
+ }
1199
+
1200
+ model SecurityEvent {
1201
+ id String @id @default(uuid())
1202
+ userId String?
1203
+ type String // login | logout | password_change | session_revoked
1204
+ ip String?
1205
+ userAgent String?
1206
+ success Boolean
1207
+ metadata Json?
1208
+ createdAt DateTime @default(now())
1209
+
1210
+ @@index([userId, createdAt])
1211
+ }
1212
+
1213
+ /// ─────────────────────────────────────────────
1214
+ /// BILLING / WAITLIST / JOBS / ONBOARDING
1215
+ /// ─────────────────────────────────────────────
1216
+
1217
+ model Subscription {
1218
+ id String @id @default(uuid())
1219
+
1220
+ userId String
1221
+ plan Plan
1222
+ status SubscriptionStatus
1223
+
1224
+ provider BillingProvider // razorpay | stripe | juspay
1225
+ providerSubscriptionId String @unique
1226
+ providerPlanId String?
1227
+
1228
+ billingCustomerId String
1229
+
1230
+ // Lifecycle
1231
+ startedAt DateTime
1232
+ endedAt DateTime?
1233
+
1234
+ // Billing cycle
1235
+ currentPeriodStart DateTime?
1236
+ currentPeriodEnd DateTime?
1237
+ nextPayment DateTime?
1238
+
1239
+ metadata Json?
1240
+
1241
+ user User @relation(fields: [userId], references: [id])
1242
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
1243
+ invoices Invoice[]
1244
+ subscriptionEvents SubscriptionEvent[]
1245
+
1246
+ @@index([provider, providerSubscriptionId])
1247
+ @@index([billingCustomerId])
1248
+ }
1249
+
1250
+ model Invoice {
1251
+ id String @id @default(uuid())
1252
+
1253
+ userId String
1254
+ subscriptionId String?
1255
+ billingCustomerId String
1256
+
1257
+ provider BillingProvider // razorpay | stripe | juspay
1258
+ providerInvoiceId String
1259
+
1260
+ amount Int
1261
+ currency String
1262
+ status InvoiceStatus
1263
+
1264
+ periodStart DateTime?
1265
+ periodEnd DateTime?
1266
+
1267
+ hostedInvoiceUrl String?
1268
+ pdfUrl String?
1269
+
1270
+ metadata Json?
1271
+
1272
+ createdAt DateTime @default(now())
1273
+
1274
+ user User @relation(fields: [userId], references: [id])
1275
+ subscription Subscription? @relation(fields: [subscriptionId], references: [id])
1276
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
1277
+
1278
+ @@unique([provider, providerInvoiceId])
1279
+ @@index([billingCustomerId])
1280
+ }
1281
+
1282
+ model BillingEvent {
1283
+ id String @id @default(uuid())
1284
+
1285
+ provider BillingProvider // razorpay | stripe | juspay
1286
+ eventType String
1287
+ eventId String
1288
+
1289
+ payload Json
1290
+
1291
+ status BillingEventStatus @default(received)
1292
+ processedAt DateTime?
1293
+ error String?
1294
+
1295
+ createdAt DateTime @default(now())
1296
+
1297
+ @@unique([provider, eventId])
1298
+ @@index([provider, eventType])
1299
+ }
1300
+
1301
+ model PaymentMethod {
1302
+ id String @id @default(uuid())
1303
+
1304
+ userId String
1305
+ billingCustomerId String
1306
+
1307
+ provider BillingProvider // razorpay | stripe | juspay
1308
+ providerPaymentMethodId String // token_xxx, pm_xxx
1309
+
1310
+ type PaymentMethodType // card | upi | bank
1311
+ brand String?
1312
+ last4 String?
1313
+ expMonth Int?
1314
+ expYear Int?
1315
+
1316
+ isDefault Boolean @default(false)
1317
+ status PaymentMethodStatus @default(active)
1318
+
1319
+ metadata Json?
1320
+
1321
+ createdAt DateTime @default(now())
1322
+ updatedAt DateTime @updatedAt
1323
+
1324
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1325
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
1326
+
1327
+ @@unique([provider, providerPaymentMethodId])
1328
+ @@index([billingCustomerId])
1329
+ }
1330
+
1331
+ model BillingCustomer {
1332
+ id String @id @default(uuid())
1333
+
1334
+ userId String
1335
+ provider BillingProvider // razorpay | stripe | juspay
1336
+ providerCustomerId String // cust_xxx, cus_xxx
1337
+
1338
+ email String?
1339
+ metadata Json?
1340
+
1341
+ createdAt DateTime @default(now())
1342
+ updatedAt DateTime @updatedAt
1343
+
1344
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1345
+ subscriptions Subscription[]
1346
+ invoices Invoice[]
1347
+ paymentMethods PaymentMethod[]
1348
+ billingLedgers BillingLedger[]
1349
+ creditPurchases CreditPurchase[]
1350
+ refunds Refund[]
1351
+
1352
+ @@unique([provider, providerCustomerId])
1353
+ @@unique([userId, provider])
1354
+ @@index([providerCustomerId])
1355
+ }
1356
+
1357
+ model SubscriptionEvent {
1358
+ id String @id @default(uuid())
1359
+
1360
+ subscriptionId String
1361
+ provider BillingProvider
1362
+ eventType SubscriptionEventType
1363
+ payload Json
1364
+
1365
+ createdAt DateTime @default(now())
1366
+
1367
+ subscription Subscription @relation(fields: [subscriptionId], references: [id])
1368
+
1369
+ @@index([subscriptionId, createdAt])
1370
+ }
1371
+
1372
+ model BillingLedger {
1373
+ id String @id @default(uuid())
1374
+
1375
+ userId String
1376
+ billingCustomerId String
1377
+
1378
+ provider BillingProvider
1379
+
1380
+ entryType BillingLedgerEntryType // charge | refund | credit | debit | adjustment
1381
+ direction BillingLedgerDirection // debit | credit
1382
+
1383
+ amount Int
1384
+ currency String
1385
+
1386
+ referenceType String // invoice | subscription | payment | coupon | reward
1387
+ referenceId String
1388
+
1389
+ description String?
1390
+ metadata Json?
1391
+
1392
+ createdAt DateTime @default(now())
1393
+
1394
+ user User @relation(fields: [userId], references: [id])
1395
+ billingCustomer BillingCustomer @relation(fields: [billingCustomerId], references: [id])
1396
+
1397
+ @@index([userId, createdAt])
1398
+ @@index([billingCustomerId, createdAt])
1399
+ @@index([provider, createdAt])
1400
+ }
1401
+
1402
+ model Coupon {
1403
+ id String @id @default(uuid())
1404
+
1405
+ code String @unique
1406
+
1407
+ discountType CouponDiscountType
1408
+ discountValue Int // % or flat amount (minor units)
1409
+
1410
+ currency String? // required for flat discounts
1411
+
1412
+ maxRedemptions Int?
1413
+ redeemedCount Int @default(0)
1414
+
1415
+ validFrom DateTime?
1416
+ validUntil DateTime?
1417
+
1418
+ applicablePlans Plan[]
1419
+ redemptionScope CouponRedemptionScope
1420
+
1421
+ active Boolean @default(true)
1422
+
1423
+ metadata Json?
1424
+
1425
+ createdAt DateTime @default(now())
1426
+ updatedAt DateTime @updatedAt
1427
+ creditPurchases CreditPurchase[]
1428
+ }
1429
+
1430
+ model RevenueAggregate {
1431
+ id String @id @default(uuid())
1432
+
1433
+ period String // YYYY-MM (e.g. 2026-02)
1434
+ provider BillingProvider
1435
+
1436
+ grossRevenue Int
1437
+ refunds Int
1438
+ credits Int
1439
+ netRevenue Int
1440
+
1441
+ currency String
1442
+
1443
+ updatedAt DateTime @updatedAt
1444
+
1445
+ @@unique([period, provider, currency])
1446
+ @@index([period])
1447
+ }
1448
+
1449
+ model WaitList {
1450
+ id String @id @default(uuid())
1451
+ email String @unique
1452
+ name String?
1453
+ company String?
1454
+ role String?
1455
+ teamSize String?
1456
+ useCase String?
1457
+ consentToUpdates Boolean
1458
+ referralCode String? @unique
1459
+ referredBy String?
1460
+
1461
+ createdAt DateTime @default(now())
1462
+ updatedAt DateTime @updatedAt
1463
+ }
1464
+
1465
+ model Job {
1466
+ id String @id @default(uuid())
1467
+ type String
1468
+ status JobStatus @default(pending)
1469
+ payload Json
1470
+
1471
+ /// Retry management
1472
+ retries Int @default(0)
1473
+ maxRetries Int @default(3)
1474
+ lastError String?
1475
+ /// Track all errors for debugging
1476
+ errorHistory Json?
1477
+
1478
+ /// Exponential backoff handling
1479
+ nextRetryAt DateTime?
1480
+ backoffMs Int @default(1000)
1481
+
1482
+ /// Priority for queue ordering
1483
+ priority Int @default(0) // Higher = more urgent
1484
+
1485
+ /// Which queue this belongs to
1486
+ queueName String @default("default")
1487
+
1488
+ /// Job locking (for distributed workers)
1489
+ lockedBy String? // Worker instance ID
1490
+ lockedAt DateTime?
1491
+ lockTimeout DateTime?
1492
+
1493
+ /// Progress tracking for long-running jobs
1494
+ progress Int? // 0-100 percentage
1495
+ progressMessage String?
1496
+
1497
+ /// Timing
1498
+ scheduledAt DateTime?
1499
+ startedAt DateTime?
1500
+ finishedAt DateTime?
1501
+
1502
+ /// Execution timeout
1503
+ timeoutMs Int?
1504
+
1505
+ /// Dead letter handling
1506
+ movedToDlq Boolean @default(false)
1507
+ dlqReason String?
1508
+
1509
+ /// Idempotency check
1510
+ idempotencyKey String? @unique
1511
+
1512
+ /// Links to domain models
1513
+ userId String?
1514
+ workflowRunId String?
1515
+
1516
+ metadata Json?
1517
+
1518
+ createdAt DateTime @default(now())
1519
+ updatedAt DateTime @updatedAt
1520
+
1521
+ workflowRun WorkflowRun?
1522
+
1523
+ @@index([status, scheduledAt])
1524
+ @@index([status, priority])
1525
+ @@index([queueName, status])
1526
+ @@index([lockedBy, status])
1527
+ @@index([type, status])
1528
+ @@index([userId])
1529
+ @@index([movedToDlq])
1530
+ }
1531
+
1532
+ model Onboarding {
1533
+ id String @id @default(uuid())
1534
+ userId String @unique
1535
+ persona String?
1536
+ setupType String?
1537
+ progress Json?
1538
+ completed Boolean @default(false)
1539
+
1540
+ createdAt DateTime @default(now())
1541
+ updatedAt DateTime @updatedAt
1542
+
1543
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1544
+ }
1545
+
1546
+ /////////////////////
1547
+ // Unique Visitors
1548
+ //////////////////////
1549
+ model Visitor {
1550
+ id String @id @default(uuid())
1551
+ visitorId String @unique // cookie or fingerprint ID
1552
+ ipAddress String?
1553
+ userAgent String?
1554
+ country String? // optional if you plan to use GeoIP later
1555
+ referrer String?
1556
+ firstVisit DateTime @default(now())
1557
+ lastVisit DateTime @updatedAt
1558
+ visitCount Int @default(1)
1559
+
1560
+ createdAt DateTime @default(now())
1561
+ updatedAt DateTime @updatedAt
1562
+ postReactions PostReaction[]
1563
+ postShares PostShare[]
1564
+
1565
+ @@index([createdAt])
1566
+ }
1567
+
1568
+ model EmailCampaign {
1569
+ id String @id @default(uuid())
1570
+ name String
1571
+ templateId String
1572
+ subject String
1573
+ audience String // e.g. "waitlist", "users", "custom"
1574
+ segmentFilter Json? // optional query/filter metadata
1575
+ sentCount Int @default(0)
1576
+ status String @default("draft") // draft | sending | sent | failed
1577
+ metadata Json?
1578
+ createdById String?
1579
+ createdAt DateTime @default(now())
1580
+ updatedAt DateTime @updatedAt
1581
+
1582
+ logs EmailSendLog[]
1583
+ }
1584
+
1585
+ model EmailSendLog {
1586
+ id String @id @default(uuid())
1587
+ campaignId String
1588
+ recipient String
1589
+ status String
1590
+ messageId String?
1591
+ error String?
1592
+ metadata Json?
1593
+ sentAt DateTime @default(now())
1594
+ openCount Int @default(0)
1595
+ clickCount Int @default(0)
1596
+ lastEventAt DateTime?
1597
+
1598
+ campaign EmailCampaign @relation(fields: [campaignId], references: [id])
1599
+ }
1600
+
1601
+ model Post {
1602
+ id String @id @default(uuid())
1603
+ title String
1604
+ slug String @unique
1605
+ excerpt String?
1606
+ type PostType @default(BLOG)
1607
+ status Status @default(draft)
1608
+
1609
+ content Json
1610
+ contentHtml String?
1611
+
1612
+ featuredImage String?
1613
+
1614
+ // many-to-many pivot
1615
+ tags PostTag[] @relation("PostTags")
1616
+
1617
+ authorId String?
1618
+ author User? @relation(fields: [authorId], references: [id])
1619
+
1620
+ publishedAt DateTime?
1621
+ createdAt DateTime @default(now())
1622
+ updatedAt DateTime @updatedAt
1623
+ postComments PostComment[]
1624
+ postReactions PostReaction[]
1625
+ postShares PostShare[]
1626
+
1627
+ @@index([type])
1628
+ @@index([status])
1629
+ @@index([publishedAt])
1630
+ }
1631
+
1632
+ model Tag {
1633
+ id String @id @default(uuid())
1634
+ name String @unique
1635
+ color String @default("blue")
1636
+ // inverse many-to-many pivot
1637
+ posts PostTag[] @relation("PostTags")
1638
+ }
1639
+
1640
+ model PostTag {
1641
+ postId String
1642
+ tagId String
1643
+
1644
+ // Add relation names
1645
+ post Post @relation("PostTags", fields: [postId], references: [id], onDelete: Cascade)
1646
+ tag Tag @relation("PostTags", fields: [tagId], references: [id], onDelete: Cascade)
1647
+
1648
+ @@id([postId, tagId])
1649
+ @@index([tagId])
1650
+ }
1651
+
1652
+ /// ─────────────────────────────────────────────
1653
+ /// COMMENT IDENTITIES (Name + Email Login-less System)
1654
+ /// ─────────────────────────────────────────────
1655
+
1656
+ model CommentIdentity {
1657
+ id String @id @default(uuid())
1658
+ name String
1659
+ email String @unique
1660
+ verified Boolean @default(false)
1661
+ metadata Json?
1662
+
1663
+ createdAt DateTime @default(now())
1664
+ updatedAt DateTime @updatedAt
1665
+
1666
+ comments PostComment[]
1667
+ postReactions PostReaction[]
1668
+ postShares PostShare[]
1669
+
1670
+ @@index([email])
1671
+ }
1672
+
1673
+ /// ─────────────────────────────────────────────
1674
+ /// POST COMMENTS (Revised to use CommentIdentity)
1675
+ /// ─────────────────────────────────────────────
1676
+
1677
+ model PostComment {
1678
+ id String @id @default(uuid())
1679
+ postId String
1680
+ identityId String? // Instead of userId (for public commenters)
1681
+ parentId String? // Threaded comments
1682
+
1683
+ content String
1684
+ status Status @default(active)
1685
+ deletedAt DateTime?
1686
+
1687
+ // Relations
1688
+ post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
1689
+ identity CommentIdentity? @relation(fields: [identityId], references: [id])
1690
+ parent PostComment? @relation("CommentReplies", fields: [parentId], references: [id])
1691
+ replies PostComment[] @relation("CommentReplies")
1692
+
1693
+ createdAt DateTime @default(now())
1694
+ updatedAt DateTime @updatedAt
1695
+
1696
+ @@index([postId])
1697
+ @@index([identityId])
1698
+ @@index([parentId])
1699
+ @@index([status])
1700
+ }
1701
+
1702
+ /// ─────────────────────────────────────────────
1703
+ /// POST REACTIONS (LIKE, LOVE, CLAP, FIRE, WOW)
1704
+ /// ─────────────────────────────────────────────
1705
+
1706
+ model PostReaction {
1707
+ id String @id @default(uuid())
1708
+ postId String
1709
+ visitorId String? // Could be Visitor.visitorId
1710
+ identityId String? // If commenter also reacts
1711
+ type ReactionType
1712
+
1713
+ status Status @default(active)
1714
+ deletedAt DateTime?
1715
+
1716
+ post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
1717
+ visitor Visitor? @relation(fields: [visitorId], references: [visitorId])
1718
+ identity CommentIdentity? @relation(fields: [identityId], references: [id])
1719
+
1720
+ createdAt DateTime @default(now())
1721
+ updatedAt DateTime @updatedAt
1722
+
1723
+ @@unique([postId, visitorId, type])
1724
+ @@unique([postId, identityId, type])
1725
+ @@index([postId])
1726
+ @@index([visitorId])
1727
+ @@index([identityId])
1728
+ @@index([type])
1729
+ }
1730
+
1731
+ /// ─────────────────────────────────────────────
1732
+ /// POST SHARES (Analytics + Share Platform Info)
1733
+ /// ─────────────────────────────────────────────
1734
+
1735
+ model PostShare {
1736
+ id String @id @default(uuid())
1737
+ postId String
1738
+ visitorId String?
1739
+ identityId String?
1740
+ platform String? // twitter | whatsapp | copy | linkedin | etc.
1741
+ metadata Json?
1742
+
1743
+ post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
1744
+ visitor Visitor? @relation(fields: [visitorId], references: [visitorId])
1745
+ identity CommentIdentity? @relation(fields: [identityId], references: [id])
1746
+
1747
+ createdAt DateTime @default(now())
1748
+
1749
+ @@index([postId])
1750
+ @@index([visitorId])
1751
+ @@index([identityId])
1752
+ @@index([platform])
1753
+ }
1754
+
1755
+ //// _________________________________________________________________
1756
+ //// CREDITS PURCHASES & REFUNDS
1757
+ //// _________________________________________________________________
1758
+
1759
+ model CreditPurchase {
1760
+ id String @id @default(uuid())
1761
+
1762
+ userId String
1763
+ billingCustomerId String?
1764
+
1765
+ provider BillingProvider
1766
+ providerOrderId String @unique // Razorpay order_xxx
1767
+ providerPaymentId String? // Razorpay pay_xxx
1768
+
1769
+ creditAmount Int // Number of credits purchased
1770
+ pricePaid Int // Amount in paise/cents
1771
+ currency String @default("INR")
1772
+
1773
+ status CreditPurchaseStatus @default(pending)
1774
+
1775
+ couponId String?
1776
+ discountAmount Int?
1777
+
1778
+ metadata Json?
1779
+
1780
+ paidAt DateTime?
1781
+ refundedAt DateTime?
1782
+
1783
+ createdAt DateTime @default(now())
1784
+ updatedAt DateTime @updatedAt
1785
+
1786
+ user User @relation(fields: [userId], references: [id])
1787
+ billingCustomer BillingCustomer? @relation(fields: [billingCustomerId], references: [id])
1788
+ coupon Coupon? @relation(fields: [couponId], references: [id])
1789
+
1790
+ @@index([userId])
1791
+ @@index([provider, providerOrderId])
1792
+ @@index([status])
1793
+ }
1794
+
1795
+ model Refund {
1796
+ id String @id @default(uuid())
1797
+
1798
+ userId String
1799
+ billingCustomerId String?
1800
+
1801
+ provider BillingProvider
1802
+ providerRefundId String @unique // Razorpay rfnd_xxx
1803
+ providerPaymentId String // Original payment
1804
+
1805
+ amount Int
1806
+ currency String
1807
+
1808
+ reason String?
1809
+ status String @default("pending") // pending | processed | failed
1810
+
1811
+ // Link to original purchase
1812
+ invoiceId String?
1813
+ creditPurchaseId String?
1814
+
1815
+ metadata Json?
1816
+
1817
+ processedAt DateTime?
1818
+ createdAt DateTime @default(now())
1819
+
1820
+ user User @relation(fields: [userId], references: [id])
1821
+ billingCustomer BillingCustomer? @relation(fields: [billingCustomerId], references: [id])
1822
+
1823
+ @@index([userId])
1824
+ @@index([provider, providerRefundId])
1825
+ }
1826
+
1827
+ /// ─────────────────────────────────────────────────────────────
1828
+ /// TOOL REGISTRY (FUNCTION CALLING)
1829
+ /// ─────────────────────────────────────────────────────────────
1830
+
1831
+ /// Dynamic tool registry
1832
+ /// Defines what tools/functions AI can call
1833
+ /// Each tool has OpenAI-style function schema
1834
+ model Tool {
1835
+ id String @id @default(uuid())
1836
+
1837
+ /// Unique identifier: "email.send", "calendar.create", etc.
1838
+ name String @unique
1839
+
1840
+ /// Human-readable name: "Send Email", "Create Event"
1841
+ displayName String
1842
+
1843
+ /// Description for AI understanding
1844
+ description String?
1845
+
1846
+ /// Categorization
1847
+ category String // email, calendar, files, messaging, etc.
1848
+ provider String? // google, slack, notion, internal, etc.
1849
+
1850
+ /// JSON Schema for function parameters
1851
+ /// Compatible with OpenAI function_calling
1852
+ schema Json
1853
+
1854
+ /// Which integration this tool requires
1855
+ requiredIntegration String?
1856
+
1857
+ /// OAuth scopes needed
1858
+ requiredScopes String[] @default([])
1859
+
1860
+ /// Where to call this tool
1861
+ /// e.g., "/api/integrations/google/gmail/send"
1862
+ endpoint String?
1863
+
1864
+ /// Whether execution is async
1865
+ isAsync Boolean @default(false)
1866
+
1867
+ /// Max execution time in ms
1868
+ timeoutMs Int @default(30000)
1869
+
1870
+ /// Whether AI should ask for confirmation before executing
1871
+ requiresConfirmation Boolean @default(false)
1872
+
1873
+ /// Danger level: 0=safe, 1=moderate, 2=dangerous
1874
+ /// Used for safety checks and warnings
1875
+ dangerLevel Int @default(0)
1876
+
1877
+ status ToolStatus @default(active)
1878
+
1879
+ /// Semantic versioning for tool changes
1880
+ version String @default("1.0.0")
1881
+
1882
+ metadata Json?
1883
+
1884
+ createdAt DateTime @default(now())
1885
+ updatedAt DateTime @updatedAt
1886
+
1887
+ /// Execution history
1888
+ executions ToolExecution[]
1889
+
1890
+ @@index([category])
1891
+ @@index([provider])
1892
+ @@index([status])
1893
+ }
1894
+
1895
+ /// Audit trail of tool executions
1896
+ /// Track when tools are called, success/failure, duration
1897
+ model ToolExecution {
1898
+ id String @id @default(uuid())
1899
+
1900
+ toolId String
1901
+ userId String
1902
+
1903
+ /// Context where tool was called
1904
+ chatSessionId String?
1905
+ workflowRunId String?
1906
+
1907
+ /// What was passed to the tool
1908
+ input Json
1909
+
1910
+ /// What tool returned
1911
+ output Json?
1912
+
1913
+ /// Error message if failed
1914
+ error String?
1915
+
1916
+ /// Did execution succeed
1917
+ success Boolean
1918
+
1919
+ /// How long it took
1920
+ durationMs Int?
1921
+
1922
+ /// Tokens used (for LLM calls)
1923
+ tokensUsed Int?
1924
+
1925
+ createdAt DateTime @default(now())
1926
+
1927
+ tool Tool @relation(fields: [toolId], references: [id])
1928
+
1929
+ @@index([toolId, createdAt])
1930
+ @@index([userId, createdAt])
1931
+ @@index([success])
1932
+ }
1933
+
1934
+ /// ─────────────────────────────────────────────────────────────
1935
+ /// DEAD LETTER QUEUE (FAILED JOB TRACKING)
1936
+ /// ─────────────────────────────────────────────────────────────
1937
+
1938
+ /// Failed jobs that exhausted all retries
1939
+ /// Kept for manual review and potential replay
1940
+ model DeadLetterJob {
1941
+ id String @id @default(uuid())
1942
+
1943
+ /// Reference to original job ID
1944
+ originalJobId String
1945
+
1946
+ /// Job type (workflow, ingestion, etc.)
1947
+ type String
1948
+
1949
+ /// Original payload
1950
+ payload Json
1951
+
1952
+ /// Why it ended up in DLQ
1953
+ failureReason String
1954
+
1955
+ /// History of errors from all retry attempts
1956
+ errorHistory Json?
1957
+
1958
+ /// How many times it was retried
1959
+ retryCount Int
1960
+
1961
+ /// Manual review tracking
1962
+ reviewed Boolean @default(false)
1963
+ reviewedBy String?
1964
+ reviewedAt DateTime?
1965
+
1966
+ /// When/if this job was replayed
1967
+ replayedAt DateTime?
1968
+
1969
+ metadata Json?
1970
+
1971
+ /// When the original job was created
1972
+ originalCreatedAt DateTime
1973
+
1974
+ /// When it was moved to DLQ
1975
+ createdAt DateTime @default(now())
1976
+
1977
+ @@index([type])
1978
+ @@index([reviewed])
1979
+ @@index([createdAt])
1980
+ }