@trycompai/db 1.3.18 → 1.3.19-canary.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
@@ -53,14 +53,16 @@ enum AttachmentType {
53
53
 
54
54
  // ===== auth.prisma =====
55
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?
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}")
64
66
 
65
67
  accounts Account[]
66
68
  auditLog AuditLog[]
@@ -147,12 +149,13 @@ model Member {
147
149
 
148
150
  department Departments @default(none)
149
151
  isActive Boolean @default(true)
150
- deactivated Boolean @default(false)
152
+ deactivated Boolean @default(false)
151
153
  employeeTrainingVideoCompletion EmployeeTrainingVideoCompletion[]
152
154
  fleetDmLabelId Int?
153
155
 
154
156
  assignedPolicies Policy[] @relation("PolicyAssignee") // Policies where this member is an assignee
155
157
  approvedPolicies Policy[] @relation("PolicyApprover") // Policies where this member is an approver
158
+ approvedSOADocuments SOADocument[] @relation("SOADocumentApprover") // SOA documents where this member is an approver
156
159
  risks Risk[]
157
160
  tasks Task[]
158
161
  vendors Vendor[]
@@ -173,16 +176,17 @@ model Invitation {
173
176
  expiresAt DateTime
174
177
  inviterId String
175
178
  user User @relation(fields: [inviterId], references: [id], onDelete: Cascade)
179
+ createdAt DateTime @default(now())
176
180
  }
177
181
 
178
182
  // This is only for the app to consume, shouldn't be enforced by DB
179
183
  // Otherwise it won't work with Better Auth, as per https://www.better-auth.com/docs/plugins/organization#access-control
180
184
  enum Role {
181
- owner
182
- admin
183
- auditor
184
- employee
185
- contractor
185
+ owner
186
+ admin
187
+ auditor
188
+ employee
189
+ contractor
186
190
  }
187
191
 
188
192
  enum PolicyStatus {
@@ -392,6 +396,8 @@ model FrameworkEditorFramework {
392
396
 
393
397
  requirements FrameworkEditorRequirement[]
394
398
  frameworkInstances FrameworkInstance[]
399
+ soaConfigurations SOAFrameworkConfiguration[] // Multiple SOA config versions per framework
400
+ soaDocuments SOADocument[] // SOA documents from organizations
395
401
 
396
402
  // Dates
397
403
  createdAt DateTime @default(now())
@@ -522,15 +528,15 @@ model IntegrationResult {
522
528
 
523
529
  // ===== knowledge-base-document.prisma =====
524
530
  model KnowledgeBaseDocument {
525
- id String @id @default(dbgenerated("generate_prefixed_cuid('kbd'::text)"))
526
- name String // Original filename
527
- description String? // Optional user description/notes
528
- s3Key String // S3 storage key (e.g., "org123/knowledge-base-documents/timestamp-file.pdf")
529
- fileType String // MIME type (e.g., "application/pdf")
530
- fileSize Int // File size in bytes
531
+ id String @id @default(dbgenerated("generate_prefixed_cuid('kbd'::text)"))
532
+ name String // Original filename
533
+ description String? // Optional user description/notes
534
+ s3Key String // S3 storage key (e.g., "org123/knowledge-base-documents/timestamp-file.pdf")
535
+ fileType String // MIME type (e.g., "application/pdf")
536
+ fileSize Int // File size in bytes
531
537
  processingStatus KnowledgeBaseDocumentProcessingStatus @default(pending) // Track indexing status
532
- processedAt DateTime? // When indexing completed
533
- triggerRunId String? // Trigger.dev run ID for tracking processing progress
538
+ processedAt DateTime? // When indexing completed
539
+ triggerRunId String? // Trigger.dev run ID for tracking processing progress
534
540
 
535
541
  // Dates
536
542
  createdAt DateTime @default(now())
@@ -547,14 +553,13 @@ model KnowledgeBaseDocument {
547
553
  }
548
554
 
549
555
  enum KnowledgeBaseDocumentProcessingStatus {
550
- pending // Uploaded but not yet processed/indexed
551
- processing // Currently being processed/indexed
552
- completed // Successfully indexed in vector database
553
- failed // Processing failed
556
+ pending // Uploaded but not yet processed/indexed
557
+ processing // Currently being processed/indexed
558
+ completed // Successfully indexed in vector database
559
+ failed // Processing failed
554
560
  }
555
561
 
556
562
 
557
-
558
563
  // ===== onboarding.prisma =====
559
564
  model Onboarding {
560
565
  organizationId String @id
@@ -594,29 +599,31 @@ model Organization {
594
599
  fleetDmLabelId Int?
595
600
  isFleetSetupCompleted Boolean @default(false)
596
601
 
597
- apiKeys ApiKey[]
598
- auditLog AuditLog[]
599
- controls Control[]
600
- frameworkInstances FrameworkInstance[]
601
- integrations Integration[]
602
- invitations Invitation[]
603
- members Member[]
604
- policy Policy[]
605
- risk Risk[]
606
- vendors Vendor[]
607
- tasks Task[]
608
- comments Comment[]
609
- attachments Attachment[]
610
- trust Trust[]
611
- context Context[]
612
- secrets Secret[]
613
- trustAccessRequests TrustAccessRequest[]
614
- trustNdaAgreements TrustNDAAgreement[]
615
- trustDocuments TrustDocument[]
616
- knowledgeBaseDocuments KnowledgeBaseDocument[]
617
- questionnaires Questionnaire[]
602
+ apiKeys ApiKey[]
603
+ auditLog AuditLog[]
604
+ controls Control[]
605
+ frameworkInstances FrameworkInstance[]
606
+ integrations Integration[]
607
+ invitations Invitation[]
608
+ members Member[]
609
+ policy Policy[]
610
+ risk Risk[]
611
+ vendors Vendor[]
612
+ tasks Task[]
613
+ comments Comment[]
614
+ attachments Attachment[]
615
+ trust Trust[]
616
+ context Context[]
617
+ secrets Secret[]
618
+ trustAccessRequests TrustAccessRequest[]
619
+ trustNdaAgreements TrustNDAAgreement[]
620
+ trustDocuments TrustDocument[]
621
+ trustResources TrustResource[] @relation("OrganizationTrustResources")
622
+ knowledgeBaseDocuments KnowledgeBaseDocument[]
623
+ questionnaires Questionnaire[]
618
624
  securityQuestionnaireManualAnswers SecurityQuestionnaireManualAnswer[]
619
-
625
+ soaDocuments SOADocument[]
626
+ primaryColor String?
620
627
  @@index([slug])
621
628
  }
622
629
 
@@ -665,15 +672,15 @@ model Policy {
665
672
 
666
673
  // ===== questionnaire.prisma =====
667
674
  model Questionnaire {
668
- id String @id @default(dbgenerated("generate_prefixed_cuid('qst'::text)"))
669
- filename String // Original filename
670
- s3Key String // S3 storage key for the uploaded file
671
- fileType String // MIME type (e.g., "application/pdf")
672
- fileSize Int // File size in bytes
673
- status QuestionnaireStatus @default(parsing) // Parsing status
674
- parsedAt DateTime? // When parsing completed
675
- totalQuestions Int @default(0) // Total number of questions parsed
676
- answeredQuestions Int @default(0) // Number of questions with answers
675
+ id String @id @default(dbgenerated("generate_prefixed_cuid('qst'::text)"))
676
+ filename String // Original filename
677
+ s3Key String // S3 storage key for the uploaded file
678
+ fileType String // MIME type (e.g., "application/pdf")
679
+ fileSize Int // File size in bytes
680
+ status QuestionnaireStatus @default(parsing) // Parsing status
681
+ parsedAt DateTime? // When parsing completed
682
+ totalQuestions Int @default(0) // Total number of questions parsed
683
+ answeredQuestions Int @default(0) // Number of questions with answers
677
684
 
678
685
  // Dates
679
686
  createdAt DateTime @default(now())
@@ -681,7 +688,7 @@ model Questionnaire {
681
688
 
682
689
  // Relationships
683
690
  organizationId String
684
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
691
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
685
692
  questions QuestionnaireQuestionAnswer[]
686
693
  manualAnswers SecurityQuestionnaireManualAnswer[] // Manual answers saved from this questionnaire
687
694
 
@@ -691,14 +698,14 @@ model Questionnaire {
691
698
  }
692
699
 
693
700
  model QuestionnaireQuestionAnswer {
694
- id String @id @default(dbgenerated("generate_prefixed_cuid('qqa'::text)"))
695
- question String // The question text
696
- answer String? // The answer (nullable if not provided in file or not generated yet)
697
- status QuestionnaireAnswerStatus @default(untouched) // Answer status
698
- questionIndex Int // Order/index of the question in the questionnaire
699
- sources Json? // Sources used for generated answers (array of source objects)
700
- generatedAt DateTime? // When answer was generated (if status is generated)
701
- updatedBy String? // User ID who last updated the answer (if manual)
701
+ id String @id @default(dbgenerated("generate_prefixed_cuid('qqa'::text)"))
702
+ question String // The question text
703
+ answer String? // The answer (nullable if not provided in file or not generated yet)
704
+ status QuestionnaireAnswerStatus @default(untouched) // Answer status
705
+ questionIndex Int // Order/index of the question in the questionnaire
706
+ sources Json? // Sources used for generated answers (array of source objects)
707
+ generatedAt DateTime? // When answer was generated (if status is generated)
708
+ updatedBy String? // User ID who last updated the answer (if manual)
702
709
 
703
710
  // Dates
704
711
  createdAt DateTime @default(now())
@@ -714,19 +721,18 @@ model QuestionnaireQuestionAnswer {
714
721
  }
715
722
 
716
723
  enum QuestionnaireStatus {
717
- parsing // Currently being parsed
718
- completed // Successfully parsed
719
- failed // Parsing failed
724
+ parsing // Currently being parsed
725
+ completed // Successfully parsed
726
+ failed // Parsing failed
720
727
  }
721
728
 
722
729
  enum QuestionnaireAnswerStatus {
723
- untouched // No answer yet (empty or not generated)
724
- generated // AI generated answer
725
- manual // Manually written/edited by user
730
+ untouched // No answer yet (empty or not generated)
731
+ generated // AI generated answer
732
+ manual // Manually written/edited by user
726
733
  }
727
734
 
728
735
 
729
-
730
736
  // ===== requirement.prisma =====
731
737
  model RequirementMap {
732
738
  id String @id @default(dbgenerated("generate_prefixed_cuid('req'::text)"))
@@ -827,36 +833,35 @@ model Secret {
827
833
 
828
834
  // ===== security-questionnaire-manual-answer.prisma =====
829
835
  model SecurityQuestionnaireManualAnswer {
830
- id String @id @default(dbgenerated("generate_prefixed_cuid('sqma'::text)"))
831
- question String // The question text
832
- answer String // The answer text (required for saved answers)
833
- tags String[] @default([]) // Optional tags for categorization
834
-
836
+ id String @id @default(dbgenerated("generate_prefixed_cuid('sqma'::text)"))
837
+ question String // The question text
838
+ answer String // The answer text (required for saved answers)
839
+ tags String[] @default([]) // Optional tags for categorization
840
+
835
841
  // Optional reference to original questionnaire (for tracking)
836
842
  sourceQuestionnaireId String?
837
843
  sourceQuestionnaire Questionnaire? @relation(fields: [sourceQuestionnaireId], references: [id], onDelete: SetNull)
838
-
844
+
839
845
  // User who created/updated this answer
840
- createdBy String? // User ID
841
- updatedBy String? // User ID
842
-
846
+ createdBy String? // User ID
847
+ updatedBy String? // User ID
848
+
843
849
  // Dates
844
850
  createdAt DateTime @default(now())
845
851
  updatedAt DateTime @updatedAt
846
-
852
+
847
853
  // Relationships
848
854
  organizationId String
849
855
  organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
850
-
856
+
857
+ @@unique([organizationId, question]) // Prevent duplicate questions per organization
851
858
  @@index([organizationId])
852
859
  @@index([organizationId, question])
853
860
  @@index([tags])
854
861
  @@index([createdAt])
855
- @@unique([organizationId, question]) // Prevent duplicate questions per organization
856
862
  }
857
863
 
858
864
 
859
-
860
865
  // ===== shared.prisma =====
861
866
  model ApiKey {
862
867
  id String @id @default(dbgenerated("generate_prefixed_cuid('apk'::text)"))
@@ -965,6 +970,143 @@ enum Impact {
965
970
  }
966
971
 
967
972
 
973
+ // ===== soa.prisma =====
974
+ // Statement of Applicability (SOA) Auto-complete Configuration and Answers
975
+
976
+ model SOAFrameworkConfiguration {
977
+ id String @id @default(dbgenerated("generate_prefixed_cuid('soa_cfg'::text)"))
978
+ frameworkId String
979
+ framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id], onDelete: Cascade)
980
+
981
+ // Configuration versioning - allows multiple configurations per framework
982
+ version Int @default(1) // Version number for this configuration (increments when config changes)
983
+ isLatest Boolean @default(true) // Whether this is the latest configuration version
984
+
985
+ // Column definitions for SOA structure (template used when creating new documents)
986
+ columns Json // Array of { name: string, type: string } objects
987
+ // Example: [{ name: "Control ID", type: "string" }, { name: "Control Name", type: "string" }, { name: "Applicable", type: "boolean" }, { name: "Justification", type: "text" }]
988
+
989
+ // Predefined questions for this framework
990
+ // Documents reference a specific configuration version via SOADocument.configurationId
991
+ // Old documents keep their old config version, new documents use new config version
992
+ questions Json // Array of question objects with unique IDs
993
+ // Example: [{ id: "A.5.1.1", text: "Is this control applicable?", columnMapping: "Applicable", controlId: "A.5.1.1" }, ...]
994
+ // IMPORTANT: question.id must be unique and stable - this is what SOAAnswer.questionId references
995
+
996
+ // Dates
997
+ createdAt DateTime @default(now())
998
+ updatedAt DateTime @updatedAt
999
+
1000
+ // Relationships
1001
+ documents SOADocument[]
1002
+
1003
+ @@unique([frameworkId, version]) // Prevent duplicate configuration versions
1004
+ @@index([frameworkId])
1005
+ @@index([frameworkId, version])
1006
+ @@index([frameworkId, isLatest])
1007
+ }
1008
+
1009
+ model SOADocument {
1010
+ id String @id @default(dbgenerated("generate_prefixed_cuid('soa_doc'::text)"))
1011
+
1012
+ // Framework and organization context
1013
+ frameworkId String
1014
+ framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id], onDelete: Cascade)
1015
+ organizationId String
1016
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1017
+
1018
+ // Configuration reference - references a specific SOAFrameworkConfiguration version
1019
+ // Each document version can use a different configuration version
1020
+ // Old documents keep their old config, new documents use new config
1021
+ configurationId String
1022
+ configuration SOAFrameworkConfiguration @relation(fields: [configurationId], references: [id], onDelete: Cascade)
1023
+
1024
+ // Document versioning
1025
+ version Int @default(1) // Version number for this document (increments yearly)
1026
+ isLatest Boolean @default(true) // Whether this is the latest version
1027
+
1028
+ // Document status
1029
+ status SOADocumentStatus @default(draft) // draft, in_progress, completed
1030
+
1031
+ // Document metadata
1032
+ totalQuestions Int @default(0) // Total number of questions in this document
1033
+ answeredQuestions Int @default(0) // Number of questions with answers
1034
+
1035
+ // Approval tracking
1036
+ preparedBy String @default("Comp AI") // Always "Comp AI"
1037
+ approverId String? // Member ID who will approve this document (set when submitted for approval)
1038
+ approver Member? @relation("SOADocumentApprover", fields: [approverId], references: [id], onDelete: SetNull, onUpdate: Cascade)
1039
+ approvedAt DateTime? // When document was approved
1040
+
1041
+ // Dates
1042
+ completedAt DateTime? // When document was completed
1043
+ createdAt DateTime @default(now())
1044
+ updatedAt DateTime @updatedAt
1045
+
1046
+ // Relationships
1047
+ answers SOAAnswer[]
1048
+
1049
+ @@unique([frameworkId, organizationId, version]) // Prevent duplicate versions
1050
+ @@index([frameworkId, organizationId])
1051
+ @@index([frameworkId, organizationId, version])
1052
+ @@index([frameworkId, organizationId, isLatest])
1053
+ @@index([configurationId])
1054
+ @@index([status])
1055
+ }
1056
+
1057
+ model SOAAnswer {
1058
+ id String @id @default(dbgenerated("generate_prefixed_cuid('soa_ans'::text)"))
1059
+
1060
+ // Document context (replaces direct framework/organization link)
1061
+ documentId String
1062
+ document SOADocument @relation(fields: [documentId], references: [id], onDelete: Cascade)
1063
+
1064
+ // Question reference - references question.id from SOADocument.configuration.questions
1065
+ // References the specific configuration version that the document uses
1066
+ // If config changes, old documents still reference their old config version
1067
+ questionId String // Must match a question.id from SOADocument.configuration.questions
1068
+
1069
+ // Answer data - simple text answer
1070
+ answer String? // Text answer (nullable if not generated yet)
1071
+
1072
+ // Answer metadata
1073
+ status SOAAnswerStatus @default(untouched) // untouched, generated, manual
1074
+ sources Json? // Sources used for generated answers (similar to questionnaire)
1075
+ generatedAt DateTime? // When answer was generated
1076
+
1077
+ // Answer versioning (within the document)
1078
+ answerVersion Int @default(1) // Version number for this specific answer
1079
+ isLatestAnswer Boolean @default(true) // Whether this is the latest version of this answer
1080
+
1081
+ // User tracking
1082
+ createdBy String? // User ID who created this answer
1083
+ updatedBy String? // User ID who last updated this answer
1084
+
1085
+ // Dates
1086
+ createdAt DateTime @default(now())
1087
+ updatedAt DateTime @updatedAt
1088
+
1089
+ @@unique([documentId, questionId, answerVersion]) // Prevent duplicate answer versions
1090
+ @@index([documentId])
1091
+ @@index([documentId, questionId])
1092
+ @@index([documentId, questionId, isLatestAnswer])
1093
+ @@index([status])
1094
+ }
1095
+
1096
+ enum SOADocumentStatus {
1097
+ draft // Document is being created/edited
1098
+ in_progress // Document is being generated
1099
+ needs_review // Document is submitted for approval
1100
+ completed // Document is complete and approved
1101
+ }
1102
+
1103
+ enum SOAAnswerStatus {
1104
+ untouched // No answer yet (not generated)
1105
+ generated // AI generated answer
1106
+ manual // Manually written/edited by user
1107
+ }
1108
+
1109
+
968
1110
  // ===== task.prisma =====
969
1111
  model Task {
970
1112
  // Metadata
@@ -1067,6 +1209,33 @@ enum FrameworkStatus {
1067
1209
  compliant
1068
1210
  }
1069
1211
 
1212
+ enum TrustFramework {
1213
+ iso_27001
1214
+ iso_42001
1215
+ gdpr
1216
+ hipaa
1217
+ soc2_type1
1218
+ soc2_type2
1219
+ pci_dss
1220
+ nen_7510
1221
+ iso_9001
1222
+ }
1223
+
1224
+ model TrustResource {
1225
+ id String @id @default(dbgenerated("generate_prefixed_cuid('tcr'::text)"))
1226
+ organizationId String
1227
+ organization Organization @relation("OrganizationTrustResources", fields: [organizationId], references: [id], onDelete: Cascade)
1228
+ framework TrustFramework
1229
+ s3Key String
1230
+ fileName String
1231
+ fileSize Int
1232
+ createdAt DateTime @default(now())
1233
+ updatedAt DateTime @updatedAt
1234
+
1235
+ @@unique([organizationId, framework])
1236
+ @@index([organizationId])
1237
+ }
1238
+
1070
1239
  model TrustAccessRequest {
1071
1240
  id String @id @default(dbgenerated("generate_prefixed_cuid('tar'::text)"))
1072
1241
  organizationId String
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@trycompai/db",
3
3
  "description": "Database package with Prisma client and schema for Comp AI",
4
- "version": "1.3.18",
4
+ "version": "1.3.19-canary.3",
5
5
  "dependencies": {
6
6
  "@prisma/client": "^6.13.0",
7
7
  "dotenv": "^16.4.5",