@varaos/db 1.3.5 → 1.4.1

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