@trycompai/db 1.3.22 → 2.0.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,2193 +0,0 @@
1
- generator client {
2
- provider = "prisma-client-js"
3
- previewFeatures = ["postgresqlExtensions"]
4
- binaryTargets = ["rhel-openssl-3.0.x", "native", "debian-openssl-3.0.x", "linux-musl-openssl-3.0.x", "linux-musl-arm64-openssl-3.0.x"]
5
- }
6
-
7
- datasource db {
8
- provider = "postgresql"
9
- url = env("DATABASE_URL")
10
- extensions = [pgcrypto]
11
- }
12
-
13
-
14
- // ===== attachments.prisma =====
15
- model Attachment {
16
- id String @id @default(dbgenerated("generate_prefixed_cuid('att'::text)"))
17
- name String
18
- url String
19
- type AttachmentType
20
- entityId String
21
- entityType AttachmentEntityType
22
-
23
- // Dates
24
- createdAt DateTime @default(now())
25
- updatedAt DateTime @updatedAt
26
-
27
- // Relationships
28
- organizationId String
29
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
30
- comment Comment? @relation(fields: [commentId], references: [id])
31
- commentId String?
32
-
33
- @@index([entityId, entityType])
34
- }
35
-
36
- enum AttachmentEntityType {
37
- task
38
- vendor
39
- risk
40
- comment
41
- trust_nda
42
- task_item
43
- }
44
-
45
- enum AttachmentType {
46
- image
47
- video
48
- audio
49
- document
50
- other
51
- }
52
-
53
-
54
- // ===== auth.prisma =====
55
- model User {
56
- id String @id @default(dbgenerated("generate_prefixed_cuid('usr'::text)"))
57
- name String
58
- email String
59
- emailVerified Boolean
60
- image String?
61
- createdAt DateTime @default(now())
62
- updatedAt DateTime @updatedAt
63
- lastLogin DateTime?
64
- emailNotificationsUnsubscribed Boolean @default(false)
65
- emailPreferences Json? @default("{\"policyNotifications\":true,\"taskReminders\":true,\"weeklyTaskDigest\":true,\"unassignedItemsNotifications\":true}")
66
- isPlatformAdmin Boolean @default(false)
67
-
68
- accounts Account[]
69
- auditLog AuditLog[]
70
- integrationResults IntegrationResult[]
71
- invitations Invitation[]
72
- members Member[]
73
- sessions Session[]
74
- fleetPolicyResults FleetPolicyResult[]
75
-
76
- @@unique([email])
77
- }
78
-
79
- model EmployeeTrainingVideoCompletion {
80
- id String @id @default(dbgenerated("generate_prefixed_cuid('evc'::text)"))
81
- completedAt DateTime?
82
- videoId String
83
-
84
- memberId String
85
- member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
86
-
87
- @@unique([memberId, videoId])
88
- @@index([memberId])
89
- }
90
-
91
- model Session {
92
- id String @id @default(dbgenerated("generate_prefixed_cuid('ses'::text)"))
93
- expiresAt DateTime
94
- token String
95
- createdAt DateTime @default(now())
96
- updatedAt DateTime @updatedAt
97
- ipAddress String?
98
- userAgent String?
99
- userId String
100
- activeOrganizationId String?
101
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
102
-
103
- @@unique([token])
104
- }
105
-
106
- model Account {
107
- id String @id @default(dbgenerated("generate_prefixed_cuid('acc'::text)"))
108
- accountId String
109
- providerId String
110
- userId String
111
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
112
- accessToken String?
113
- refreshToken String?
114
- idToken String?
115
- accessTokenExpiresAt DateTime?
116
- refreshTokenExpiresAt DateTime?
117
- scope String?
118
- password String?
119
- createdAt DateTime
120
- updatedAt DateTime
121
- }
122
-
123
- model Verification {
124
- id String @id @default(dbgenerated("generate_prefixed_cuid('ver'::text)"))
125
- identifier String
126
- value String
127
- expiresAt DateTime
128
- createdAt DateTime @default(now())
129
- updatedAt DateTime @updatedAt
130
- }
131
-
132
- // JWT Plugin - Required by Better Auth JWT plugin
133
- // https://www.better-auth.com/docs/plugins/jwt
134
- model Jwks {
135
- id String @id @default(dbgenerated("generate_prefixed_cuid('jwk'::text)"))
136
- publicKey String
137
- privateKey String
138
- createdAt DateTime @default(now())
139
-
140
- @@map("jwks")
141
- }
142
-
143
- model Member {
144
- id String @id @default(dbgenerated("generate_prefixed_cuid('mem'::text)"))
145
- organizationId String
146
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
147
- userId String
148
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
149
- role String // Purposefully a string, since BetterAuth doesn't support enums this way
150
- createdAt DateTime @default(now())
151
-
152
- department Departments @default(none)
153
- isActive Boolean @default(true)
154
- deactivated Boolean @default(false)
155
- employeeTrainingVideoCompletion EmployeeTrainingVideoCompletion[]
156
- fleetDmLabelId Int?
157
-
158
- assignedPolicies Policy[] @relation("PolicyAssignee") // Policies where this member is an assignee
159
- approvedPolicies Policy[] @relation("PolicyApprover") // Policies where this member is an approver
160
- approvedSOADocuments SOADocument[] @relation("SOADocumentApprover") // SOA documents where this member is an approver
161
- risks Risk[]
162
- tasks Task[]
163
- vendors Vendor[]
164
- comments Comment[]
165
- auditLogs AuditLog[]
166
- reviewedAccessRequests TrustAccessRequest[] @relation("TrustAccessRequestReviewer")
167
- issuedGrants TrustAccessGrant[] @relation("IssuedGrants")
168
- revokedGrants TrustAccessGrant[] @relation("RevokedGrants")
169
- createdTaskItems TaskItem[] @relation("TaskItemCreator")
170
- updatedTaskItems TaskItem[] @relation("TaskItemUpdater")
171
- assignedTaskItems TaskItem[] @relation("TaskItemAssignee")
172
- createdFindings Finding[] @relation("FindingCreatedBy")
173
- publishedPolicyVersions PolicyVersion[] @relation("PolicyVersionPublisher")
174
- }
175
-
176
- model Invitation {
177
- id String @id @default(dbgenerated("generate_prefixed_cuid('inv'::text)"))
178
- organizationId String
179
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
180
- email String
181
- role String // Purposefully a string, since BetterAuth doesn't support enums this way
182
- status String
183
- expiresAt DateTime
184
- inviterId String
185
- user User @relation(fields: [inviterId], references: [id], onDelete: Cascade)
186
- createdAt DateTime @default(now())
187
- }
188
-
189
- // This is only for the app to consume, shouldn't be enforced by DB
190
- // Otherwise it won't work with Better Auth, as per https://www.better-auth.com/docs/plugins/organization#access-control
191
- enum Role {
192
- owner
193
- admin
194
- auditor
195
- employee
196
- contractor
197
- }
198
-
199
- enum PolicyStatus {
200
- draft
201
- published
202
- needs_review
203
- }
204
-
205
-
206
- // ===== automation-run.prisma =====
207
- model EvidenceAutomationRun {
208
- id String @id @default(dbgenerated("generate_prefixed_cuid('ear'::text)"))
209
- createdAt DateTime @default(now())
210
- updatedAt DateTime @updatedAt
211
-
212
- // Relations
213
- evidenceAutomationId String
214
- evidenceAutomation EvidenceAutomation @relation(fields: [evidenceAutomationId], references: [id], onDelete: Cascade)
215
-
216
- // Run details
217
- status EvidenceAutomationRunStatus @default(pending)
218
- startedAt DateTime?
219
- completedAt DateTime?
220
-
221
- // Results
222
- success Boolean?
223
- error String?
224
- logs Json?
225
- output Json?
226
-
227
- // Evaluation
228
- evaluationStatus EvidenceAutomationEvaluationStatus?
229
- evaluationReason String?
230
-
231
- // Metadata
232
- triggeredBy EvidenceAutomationTrigger @default(scheduled)
233
- runDuration Int? // in milliseconds
234
- version Int? // Version number that was executed (null = draft)
235
- Task Task? @relation(fields: [taskId], references: [id])
236
- taskId String?
237
-
238
- @@index([evidenceAutomationId])
239
- @@index([status])
240
- @@index([createdAt])
241
- @@index([version])
242
- }
243
-
244
- enum EvidenceAutomationRunStatus {
245
- pending
246
- running
247
- completed
248
- failed
249
- cancelled
250
- }
251
-
252
- enum EvidenceAutomationTrigger {
253
- manual
254
- scheduled
255
- api
256
- }
257
-
258
- enum EvidenceAutomationEvaluationStatus {
259
- pass
260
- fail
261
- }
262
-
263
-
264
- // ===== automation-version.prisma =====
265
- model EvidenceAutomationVersion {
266
- id String @id @default(dbgenerated("generate_prefixed_cuid('eav'::text)"))
267
- createdAt DateTime @default(now())
268
- updatedAt DateTime @updatedAt
269
-
270
- // Relations
271
- evidenceAutomationId String
272
- evidenceAutomation EvidenceAutomation @relation(fields: [evidenceAutomationId], references: [id], onDelete: Cascade)
273
-
274
- // Version details
275
- version Int // Sequential version number (1, 2, 3...)
276
- scriptKey String // S3 key for this version's script
277
- publishedBy String? // User ID who published
278
- changelog String? // Optional description of changes
279
-
280
- @@unique([evidenceAutomationId, version])
281
- @@index([evidenceAutomationId])
282
- @@index([createdAt])
283
- }
284
-
285
-
286
- // ===== automation.prisma =====
287
- model EvidenceAutomation {
288
- id String @id @default(dbgenerated("generate_prefixed_cuid('aut'::text)"))
289
- name String
290
- description String?
291
- createdAt DateTime @default(now())
292
- isEnabled Boolean @default(false)
293
-
294
- chatHistory String?
295
- evaluationCriteria String?
296
-
297
- taskId String
298
- task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
299
-
300
- // Relations
301
- runs EvidenceAutomationRun[]
302
- versions EvidenceAutomationVersion[]
303
-
304
- @@index([taskId])
305
- }
306
-
307
-
308
- // ===== browserbase-context.prisma =====
309
- /// Stores Browserbase context IDs for browser-based automation
310
- /// One context per organization - shared like a normal browser
311
- model BrowserbaseContext {
312
- id String @id @default(dbgenerated("generate_prefixed_cuid('bbc'::text)"))
313
-
314
- /// Organization that owns this browser context
315
- organizationId String @unique
316
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
317
-
318
- /// Browserbase context ID from their API
319
- contextId String
320
-
321
- createdAt DateTime @default(now())
322
- updatedAt DateTime @updatedAt
323
-
324
- @@index([organizationId])
325
- }
326
-
327
- /// Browser automation configuration linked to a task
328
- model BrowserAutomation {
329
- id String @id @default(dbgenerated("generate_prefixed_cuid('bau'::text)"))
330
- name String
331
- description String?
332
-
333
- /// Task this automation belongs to
334
- taskId String
335
- task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
336
-
337
- /// Starting URL for the automation
338
- targetUrl String
339
-
340
- /// Natural language instruction for the AI agent
341
- instruction String
342
-
343
- /// Whether automation is enabled for scheduled runs
344
- isEnabled Boolean @default(false)
345
-
346
- /// Cron expression for scheduled runs (null = manual only)
347
- schedule String?
348
-
349
- createdAt DateTime @default(now())
350
- updatedAt DateTime @updatedAt
351
-
352
- runs BrowserAutomationRun[]
353
-
354
- @@index([taskId])
355
- }
356
-
357
- /// Records of browser automation executions
358
- model BrowserAutomationRun {
359
- id String @id @default(dbgenerated("generate_prefixed_cuid('bar'::text)"))
360
-
361
- /// Parent automation
362
- automationId String
363
- automation BrowserAutomation @relation(fields: [automationId], references: [id], onDelete: Cascade)
364
-
365
- /// Execution status
366
- status BrowserAutomationRunStatus @default(pending)
367
-
368
- /// Timestamps
369
- startedAt DateTime?
370
- completedAt DateTime?
371
-
372
- /// Duration in milliseconds
373
- durationMs Int?
374
-
375
- /// Screenshot URL in S3 (if successful)
376
- screenshotUrl String?
377
-
378
- /// Evaluation result - whether the automation fulfilled the task requirements
379
- evaluationStatus BrowserAutomationEvaluationStatus?
380
-
381
- /// AI explanation of why it passed or failed
382
- evaluationReason String?
383
-
384
- /// Error message (if failed)
385
- error String?
386
-
387
- createdAt DateTime @default(now())
388
-
389
- @@index([automationId])
390
- @@index([status])
391
- @@index([createdAt])
392
- }
393
-
394
- enum BrowserAutomationEvaluationStatus {
395
- pass
396
- fail
397
- }
398
-
399
- enum BrowserAutomationRunStatus {
400
- pending
401
- running
402
- completed
403
- failed
404
- }
405
-
406
-
407
- // ===== comment.prisma =====
408
- model Comment {
409
- id String @id @default(dbgenerated("generate_prefixed_cuid('cmt'::text)"))
410
- content String
411
- entityId String
412
- entityType CommentEntityType
413
-
414
- // Dates
415
- createdAt DateTime @default(now())
416
-
417
- // Relationships
418
- authorId String
419
- author Member @relation(fields: [authorId], references: [id])
420
- organizationId String
421
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
422
-
423
- // Relation to Attachments
424
- attachments Attachment[]
425
-
426
- @@index([entityId])
427
- }
428
-
429
- enum CommentEntityType {
430
- task
431
- vendor
432
- risk
433
- policy
434
- }
435
-
436
-
437
- // ===== context.prisma =====
438
- model Context {
439
- id String @id @default(dbgenerated("generate_prefixed_cuid('ctx'::text)"))
440
- organizationId String
441
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
442
-
443
- question String
444
- answer String
445
-
446
- tags String[]
447
-
448
- createdAt DateTime @default(now())
449
- updatedAt DateTime @updatedAt
450
-
451
- @@index([organizationId])
452
- @@index([question])
453
- @@index([answer])
454
- @@index([tags])
455
- }
456
-
457
-
458
- // ===== control.prisma =====
459
- model Control {
460
- // Metadata
461
- id String @id @default(dbgenerated("generate_prefixed_cuid('ctl'::text)"))
462
- name String
463
- description String
464
-
465
- // Review dates
466
- lastReviewDate DateTime?
467
- nextReviewDate DateTime?
468
-
469
- // Relationships
470
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
471
- organizationId String
472
- requirementsMapped RequirementMap[]
473
- tasks Task[]
474
- policies Policy[]
475
- controlTemplateId String?
476
- controlTemplate FrameworkEditorControlTemplate? @relation(fields: [controlTemplateId], references: [id])
477
-
478
- @@index([organizationId])
479
- }
480
-
481
-
482
- // ===== finding.prisma =====
483
- enum FindingType {
484
- soc2
485
- iso27001
486
- }
487
-
488
- enum FindingStatus {
489
- open
490
- ready_for_review
491
- needs_revision
492
- closed
493
- }
494
-
495
- model FindingTemplate {
496
- id String @id @default(dbgenerated("generate_prefixed_cuid('fnd_t'::text)"))
497
- category String // e.g., "evidence_issue", "further_evidence", "task_specific", "na_incorrect"
498
- title String // Short title
499
- content String // Full message template
500
- order Int @default(0)
501
- createdAt DateTime @default(now())
502
- updatedAt DateTime @updatedAt
503
-
504
- findings Finding[]
505
- }
506
-
507
- model Finding {
508
- id String @id @default(dbgenerated("generate_prefixed_cuid('fnd'::text)"))
509
- type FindingType @default(soc2)
510
- status FindingStatus @default(open)
511
- content String // Custom message or copied from template
512
- revisionNote String? // Auditor's note when requesting revision
513
-
514
- createdAt DateTime @default(now())
515
- updatedAt DateTime @updatedAt
516
-
517
- // Relationships
518
- taskId String
519
- task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
520
- templateId String?
521
- template FindingTemplate? @relation(fields: [templateId], references: [id])
522
- createdById String
523
- createdBy Member @relation("FindingCreatedBy", fields: [createdById], references: [id])
524
- organizationId String
525
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
526
-
527
- @@index([taskId])
528
- @@index([organizationId, status])
529
- }
530
-
531
-
532
- // ===== fleet-policy-result.prisma =====
533
- model FleetPolicyResult {
534
- id String @id @default(dbgenerated("generate_prefixed_cuid('fpr'::text)"))
535
- userId String
536
- organizationId String
537
- fleetPolicyId Int
538
- fleetPolicyName String
539
- fleetPolicyResponse String
540
- attachments String[] @default([])
541
- createdAt DateTime @default(now())
542
- updatedAt DateTime @updatedAt
543
-
544
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
545
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
546
-
547
- @@index([userId])
548
- @@index([organizationId])
549
- }
550
-
551
-
552
- // ===== framework-editor.prisma =====
553
- // --- Data for Framework Editor ---
554
- model FrameworkEditorVideo {
555
- id String @id @default(dbgenerated("generate_prefixed_cuid('frk_vi'::text)"))
556
- title String
557
- description String
558
- youtubeId String
559
- url String
560
-
561
- // Dates
562
- createdAt DateTime @default(now())
563
- updatedAt DateTime @default(now()) @updatedAt
564
- }
565
-
566
- model FrameworkEditorFramework {
567
- id String @id @default(dbgenerated("generate_prefixed_cuid('frk'::text)"))
568
- name String // e.g., "soc2", "iso27001"
569
- version String
570
- description String
571
- visible Boolean @default(false)
572
-
573
- requirements FrameworkEditorRequirement[]
574
- frameworkInstances FrameworkInstance[]
575
- soaConfigurations SOAFrameworkConfiguration[] // Multiple SOA config versions per framework
576
- soaDocuments SOADocument[] // SOA documents from organizations
577
-
578
- // Dates
579
- createdAt DateTime @default(now())
580
- updatedAt DateTime @default(now()) @updatedAt
581
- }
582
-
583
- model FrameworkEditorRequirement {
584
- id String @id @default(dbgenerated("generate_prefixed_cuid('frk_rq'::text)"))
585
- frameworkId String
586
- framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id])
587
-
588
- name String // Original requirement ID within that framework, e.g., "Privacy"
589
- identifier String @default("") // Unique identifier for the requirement, e.g., "cc1-1"
590
- description String
591
-
592
- controlTemplates FrameworkEditorControlTemplate[]
593
- requirementMaps RequirementMap[]
594
-
595
- // Dates
596
- createdAt DateTime @default(now())
597
- updatedAt DateTime @default(now()) @updatedAt
598
- }
599
-
600
- model FrameworkEditorPolicyTemplate {
601
- id String @id @default(dbgenerated("generate_prefixed_cuid('frk_pt'::text)"))
602
- name String
603
- description String
604
- frequency Frequency // Using the enum from shared.prisma
605
- department Departments // Using the enum from shared.prisma
606
- content Json
607
-
608
- controlTemplates FrameworkEditorControlTemplate[]
609
-
610
- // Dates
611
- createdAt DateTime @default(now())
612
- updatedAt DateTime @default(now()) @updatedAt
613
-
614
- // Instances
615
- policies Policy[]
616
- }
617
-
618
- model FrameworkEditorTaskTemplate {
619
- id String @id @default(dbgenerated("generate_prefixed_cuid('frk_tt'::text)"))
620
- name String
621
- description String
622
- frequency Frequency // Using the enum from shared.prisma
623
- department Departments // Using the enum from shared.prisma
624
- automationStatus TaskAutomationStatus @default(AUTOMATED)
625
-
626
- controlTemplates FrameworkEditorControlTemplate[]
627
-
628
- // Dates
629
- createdAt DateTime @default(now())
630
- updatedAt DateTime @default(now()) @updatedAt
631
-
632
- // Instances
633
- tasks Task[]
634
- }
635
-
636
- model FrameworkEditorControlTemplate {
637
- id String @id @default(dbgenerated("generate_prefixed_cuid('frk_ct'::text)"))
638
- name String
639
- description String
640
-
641
- policyTemplates FrameworkEditorPolicyTemplate[]
642
- requirements FrameworkEditorRequirement[]
643
- taskTemplates FrameworkEditorTaskTemplate[]
644
-
645
- // Dates
646
- createdAt DateTime @default(now())
647
- updatedAt DateTime @default(now()) @updatedAt
648
-
649
- // Instances
650
- controls Control[]
651
- }
652
-
653
-
654
- // ===== framework.prisma =====
655
- model FrameworkInstance {
656
- // Metadata
657
- id String @id @default(dbgenerated("generate_prefixed_cuid('frm'::text)"))
658
- organizationId String
659
-
660
- frameworkId String
661
- framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id], onDelete: Cascade)
662
-
663
- // Relationships
664
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
665
- requirementsMapped RequirementMap[]
666
-
667
- @@unique([organizationId, frameworkId])
668
- }
669
-
670
-
671
- // ===== integration-platform.prisma =====
672
- // ===== Integration Platform =====
673
- // New integration platform models for scalable, config-driven integrations
674
-
675
- /// Stores metadata about available integration providers (synced from code manifests)
676
- model IntegrationProvider {
677
- id String @id @default(dbgenerated("generate_prefixed_cuid('prv'::text)"))
678
- /// Unique slug matching manifest ID (e.g., "github", "slack")
679
- slug String @unique
680
- /// Display name
681
- name String
682
- /// Category for grouping
683
- category String
684
- /// Hash of manifest for detecting changes
685
- manifestHash String?
686
- /// Capabilities JSON array
687
- capabilities Json @default("[]")
688
- /// Whether provider is active
689
- isActive Boolean @default(true)
690
-
691
- createdAt DateTime @default(now())
692
- updatedAt DateTime @updatedAt
693
-
694
- connections IntegrationConnection[]
695
-
696
- @@index([slug])
697
- @@index([category])
698
- }
699
-
700
- /// Represents an organization's connection to an integration provider
701
- model IntegrationConnection {
702
- id String @id @default(dbgenerated("generate_prefixed_cuid('icn'::text)"))
703
-
704
- /// Reference to the provider
705
- providerId String
706
- provider IntegrationProvider @relation(fields: [providerId], references: [id], onDelete: Cascade)
707
-
708
- /// Organization that owns this connection
709
- organizationId String
710
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
711
-
712
- /// Connection status
713
- status IntegrationConnectionStatus @default(pending)
714
-
715
- /// Auth strategy used (oauth2, api_key, basic, jwt, custom)
716
- authStrategy String
717
-
718
- /// Reference to active credential version
719
- activeCredentialVersionId String?
720
-
721
- /// Last successful sync timestamp
722
- lastSyncAt DateTime?
723
-
724
- /// Next scheduled sync timestamp
725
- nextSyncAt DateTime?
726
-
727
- /// Custom sync cadence (cron expression), null = use default
728
- syncCadence String?
729
-
730
- /// Additional metadata (e.g., connected account info)
731
- metadata Json?
732
-
733
- /// User-configured variables for checks (collected after OAuth)
734
- variables Json?
735
-
736
- /// Error message if status is error
737
- errorMessage String?
738
-
739
- createdAt DateTime @default(now())
740
- updatedAt DateTime @updatedAt
741
-
742
- credentialVersions IntegrationCredentialVersion[]
743
- runs IntegrationRun[]
744
- findings IntegrationPlatformFinding[]
745
- checkRuns IntegrationCheckRun[]
746
-
747
- @@index([organizationId])
748
- @@index([providerId])
749
- @@index([providerId, organizationId])
750
- @@index([status])
751
- }
752
-
753
- enum IntegrationConnectionStatus {
754
- pending // Awaiting credential setup
755
- active // Connected and operational
756
- error // Connection has errors
757
- paused // Manually paused by user
758
- disconnected // User disconnected
759
- }
760
-
761
- /// Stores encrypted credentials with versioning for audit trail
762
- model IntegrationCredentialVersion {
763
- id String @id @default(dbgenerated("generate_prefixed_cuid('icv'::text)"))
764
-
765
- /// Parent connection
766
- connectionId String
767
- connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
768
-
769
- /// Encrypted credential payload (JSON with encrypted fields)
770
- encryptedPayload Json
771
-
772
- /// Version number (auto-increment per connection)
773
- version Int
774
-
775
- /// Token expiration (for OAuth tokens)
776
- expiresAt DateTime?
777
-
778
- /// When this version was rotated/replaced
779
- rotatedAt DateTime?
780
-
781
- createdAt DateTime @default(now())
782
-
783
- @@unique([connectionId, version])
784
- @@index([connectionId])
785
- }
786
-
787
- /// Records each sync/job execution for audit and debugging
788
- model IntegrationRun {
789
- id String @id @default(dbgenerated("generate_prefixed_cuid('irn'::text)"))
790
-
791
- /// Parent connection
792
- connectionId String
793
- connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
794
-
795
- /// Type of job
796
- jobType IntegrationRunJobType
797
-
798
- /// Execution status
799
- status IntegrationRunStatus @default(pending)
800
-
801
- /// Timestamps
802
- startedAt DateTime?
803
- completedAt DateTime?
804
-
805
- /// Duration in milliseconds
806
- durationMs Int?
807
-
808
- /// Number of findings from this run
809
- findingsCount Int @default(0)
810
-
811
- /// Error details if failed
812
- error Json?
813
-
814
- /// Additional metadata (trigger source, cursor, etc.)
815
- metadata Json?
816
-
817
- createdAt DateTime @default(now())
818
-
819
- findings IntegrationPlatformFinding[]
820
-
821
- @@index([connectionId])
822
- @@index([status])
823
- @@index([createdAt])
824
- }
825
-
826
- enum IntegrationRunJobType {
827
- full_sync
828
- delta_sync
829
- webhook
830
- manual
831
- test_connection
832
- }
833
-
834
- enum IntegrationRunStatus {
835
- pending
836
- running
837
- success
838
- failed
839
- cancelled
840
- }
841
-
842
- /// Stores findings/results from integration syncs
843
- model IntegrationPlatformFinding {
844
- id String @id @default(dbgenerated("generate_prefixed_cuid('ipf'::text)"))
845
-
846
- /// Parent run (optional - webhooks may not have runs)
847
- runId String?
848
- run IntegrationRun? @relation(fields: [runId], references: [id], onDelete: SetNull)
849
-
850
- /// Parent connection
851
- connectionId String
852
- connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
853
-
854
- /// Resource classification
855
- resourceType String
856
- resourceId String
857
-
858
- /// Finding details
859
- title String
860
- description String?
861
-
862
- /// Severity level
863
- severity IntegrationFindingSeverity @default(info)
864
-
865
- /// Finding status
866
- status IntegrationFindingStatus @default(open)
867
-
868
- /// Remediation guidance
869
- remediation String?
870
-
871
- /// Raw payload from provider
872
- rawPayload Json?
873
-
874
- createdAt DateTime @default(now())
875
- updatedAt DateTime @updatedAt
876
-
877
- @@index([connectionId])
878
- @@index([runId])
879
- @@index([resourceType, resourceId])
880
- @@index([severity])
881
- @@index([status])
882
- }
883
-
884
- enum IntegrationFindingSeverity {
885
- info
886
- low
887
- medium
888
- high
889
- critical
890
- }
891
-
892
- enum IntegrationFindingStatus {
893
- open
894
- resolved
895
- ignored
896
- }
897
-
898
- /// Stores OAuth state for CSRF protection during OAuth flow
899
- model IntegrationOAuthState {
900
- id String @id @default(dbgenerated("generate_prefixed_cuid('ios'::text)"))
901
-
902
- /// Random state parameter
903
- state String @unique
904
-
905
- /// Provider slug
906
- providerSlug String
907
-
908
- /// Organization initiating the OAuth
909
- organizationId String
910
-
911
- /// User initiating the OAuth
912
- userId String
913
-
914
- /// PKCE code verifier (if using PKCE)
915
- codeVerifier String?
916
-
917
- /// Redirect URL after OAuth completes
918
- redirectUrl String?
919
-
920
- /// Expiration timestamp
921
- expiresAt DateTime
922
-
923
- createdAt DateTime @default(now())
924
-
925
- @@index([state])
926
- @@index([expiresAt])
927
- }
928
-
929
- /// Stores organization-level OAuth app credentials
930
- /// Allows orgs (especially self-hosters) to use their own OAuth apps
931
- model IntegrationOAuthApp {
932
- id String @id @default(dbgenerated("generate_prefixed_cuid('ioa'::text)"))
933
-
934
- /// Provider slug (e.g., "github", "slack")
935
- providerSlug String
936
-
937
- /// Organization that owns this OAuth app config
938
- organizationId String
939
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
940
-
941
- /// Encrypted client ID
942
- encryptedClientId Json
943
-
944
- /// Encrypted client secret
945
- encryptedClientSecret Json
946
-
947
- /// Optional: custom scopes (overrides manifest defaults)
948
- customScopes String[]
949
-
950
- /// Provider-specific settings (e.g., Rippling app name for authorize URL)
951
- /// Stored as JSON: { "appName": "compai533c" }
952
- customSettings Json?
953
-
954
- /// Whether this config is active
955
- isActive Boolean @default(true)
956
-
957
- createdAt DateTime @default(now())
958
- updatedAt DateTime @updatedAt
959
-
960
- @@unique([providerSlug, organizationId])
961
- @@index([organizationId])
962
- @@index([providerSlug])
963
- }
964
-
965
- /// Records check runs linked to tasks for compliance verification
966
- model IntegrationCheckRun {
967
- id String @id @default(dbgenerated("generate_prefixed_cuid('icr'::text)"))
968
-
969
- /// Parent connection
970
- connectionId String
971
- connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
972
-
973
- /// Task being verified (optional - checks can run without a task)
974
- taskId String?
975
- task Task? @relation(fields: [taskId], references: [id], onDelete: SetNull)
976
-
977
- /// Check ID from the manifest
978
- checkId String
979
-
980
- /// Check name (denormalized for display)
981
- checkName String
982
-
983
- /// Execution status
984
- status IntegrationRunStatus @default(pending)
985
-
986
- /// Timestamps
987
- startedAt DateTime?
988
- completedAt DateTime?
989
-
990
- /// Duration in milliseconds
991
- durationMs Int?
992
-
993
- /// Summary counts
994
- totalChecked Int @default(0)
995
- passedCount Int @default(0)
996
- failedCount Int @default(0)
997
-
998
- /// Error message if failed
999
- errorMessage String?
1000
-
1001
- /// Full execution logs (JSON array)
1002
- logs Json?
1003
-
1004
- createdAt DateTime @default(now())
1005
-
1006
- /// Results from this check run
1007
- results IntegrationCheckResult[]
1008
-
1009
- @@index([connectionId])
1010
- @@index([taskId])
1011
- @@index([checkId])
1012
- @@index([status])
1013
- @@index([createdAt])
1014
- }
1015
-
1016
- /// Stores individual results (pass/fail) from check runs
1017
- model IntegrationCheckResult {
1018
- id String @id @default(dbgenerated("generate_prefixed_cuid('icx'::text)"))
1019
-
1020
- /// Parent check run
1021
- checkRunId String
1022
- checkRun IntegrationCheckRun @relation(fields: [checkRunId], references: [id], onDelete: Cascade)
1023
-
1024
- /// Whether this result is a pass or fail
1025
- passed Boolean
1026
-
1027
- /// Resource classification
1028
- resourceType String
1029
- resourceId String
1030
-
1031
- /// Result details
1032
- title String
1033
- description String?
1034
-
1035
- /// Severity (for failures)
1036
- severity IntegrationFindingSeverity?
1037
-
1038
- /// Remediation guidance (for failures)
1039
- remediation String?
1040
-
1041
- /// Evidence/proof (JSON - API response data)
1042
- evidence Json?
1043
-
1044
- /// When this evidence was collected
1045
- collectedAt DateTime @default(now())
1046
-
1047
- @@index([checkRunId])
1048
- @@index([passed])
1049
- @@index([resourceType, resourceId])
1050
- }
1051
-
1052
- /// Stores platform-wide OAuth app credentials
1053
- /// Used by platform operators to provide default OAuth apps for all users
1054
- model IntegrationPlatformCredential {
1055
- id String @id @default(dbgenerated("generate_prefixed_cuid('ipc'::text)"))
1056
-
1057
- /// Provider slug (e.g., "github", "slack") - unique per platform
1058
- providerSlug String @unique
1059
-
1060
- /// Encrypted client ID
1061
- encryptedClientId Json
1062
-
1063
- /// Encrypted client secret
1064
- encryptedClientSecret Json
1065
-
1066
- /// Optional: custom scopes (overrides manifest defaults)
1067
- customScopes String[]
1068
-
1069
- /// Provider-specific settings (e.g., Rippling app name for authorize URL)
1070
- /// Stored as JSON: { "appName": "compai533c" }
1071
- customSettings Json?
1072
-
1073
- /// Whether this credential is active
1074
- isActive Boolean @default(true)
1075
-
1076
- /// Who created this credential
1077
- createdById String?
1078
-
1079
- /// Who last updated this credential
1080
- updatedById String?
1081
-
1082
- createdAt DateTime @default(now())
1083
- updatedAt DateTime @updatedAt
1084
-
1085
- @@index([providerSlug])
1086
- }
1087
-
1088
-
1089
- // ===== integration.prisma =====
1090
- model Integration {
1091
- id String @id @default(dbgenerated("generate_prefixed_cuid('int'::text)"))
1092
- name String
1093
- integrationId String
1094
- settings Json
1095
- userSettings Json
1096
- organizationId String
1097
- lastRunAt DateTime?
1098
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1099
- results IntegrationResult[]
1100
-
1101
- @@index([organizationId])
1102
- }
1103
-
1104
- model IntegrationResult {
1105
- id String @id @default(dbgenerated("generate_prefixed_cuid('itr'::text)"))
1106
- title String?
1107
- description String?
1108
- remediation String?
1109
- status String?
1110
- severity String?
1111
- resultDetails Json?
1112
- completedAt DateTime? @default(now())
1113
- integrationId String
1114
- organizationId String
1115
- assignedUserId String?
1116
-
1117
- assignedUser User? @relation(fields: [assignedUserId], references: [id], onDelete: Cascade)
1118
- integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
1119
-
1120
- @@index([integrationId])
1121
- }
1122
-
1123
-
1124
- // ===== knowledge-base-document.prisma =====
1125
- model KnowledgeBaseDocument {
1126
- id String @id @default(dbgenerated("generate_prefixed_cuid('kbd'::text)"))
1127
- name String // Original filename
1128
- description String? // Optional user description/notes
1129
- s3Key String // S3 storage key (e.g., "org123/knowledge-base-documents/timestamp-file.pdf")
1130
- fileType String // MIME type (e.g., "application/pdf")
1131
- fileSize Int // File size in bytes
1132
- processingStatus KnowledgeBaseDocumentProcessingStatus @default(pending) // Track indexing status
1133
- processedAt DateTime? // When indexing completed
1134
- triggerRunId String? // Trigger.dev run ID for tracking processing progress
1135
-
1136
- // Dates
1137
- createdAt DateTime @default(now())
1138
- updatedAt DateTime @updatedAt
1139
-
1140
- // Relationships
1141
- organizationId String
1142
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1143
-
1144
- @@index([organizationId])
1145
- @@index([organizationId, processingStatus])
1146
- @@index([s3Key])
1147
- @@index([triggerRunId])
1148
- }
1149
-
1150
- enum KnowledgeBaseDocumentProcessingStatus {
1151
- pending // Uploaded but not yet processed/indexed
1152
- processing // Currently being processed/indexed
1153
- completed // Successfully indexed in vector database
1154
- failed // Processing failed
1155
- }
1156
-
1157
-
1158
- // ===== onboarding.prisma =====
1159
- model Onboarding {
1160
- organizationId String @id
1161
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1162
- policies Boolean @default(false)
1163
- employees Boolean @default(false)
1164
- vendors Boolean @default(false)
1165
- integrations Boolean @default(false)
1166
- risk Boolean @default(false)
1167
- team Boolean @default(false)
1168
- tasks Boolean @default(false)
1169
- callBooked Boolean @default(false)
1170
- companyBookingDetails Json?
1171
- companyDetails Json?
1172
- triggerJobId String?
1173
- triggerJobCompleted Boolean @default(false)
1174
-
1175
- @@index([organizationId])
1176
- }
1177
-
1178
-
1179
- // ===== organization.prisma =====
1180
- model Organization {
1181
- id String @id @default(dbgenerated("generate_prefixed_cuid('org'::text)"))
1182
- name String
1183
- slug String @unique @default(dbgenerated("generate_prefixed_cuid('slug'::text)"))
1184
- logo String?
1185
- createdAt DateTime @default(now())
1186
- metadata String?
1187
- onboarding Onboarding?
1188
- website String?
1189
- onboardingCompleted Boolean @default(false)
1190
- hasAccess Boolean @default(false)
1191
- advancedModeEnabled Boolean @default(false)
1192
-
1193
- // FleetDM
1194
- fleetDmLabelId Int?
1195
- isFleetSetupCompleted Boolean @default(false)
1196
-
1197
- // Employee sync provider (e.g., 'google-workspace', 'rippling')
1198
- // When set, the scheduled sync will only use this provider
1199
- employeeSyncProvider String?
1200
-
1201
- apiKeys ApiKey[]
1202
- auditLog AuditLog[]
1203
- controls Control[]
1204
- frameworkInstances FrameworkInstance[]
1205
- integrations Integration[]
1206
- invitations Invitation[]
1207
- members Member[]
1208
- policy Policy[]
1209
- risk Risk[]
1210
- vendors Vendor[]
1211
- tasks Task[]
1212
- taskItems TaskItem[]
1213
- comments Comment[]
1214
- attachments Attachment[]
1215
- trust Trust[]
1216
- context Context[]
1217
- secrets Secret[]
1218
- trustAccessRequests TrustAccessRequest[]
1219
- trustNdaAgreements TrustNDAAgreement[]
1220
- trustDocuments TrustDocument[]
1221
- trustResources TrustResource[] @relation("OrganizationTrustResources")
1222
- trustCustomLinks TrustCustomLink[]
1223
- knowledgeBaseDocuments KnowledgeBaseDocument[]
1224
- questionnaires Questionnaire[]
1225
- securityQuestionnaireManualAnswers SecurityQuestionnaireManualAnswer[]
1226
- soaDocuments SOADocument[]
1227
- primaryColor String?
1228
- trustPortalFaqs Json? // Array of { question: string, answer: string, order: number }
1229
-
1230
- // Integration Platform
1231
- integrationConnections IntegrationConnection[]
1232
- integrationOAuthApps IntegrationOAuthApp[]
1233
-
1234
- // Browser Automation
1235
- browserbaseContext BrowserbaseContext?
1236
- fleetPolicyResults FleetPolicyResult[]
1237
-
1238
- // Findings
1239
- findings Finding[]
1240
-
1241
- @@index([slug])
1242
- }
1243
-
1244
-
1245
- // ===== policy.prisma =====
1246
- enum PolicyDisplayFormat {
1247
- EDITOR
1248
- PDF
1249
- }
1250
-
1251
- model Policy {
1252
- id String @id @default(dbgenerated("generate_prefixed_cuid('pol'::text)"))
1253
- name String
1254
- description String?
1255
- status PolicyStatus @default(draft)
1256
- content Json[]
1257
- draftContent Json[] @default([])
1258
- frequency Frequency?
1259
- department Departments?
1260
- isRequiredToSign Boolean @default(true)
1261
- signedBy String[] @default([])
1262
- reviewDate DateTime?
1263
- isArchived Boolean @default(false)
1264
- displayFormat PolicyDisplayFormat @default(EDITOR)
1265
- pdfUrl String?
1266
-
1267
- // Dates
1268
- createdAt DateTime @default(now())
1269
- updatedAt DateTime @updatedAt
1270
- lastArchivedAt DateTime?
1271
- lastPublishedAt DateTime?
1272
-
1273
- // Relationships
1274
- organizationId String
1275
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1276
- assigneeId String?
1277
- assignee Member? @relation("PolicyAssignee", fields: [assigneeId], references: [id], onDelete: SetNull, onUpdate: Cascade)
1278
- approverId String?
1279
- approver Member? @relation("PolicyApprover", fields: [approverId], references: [id], onDelete: SetNull, onUpdate: Cascade)
1280
- policyTemplateId String?
1281
- policyTemplate FrameworkEditorPolicyTemplate? @relation(fields: [policyTemplateId], references: [id])
1282
- controls Control[]
1283
- currentVersionId String? @unique
1284
- currentVersion PolicyVersion? @relation("PolicyCurrentVersion", fields: [currentVersionId], references: [id])
1285
- pendingVersionId String?
1286
- versions PolicyVersion[] @relation("PolicyVersions")
1287
-
1288
- @@index([organizationId])
1289
- }
1290
-
1291
- model PolicyVersion {
1292
- id String @id @default(dbgenerated("generate_prefixed_cuid('pv'::text)"))
1293
- createdAt DateTime @default(now())
1294
- updatedAt DateTime @updatedAt
1295
-
1296
- // Relations
1297
- policyId String
1298
- policy Policy @relation("PolicyVersions", fields: [policyId], references: [id], onDelete: Cascade)
1299
- currentForPolicy Policy? @relation("PolicyCurrentVersion")
1300
-
1301
- // Version details
1302
- version Int
1303
- content Json[]
1304
- pdfUrl String?
1305
- publishedById String?
1306
- publishedBy Member? @relation("PolicyVersionPublisher", fields: [publishedById], references: [id], onDelete: SetNull)
1307
- changelog String?
1308
-
1309
- @@unique([policyId, version])
1310
- @@index([policyId])
1311
- @@index([createdAt])
1312
- }
1313
-
1314
-
1315
- // ===== questionnaire.prisma =====
1316
- model Questionnaire {
1317
- id String @id @default(dbgenerated("generate_prefixed_cuid('qst'::text)"))
1318
- filename String // Original filename
1319
- s3Key String // S3 storage key for the uploaded file
1320
- fileType String // MIME type (e.g., "application/pdf")
1321
- fileSize Int // File size in bytes
1322
- status QuestionnaireStatus @default(parsing) // Parsing status
1323
- parsedAt DateTime? // When parsing completed
1324
- totalQuestions Int @default(0) // Total number of questions parsed
1325
- answeredQuestions Int @default(0) // Number of questions with answers
1326
- source String @default("internal") // Source of the questionnaire: 'internal' (from app) or 'external' (from trust portal)
1327
-
1328
- // Dates
1329
- createdAt DateTime @default(now())
1330
- updatedAt DateTime @updatedAt
1331
-
1332
- // Relationships
1333
- organizationId String
1334
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1335
- questions QuestionnaireQuestionAnswer[]
1336
- manualAnswers SecurityQuestionnaireManualAnswer[] // Manual answers saved from this questionnaire
1337
-
1338
- @@index([organizationId])
1339
- @@index([organizationId, createdAt])
1340
- @@index([status])
1341
- @@index([source])
1342
- }
1343
-
1344
- model QuestionnaireQuestionAnswer {
1345
- id String @id @default(dbgenerated("generate_prefixed_cuid('qqa'::text)"))
1346
- question String // The question text
1347
- answer String? // The answer (nullable if not provided in file or not generated yet)
1348
- status QuestionnaireAnswerStatus @default(untouched) // Answer status
1349
- questionIndex Int // Order/index of the question in the questionnaire
1350
- sources Json? // Sources used for generated answers (array of source objects)
1351
- generatedAt DateTime? // When answer was generated (if status is generated)
1352
- updatedBy String? // User ID who last updated the answer (if manual)
1353
-
1354
- // Dates
1355
- createdAt DateTime @default(now())
1356
- updatedAt DateTime @updatedAt
1357
-
1358
- // Relationships
1359
- questionnaireId String
1360
- questionnaire Questionnaire @relation(fields: [questionnaireId], references: [id], onDelete: Cascade)
1361
-
1362
- @@index([questionnaireId])
1363
- @@index([questionnaireId, questionIndex])
1364
- @@index([status])
1365
- }
1366
-
1367
- enum QuestionnaireStatus {
1368
- parsing // Currently being parsed
1369
- completed // Successfully parsed
1370
- failed // Parsing failed
1371
- }
1372
-
1373
- enum QuestionnaireAnswerStatus {
1374
- untouched // No answer yet (empty or not generated)
1375
- generated // AI generated answer
1376
- manual // Manually written/edited by user
1377
- }
1378
-
1379
-
1380
- // ===== requirement.prisma =====
1381
- model RequirementMap {
1382
- id String @id @default(dbgenerated("generate_prefixed_cuid('req'::text)"))
1383
-
1384
- requirementId String
1385
- requirement FrameworkEditorRequirement @relation(fields: [requirementId], references: [id], onDelete: Cascade)
1386
-
1387
- controlId String
1388
- control Control @relation(fields: [controlId], references: [id], onDelete: Cascade)
1389
-
1390
- frameworkInstanceId String
1391
- frameworkInstance FrameworkInstance @relation(fields: [frameworkInstanceId], references: [id], onDelete: Cascade)
1392
-
1393
- @@unique([controlId, frameworkInstanceId, requirementId])
1394
- @@index([requirementId, frameworkInstanceId])
1395
- }
1396
-
1397
-
1398
- // ===== risk.prisma =====
1399
- model Risk {
1400
- // Metadata
1401
- id String @id @default(dbgenerated("generate_prefixed_cuid('rsk'::text)"))
1402
- title String
1403
- description String
1404
- category RiskCategory
1405
- department Departments?
1406
- status RiskStatus @default(open)
1407
- likelihood Likelihood @default(very_unlikely)
1408
- impact Impact @default(insignificant)
1409
- residualLikelihood Likelihood @default(very_unlikely)
1410
- residualImpact Impact @default(insignificant)
1411
- treatmentStrategyDescription String?
1412
- treatmentStrategy RiskTreatmentType @default(accept)
1413
-
1414
- // Dates
1415
- createdAt DateTime @default(now())
1416
- updatedAt DateTime @updatedAt
1417
-
1418
- // Relationships
1419
- organizationId String
1420
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1421
- assigneeId String?
1422
- assignee Member? @relation(fields: [assigneeId], references: [id])
1423
- tasks Task[]
1424
-
1425
- @@index([organizationId])
1426
- @@index([category])
1427
- @@index([status])
1428
- }
1429
-
1430
- enum RiskTreatmentType {
1431
- accept
1432
- avoid
1433
- mitigate
1434
- transfer
1435
- }
1436
-
1437
- enum RiskCategory {
1438
- customer
1439
- fraud
1440
- governance
1441
- operations
1442
- other
1443
- people
1444
- regulatory
1445
- reporting
1446
- resilience
1447
- technology
1448
- vendor_management
1449
- }
1450
-
1451
- enum RiskStatus {
1452
- open
1453
- pending
1454
- closed
1455
- archived
1456
- }
1457
-
1458
-
1459
- // ===== secret.prisma =====
1460
- model Secret {
1461
- id String @id @default(dbgenerated("generate_prefixed_cuid('sec'::text)"))
1462
- organizationId String @map("organization_id")
1463
- name String
1464
- value String @db.Text // Encrypted value
1465
- description String? @db.Text
1466
- category String? // e.g., "api", "webhook", "database", etc.
1467
- lastUsedAt DateTime? @map("last_used_at")
1468
- createdAt DateTime @default(now()) @map("created_at")
1469
- updatedAt DateTime @updatedAt @map("updated_at")
1470
-
1471
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1472
-
1473
- @@unique([organizationId, name])
1474
- @@map("secrets")
1475
- }
1476
-
1477
-
1478
- // ===== security-questionnaire-manual-answer.prisma =====
1479
- model SecurityQuestionnaireManualAnswer {
1480
- id String @id @default(dbgenerated("generate_prefixed_cuid('sqma'::text)"))
1481
- question String // The question text
1482
- answer String // The answer text (required for saved answers)
1483
- tags String[] @default([]) // Optional tags for categorization
1484
-
1485
- // Optional reference to original questionnaire (for tracking)
1486
- sourceQuestionnaireId String?
1487
- sourceQuestionnaire Questionnaire? @relation(fields: [sourceQuestionnaireId], references: [id], onDelete: SetNull)
1488
-
1489
- // User who created/updated this answer
1490
- createdBy String? // User ID
1491
- updatedBy String? // User ID
1492
-
1493
- // Dates
1494
- createdAt DateTime @default(now())
1495
- updatedAt DateTime @updatedAt
1496
-
1497
- // Relationships
1498
- organizationId String
1499
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1500
-
1501
- @@unique([organizationId, question]) // Prevent duplicate questions per organization
1502
- @@index([organizationId])
1503
- @@index([organizationId, question])
1504
- @@index([tags])
1505
- @@index([createdAt])
1506
- }
1507
-
1508
-
1509
- // ===== shared.prisma =====
1510
- model ApiKey {
1511
- id String @id @default(dbgenerated("generate_prefixed_cuid('apk'::text)"))
1512
- name String
1513
- key String @unique
1514
- salt String?
1515
- createdAt DateTime @default(now())
1516
- expiresAt DateTime?
1517
- lastUsedAt DateTime?
1518
- isActive Boolean @default(true)
1519
-
1520
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1521
- organizationId String
1522
-
1523
- @@index([organizationId])
1524
- @@index([key])
1525
- }
1526
-
1527
- model AuditLog {
1528
- id String @id @default(dbgenerated("generate_prefixed_cuid('aud'::text)"))
1529
- timestamp DateTime @default(now())
1530
- organizationId String
1531
- userId String
1532
- memberId String?
1533
- data Json
1534
- description String?
1535
- entityId String?
1536
- entityType AuditLogEntityType?
1537
-
1538
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1539
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1540
- member Member? @relation(fields: [memberId], references: [id], onDelete: Cascade)
1541
-
1542
- @@index([userId])
1543
- @@index([organizationId])
1544
- @@index([memberId])
1545
- @@index([entityType])
1546
- }
1547
-
1548
- enum AuditLogEntityType {
1549
- organization
1550
- framework
1551
- requirement
1552
- control
1553
- policy
1554
- task
1555
- people
1556
- risk
1557
- vendor
1558
- tests
1559
- integration
1560
- trust
1561
- finding
1562
- }
1563
-
1564
- model GlobalVendors {
1565
- website String @id @unique
1566
- company_name String?
1567
- legal_name String?
1568
- company_description String?
1569
- company_hq_address String?
1570
- privacy_policy_url String?
1571
- terms_of_service_url String?
1572
- service_level_agreement_url String?
1573
- security_page_url String?
1574
- trust_page_url String?
1575
- security_certifications String[]
1576
- subprocessors String[]
1577
- type_of_company String?
1578
-
1579
- // Vendor Risk Assessment (shared across all organizations)
1580
- riskAssessmentData Json?
1581
- riskAssessmentVersion String?
1582
- riskAssessmentUpdatedAt DateTime?
1583
-
1584
- approved Boolean @default(false)
1585
- createdAt DateTime @default(now())
1586
-
1587
- @@index([website])
1588
- }
1589
-
1590
- enum Departments {
1591
- none
1592
- admin
1593
- gov
1594
- hr
1595
- it
1596
- itsm
1597
- qms
1598
- }
1599
-
1600
- enum Frequency {
1601
- monthly
1602
- quarterly
1603
- yearly
1604
- }
1605
-
1606
- enum Likelihood {
1607
- very_unlikely
1608
- unlikely
1609
- possible
1610
- likely
1611
- very_likely
1612
- }
1613
-
1614
- enum Impact {
1615
- insignificant
1616
- minor
1617
- moderate
1618
- major
1619
- severe
1620
- }
1621
-
1622
-
1623
- // ===== soa.prisma =====
1624
- // Statement of Applicability (SOA) Auto-complete Configuration and Answers
1625
-
1626
- model SOAFrameworkConfiguration {
1627
- id String @id @default(dbgenerated("generate_prefixed_cuid('soa_cfg'::text)"))
1628
- frameworkId String
1629
- framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id], onDelete: Cascade)
1630
-
1631
- // Configuration versioning - allows multiple configurations per framework
1632
- version Int @default(1) // Version number for this configuration (increments when config changes)
1633
- isLatest Boolean @default(true) // Whether this is the latest configuration version
1634
-
1635
- // Column definitions for SOA structure (template used when creating new documents)
1636
- columns Json // Array of { name: string, type: string } objects
1637
- // Example: [{ name: "Control ID", type: "string" }, { name: "Control Name", type: "string" }, { name: "Applicable", type: "boolean" }, { name: "Justification", type: "text" }]
1638
-
1639
- // Predefined questions for this framework
1640
- // Documents reference a specific configuration version via SOADocument.configurationId
1641
- // Old documents keep their old config version, new documents use new config version
1642
- questions Json // Array of question objects with unique IDs
1643
- // Example: [{ id: "A.5.1.1", text: "Is this control applicable?", columnMapping: "Applicable", controlId: "A.5.1.1" }, ...]
1644
- // IMPORTANT: question.id must be unique and stable - this is what SOAAnswer.questionId references
1645
-
1646
- // Dates
1647
- createdAt DateTime @default(now())
1648
- updatedAt DateTime @updatedAt
1649
-
1650
- // Relationships
1651
- documents SOADocument[]
1652
-
1653
- @@unique([frameworkId, version]) // Prevent duplicate configuration versions
1654
- @@index([frameworkId])
1655
- @@index([frameworkId, version])
1656
- @@index([frameworkId, isLatest])
1657
- }
1658
-
1659
- model SOADocument {
1660
- id String @id @default(dbgenerated("generate_prefixed_cuid('soa_doc'::text)"))
1661
-
1662
- // Framework and organization context
1663
- frameworkId String
1664
- framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id], onDelete: Cascade)
1665
- organizationId String
1666
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1667
-
1668
- // Configuration reference - references a specific SOAFrameworkConfiguration version
1669
- // Each document version can use a different configuration version
1670
- // Old documents keep their old config, new documents use new config
1671
- configurationId String
1672
- configuration SOAFrameworkConfiguration @relation(fields: [configurationId], references: [id], onDelete: Cascade)
1673
-
1674
- // Document versioning
1675
- version Int @default(1) // Version number for this document (increments yearly)
1676
- isLatest Boolean @default(true) // Whether this is the latest version
1677
-
1678
- // Document status
1679
- status SOADocumentStatus @default(draft) // draft, in_progress, completed
1680
-
1681
- // Document metadata
1682
- totalQuestions Int @default(0) // Total number of questions in this document
1683
- answeredQuestions Int @default(0) // Number of questions with answers
1684
-
1685
- // Approval tracking
1686
- preparedBy String @default("Comp AI") // Always "Comp AI"
1687
- approverId String? // Member ID who will approve this document (set when submitted for approval)
1688
- approver Member? @relation("SOADocumentApprover", fields: [approverId], references: [id], onDelete: SetNull, onUpdate: Cascade)
1689
- approvedAt DateTime? // When document was approved
1690
-
1691
- // Dates
1692
- completedAt DateTime? // When document was completed
1693
- createdAt DateTime @default(now())
1694
- updatedAt DateTime @updatedAt
1695
-
1696
- // Relationships
1697
- answers SOAAnswer[]
1698
-
1699
- @@unique([frameworkId, organizationId, version]) // Prevent duplicate versions
1700
- @@index([frameworkId, organizationId])
1701
- @@index([frameworkId, organizationId, version])
1702
- @@index([frameworkId, organizationId, isLatest])
1703
- @@index([configurationId])
1704
- @@index([status])
1705
- }
1706
-
1707
- model SOAAnswer {
1708
- id String @id @default(dbgenerated("generate_prefixed_cuid('soa_ans'::text)"))
1709
-
1710
- // Document context (replaces direct framework/organization link)
1711
- documentId String
1712
- document SOADocument @relation(fields: [documentId], references: [id], onDelete: Cascade)
1713
-
1714
- // Question reference - references question.id from SOADocument.configuration.questions
1715
- // References the specific configuration version that the document uses
1716
- // If config changes, old documents still reference their old config version
1717
- questionId String // Must match a question.id from SOADocument.configuration.questions
1718
-
1719
- // Answer data - simple text answer
1720
- answer String? // Text answer (nullable if not generated yet)
1721
-
1722
- // Answer metadata
1723
- status SOAAnswerStatus @default(untouched) // untouched, generated, manual
1724
- sources Json? // Sources used for generated answers (similar to questionnaire)
1725
- generatedAt DateTime? // When answer was generated
1726
-
1727
- // Answer versioning (within the document)
1728
- answerVersion Int @default(1) // Version number for this specific answer
1729
- isLatestAnswer Boolean @default(true) // Whether this is the latest version of this answer
1730
-
1731
- // User tracking
1732
- createdBy String? // User ID who created this answer
1733
- updatedBy String? // User ID who last updated this answer
1734
-
1735
- // Dates
1736
- createdAt DateTime @default(now())
1737
- updatedAt DateTime @updatedAt
1738
-
1739
- @@unique([documentId, questionId, answerVersion]) // Prevent duplicate answer versions
1740
- @@index([documentId])
1741
- @@index([documentId, questionId])
1742
- @@index([documentId, questionId, isLatestAnswer])
1743
- @@index([status])
1744
- }
1745
-
1746
- enum SOADocumentStatus {
1747
- draft // Document is being created/edited
1748
- in_progress // Document is being generated
1749
- needs_review // Document is submitted for approval
1750
- completed // Document is complete and approved
1751
- }
1752
-
1753
- enum SOAAnswerStatus {
1754
- untouched // No answer yet (not generated)
1755
- generated // AI generated answer
1756
- manual // Manually written/edited by user
1757
- }
1758
-
1759
-
1760
- // ===== task-item.prisma =====
1761
- model TaskItem {
1762
- id String @id @default(dbgenerated("generate_prefixed_cuid('tski'::text)"))
1763
- title String
1764
- description String?
1765
- status TaskItemStatus @default(todo)
1766
- priority TaskItemPriority @default(medium)
1767
-
1768
- // Polymorphic relation (like Comment and Attachment)
1769
- entityId String
1770
- entityType TaskItemEntityType
1771
-
1772
- // Assignment (nullable)
1773
- assigneeId String?
1774
- assignee Member? @relation("TaskItemAssignee", fields: [assigneeId], references: [id], onDelete: SetNull)
1775
-
1776
- // Creator & Updater
1777
- createdById String
1778
- createdBy Member @relation("TaskItemCreator", fields: [createdById], references: [id])
1779
- updatedById String?
1780
- updatedBy Member? @relation("TaskItemUpdater", fields: [updatedById], references: [id])
1781
-
1782
- // Relationships
1783
- organizationId String
1784
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1785
-
1786
- // Dates
1787
- createdAt DateTime @default(now())
1788
- updatedAt DateTime @updatedAt
1789
-
1790
- @@index([entityId, entityType])
1791
- @@index([organizationId])
1792
- @@index([assigneeId])
1793
- @@index([status])
1794
- @@index([priority])
1795
- }
1796
-
1797
- enum TaskItemStatus {
1798
- todo
1799
- in_progress
1800
- in_review
1801
- done
1802
- canceled
1803
- }
1804
-
1805
- enum TaskItemPriority {
1806
- urgent
1807
- high
1808
- medium
1809
- low
1810
- }
1811
-
1812
- enum TaskItemEntityType {
1813
- vendor
1814
- risk
1815
- }
1816
-
1817
-
1818
- // ===== task.prisma =====
1819
- model Task {
1820
- // Metadata
1821
- id String @id @default(dbgenerated("generate_prefixed_cuid('tsk'::text)"))
1822
- title String
1823
- description String
1824
- status TaskStatus @default(todo)
1825
- automationStatus TaskAutomationStatus @default(AUTOMATED)
1826
- frequency TaskFrequency?
1827
- department Departments? @default(none)
1828
- order Int @default(0)
1829
-
1830
- // Dates
1831
- createdAt DateTime @default(now())
1832
- updatedAt DateTime @updatedAt
1833
- lastCompletedAt DateTime?
1834
- reviewDate DateTime?
1835
-
1836
- // Relationships
1837
- assigneeId String?
1838
- assignee Member? @relation(fields: [assigneeId], references: [id])
1839
- organizationId String
1840
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1841
- taskTemplateId String?
1842
- taskTemplate FrameworkEditorTaskTemplate? @relation(fields: [taskTemplateId], references: [id])
1843
- controls Control[]
1844
- vendors Vendor[]
1845
- risks Risk[]
1846
- evidenceAutomations EvidenceAutomation[]
1847
- browserAutomations BrowserAutomation[]
1848
-
1849
- EvidenceAutomationRun EvidenceAutomationRun[]
1850
- integrationCheckRuns IntegrationCheckRun[]
1851
- findings Finding[]
1852
- }
1853
-
1854
- enum TaskStatus {
1855
- todo
1856
- in_progress
1857
- done
1858
- not_relevant
1859
- failed
1860
- }
1861
-
1862
- enum TaskFrequency {
1863
- daily
1864
- weekly
1865
- monthly
1866
- quarterly
1867
- yearly
1868
- }
1869
-
1870
- enum TaskAutomationStatus {
1871
- AUTOMATED
1872
- MANUAL
1873
- }
1874
-
1875
-
1876
- // ===== trust.prisma =====
1877
- model Trust {
1878
- organizationId String
1879
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1880
- friendlyUrl String? @unique
1881
- domain String?
1882
- domainVerified Boolean @default(false)
1883
- isVercelDomain Boolean @default(false)
1884
- vercelVerification String?
1885
- status TrustStatus @default(published)
1886
- contactEmail String?
1887
-
1888
- /// Domains that bypass NDA signing when requesting trust portal access
1889
- allowedDomains String[] @default([])
1890
-
1891
- email String?
1892
- privacyPolicy String?
1893
- soc2 Boolean @default(false)
1894
- soc2type1 Boolean @default(false)
1895
- soc2type2 Boolean @default(false)
1896
- iso27001 Boolean @default(false)
1897
- iso42001 Boolean @default(false)
1898
- nen7510 Boolean @default(false)
1899
- gdpr Boolean @default(false)
1900
- hipaa Boolean @default(false)
1901
- pci_dss Boolean @default(false)
1902
- iso9001 Boolean @default(false)
1903
-
1904
- soc2_status FrameworkStatus @default(started)
1905
- soc2type1_status FrameworkStatus @default(started)
1906
- soc2type2_status FrameworkStatus @default(started)
1907
- iso27001_status FrameworkStatus @default(started)
1908
- iso42001_status FrameworkStatus @default(started)
1909
- nen7510_status FrameworkStatus @default(started)
1910
- gdpr_status FrameworkStatus @default(started)
1911
- hipaa_status FrameworkStatus @default(started)
1912
- pci_dss_status FrameworkStatus @default(started)
1913
- iso9001_status FrameworkStatus @default(started)
1914
-
1915
- // Overview section for public trust portal
1916
- overviewTitle String?
1917
- overviewContent String? // Markdown content with links
1918
- showOverview Boolean @default(false)
1919
-
1920
- // Favicon for trust portal (stored in S3)
1921
- favicon String?
1922
-
1923
- @@id([status, organizationId])
1924
- @@unique([organizationId])
1925
- @@index([organizationId])
1926
- @@index([friendlyUrl])
1927
- }
1928
-
1929
- enum TrustStatus {
1930
- draft
1931
- published
1932
- }
1933
-
1934
- enum FrameworkStatus {
1935
- started
1936
- in_progress
1937
- compliant
1938
- }
1939
-
1940
- enum TrustFramework {
1941
- iso_27001
1942
- iso_42001
1943
- gdpr
1944
- hipaa
1945
- soc2_type1
1946
- soc2_type2
1947
- pci_dss
1948
- nen_7510
1949
- iso_9001
1950
- }
1951
-
1952
- model TrustResource {
1953
- id String @id @default(dbgenerated("generate_prefixed_cuid('tcr'::text)"))
1954
- organizationId String
1955
- organization Organization @relation("OrganizationTrustResources", fields: [organizationId], references: [id], onDelete: Cascade)
1956
- framework TrustFramework
1957
- s3Key String
1958
- fileName String
1959
- fileSize Int
1960
- createdAt DateTime @default(now())
1961
- updatedAt DateTime @updatedAt
1962
-
1963
- @@unique([organizationId, framework])
1964
- @@index([organizationId])
1965
- }
1966
-
1967
- model TrustAccessRequest {
1968
- id String @id @default(dbgenerated("generate_prefixed_cuid('tar'::text)"))
1969
- organizationId String
1970
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1971
-
1972
- name String
1973
- email String
1974
- company String?
1975
- jobTitle String?
1976
- purpose String?
1977
- requestedDurationDays Int?
1978
-
1979
- status TrustAccessRequestStatus @default(under_review)
1980
- reviewerMemberId String?
1981
- reviewer Member? @relation("TrustAccessRequestReviewer", fields: [reviewerMemberId], references: [id], onDelete: SetNull)
1982
- reviewedAt DateTime?
1983
- decisionReason String?
1984
-
1985
- ipAddress String?
1986
- userAgent String?
1987
-
1988
- createdAt DateTime @default(now())
1989
- updatedAt DateTime @updatedAt
1990
-
1991
- grant TrustAccessGrant? @relation("RequestGrant")
1992
- ndaAgreements TrustNDAAgreement[] @relation("RequestNDA")
1993
-
1994
- @@index([organizationId])
1995
- @@index([email])
1996
- @@index([status])
1997
- @@index([organizationId, status])
1998
- }
1999
-
2000
- model TrustAccessGrant {
2001
- id String @id @default(dbgenerated("generate_prefixed_cuid('tag'::text)"))
2002
-
2003
- accessRequestId String @unique
2004
- accessRequest TrustAccessRequest @relation("RequestGrant", fields: [accessRequestId], references: [id], onDelete: Cascade)
2005
-
2006
- subjectEmail String
2007
-
2008
- status TrustAccessGrantStatus @default(active)
2009
- expiresAt DateTime
2010
-
2011
- accessToken String? @unique
2012
- accessTokenExpiresAt DateTime?
2013
-
2014
- issuedByMemberId String?
2015
- issuedBy Member? @relation("IssuedGrants", fields: [issuedByMemberId], references: [id], onDelete: SetNull)
2016
-
2017
- revokedAt DateTime?
2018
- revokedByMemberId String?
2019
- revokedBy Member? @relation("RevokedGrants", fields: [revokedByMemberId], references: [id], onDelete: SetNull)
2020
- revokeReason String?
2021
-
2022
- createdAt DateTime @default(now())
2023
- updatedAt DateTime @updatedAt
2024
-
2025
- ndaAgreement TrustNDAAgreement? @relation("GrantNDA")
2026
-
2027
- @@index([accessRequestId])
2028
- @@index([subjectEmail])
2029
- @@index([status])
2030
- @@index([expiresAt])
2031
- @@index([status, expiresAt])
2032
- @@index([accessToken])
2033
- }
2034
-
2035
- enum TrustAccessRequestStatus {
2036
- under_review
2037
- approved
2038
- denied
2039
- canceled
2040
- }
2041
-
2042
- enum TrustAccessGrantStatus {
2043
- active
2044
- expired
2045
- revoked
2046
- }
2047
-
2048
- model TrustNDAAgreement {
2049
- id String @id @default(dbgenerated("generate_prefixed_cuid('tna'::text)"))
2050
-
2051
- organizationId String
2052
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
2053
-
2054
- accessRequestId String
2055
- accessRequest TrustAccessRequest @relation("RequestNDA", fields: [accessRequestId], references: [id], onDelete: Cascade)
2056
-
2057
- grantId String? @unique
2058
- grant TrustAccessGrant? @relation("GrantNDA", fields: [grantId], references: [id], onDelete: SetNull)
2059
-
2060
- signerName String?
2061
- signerEmail String?
2062
-
2063
- status TrustNDAStatus @default(pending)
2064
-
2065
- signToken String @unique
2066
- signTokenExpiresAt DateTime
2067
-
2068
- pdfTemplateKey String?
2069
- pdfSignedKey String?
2070
-
2071
- signedAt DateTime?
2072
-
2073
- ipAddress String?
2074
- userAgent String?
2075
-
2076
- createdAt DateTime @default(now())
2077
- updatedAt DateTime @updatedAt
2078
-
2079
- @@index([organizationId])
2080
- @@index([accessRequestId])
2081
- @@index([signToken])
2082
- @@index([status])
2083
- }
2084
-
2085
- enum TrustNDAStatus {
2086
- pending
2087
- signed
2088
- void
2089
- }
2090
-
2091
- model TrustDocument {
2092
- id String @id @default(dbgenerated("generate_prefixed_cuid('tdoc'::text)"))
2093
-
2094
- organizationId String
2095
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
2096
-
2097
- name String
2098
- description String?
2099
- s3Key String
2100
-
2101
- isActive Boolean @default(true)
2102
-
2103
- createdAt DateTime @default(now())
2104
- updatedAt DateTime @updatedAt
2105
-
2106
- @@index([organizationId])
2107
- @@index([organizationId, isActive])
2108
- }
2109
-
2110
- model TrustCustomLink {
2111
- id String @id @default(dbgenerated("generate_prefixed_cuid('tcl'::text)"))
2112
-
2113
- organizationId String
2114
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
2115
-
2116
- title String
2117
- description String?
2118
- url String
2119
- order Int @default(0)
2120
- isActive Boolean @default(true)
2121
-
2122
- createdAt DateTime @default(now())
2123
- updatedAt DateTime @updatedAt
2124
-
2125
- @@index([organizationId])
2126
- @@index([organizationId, isActive, order])
2127
- }
2128
-
2129
-
2130
- // ===== vendor.prisma =====
2131
- model Vendor {
2132
- id String @id @default(dbgenerated("generate_prefixed_cuid('vnd'::text)"))
2133
- name String
2134
- description String
2135
- category VendorCategory @default(other)
2136
- status VendorStatus @default(not_assessed)
2137
- inherentProbability Likelihood @default(very_unlikely)
2138
- inherentImpact Impact @default(insignificant)
2139
- residualProbability Likelihood @default(very_unlikely)
2140
- residualImpact Impact @default(insignificant)
2141
- website String?
2142
- isSubProcessor Boolean @default(false)
2143
-
2144
- // Trust Portal display settings
2145
- logoUrl String?
2146
- showOnTrustPortal Boolean @default(false)
2147
- trustPortalOrder Int?
2148
- complianceBadges Json? // Array of { type: 'soc2' | 'iso27001' | etc, verified: boolean }
2149
-
2150
- createdAt DateTime @default(now())
2151
- updatedAt DateTime @updatedAt
2152
-
2153
- organizationId String
2154
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
2155
- assigneeId String?
2156
- assignee Member? @relation(fields: [assigneeId], references: [id], onDelete: Cascade)
2157
- contacts VendorContact[]
2158
- tasks Task[]
2159
-
2160
- @@index([organizationId])
2161
- @@index([assigneeId])
2162
- @@index([category])
2163
- }
2164
-
2165
- model VendorContact {
2166
- id String @id @default(dbgenerated("generate_prefixed_cuid('vct'::text)"))
2167
- vendorId String
2168
- name String
2169
- email String
2170
- phone String
2171
- createdAt DateTime @default(now())
2172
- updatedAt DateTime @updatedAt
2173
- Vendor Vendor @relation(fields: [vendorId], references: [id], onDelete: Cascade)
2174
-
2175
- @@index([vendorId])
2176
- }
2177
-
2178
- enum VendorCategory {
2179
- cloud
2180
- infrastructure
2181
- software_as_a_service
2182
- finance
2183
- marketing
2184
- sales
2185
- hr
2186
- other
2187
- }
2188
-
2189
- enum VendorStatus {
2190
- not_assessed
2191
- in_progress
2192
- assessed
2193
- }