@trycompai/db 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +2 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +24 -3
- package/dist/schema.prisma +921 -546
- package/dist/scripts/backfill-framework-versions.d.ts +6 -0
- package/dist/scripts/backfill-framework-versions.d.ts.map +1 -0
- package/dist/scripts/backfill-framework-versions.js +142 -0
- package/package.json +5 -3
- package/dist/client.ts +0 -7
- package/dist/generated/prisma/client.d.ts +0 -427
- package/dist/generated/prisma/client.d.ts.map +0 -1
- package/dist/generated/prisma/client.js +0 -73
- package/dist/generated/prisma/commonInputTypes.d.ts +0 -2082
- package/dist/generated/prisma/commonInputTypes.d.ts.map +0 -1
- package/dist/generated/prisma/commonInputTypes.js +0 -11
- package/dist/generated/prisma/enums.d.ts +0 -367
- package/dist/generated/prisma/enums.d.ts.map +0 -1
- package/dist/generated/prisma/enums.js +0 -329
- package/dist/generated/prisma/internal/class.d.ts +0 -1000
- package/dist/generated/prisma/internal/class.d.ts.map +0 -1
- package/dist/generated/prisma/internal/class.js +0 -87
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +0 -8063
- package/dist/generated/prisma/internal/prismaNamespace.d.ts.map +0 -1
- package/dist/generated/prisma/internal/prismaNamespace.js +0 -1256
- package/dist/generated/prisma/models/Account.d.ts +0 -1456
- package/dist/generated/prisma/models/Account.d.ts.map +0 -1
- package/dist/generated/prisma/models/Account.js +0 -2
- package/dist/generated/prisma/models/ApiKey.d.ts +0 -1387
- package/dist/generated/prisma/models/ApiKey.d.ts.map +0 -1
- package/dist/generated/prisma/models/ApiKey.js +0 -2
- package/dist/generated/prisma/models/Attachment.d.ts +0 -1520
- package/dist/generated/prisma/models/Attachment.d.ts.map +0 -1
- package/dist/generated/prisma/models/Attachment.js +0 -2
- package/dist/generated/prisma/models/AuditLog.d.ts +0 -1590
- package/dist/generated/prisma/models/AuditLog.d.ts.map +0 -1
- package/dist/generated/prisma/models/AuditLog.js +0 -2
- package/dist/generated/prisma/models/BrowserAutomation.d.ts +0 -1507
- package/dist/generated/prisma/models/BrowserAutomation.d.ts.map +0 -1
- package/dist/generated/prisma/models/BrowserAutomation.js +0 -2
- package/dist/generated/prisma/models/BrowserAutomationRun.d.ts +0 -1455
- package/dist/generated/prisma/models/BrowserAutomationRun.d.ts.map +0 -1
- package/dist/generated/prisma/models/BrowserAutomationRun.js +0 -2
- package/dist/generated/prisma/models/BrowserbaseContext.d.ts +0 -1139
- package/dist/generated/prisma/models/BrowserbaseContext.d.ts.map +0 -1
- package/dist/generated/prisma/models/BrowserbaseContext.js +0 -2
- package/dist/generated/prisma/models/Comment.d.ts +0 -1502
- package/dist/generated/prisma/models/Comment.d.ts.map +0 -1
- package/dist/generated/prisma/models/Comment.js +0 -2
- package/dist/generated/prisma/models/Context.d.ts +0 -1254
- package/dist/generated/prisma/models/Context.d.ts.map +0 -1
- package/dist/generated/prisma/models/Context.js +0 -2
- package/dist/generated/prisma/models/Control.d.ts +0 -1965
- package/dist/generated/prisma/models/Control.d.ts.map +0 -1
- package/dist/generated/prisma/models/Control.js +0 -2
- package/dist/generated/prisma/models/ControlDocumentType.d.ts +0 -1115
- package/dist/generated/prisma/models/ControlDocumentType.d.ts.map +0 -1
- package/dist/generated/prisma/models/ControlDocumentType.js +0 -2
- package/dist/generated/prisma/models/Device.d.ts +0 -1858
- package/dist/generated/prisma/models/Device.d.ts.map +0 -1
- package/dist/generated/prisma/models/Device.js +0 -2
- package/dist/generated/prisma/models/DynamicCheck.d.ts +0 -1517
- package/dist/generated/prisma/models/DynamicCheck.d.ts.map +0 -1
- package/dist/generated/prisma/models/DynamicCheck.js +0 -2
- package/dist/generated/prisma/models/DynamicIntegration.d.ts +0 -1528
- package/dist/generated/prisma/models/DynamicIntegration.d.ts.map +0 -1
- package/dist/generated/prisma/models/DynamicIntegration.js +0 -2
- package/dist/generated/prisma/models/EmployeeTrainingVideoCompletion.d.ts +0 -1146
- package/dist/generated/prisma/models/EmployeeTrainingVideoCompletion.d.ts.map +0 -1
- package/dist/generated/prisma/models/EmployeeTrainingVideoCompletion.js +0 -2
- package/dist/generated/prisma/models/EvidenceAutomation.d.ts +0 -1533
- package/dist/generated/prisma/models/EvidenceAutomation.d.ts.map +0 -1
- package/dist/generated/prisma/models/EvidenceAutomation.js +0 -2
- package/dist/generated/prisma/models/EvidenceAutomationRun.d.ts +0 -1833
- package/dist/generated/prisma/models/EvidenceAutomationRun.d.ts.map +0 -1
- package/dist/generated/prisma/models/EvidenceAutomationRun.js +0 -2
- package/dist/generated/prisma/models/EvidenceAutomationVersion.d.ts +0 -1331
- package/dist/generated/prisma/models/EvidenceAutomationVersion.d.ts.map +0 -1
- package/dist/generated/prisma/models/EvidenceAutomationVersion.js +0 -2
- package/dist/generated/prisma/models/EvidenceSubmission.d.ts +0 -1905
- package/dist/generated/prisma/models/EvidenceSubmission.d.ts.map +0 -1
- package/dist/generated/prisma/models/EvidenceSubmission.js +0 -2
- package/dist/generated/prisma/models/Finding.d.ts +0 -2386
- package/dist/generated/prisma/models/Finding.d.ts.map +0 -1
- package/dist/generated/prisma/models/Finding.js +0 -2
- package/dist/generated/prisma/models/FindingTemplate.d.ts +0 -1264
- package/dist/generated/prisma/models/FindingTemplate.d.ts.map +0 -1
- package/dist/generated/prisma/models/FindingTemplate.js +0 -2
- package/dist/generated/prisma/models/FleetPolicyResult.d.ts +0 -1484
- package/dist/generated/prisma/models/FleetPolicyResult.d.ts.map +0 -1
- package/dist/generated/prisma/models/FleetPolicyResult.js +0 -2
- package/dist/generated/prisma/models/FrameworkEditorControlTemplate.d.ts +0 -1669
- package/dist/generated/prisma/models/FrameworkEditorControlTemplate.d.ts.map +0 -1
- package/dist/generated/prisma/models/FrameworkEditorControlTemplate.js +0 -2
- package/dist/generated/prisma/models/FrameworkEditorFramework.d.ts +0 -1581
- package/dist/generated/prisma/models/FrameworkEditorFramework.d.ts.map +0 -1
- package/dist/generated/prisma/models/FrameworkEditorFramework.js +0 -2
- package/dist/generated/prisma/models/FrameworkEditorPolicyTemplate.d.ts +0 -1428
- package/dist/generated/prisma/models/FrameworkEditorPolicyTemplate.d.ts.map +0 -1
- package/dist/generated/prisma/models/FrameworkEditorPolicyTemplate.js +0 -2
- package/dist/generated/prisma/models/FrameworkEditorRequirement.d.ts +0 -1525
- package/dist/generated/prisma/models/FrameworkEditorRequirement.d.ts.map +0 -1
- package/dist/generated/prisma/models/FrameworkEditorRequirement.js +0 -2
- package/dist/generated/prisma/models/FrameworkEditorTaskTemplate.d.ts +0 -1434
- package/dist/generated/prisma/models/FrameworkEditorTaskTemplate.d.ts.map +0 -1
- package/dist/generated/prisma/models/FrameworkEditorTaskTemplate.js +0 -2
- package/dist/generated/prisma/models/FrameworkEditorVideo.d.ts +0 -1054
- package/dist/generated/prisma/models/FrameworkEditorVideo.d.ts.map +0 -1
- package/dist/generated/prisma/models/FrameworkEditorVideo.js +0 -2
- package/dist/generated/prisma/models/FrameworkInstance.d.ts +0 -1321
- package/dist/generated/prisma/models/FrameworkInstance.d.ts.map +0 -1
- package/dist/generated/prisma/models/FrameworkInstance.js +0 -2
- package/dist/generated/prisma/models/GlobalVendors.d.ts +0 -1358
- package/dist/generated/prisma/models/GlobalVendors.d.ts.map +0 -1
- package/dist/generated/prisma/models/GlobalVendors.js +0 -2
- package/dist/generated/prisma/models/Integration.d.ts +0 -1363
- package/dist/generated/prisma/models/Integration.d.ts.map +0 -1
- package/dist/generated/prisma/models/Integration.js +0 -2
- package/dist/generated/prisma/models/IntegrationCheckResult.d.ts +0 -1408
- package/dist/generated/prisma/models/IntegrationCheckResult.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationCheckResult.js +0 -2
- package/dist/generated/prisma/models/IntegrationCheckRun.d.ts +0 -1958
- package/dist/generated/prisma/models/IntegrationCheckRun.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationCheckRun.js +0 -2
- package/dist/generated/prisma/models/IntegrationConnection.d.ts +0 -2472
- package/dist/generated/prisma/models/IntegrationConnection.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationConnection.js +0 -2
- package/dist/generated/prisma/models/IntegrationCredentialVersion.d.ts +0 -1298
- package/dist/generated/prisma/models/IntegrationCredentialVersion.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationCredentialVersion.js +0 -2
- package/dist/generated/prisma/models/IntegrationOAuthApp.d.ts +0 -1362
- package/dist/generated/prisma/models/IntegrationOAuthApp.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationOAuthApp.js +0 -2
- package/dist/generated/prisma/models/IntegrationOAuthState.d.ts +0 -1131
- package/dist/generated/prisma/models/IntegrationOAuthState.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationOAuthState.js +0 -2
- package/dist/generated/prisma/models/IntegrationPlatformCredential.d.ts +0 -1237
- package/dist/generated/prisma/models/IntegrationPlatformCredential.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationPlatformCredential.js +0 -2
- package/dist/generated/prisma/models/IntegrationPlatformFinding.d.ts +0 -1652
- package/dist/generated/prisma/models/IntegrationPlatformFinding.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationPlatformFinding.js +0 -2
- package/dist/generated/prisma/models/IntegrationProvider.d.ts +0 -1300
- package/dist/generated/prisma/models/IntegrationProvider.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationProvider.js +0 -2
- package/dist/generated/prisma/models/IntegrationResult.d.ts +0 -1539
- package/dist/generated/prisma/models/IntegrationResult.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationResult.js +0 -2
- package/dist/generated/prisma/models/IntegrationRun.d.ts +0 -1596
- package/dist/generated/prisma/models/IntegrationRun.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationRun.js +0 -2
- package/dist/generated/prisma/models/IntegrationSyncLog.d.ts +0 -1716
- package/dist/generated/prisma/models/IntegrationSyncLog.d.ts.map +0 -1
- package/dist/generated/prisma/models/IntegrationSyncLog.js +0 -2
- package/dist/generated/prisma/models/Invitation.d.ts +0 -1404
- package/dist/generated/prisma/models/Invitation.d.ts.map +0 -1
- package/dist/generated/prisma/models/Invitation.js +0 -2
- package/dist/generated/prisma/models/Jwks.d.ts +0 -998
- package/dist/generated/prisma/models/Jwks.d.ts.map +0 -1
- package/dist/generated/prisma/models/Jwks.js +0 -2
- package/dist/generated/prisma/models/KnowledgeBaseDocument.d.ts +0 -1463
- package/dist/generated/prisma/models/KnowledgeBaseDocument.d.ts.map +0 -1
- package/dist/generated/prisma/models/KnowledgeBaseDocument.js +0 -2
- package/dist/generated/prisma/models/Member.d.ts +0 -5530
- package/dist/generated/prisma/models/Member.d.ts.map +0 -1
- package/dist/generated/prisma/models/Member.js +0 -2
- package/dist/generated/prisma/models/Onboarding.d.ts +0 -1376
- package/dist/generated/prisma/models/Onboarding.d.ts.map +0 -1
- package/dist/generated/prisma/models/Onboarding.js +0 -2
- package/dist/generated/prisma/models/Organization.d.ts +0 -14367
- package/dist/generated/prisma/models/Organization.d.ts.map +0 -1
- package/dist/generated/prisma/models/Organization.js +0 -2
- package/dist/generated/prisma/models/OrganizationBilling.d.ts +0 -1222
- package/dist/generated/prisma/models/OrganizationBilling.d.ts.map +0 -1
- package/dist/generated/prisma/models/OrganizationBilling.js +0 -2
- package/dist/generated/prisma/models/OrganizationChart.d.ts +0 -1248
- package/dist/generated/prisma/models/OrganizationChart.d.ts.map +0 -1
- package/dist/generated/prisma/models/OrganizationChart.js +0 -2
- package/dist/generated/prisma/models/OrganizationRole.d.ts +0 -1251
- package/dist/generated/prisma/models/OrganizationRole.d.ts.map +0 -1
- package/dist/generated/prisma/models/OrganizationRole.js +0 -2
- package/dist/generated/prisma/models/PentestSubscription.d.ts +0 -1497
- package/dist/generated/prisma/models/PentestSubscription.d.ts.map +0 -1
- package/dist/generated/prisma/models/PentestSubscription.js +0 -2
- package/dist/generated/prisma/models/Policy.d.ts +0 -3356
- package/dist/generated/prisma/models/Policy.d.ts.map +0 -1
- package/dist/generated/prisma/models/Policy.js +0 -2
- package/dist/generated/prisma/models/PolicyVersion.d.ts +0 -1619
- package/dist/generated/prisma/models/PolicyVersion.d.ts.map +0 -1
- package/dist/generated/prisma/models/PolicyVersion.js +0 -2
- package/dist/generated/prisma/models/Questionnaire.d.ts +0 -1808
- package/dist/generated/prisma/models/Questionnaire.d.ts.map +0 -1
- package/dist/generated/prisma/models/Questionnaire.js +0 -2
- package/dist/generated/prisma/models/QuestionnaireQuestionAnswer.d.ts +0 -1422
- package/dist/generated/prisma/models/QuestionnaireQuestionAnswer.d.ts.map +0 -1
- package/dist/generated/prisma/models/QuestionnaireQuestionAnswer.js +0 -2
- package/dist/generated/prisma/models/RequirementMap.d.ts +0 -1345
- package/dist/generated/prisma/models/RequirementMap.d.ts.map +0 -1
- package/dist/generated/prisma/models/RequirementMap.js +0 -2
- package/dist/generated/prisma/models/Risk.d.ts +0 -1975
- package/dist/generated/prisma/models/Risk.d.ts.map +0 -1
- package/dist/generated/prisma/models/Risk.js +0 -2
- package/dist/generated/prisma/models/RoleNotificationSetting.d.ts +0 -1391
- package/dist/generated/prisma/models/RoleNotificationSetting.d.ts.map +0 -1
- package/dist/generated/prisma/models/RoleNotificationSetting.js +0 -2
- package/dist/generated/prisma/models/SOAAnswer.d.ts +0 -1498
- package/dist/generated/prisma/models/SOAAnswer.d.ts.map +0 -1
- package/dist/generated/prisma/models/SOAAnswer.js +0 -2
- package/dist/generated/prisma/models/SOADocument.d.ts +0 -2272
- package/dist/generated/prisma/models/SOADocument.d.ts.map +0 -1
- package/dist/generated/prisma/models/SOADocument.js +0 -2
- package/dist/generated/prisma/models/SOAFrameworkConfiguration.d.ts +0 -1445
- package/dist/generated/prisma/models/SOAFrameworkConfiguration.d.ts.map +0 -1
- package/dist/generated/prisma/models/SOAFrameworkConfiguration.js +0 -2
- package/dist/generated/prisma/models/Secret.d.ts +0 -1321
- package/dist/generated/prisma/models/Secret.d.ts.map +0 -1
- package/dist/generated/prisma/models/Secret.js +0 -2
- package/dist/generated/prisma/models/SecurityPenetrationTestRun.d.ts +0 -1176
- package/dist/generated/prisma/models/SecurityPenetrationTestRun.d.ts.map +0 -1
- package/dist/generated/prisma/models/SecurityPenetrationTestRun.js +0 -2
- package/dist/generated/prisma/models/SecurityQuestionnaireManualAnswer.d.ts +0 -1510
- package/dist/generated/prisma/models/SecurityQuestionnaireManualAnswer.d.ts.map +0 -1
- package/dist/generated/prisma/models/SecurityQuestionnaireManualAnswer.js +0 -2
- package/dist/generated/prisma/models/Session.d.ts +0 -1351
- package/dist/generated/prisma/models/Session.d.ts.map +0 -1
- package/dist/generated/prisma/models/Session.js +0 -2
- package/dist/generated/prisma/models/Task.d.ts +0 -3980
- package/dist/generated/prisma/models/Task.d.ts.map +0 -1
- package/dist/generated/prisma/models/Task.js +0 -2
- package/dist/generated/prisma/models/TaskItem.d.ts +0 -1961
- package/dist/generated/prisma/models/TaskItem.d.ts.map +0 -1
- package/dist/generated/prisma/models/TaskItem.js +0 -2
- package/dist/generated/prisma/models/Trust.d.ts +0 -2242
- package/dist/generated/prisma/models/Trust.d.ts.map +0 -1
- package/dist/generated/prisma/models/Trust.js +0 -2
- package/dist/generated/prisma/models/TrustAccessGrant.d.ts +0 -1888
- package/dist/generated/prisma/models/TrustAccessGrant.d.ts.map +0 -1
- package/dist/generated/prisma/models/TrustAccessGrant.js +0 -2
- package/dist/generated/prisma/models/TrustAccessRequest.d.ts +0 -2103
- package/dist/generated/prisma/models/TrustAccessRequest.d.ts.map +0 -1
- package/dist/generated/prisma/models/TrustAccessRequest.js +0 -2
- package/dist/generated/prisma/models/TrustCustomLink.d.ts +0 -1354
- package/dist/generated/prisma/models/TrustCustomLink.d.ts.map +0 -1
- package/dist/generated/prisma/models/TrustCustomLink.js +0 -2
- package/dist/generated/prisma/models/TrustDocument.d.ts +0 -1281
- package/dist/generated/prisma/models/TrustDocument.d.ts.map +0 -1
- package/dist/generated/prisma/models/TrustDocument.js +0 -2
- package/dist/generated/prisma/models/TrustNDAAgreement.d.ts +0 -1877
- package/dist/generated/prisma/models/TrustNDAAgreement.d.ts.map +0 -1
- package/dist/generated/prisma/models/TrustNDAAgreement.js +0 -2
- package/dist/generated/prisma/models/TrustResource.d.ts +0 -1328
- package/dist/generated/prisma/models/TrustResource.d.ts.map +0 -1
- package/dist/generated/prisma/models/TrustResource.js +0 -2
- package/dist/generated/prisma/models/User.d.ts +0 -3070
- package/dist/generated/prisma/models/User.d.ts.map +0 -1
- package/dist/generated/prisma/models/User.js +0 -2
- package/dist/generated/prisma/models/Vendor.d.ts +0 -2307
- package/dist/generated/prisma/models/Vendor.d.ts.map +0 -1
- package/dist/generated/prisma/models/Vendor.js +0 -2
- package/dist/generated/prisma/models/VendorContact.d.ts +0 -1246
- package/dist/generated/prisma/models/VendorContact.d.ts.map +0 -1
- package/dist/generated/prisma/models/VendorContact.js +0 -2
- package/dist/generated/prisma/models/Verification.d.ts +0 -1026
- package/dist/generated/prisma/models/Verification.d.ts.map +0 -1
- package/dist/generated/prisma/models/Verification.js +0 -2
- package/dist/generated/prisma/models.d.ts +0 -82
- package/dist/generated/prisma/models.d.ts.map +0 -1
- package/dist/generated/prisma/models.js +0 -2
- package/dist/index.ts +0 -1
package/dist/schema.prisma
CHANGED
|
@@ -9,7 +9,6 @@ datasource db {
|
|
|
9
9
|
extensions = [pgcrypto]
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
// ===== attachments.prisma =====
|
|
14
13
|
model Attachment {
|
|
15
14
|
id String @id @default(dbgenerated("generate_prefixed_cuid('att'::text)"))
|
|
@@ -49,7 +48,6 @@ enum AttachmentType {
|
|
|
49
48
|
other
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
|
|
53
51
|
// ===== auth.prisma =====
|
|
54
52
|
model User {
|
|
55
53
|
id String @id @default(dbgenerated("generate_prefixed_cuid('usr'::text)"))
|
|
@@ -68,16 +66,20 @@ model User {
|
|
|
68
66
|
banExpires DateTime?
|
|
69
67
|
isPlatformAdmin Boolean @default(false)
|
|
70
68
|
|
|
71
|
-
accounts
|
|
72
|
-
auditLog
|
|
73
|
-
integrationResults
|
|
74
|
-
invitations
|
|
75
|
-
members
|
|
76
|
-
sessions
|
|
77
|
-
fleetPolicyResults
|
|
78
|
-
evidenceSubmissions
|
|
79
|
-
evidenceReviews
|
|
80
|
-
adminFindings
|
|
69
|
+
accounts Account[]
|
|
70
|
+
auditLog AuditLog[]
|
|
71
|
+
integrationResults IntegrationResult[]
|
|
72
|
+
invitations Invitation[]
|
|
73
|
+
members Member[]
|
|
74
|
+
sessions Session[]
|
|
75
|
+
fleetPolicyResults FleetPolicyResult[]
|
|
76
|
+
evidenceSubmissions EvidenceSubmission[] @relation("EvidenceSubmitter")
|
|
77
|
+
evidenceReviews EvidenceSubmission[] @relation("EvidenceReviewer")
|
|
78
|
+
adminFindings Finding[] @relation("AdminFindingCreator")
|
|
79
|
+
timelinePhaseCompletions TimelinePhase[]
|
|
80
|
+
lockedTimelineInstances TimelineInstance[] @relation("TimelineInstanceLockedBy")
|
|
81
|
+
unlockedTimelineInstances TimelineInstance[] @relation("TimelineInstanceUnlockedBy")
|
|
82
|
+
publishedFrameworkVersions FrameworkVersion[] @relation("FrameworkVersionPublisher")
|
|
81
83
|
|
|
82
84
|
@@unique([email])
|
|
83
85
|
}
|
|
@@ -105,9 +107,15 @@ model Session {
|
|
|
105
107
|
userId String
|
|
106
108
|
activeOrganizationId String?
|
|
107
109
|
impersonatedBy String?
|
|
108
|
-
|
|
110
|
+
|
|
111
|
+
deviceAgent Boolean @default(false)
|
|
112
|
+
deviceAgentFor Device[] @relation("DeviceAgentSession")
|
|
113
|
+
|
|
114
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
109
115
|
|
|
110
116
|
@@unique([token])
|
|
117
|
+
@@index([userId])
|
|
118
|
+
@@index([deviceAgent])
|
|
111
119
|
}
|
|
112
120
|
|
|
113
121
|
model Account {
|
|
@@ -166,24 +174,26 @@ model Member {
|
|
|
166
174
|
employeeTrainingVideoCompletion EmployeeTrainingVideoCompletion[]
|
|
167
175
|
fleetDmLabelId Int?
|
|
168
176
|
|
|
169
|
-
assignedPolicies
|
|
170
|
-
approvedPolicies
|
|
171
|
-
approvedSOADocuments
|
|
172
|
-
risks
|
|
173
|
-
tasks
|
|
174
|
-
vendors
|
|
175
|
-
comments
|
|
176
|
-
auditLogs
|
|
177
|
-
reviewedAccessRequests
|
|
178
|
-
issuedGrants
|
|
179
|
-
revokedGrants
|
|
180
|
-
createdTaskItems
|
|
181
|
-
updatedTaskItems
|
|
182
|
-
assignedTaskItems
|
|
183
|
-
createdFindings
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
177
|
+
assignedPolicies Policy[] @relation("PolicyAssignee") // Policies where this member is an assignee
|
|
178
|
+
approvedPolicies Policy[] @relation("PolicyApprover") // Policies where this member is an approver
|
|
179
|
+
approvedSOADocuments SOADocument[] @relation("SOADocumentApprover") // SOA documents where this member is an approver
|
|
180
|
+
risks Risk[]
|
|
181
|
+
tasks Task[]
|
|
182
|
+
vendors Vendor[]
|
|
183
|
+
comments Comment[]
|
|
184
|
+
auditLogs AuditLog[]
|
|
185
|
+
reviewedAccessRequests TrustAccessRequest[] @relation("TrustAccessRequestReviewer")
|
|
186
|
+
issuedGrants TrustAccessGrant[] @relation("IssuedGrants")
|
|
187
|
+
revokedGrants TrustAccessGrant[] @relation("RevokedGrants")
|
|
188
|
+
createdTaskItems TaskItem[] @relation("TaskItemCreator")
|
|
189
|
+
updatedTaskItems TaskItem[] @relation("TaskItemUpdater")
|
|
190
|
+
assignedTaskItems TaskItem[] @relation("TaskItemAssignee")
|
|
191
|
+
createdFindings Finding[] @relation("FindingCreatedBy")
|
|
192
|
+
subjectFindings Finding[] @relation("FindingSubject")
|
|
193
|
+
publishedPolicyVersions PolicyVersion[] @relation("PolicyVersionPublisher")
|
|
194
|
+
performedFrameworkSyncOperations FrameworkSyncOperation[] @relation("FrameworkSyncOperationPerformer")
|
|
195
|
+
approvedTasks Task[] @relation("TaskApprover")
|
|
196
|
+
devices Device[]
|
|
187
197
|
}
|
|
188
198
|
|
|
189
199
|
model Invitation {
|
|
@@ -232,7 +242,6 @@ enum PolicyStatus {
|
|
|
232
242
|
needs_review
|
|
233
243
|
}
|
|
234
244
|
|
|
235
|
-
|
|
236
245
|
// ===== automation-run.prisma =====
|
|
237
246
|
model EvidenceAutomationRun {
|
|
238
247
|
id String @id @default(dbgenerated("generate_prefixed_cuid('ear'::text)"))
|
|
@@ -290,7 +299,6 @@ enum EvidenceAutomationEvaluationStatus {
|
|
|
290
299
|
fail
|
|
291
300
|
}
|
|
292
301
|
|
|
293
|
-
|
|
294
302
|
// ===== automation-version.prisma =====
|
|
295
303
|
model EvidenceAutomationVersion {
|
|
296
304
|
id String @id @default(dbgenerated("generate_prefixed_cuid('eav'::text)"))
|
|
@@ -312,14 +320,15 @@ model EvidenceAutomationVersion {
|
|
|
312
320
|
@@index([createdAt])
|
|
313
321
|
}
|
|
314
322
|
|
|
315
|
-
|
|
316
323
|
// ===== automation.prisma =====
|
|
317
324
|
model EvidenceAutomation {
|
|
318
|
-
id
|
|
319
|
-
name
|
|
320
|
-
description
|
|
321
|
-
createdAt
|
|
322
|
-
isEnabled
|
|
325
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('aut'::text)"))
|
|
326
|
+
name String
|
|
327
|
+
description String?
|
|
328
|
+
createdAt DateTime @default(now())
|
|
329
|
+
isEnabled Boolean @default(false)
|
|
330
|
+
scheduleFrequency TaskFrequency @default(daily)
|
|
331
|
+
lastRunAt DateTime?
|
|
323
332
|
|
|
324
333
|
chatHistory String?
|
|
325
334
|
evaluationCriteria String?
|
|
@@ -334,106 +343,108 @@ model EvidenceAutomation {
|
|
|
334
343
|
@@index([taskId])
|
|
335
344
|
}
|
|
336
345
|
|
|
337
|
-
|
|
338
346
|
// ===== browserbase-context.prisma =====
|
|
339
347
|
/// Stores Browserbase context IDs for browser-based automation
|
|
340
348
|
/// One context per organization - shared like a normal browser
|
|
341
349
|
model BrowserbaseContext {
|
|
342
|
-
|
|
350
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('bbc'::text)"))
|
|
343
351
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
352
|
+
/// Organization that owns this browser context
|
|
353
|
+
organizationId String @unique
|
|
354
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
347
355
|
|
|
348
|
-
|
|
349
|
-
|
|
356
|
+
/// Browserbase context ID from their API
|
|
357
|
+
contextId String
|
|
350
358
|
|
|
351
|
-
|
|
352
|
-
|
|
359
|
+
createdAt DateTime @default(now())
|
|
360
|
+
updatedAt DateTime @updatedAt
|
|
353
361
|
|
|
354
|
-
|
|
362
|
+
@@index([organizationId])
|
|
355
363
|
}
|
|
356
364
|
|
|
357
365
|
/// Browser automation configuration linked to a task
|
|
358
366
|
model BrowserAutomation {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
367
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('bau'::text)"))
|
|
368
|
+
name String
|
|
369
|
+
description String?
|
|
362
370
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
371
|
+
/// Task this automation belongs to
|
|
372
|
+
taskId String
|
|
373
|
+
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
|
366
374
|
|
|
367
|
-
|
|
368
|
-
|
|
375
|
+
/// Starting URL for the automation
|
|
376
|
+
targetUrl String
|
|
369
377
|
|
|
370
|
-
|
|
371
|
-
|
|
378
|
+
/// Natural language instruction for the AI agent
|
|
379
|
+
instruction String
|
|
372
380
|
|
|
373
|
-
|
|
374
|
-
|
|
381
|
+
/// Optional natural-language criteria used to evaluate whether the
|
|
382
|
+
/// automation's outcome satisfies the auditor's requirement.
|
|
383
|
+
/// When null, runs don't produce a pass/fail verdict — only a screenshot.
|
|
384
|
+
evaluationCriteria String?
|
|
375
385
|
|
|
376
|
-
|
|
377
|
-
|
|
386
|
+
/// Whether automation is enabled for scheduled runs
|
|
387
|
+
isEnabled Boolean @default(false)
|
|
388
|
+
scheduleFrequency TaskFrequency @default(daily)
|
|
389
|
+
lastRunAt DateTime?
|
|
378
390
|
|
|
379
|
-
|
|
380
|
-
|
|
391
|
+
createdAt DateTime @default(now())
|
|
392
|
+
updatedAt DateTime @updatedAt
|
|
381
393
|
|
|
382
|
-
|
|
394
|
+
runs BrowserAutomationRun[]
|
|
383
395
|
|
|
384
|
-
|
|
396
|
+
@@index([taskId])
|
|
385
397
|
}
|
|
386
398
|
|
|
387
399
|
/// Records of browser automation executions
|
|
388
400
|
model BrowserAutomationRun {
|
|
389
|
-
|
|
401
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('bar'::text)"))
|
|
390
402
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
403
|
+
/// Parent automation
|
|
404
|
+
automationId String
|
|
405
|
+
automation BrowserAutomation @relation(fields: [automationId], references: [id], onDelete: Cascade)
|
|
394
406
|
|
|
395
|
-
|
|
396
|
-
|
|
407
|
+
/// Execution status
|
|
408
|
+
status BrowserAutomationRunStatus @default(pending)
|
|
397
409
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
410
|
+
/// Timestamps
|
|
411
|
+
startedAt DateTime?
|
|
412
|
+
completedAt DateTime?
|
|
401
413
|
|
|
402
|
-
|
|
403
|
-
|
|
414
|
+
/// Duration in milliseconds
|
|
415
|
+
durationMs Int?
|
|
404
416
|
|
|
405
|
-
|
|
406
|
-
|
|
417
|
+
/// Screenshot URL in S3 (if successful)
|
|
418
|
+
screenshotUrl String?
|
|
407
419
|
|
|
408
|
-
|
|
409
|
-
|
|
420
|
+
/// Evaluation result - whether the automation fulfilled the task requirements
|
|
421
|
+
evaluationStatus BrowserAutomationEvaluationStatus?
|
|
410
422
|
|
|
411
|
-
|
|
412
|
-
|
|
423
|
+
/// AI explanation of why it passed or failed
|
|
424
|
+
evaluationReason String?
|
|
413
425
|
|
|
414
|
-
|
|
415
|
-
|
|
426
|
+
/// Error message (if failed)
|
|
427
|
+
error String?
|
|
416
428
|
|
|
417
|
-
|
|
429
|
+
createdAt DateTime @default(now())
|
|
418
430
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
431
|
+
@@index([automationId])
|
|
432
|
+
@@index([status])
|
|
433
|
+
@@index([createdAt])
|
|
422
434
|
}
|
|
423
435
|
|
|
424
436
|
enum BrowserAutomationEvaluationStatus {
|
|
425
|
-
|
|
426
|
-
|
|
437
|
+
pass
|
|
438
|
+
fail
|
|
427
439
|
}
|
|
428
440
|
|
|
429
441
|
enum BrowserAutomationRunStatus {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
442
|
+
pending
|
|
443
|
+
running
|
|
444
|
+
completed
|
|
445
|
+
failed
|
|
434
446
|
}
|
|
435
447
|
|
|
436
|
-
|
|
437
448
|
// ===== comment.prisma =====
|
|
438
449
|
model Comment {
|
|
439
450
|
id String @id @default(dbgenerated("generate_prefixed_cuid('cmt'::text)"))
|
|
@@ -463,7 +474,6 @@ enum CommentEntityType {
|
|
|
463
474
|
policy
|
|
464
475
|
}
|
|
465
476
|
|
|
466
|
-
|
|
467
477
|
// ===== context.prisma =====
|
|
468
478
|
model Context {
|
|
469
479
|
id String @id @default(dbgenerated("generate_prefixed_cuid('ctx'::text)"))
|
|
@@ -484,7 +494,6 @@ model Context {
|
|
|
484
494
|
@@index([tags])
|
|
485
495
|
}
|
|
486
496
|
|
|
487
|
-
|
|
488
497
|
// ===== control-document-type.prisma =====
|
|
489
498
|
model ControlDocumentType {
|
|
490
499
|
id String @id @default(dbgenerated("generate_prefixed_cuid('cdt'::text)"))
|
|
@@ -496,7 +505,6 @@ model ControlDocumentType {
|
|
|
496
505
|
@@index([controlId])
|
|
497
506
|
}
|
|
498
507
|
|
|
499
|
-
|
|
500
508
|
// ===== control.prisma =====
|
|
501
509
|
model Control {
|
|
502
510
|
// Metadata
|
|
@@ -508,19 +516,67 @@ model Control {
|
|
|
508
516
|
lastReviewDate DateTime?
|
|
509
517
|
nextReviewDate DateTime?
|
|
510
518
|
|
|
519
|
+
// Sync-driven archive (set by FrameworkSyncOperation when the control
|
|
520
|
+
// template is removed from the framework's latest version and no other
|
|
521
|
+
// framework instance in the org still references it). Distinct from user
|
|
522
|
+
// archive (no user archive exists on Control today).
|
|
523
|
+
archivedAt DateTime?
|
|
524
|
+
|
|
511
525
|
// Relationships
|
|
512
|
-
organization
|
|
513
|
-
organizationId
|
|
514
|
-
requirementsMapped
|
|
515
|
-
tasks
|
|
516
|
-
policies
|
|
517
|
-
controlTemplateId
|
|
518
|
-
controlTemplate
|
|
526
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
527
|
+
organizationId String
|
|
528
|
+
requirementsMapped RequirementMap[]
|
|
529
|
+
tasks Task[]
|
|
530
|
+
policies Policy[]
|
|
531
|
+
controlTemplateId String?
|
|
532
|
+
controlTemplate FrameworkEditorControlTemplate? @relation(fields: [controlTemplateId], references: [id])
|
|
519
533
|
controlDocumentTypes ControlDocumentType[]
|
|
520
534
|
|
|
521
535
|
@@index([organizationId])
|
|
536
|
+
@@index([organizationId, archivedAt])
|
|
522
537
|
}
|
|
523
538
|
|
|
539
|
+
// ===== custom-framework.prisma =====
|
|
540
|
+
model CustomFramework {
|
|
541
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('cfrm'::text)"))
|
|
542
|
+
name String
|
|
543
|
+
description String
|
|
544
|
+
version String @default("1.0.0")
|
|
545
|
+
|
|
546
|
+
organizationId String
|
|
547
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
548
|
+
|
|
549
|
+
requirements CustomRequirement[]
|
|
550
|
+
instances FrameworkInstance[]
|
|
551
|
+
|
|
552
|
+
createdAt DateTime @default(now())
|
|
553
|
+
updatedAt DateTime @default(now()) @updatedAt
|
|
554
|
+
|
|
555
|
+
@@unique([id, organizationId])
|
|
556
|
+
@@index([organizationId])
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
model CustomRequirement {
|
|
560
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('creq'::text)"))
|
|
561
|
+
name String
|
|
562
|
+
description String
|
|
563
|
+
identifier String
|
|
564
|
+
|
|
565
|
+
organizationId String
|
|
566
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
567
|
+
customFrameworkId String
|
|
568
|
+
// Composite FK onto (id, organizationId) so tenant consistency with the
|
|
569
|
+
// referenced CustomFramework is enforced at the DB level.
|
|
570
|
+
customFramework CustomFramework @relation(fields: [customFrameworkId, organizationId], references: [id, organizationId], onDelete: Cascade)
|
|
571
|
+
|
|
572
|
+
requirementMaps RequirementMap[]
|
|
573
|
+
|
|
574
|
+
createdAt DateTime @default(now())
|
|
575
|
+
updatedAt DateTime @default(now()) @updatedAt
|
|
576
|
+
|
|
577
|
+
@@unique([customFrameworkId, identifier])
|
|
578
|
+
@@index([organizationId])
|
|
579
|
+
}
|
|
524
580
|
|
|
525
581
|
// ===== device.prisma =====
|
|
526
582
|
model Device {
|
|
@@ -537,22 +593,28 @@ model Device {
|
|
|
537
593
|
organizationId String
|
|
538
594
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
539
595
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
596
|
+
agentSessionId String?
|
|
597
|
+
agentSession Session? @relation("DeviceAgentSession", fields: [agentSessionId], references: [id], onDelete: SetNull)
|
|
598
|
+
|
|
599
|
+
isCompliant Boolean @default(false)
|
|
600
|
+
diskEncryptionEnabled Boolean @default(false)
|
|
601
|
+
antivirusEnabled Boolean @default(false)
|
|
602
|
+
passwordPolicySet Boolean @default(false)
|
|
603
|
+
screenLockEnabled Boolean @default(false)
|
|
545
604
|
checkDetails Json?
|
|
546
605
|
|
|
547
606
|
lastCheckIn DateTime?
|
|
548
607
|
agentVersion String?
|
|
549
|
-
installedAt DateTime
|
|
550
|
-
updatedAt DateTime
|
|
608
|
+
installedAt DateTime @default(now())
|
|
609
|
+
updatedAt DateTime @updatedAt
|
|
610
|
+
|
|
611
|
+
findings Finding[]
|
|
551
612
|
|
|
552
613
|
@@unique([serialNumber, organizationId])
|
|
553
614
|
@@index([memberId])
|
|
554
615
|
@@index([organizationId])
|
|
555
616
|
@@index([isCompliant])
|
|
617
|
+
@@index([agentSessionId])
|
|
556
618
|
}
|
|
557
619
|
|
|
558
620
|
enum DevicePlatform {
|
|
@@ -561,7 +623,6 @@ enum DevicePlatform {
|
|
|
561
623
|
linux
|
|
562
624
|
}
|
|
563
625
|
|
|
564
|
-
|
|
565
626
|
// ===== dynamic-integration.prisma =====
|
|
566
627
|
// ===== Dynamic Integration Platform =====
|
|
567
628
|
// Stores integration manifests and declarative check definitions in the database
|
|
@@ -569,93 +630,98 @@ enum DevicePlatform {
|
|
|
569
630
|
|
|
570
631
|
/// Stores a full integration manifest as JSON — replaces hand-written TypeScript manifests
|
|
571
632
|
model DynamicIntegration {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
633
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('din'::text)"))
|
|
634
|
+
/// Unique slug (e.g., "azure-devops", "office-365")
|
|
635
|
+
slug String @unique
|
|
636
|
+
/// Display name
|
|
637
|
+
name String
|
|
638
|
+
/// Short description for catalog
|
|
639
|
+
description String
|
|
640
|
+
/// Category for grouping
|
|
641
|
+
category String
|
|
642
|
+
/// Logo URL
|
|
643
|
+
logoUrl String
|
|
644
|
+
/// URL to documentation
|
|
645
|
+
docsUrl String?
|
|
585
646
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
647
|
+
/// API base URL for ctx.fetch
|
|
648
|
+
baseUrl String?
|
|
649
|
+
/// Default headers (JSON object)
|
|
650
|
+
defaultHeaders Json?
|
|
590
651
|
|
|
591
|
-
|
|
592
|
-
|
|
652
|
+
/// Auth strategy config (JSON — matches AuthStrategy type: oauth2/api_key/basic/jwt/custom)
|
|
653
|
+
authConfig Json
|
|
593
654
|
|
|
594
|
-
|
|
595
|
-
|
|
655
|
+
/// Capabilities JSON array (default ["checks"])
|
|
656
|
+
capabilities Json @default("[\"checks\"]")
|
|
596
657
|
|
|
597
|
-
|
|
598
|
-
|
|
658
|
+
/// Whether multiple connections per org are allowed
|
|
659
|
+
supportsMultipleConnections Boolean @default(false)
|
|
599
660
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
661
|
+
/// Declarative sync definition (JSON — DSL steps that produce employee list)
|
|
662
|
+
/// When present and capabilities includes 'sync', enables employee sync
|
|
663
|
+
syncDefinition Json?
|
|
603
664
|
|
|
604
|
-
|
|
605
|
-
|
|
665
|
+
/// Services metadata (JSON array of { id, name, description, enabledByDefault?, implemented? })
|
|
666
|
+
services Json?
|
|
606
667
|
|
|
607
|
-
|
|
608
|
-
|
|
668
|
+
/// Whether this dynamic integration is active
|
|
669
|
+
isActive Boolean @default(true)
|
|
609
670
|
|
|
610
|
-
|
|
671
|
+
createdAt DateTime @default(now())
|
|
672
|
+
updatedAt DateTime @updatedAt
|
|
673
|
+
|
|
674
|
+
checks DynamicCheck[]
|
|
611
675
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
676
|
+
@@index([slug])
|
|
677
|
+
@@index([category])
|
|
678
|
+
@@index([isActive])
|
|
615
679
|
}
|
|
616
680
|
|
|
617
681
|
/// Stores a declarative check definition — DSL JSON replaces hand-written run() functions
|
|
618
682
|
model DynamicCheck {
|
|
619
|
-
|
|
683
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('dck'::text)"))
|
|
620
684
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
685
|
+
/// Parent integration
|
|
686
|
+
integrationId String
|
|
687
|
+
integration DynamicIntegration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
|
|
624
688
|
|
|
625
|
-
|
|
626
|
-
|
|
689
|
+
/// Unique slug within integration (e.g., "mfa_enabled")
|
|
690
|
+
checkSlug String
|
|
627
691
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
692
|
+
/// Human-readable name
|
|
693
|
+
name String
|
|
694
|
+
/// Description of what this check does
|
|
695
|
+
description String
|
|
632
696
|
|
|
633
|
-
|
|
634
|
-
|
|
697
|
+
/// Task template ID for auto-completion (references TASK_TEMPLATES)
|
|
698
|
+
taskMapping String?
|
|
635
699
|
|
|
636
|
-
|
|
637
|
-
|
|
700
|
+
/// Default severity for findings
|
|
701
|
+
defaultSeverity String @default("medium")
|
|
638
702
|
|
|
639
|
-
|
|
640
|
-
|
|
703
|
+
/// Service ID this check belongs to (groups checks under a service)
|
|
704
|
+
service String?
|
|
641
705
|
|
|
642
|
-
|
|
643
|
-
|
|
706
|
+
/// Declarative DSL definition (JSON — the step-by-step instructions)
|
|
707
|
+
definition Json
|
|
644
708
|
|
|
645
|
-
|
|
646
|
-
|
|
709
|
+
/// Check-level variables (JSON array of CheckVariable)
|
|
710
|
+
variables Json @default("[]")
|
|
647
711
|
|
|
648
|
-
|
|
649
|
-
|
|
712
|
+
/// Whether this check is enabled
|
|
713
|
+
isEnabled Boolean @default(true)
|
|
650
714
|
|
|
651
|
-
|
|
652
|
-
|
|
715
|
+
/// Display order
|
|
716
|
+
sortOrder Int @default(0)
|
|
653
717
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
@@index([isEnabled])
|
|
657
|
-
}
|
|
718
|
+
createdAt DateTime @default(now())
|
|
719
|
+
updatedAt DateTime @updatedAt
|
|
658
720
|
|
|
721
|
+
@@unique([integrationId, checkSlug])
|
|
722
|
+
@@index([integrationId])
|
|
723
|
+
@@index([isEnabled])
|
|
724
|
+
}
|
|
659
725
|
|
|
660
726
|
// ===== evidence-submission.prisma =====
|
|
661
727
|
model EvidenceSubmission {
|
|
@@ -682,7 +748,6 @@ model EvidenceSubmission {
|
|
|
682
748
|
@@index([submittedById, status])
|
|
683
749
|
}
|
|
684
750
|
|
|
685
|
-
|
|
686
751
|
// ===== finding.prisma =====
|
|
687
752
|
enum FindingType {
|
|
688
753
|
soc2
|
|
@@ -696,6 +761,29 @@ enum FindingStatus {
|
|
|
696
761
|
closed
|
|
697
762
|
}
|
|
698
763
|
|
|
764
|
+
enum FindingSeverity {
|
|
765
|
+
low
|
|
766
|
+
medium
|
|
767
|
+
high
|
|
768
|
+
critical
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
enum FindingArea {
|
|
772
|
+
people
|
|
773
|
+
documents
|
|
774
|
+
compliance
|
|
775
|
+
// "General" buckets for cases where an auditor wants to log something like
|
|
776
|
+
// "no risks are tracked" or "the policy for X is missing" without picking a
|
|
777
|
+
// specific Risk/Vendor/Policy row.
|
|
778
|
+
risks
|
|
779
|
+
vendors
|
|
780
|
+
policies
|
|
781
|
+
// Legacy/unclassified bucket for rows backfilled from the old FindingScope
|
|
782
|
+
// enum (see migration 20260419120000). Not surfaced as a primary target
|
|
783
|
+
// option in the Create Finding sheet.
|
|
784
|
+
other
|
|
785
|
+
}
|
|
786
|
+
|
|
699
787
|
model FindingTemplate {
|
|
700
788
|
id String @id @default(dbgenerated("generate_prefixed_cuid('fnd_t'::text)"))
|
|
701
789
|
category String // e.g., "evidence_issue", "further_evidence", "task_specific", "na_incorrect"
|
|
@@ -709,37 +797,57 @@ model FindingTemplate {
|
|
|
709
797
|
}
|
|
710
798
|
|
|
711
799
|
model Finding {
|
|
712
|
-
id String
|
|
713
|
-
type FindingType
|
|
714
|
-
status FindingStatus
|
|
800
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('fnd'::text)"))
|
|
801
|
+
type FindingType @default(soc2)
|
|
802
|
+
status FindingStatus @default(open)
|
|
803
|
+
severity FindingSeverity @default(medium)
|
|
715
804
|
content String // Custom message or copied from template
|
|
716
805
|
revisionNote String? // Auditor's note when requesting revision
|
|
806
|
+
area FindingArea? // Used when the finding is not tied to a specific item
|
|
717
807
|
|
|
718
808
|
createdAt DateTime @default(now())
|
|
719
809
|
updatedAt DateTime @updatedAt
|
|
720
810
|
|
|
721
|
-
//
|
|
811
|
+
// Target relationships — exactly one target link should be set (task, evidenceSubmission,
|
|
812
|
+
// evidenceFormType, policy, vendor, risk, member, device) OR the `area` field for non-item findings.
|
|
722
813
|
taskId String?
|
|
723
814
|
task Task? @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
|
724
815
|
evidenceSubmissionId String?
|
|
725
816
|
evidenceSubmission EvidenceSubmission? @relation(fields: [evidenceSubmissionId], references: [id], onDelete: Cascade)
|
|
726
817
|
evidenceFormType EvidenceFormType?
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
818
|
+
policyId String?
|
|
819
|
+
policy Policy? @relation(fields: [policyId], references: [id], onDelete: Cascade)
|
|
820
|
+
vendorId String?
|
|
821
|
+
vendor Vendor? @relation(fields: [vendorId], references: [id], onDelete: Cascade)
|
|
822
|
+
riskId String?
|
|
823
|
+
risk Risk? @relation(fields: [riskId], references: [id], onDelete: Cascade)
|
|
824
|
+
memberId String?
|
|
825
|
+
member Member? @relation("FindingSubject", fields: [memberId], references: [id], onDelete: Cascade)
|
|
826
|
+
deviceId String?
|
|
827
|
+
device Device? @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
|
828
|
+
|
|
829
|
+
// Metadata
|
|
830
|
+
templateId String?
|
|
831
|
+
template FindingTemplate? @relation(fields: [templateId], references: [id])
|
|
832
|
+
createdById String?
|
|
833
|
+
createdBy Member? @relation("FindingCreatedBy", fields: [createdById], references: [id])
|
|
834
|
+
createdByAdminId String?
|
|
835
|
+
createdByAdmin User? @relation("AdminFindingCreator", fields: [createdByAdminId], references: [id])
|
|
836
|
+
organizationId String
|
|
837
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
735
838
|
|
|
736
839
|
@@index([taskId])
|
|
737
840
|
@@index([evidenceSubmissionId])
|
|
738
841
|
@@index([evidenceFormType])
|
|
842
|
+
@@index([policyId])
|
|
843
|
+
@@index([vendorId])
|
|
844
|
+
@@index([riskId])
|
|
845
|
+
@@index([memberId])
|
|
846
|
+
@@index([deviceId])
|
|
739
847
|
@@index([organizationId, status])
|
|
848
|
+
@@index([organizationId, severity])
|
|
740
849
|
}
|
|
741
850
|
|
|
742
|
-
|
|
743
851
|
// ===== fleet-policy-result.prisma =====
|
|
744
852
|
model FleetPolicyResult {
|
|
745
853
|
id String @id @default(dbgenerated("generate_prefixed_cuid('fpr'::text)"))
|
|
@@ -759,7 +867,6 @@ model FleetPolicyResult {
|
|
|
759
867
|
@@index([organizationId])
|
|
760
868
|
}
|
|
761
869
|
|
|
762
|
-
|
|
763
870
|
// ===== framework-editor.prisma =====
|
|
764
871
|
// --- Data for Framework Editor ---
|
|
765
872
|
model FrameworkEditorVideo {
|
|
@@ -785,6 +892,8 @@ model FrameworkEditorFramework {
|
|
|
785
892
|
frameworkInstances FrameworkInstance[]
|
|
786
893
|
soaConfigurations SOAFrameworkConfiguration[] // Multiple SOA config versions per framework
|
|
787
894
|
soaDocuments SOADocument[] // SOA documents from organizations
|
|
895
|
+
timelineTemplates TimelineTemplate[]
|
|
896
|
+
versions FrameworkVersion[]
|
|
788
897
|
|
|
789
898
|
// Dates
|
|
790
899
|
createdAt DateTime @default(now())
|
|
@@ -830,8 +939,8 @@ model FrameworkEditorTaskTemplate {
|
|
|
830
939
|
id String @id @default(dbgenerated("generate_prefixed_cuid('frk_tt'::text)"))
|
|
831
940
|
name String
|
|
832
941
|
description String
|
|
833
|
-
frequency Frequency
|
|
834
|
-
department Departments
|
|
942
|
+
frequency Frequency // Using the enum from shared.prisma
|
|
943
|
+
department Departments // Using the enum from shared.prisma
|
|
835
944
|
automationStatus TaskAutomationStatus @default(AUTOMATED)
|
|
836
945
|
|
|
837
946
|
controlTemplates FrameworkEditorControlTemplate[]
|
|
@@ -862,6 +971,67 @@ model FrameworkEditorControlTemplate {
|
|
|
862
971
|
controls Control[]
|
|
863
972
|
}
|
|
864
973
|
|
|
974
|
+
// ===== framework-sync-operation.prisma =====
|
|
975
|
+
enum FrameworkSyncOperationKind {
|
|
976
|
+
SYNC
|
|
977
|
+
ROLLBACK
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
model FrameworkSyncOperation {
|
|
981
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('fso'::text)"))
|
|
982
|
+
frameworkInstanceId String
|
|
983
|
+
frameworkInstance FrameworkInstance @relation(fields: [frameworkInstanceId], references: [id], onDelete: Cascade)
|
|
984
|
+
|
|
985
|
+
fromVersionId String
|
|
986
|
+
fromVersion FrameworkVersion @relation("FrameworkSyncOperationFromVersion", fields: [fromVersionId], references: [id])
|
|
987
|
+
toVersionId String
|
|
988
|
+
toVersion FrameworkVersion @relation("FrameworkSyncOperationToVersion", fields: [toVersionId], references: [id])
|
|
989
|
+
|
|
990
|
+
kind FrameworkSyncOperationKind
|
|
991
|
+
|
|
992
|
+
performedAt DateTime @default(now())
|
|
993
|
+
performedById String?
|
|
994
|
+
performedBy Member? @relation("FrameworkSyncOperationPerformer", fields: [performedById], references: [id], onDelete: SetNull)
|
|
995
|
+
|
|
996
|
+
// Only set when kind = SYNC
|
|
997
|
+
rollbackExpiresAt DateTime?
|
|
998
|
+
|
|
999
|
+
// Self-reference: when this sync was reversed, points at the rollback op.
|
|
1000
|
+
rolledBackByOperationId String? @unique
|
|
1001
|
+
rolledBackByOperation FrameworkSyncOperation? @relation("FrameworkSyncOperationRollback", fields: [rolledBackByOperationId], references: [id])
|
|
1002
|
+
rolledBackOperation FrameworkSyncOperation? @relation("FrameworkSyncOperationRollback")
|
|
1003
|
+
|
|
1004
|
+
undoPayload Json // structured per undo-payload.types.ts
|
|
1005
|
+
summary Json // counts for audit log / UI
|
|
1006
|
+
|
|
1007
|
+
@@index([frameworkInstanceId, performedAt])
|
|
1008
|
+
@@index([frameworkInstanceId, kind])
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
// ===== framework-version.prisma =====
|
|
1012
|
+
model FrameworkVersion {
|
|
1013
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('fvr'::text)"))
|
|
1014
|
+
frameworkId String
|
|
1015
|
+
framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id], onDelete: Cascade)
|
|
1016
|
+
|
|
1017
|
+
version String // semver-ish, e.g., "1.0.0", "2.1.0"
|
|
1018
|
+
publishedAt DateTime @default(now())
|
|
1019
|
+
publishedById String?
|
|
1020
|
+
publishedBy User? @relation("FrameworkVersionPublisher", fields: [publishedById], references: [id], onDelete: SetNull)
|
|
1021
|
+
|
|
1022
|
+
releaseNotes String? // markdown
|
|
1023
|
+
|
|
1024
|
+
// Full snapshot of all templates at publish time (see manifest.types.ts).
|
|
1025
|
+
// Immutable once published.
|
|
1026
|
+
manifest Json
|
|
1027
|
+
|
|
1028
|
+
frameworkInstances FrameworkInstance[] @relation("FrameworkInstanceCurrentVersion")
|
|
1029
|
+
syncOperationsFrom FrameworkSyncOperation[] @relation("FrameworkSyncOperationFromVersion")
|
|
1030
|
+
syncOperationsTo FrameworkSyncOperation[] @relation("FrameworkSyncOperationToVersion")
|
|
1031
|
+
|
|
1032
|
+
@@unique([frameworkId, version])
|
|
1033
|
+
@@index([frameworkId, publishedAt])
|
|
1034
|
+
}
|
|
865
1035
|
|
|
866
1036
|
// ===== framework.prisma =====
|
|
867
1037
|
model FrameworkInstance {
|
|
@@ -869,454 +1039,470 @@ model FrameworkInstance {
|
|
|
869
1039
|
id String @id @default(dbgenerated("generate_prefixed_cuid('frm'::text)"))
|
|
870
1040
|
organizationId String
|
|
871
1041
|
|
|
872
|
-
frameworkId
|
|
873
|
-
|
|
1042
|
+
// Exactly one of frameworkId / customFrameworkId is set (enforced by DB CHECK constraint).
|
|
1043
|
+
frameworkId String?
|
|
1044
|
+
framework FrameworkEditorFramework? @relation(fields: [frameworkId], references: [id], onDelete: Cascade)
|
|
1045
|
+
|
|
1046
|
+
customFrameworkId String?
|
|
1047
|
+
// Composite FK onto (id, organizationId) so an FI can only reference a
|
|
1048
|
+
// CustomFramework in its own org. Enforced at the DB level.
|
|
1049
|
+
customFramework CustomFramework? @relation(fields: [customFrameworkId, organizationId], references: [id, organizationId], onDelete: Cascade)
|
|
1050
|
+
|
|
1051
|
+
currentVersionId String?
|
|
1052
|
+
currentVersion FrameworkVersion? @relation("FrameworkInstanceCurrentVersion", fields: [currentVersionId], references: [id], onDelete: Restrict)
|
|
874
1053
|
|
|
875
1054
|
// Relationships
|
|
876
|
-
organization Organization
|
|
1055
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
877
1056
|
requirementsMapped RequirementMap[]
|
|
1057
|
+
timelineInstances TimelineInstance[]
|
|
1058
|
+
syncOperations FrameworkSyncOperation[]
|
|
878
1059
|
|
|
879
1060
|
@@unique([organizationId, frameworkId])
|
|
1061
|
+
@@unique([organizationId, customFrameworkId])
|
|
1062
|
+
@@index([customFrameworkId])
|
|
1063
|
+
@@index([currentVersionId])
|
|
880
1064
|
}
|
|
881
1065
|
|
|
882
|
-
|
|
883
1066
|
// ===== integration-platform.prisma =====
|
|
884
1067
|
// ===== Integration Platform =====
|
|
885
1068
|
// New integration platform models for scalable, config-driven integrations
|
|
886
1069
|
|
|
887
1070
|
/// Stores metadata about available integration providers (synced from code manifests)
|
|
888
1071
|
model IntegrationProvider {
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
1072
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('prv'::text)"))
|
|
1073
|
+
/// Unique slug matching manifest ID (e.g., "github", "slack")
|
|
1074
|
+
slug String @unique
|
|
1075
|
+
/// Display name
|
|
1076
|
+
name String
|
|
1077
|
+
/// Category for grouping
|
|
1078
|
+
category String
|
|
1079
|
+
/// Hash of manifest for detecting changes
|
|
1080
|
+
manifestHash String?
|
|
1081
|
+
/// Capabilities JSON array
|
|
1082
|
+
capabilities Json @default("[]")
|
|
1083
|
+
/// Whether provider is active
|
|
1084
|
+
isActive Boolean @default(true)
|
|
902
1085
|
|
|
903
|
-
|
|
904
|
-
|
|
1086
|
+
createdAt DateTime @default(now())
|
|
1087
|
+
updatedAt DateTime @updatedAt
|
|
905
1088
|
|
|
906
|
-
|
|
1089
|
+
connections IntegrationConnection[]
|
|
907
1090
|
|
|
908
|
-
|
|
909
|
-
|
|
1091
|
+
@@index([slug])
|
|
1092
|
+
@@index([category])
|
|
910
1093
|
}
|
|
911
1094
|
|
|
912
1095
|
/// Represents an organization's connection to an integration provider
|
|
913
1096
|
model IntegrationConnection {
|
|
914
|
-
|
|
1097
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('icn'::text)"))
|
|
915
1098
|
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1099
|
+
/// Reference to the provider
|
|
1100
|
+
providerId String
|
|
1101
|
+
provider IntegrationProvider @relation(fields: [providerId], references: [id], onDelete: Cascade)
|
|
919
1102
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1103
|
+
/// Organization that owns this connection
|
|
1104
|
+
organizationId String
|
|
1105
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
923
1106
|
|
|
924
|
-
|
|
925
|
-
|
|
1107
|
+
/// Connection status
|
|
1108
|
+
status IntegrationConnectionStatus @default(pending)
|
|
926
1109
|
|
|
927
|
-
|
|
928
|
-
|
|
1110
|
+
/// Auth strategy used (oauth2, api_key, basic, jwt, custom)
|
|
1111
|
+
authStrategy String
|
|
929
1112
|
|
|
930
|
-
|
|
931
|
-
|
|
1113
|
+
/// Reference to active credential version
|
|
1114
|
+
activeCredentialVersionId String?
|
|
932
1115
|
|
|
933
|
-
|
|
934
|
-
|
|
1116
|
+
/// Last successful sync timestamp
|
|
1117
|
+
lastSyncAt DateTime?
|
|
935
1118
|
|
|
936
|
-
|
|
937
|
-
|
|
1119
|
+
/// Next scheduled sync timestamp
|
|
1120
|
+
nextSyncAt DateTime?
|
|
938
1121
|
|
|
939
|
-
|
|
940
|
-
|
|
1122
|
+
/// Custom sync cadence (cron expression), null = use default
|
|
1123
|
+
syncCadence String?
|
|
941
1124
|
|
|
942
|
-
|
|
943
|
-
|
|
1125
|
+
/// Additional metadata (e.g., connected account info)
|
|
1126
|
+
metadata Json?
|
|
944
1127
|
|
|
945
|
-
|
|
946
|
-
|
|
1128
|
+
/// User-configured variables for checks (collected after OAuth)
|
|
1129
|
+
variables Json?
|
|
947
1130
|
|
|
948
|
-
|
|
949
|
-
|
|
1131
|
+
/// Error message if status is error
|
|
1132
|
+
errorMessage String?
|
|
950
1133
|
|
|
951
|
-
|
|
952
|
-
|
|
1134
|
+
createdAt DateTime @default(now())
|
|
1135
|
+
updatedAt DateTime @updatedAt
|
|
953
1136
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1137
|
+
credentialVersions IntegrationCredentialVersion[]
|
|
1138
|
+
runs IntegrationRun[]
|
|
1139
|
+
findings IntegrationPlatformFinding[]
|
|
1140
|
+
checkRuns IntegrationCheckRun[]
|
|
1141
|
+
syncLogs IntegrationSyncLog[]
|
|
1142
|
+
remediationActions RemediationAction[]
|
|
1143
|
+
remediationBatches RemediationBatch[]
|
|
959
1144
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1145
|
+
@@index([organizationId])
|
|
1146
|
+
@@index([providerId])
|
|
1147
|
+
@@index([providerId, organizationId])
|
|
1148
|
+
@@index([status])
|
|
964
1149
|
}
|
|
965
1150
|
|
|
966
1151
|
enum IntegrationConnectionStatus {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1152
|
+
pending // Awaiting credential setup
|
|
1153
|
+
active // Connected and operational
|
|
1154
|
+
error // Connection has errors
|
|
1155
|
+
paused // Manually paused by user
|
|
1156
|
+
disconnected // User disconnected
|
|
972
1157
|
}
|
|
973
1158
|
|
|
974
1159
|
/// Stores encrypted credentials with versioning for audit trail
|
|
975
1160
|
model IntegrationCredentialVersion {
|
|
976
|
-
|
|
1161
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('icv'::text)"))
|
|
977
1162
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1163
|
+
/// Parent connection
|
|
1164
|
+
connectionId String
|
|
1165
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
981
1166
|
|
|
982
|
-
|
|
983
|
-
|
|
1167
|
+
/// Encrypted credential payload (JSON with encrypted fields)
|
|
1168
|
+
encryptedPayload Json
|
|
984
1169
|
|
|
985
|
-
|
|
986
|
-
|
|
1170
|
+
/// Version number (auto-increment per connection)
|
|
1171
|
+
version Int
|
|
987
1172
|
|
|
988
|
-
|
|
989
|
-
|
|
1173
|
+
/// Token expiration (for OAuth tokens)
|
|
1174
|
+
expiresAt DateTime?
|
|
990
1175
|
|
|
991
|
-
|
|
992
|
-
|
|
1176
|
+
/// When this version was rotated/replaced
|
|
1177
|
+
rotatedAt DateTime?
|
|
993
1178
|
|
|
994
|
-
|
|
1179
|
+
createdAt DateTime @default(now())
|
|
995
1180
|
|
|
996
|
-
|
|
997
|
-
|
|
1181
|
+
@@unique([connectionId, version])
|
|
1182
|
+
@@index([connectionId])
|
|
998
1183
|
}
|
|
999
1184
|
|
|
1000
1185
|
/// Records each sync/job execution for audit and debugging
|
|
1001
1186
|
model IntegrationRun {
|
|
1002
|
-
|
|
1187
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('irn'::text)"))
|
|
1003
1188
|
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1189
|
+
/// Parent connection
|
|
1190
|
+
connectionId String
|
|
1191
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
1007
1192
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1193
|
+
/// Type of job
|
|
1194
|
+
jobType IntegrationRunJobType
|
|
1010
1195
|
|
|
1011
|
-
|
|
1012
|
-
|
|
1196
|
+
/// Execution status
|
|
1197
|
+
status IntegrationRunStatus @default(pending)
|
|
1013
1198
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1199
|
+
/// Timestamps
|
|
1200
|
+
startedAt DateTime?
|
|
1201
|
+
completedAt DateTime?
|
|
1017
1202
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1203
|
+
/// Duration in milliseconds
|
|
1204
|
+
durationMs Int?
|
|
1020
1205
|
|
|
1021
|
-
|
|
1022
|
-
|
|
1206
|
+
/// Number of findings from this run
|
|
1207
|
+
findingsCount Int @default(0)
|
|
1023
1208
|
|
|
1024
|
-
|
|
1025
|
-
|
|
1209
|
+
/// Error details if failed
|
|
1210
|
+
error Json?
|
|
1026
1211
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1212
|
+
/// Additional metadata (trigger source, cursor, etc.)
|
|
1213
|
+
metadata Json?
|
|
1029
1214
|
|
|
1030
|
-
|
|
1215
|
+
createdAt DateTime @default(now())
|
|
1031
1216
|
|
|
1032
|
-
|
|
1217
|
+
findings IntegrationPlatformFinding[]
|
|
1033
1218
|
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1219
|
+
@@index([connectionId])
|
|
1220
|
+
@@index([status])
|
|
1221
|
+
@@index([createdAt])
|
|
1037
1222
|
}
|
|
1038
1223
|
|
|
1039
1224
|
enum IntegrationRunJobType {
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1225
|
+
full_sync
|
|
1226
|
+
delta_sync
|
|
1227
|
+
webhook
|
|
1228
|
+
manual
|
|
1229
|
+
test_connection
|
|
1045
1230
|
}
|
|
1046
1231
|
|
|
1047
1232
|
enum IntegrationRunStatus {
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1233
|
+
pending
|
|
1234
|
+
running
|
|
1235
|
+
success
|
|
1236
|
+
failed
|
|
1237
|
+
cancelled
|
|
1053
1238
|
}
|
|
1054
1239
|
|
|
1055
1240
|
/// Stores findings/results from integration syncs
|
|
1056
1241
|
model IntegrationPlatformFinding {
|
|
1057
|
-
|
|
1242
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('ipf'::text)"))
|
|
1058
1243
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1244
|
+
/// Parent run (optional - webhooks may not have runs)
|
|
1245
|
+
runId String?
|
|
1246
|
+
run IntegrationRun? @relation(fields: [runId], references: [id], onDelete: SetNull)
|
|
1062
1247
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1248
|
+
/// Parent connection
|
|
1249
|
+
connectionId String
|
|
1250
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
1066
1251
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1252
|
+
/// Resource classification
|
|
1253
|
+
resourceType String
|
|
1254
|
+
resourceId String
|
|
1070
1255
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1256
|
+
/// Finding details
|
|
1257
|
+
title String
|
|
1258
|
+
description String?
|
|
1074
1259
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1260
|
+
/// Severity level
|
|
1261
|
+
severity IntegrationFindingSeverity @default(info)
|
|
1077
1262
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1263
|
+
/// Finding status
|
|
1264
|
+
status IntegrationFindingStatus @default(open)
|
|
1080
1265
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1266
|
+
/// Remediation guidance
|
|
1267
|
+
remediation String?
|
|
1083
1268
|
|
|
1084
|
-
|
|
1085
|
-
|
|
1269
|
+
/// Raw payload from provider
|
|
1270
|
+
rawPayload Json?
|
|
1086
1271
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1272
|
+
createdAt DateTime @default(now())
|
|
1273
|
+
updatedAt DateTime @updatedAt
|
|
1089
1274
|
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1275
|
+
@@index([connectionId])
|
|
1276
|
+
@@index([runId])
|
|
1277
|
+
@@index([resourceType, resourceId])
|
|
1278
|
+
@@index([severity])
|
|
1279
|
+
@@index([status])
|
|
1095
1280
|
}
|
|
1096
1281
|
|
|
1097
1282
|
enum IntegrationFindingSeverity {
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1283
|
+
info
|
|
1284
|
+
low
|
|
1285
|
+
medium
|
|
1286
|
+
high
|
|
1287
|
+
critical
|
|
1103
1288
|
}
|
|
1104
1289
|
|
|
1105
1290
|
enum IntegrationFindingStatus {
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1291
|
+
open
|
|
1292
|
+
resolved
|
|
1293
|
+
ignored
|
|
1109
1294
|
}
|
|
1110
1295
|
|
|
1111
1296
|
/// Stores OAuth state for CSRF protection during OAuth flow
|
|
1112
1297
|
model IntegrationOAuthState {
|
|
1113
|
-
|
|
1298
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('ios'::text)"))
|
|
1114
1299
|
|
|
1115
|
-
|
|
1116
|
-
|
|
1300
|
+
/// Random state parameter
|
|
1301
|
+
state String @unique
|
|
1117
1302
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1303
|
+
/// Provider slug
|
|
1304
|
+
providerSlug String
|
|
1120
1305
|
|
|
1121
|
-
|
|
1122
|
-
|
|
1306
|
+
/// Organization initiating the OAuth
|
|
1307
|
+
organizationId String
|
|
1123
1308
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1309
|
+
/// User initiating the OAuth
|
|
1310
|
+
userId String
|
|
1126
1311
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1312
|
+
/// PKCE code verifier (if using PKCE)
|
|
1313
|
+
codeVerifier String?
|
|
1129
1314
|
|
|
1130
|
-
|
|
1131
|
-
|
|
1315
|
+
/// Redirect URL after OAuth completes
|
|
1316
|
+
redirectUrl String?
|
|
1132
1317
|
|
|
1133
|
-
|
|
1134
|
-
|
|
1318
|
+
/// Expiration timestamp
|
|
1319
|
+
expiresAt DateTime
|
|
1135
1320
|
|
|
1136
|
-
|
|
1321
|
+
createdAt DateTime @default(now())
|
|
1137
1322
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1323
|
+
@@index([state])
|
|
1324
|
+
@@index([expiresAt])
|
|
1140
1325
|
}
|
|
1141
1326
|
|
|
1142
1327
|
/// Stores organization-level OAuth app credentials
|
|
1143
1328
|
/// Allows orgs (especially self-hosters) to use their own OAuth apps
|
|
1144
1329
|
model IntegrationOAuthApp {
|
|
1145
|
-
|
|
1330
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('ioa'::text)"))
|
|
1146
1331
|
|
|
1147
|
-
|
|
1148
|
-
|
|
1332
|
+
/// Provider slug (e.g., "github", "slack")
|
|
1333
|
+
providerSlug String
|
|
1149
1334
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1335
|
+
/// Organization that owns this OAuth app config
|
|
1336
|
+
organizationId String
|
|
1337
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
1153
1338
|
|
|
1154
|
-
|
|
1155
|
-
|
|
1339
|
+
/// Encrypted client ID
|
|
1340
|
+
encryptedClientId Json
|
|
1156
1341
|
|
|
1157
|
-
|
|
1158
|
-
|
|
1342
|
+
/// Encrypted client secret
|
|
1343
|
+
encryptedClientSecret Json
|
|
1159
1344
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1345
|
+
/// Optional: custom scopes (overrides manifest defaults)
|
|
1346
|
+
customScopes String[]
|
|
1162
1347
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1348
|
+
/// Provider-specific settings (e.g., Rippling app name for authorize URL)
|
|
1349
|
+
/// Stored as JSON: { "appName": "compai533c" }
|
|
1350
|
+
customSettings Json?
|
|
1166
1351
|
|
|
1167
|
-
|
|
1168
|
-
|
|
1352
|
+
/// Whether this config is active
|
|
1353
|
+
isActive Boolean @default(true)
|
|
1169
1354
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1355
|
+
createdAt DateTime @default(now())
|
|
1356
|
+
updatedAt DateTime @updatedAt
|
|
1172
1357
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1358
|
+
@@unique([providerSlug, organizationId])
|
|
1359
|
+
@@index([organizationId])
|
|
1360
|
+
@@index([providerSlug])
|
|
1176
1361
|
}
|
|
1177
1362
|
|
|
1178
1363
|
/// Records check runs linked to tasks for compliance verification
|
|
1179
1364
|
model IntegrationCheckRun {
|
|
1180
|
-
|
|
1365
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('icr'::text)"))
|
|
1181
1366
|
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1367
|
+
/// Parent connection
|
|
1368
|
+
connectionId String
|
|
1369
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
1185
1370
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1371
|
+
/// Task being verified (optional - checks can run without a task)
|
|
1372
|
+
taskId String?
|
|
1373
|
+
task Task? @relation(fields: [taskId], references: [id], onDelete: SetNull)
|
|
1189
1374
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1375
|
+
/// Check ID from the manifest
|
|
1376
|
+
checkId String
|
|
1192
1377
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1378
|
+
/// Check name (denormalized for display)
|
|
1379
|
+
checkName String
|
|
1195
1380
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1381
|
+
/// Execution status
|
|
1382
|
+
status IntegrationRunStatus @default(pending)
|
|
1198
1383
|
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1384
|
+
/// Timestamps
|
|
1385
|
+
startedAt DateTime?
|
|
1386
|
+
completedAt DateTime?
|
|
1202
1387
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1388
|
+
/// Duration in milliseconds
|
|
1389
|
+
durationMs Int?
|
|
1205
1390
|
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1391
|
+
/// Summary counts
|
|
1392
|
+
totalChecked Int @default(0)
|
|
1393
|
+
passedCount Int @default(0)
|
|
1394
|
+
failedCount Int @default(0)
|
|
1210
1395
|
|
|
1211
|
-
|
|
1212
|
-
|
|
1396
|
+
/// Error message if failed
|
|
1397
|
+
errorMessage String?
|
|
1213
1398
|
|
|
1214
|
-
|
|
1215
|
-
|
|
1399
|
+
/// Full execution logs (JSON array)
|
|
1400
|
+
logs Json?
|
|
1216
1401
|
|
|
1217
|
-
|
|
1402
|
+
createdAt DateTime @default(now())
|
|
1218
1403
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1404
|
+
/// Results from this check run
|
|
1405
|
+
results IntegrationCheckResult[]
|
|
1221
1406
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1407
|
+
@@index([connectionId])
|
|
1408
|
+
@@index([taskId])
|
|
1409
|
+
@@index([checkId])
|
|
1410
|
+
@@index([status])
|
|
1411
|
+
@@index([createdAt])
|
|
1227
1412
|
}
|
|
1228
1413
|
|
|
1229
1414
|
/// Stores individual results (pass/fail) from check runs
|
|
1230
1415
|
model IntegrationCheckResult {
|
|
1231
|
-
|
|
1416
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('icx'::text)"))
|
|
1417
|
+
|
|
1418
|
+
/// Parent check run
|
|
1419
|
+
checkRunId String
|
|
1420
|
+
checkRun IntegrationCheckRun @relation(fields: [checkRunId], references: [id], onDelete: Cascade)
|
|
1232
1421
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
checkRun IntegrationCheckRun @relation(fields: [checkRunId], references: [id], onDelete: Cascade)
|
|
1422
|
+
/// Whether this result is a pass or fail
|
|
1423
|
+
passed Boolean
|
|
1236
1424
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1425
|
+
/// Resource classification
|
|
1426
|
+
resourceType String
|
|
1427
|
+
resourceId String
|
|
1239
1428
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1429
|
+
/// Result details
|
|
1430
|
+
title String
|
|
1431
|
+
description String?
|
|
1243
1432
|
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
description String?
|
|
1433
|
+
/// Severity (for failures)
|
|
1434
|
+
severity IntegrationFindingSeverity?
|
|
1247
1435
|
|
|
1248
|
-
|
|
1249
|
-
|
|
1436
|
+
/// Remediation guidance (for failures)
|
|
1437
|
+
remediation String?
|
|
1250
1438
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1439
|
+
/// Evidence/proof (JSON - API response data)
|
|
1440
|
+
evidence Json?
|
|
1253
1441
|
|
|
1254
|
-
|
|
1255
|
-
|
|
1442
|
+
/// When this evidence was collected
|
|
1443
|
+
collectedAt DateTime @default(now())
|
|
1256
1444
|
|
|
1257
|
-
|
|
1258
|
-
collectedAt DateTime @default(now())
|
|
1445
|
+
remediationActions RemediationAction[]
|
|
1259
1446
|
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1447
|
+
@@index([checkRunId])
|
|
1448
|
+
@@index([passed])
|
|
1449
|
+
@@index([resourceType, resourceId])
|
|
1263
1450
|
}
|
|
1264
1451
|
|
|
1265
1452
|
/// Stores platform-wide OAuth app credentials
|
|
1266
1453
|
/// Used by platform operators to provide default OAuth apps for all users
|
|
1267
1454
|
model IntegrationPlatformCredential {
|
|
1268
|
-
|
|
1455
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('ipc'::text)"))
|
|
1269
1456
|
|
|
1270
|
-
|
|
1271
|
-
|
|
1457
|
+
/// Provider slug (e.g., "github", "slack") - unique per platform
|
|
1458
|
+
providerSlug String @unique
|
|
1272
1459
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1460
|
+
/// Encrypted client ID
|
|
1461
|
+
encryptedClientId Json
|
|
1275
1462
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1463
|
+
/// Encrypted client secret
|
|
1464
|
+
encryptedClientSecret Json
|
|
1278
1465
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1466
|
+
/// Masked display hint for client ID (computed at write time)
|
|
1467
|
+
clientIdHint String?
|
|
1281
1468
|
|
|
1282
|
-
|
|
1283
|
-
|
|
1469
|
+
/// Masked display hint for client secret (computed at write time)
|
|
1470
|
+
clientSecretHint String?
|
|
1284
1471
|
|
|
1285
|
-
|
|
1286
|
-
|
|
1472
|
+
/// Optional: custom scopes (overrides manifest defaults)
|
|
1473
|
+
customScopes String[]
|
|
1287
1474
|
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1475
|
+
/// Provider-specific settings (e.g., Rippling app name for authorize URL)
|
|
1476
|
+
/// Stored as JSON: { "appName": "compai533c" }
|
|
1477
|
+
customSettings Json?
|
|
1291
1478
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1479
|
+
/// Whether this credential is active
|
|
1480
|
+
isActive Boolean @default(true)
|
|
1294
1481
|
|
|
1295
|
-
|
|
1296
|
-
|
|
1482
|
+
/// Who created this credential
|
|
1483
|
+
createdById String?
|
|
1297
1484
|
|
|
1298
|
-
|
|
1299
|
-
|
|
1485
|
+
/// Who last updated this credential
|
|
1486
|
+
updatedById String?
|
|
1300
1487
|
|
|
1301
|
-
|
|
1302
|
-
|
|
1488
|
+
createdAt DateTime @default(now())
|
|
1489
|
+
updatedAt DateTime @updatedAt
|
|
1303
1490
|
|
|
1304
|
-
|
|
1491
|
+
@@index([providerSlug])
|
|
1305
1492
|
}
|
|
1306
1493
|
|
|
1307
|
-
|
|
1308
1494
|
// ===== integration-sync-log.prisma =====
|
|
1309
1495
|
// ===== Integration Sync Log =====
|
|
1310
1496
|
// Generic audit trail for integration sync operations (employee sync, role discovery, etc.)
|
|
1311
1497
|
|
|
1312
1498
|
model IntegrationSyncLog {
|
|
1313
|
-
id String
|
|
1499
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('isl'::text)"))
|
|
1314
1500
|
connectionId String
|
|
1315
|
-
connection IntegrationConnection
|
|
1501
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
1316
1502
|
organizationId String
|
|
1317
|
-
organization Organization
|
|
1503
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
1318
1504
|
|
|
1319
|
-
/// Provider slug (e.g., "
|
|
1505
|
+
/// Provider slug (e.g., "google-workspace", "rippling", "jumpcloud")
|
|
1320
1506
|
provider String
|
|
1321
1507
|
/// Event type (e.g., "employee_sync", "role_discovery", "role_mapping_save")
|
|
1322
1508
|
eventType String
|
|
@@ -1352,7 +1538,6 @@ enum IntegrationSyncLogStatus {
|
|
|
1352
1538
|
failed
|
|
1353
1539
|
}
|
|
1354
1540
|
|
|
1355
|
-
|
|
1356
1541
|
// ===== integration.prisma =====
|
|
1357
1542
|
model Integration {
|
|
1358
1543
|
id String @id @default(dbgenerated("generate_prefixed_cuid('int'::text)"))
|
|
@@ -1387,7 +1572,6 @@ model IntegrationResult {
|
|
|
1387
1572
|
@@index([integrationId])
|
|
1388
1573
|
}
|
|
1389
1574
|
|
|
1390
|
-
|
|
1391
1575
|
// ===== knowledge-base-document.prisma =====
|
|
1392
1576
|
model KnowledgeBaseDocument {
|
|
1393
1577
|
id String @id @default(dbgenerated("generate_prefixed_cuid('kbd'::text)"))
|
|
@@ -1421,13 +1605,12 @@ enum KnowledgeBaseDocumentProcessingStatus {
|
|
|
1421
1605
|
failed // Processing failed
|
|
1422
1606
|
}
|
|
1423
1607
|
|
|
1424
|
-
|
|
1425
1608
|
// ===== notification-policy.prisma =====
|
|
1426
1609
|
model RoleNotificationSetting {
|
|
1427
|
-
id
|
|
1428
|
-
organizationId
|
|
1429
|
-
organization
|
|
1430
|
-
role
|
|
1610
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('rns'::text)"))
|
|
1611
|
+
organizationId String
|
|
1612
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
1613
|
+
role String // "owner", "admin", "auditor", "employee", "contractor", or custom role name
|
|
1431
1614
|
|
|
1432
1615
|
policyNotifications Boolean @default(true)
|
|
1433
1616
|
taskReminders Boolean @default(true)
|
|
@@ -1443,7 +1626,6 @@ model RoleNotificationSetting {
|
|
|
1443
1626
|
@@map("role_notification_setting")
|
|
1444
1627
|
}
|
|
1445
1628
|
|
|
1446
|
-
|
|
1447
1629
|
// ===== onboarding.prisma =====
|
|
1448
1630
|
model Onboarding {
|
|
1449
1631
|
organizationId String @id
|
|
@@ -1464,7 +1646,6 @@ model Onboarding {
|
|
|
1464
1646
|
@@index([organizationId])
|
|
1465
1647
|
}
|
|
1466
1648
|
|
|
1467
|
-
|
|
1468
1649
|
// ===== org-chart.prisma =====
|
|
1469
1650
|
model OrganizationChart {
|
|
1470
1651
|
id String @id @default(dbgenerated("generate_prefixed_cuid('och'::text)"))
|
|
@@ -1481,7 +1662,6 @@ model OrganizationChart {
|
|
|
1481
1662
|
@@index([organizationId])
|
|
1482
1663
|
}
|
|
1483
1664
|
|
|
1484
|
-
|
|
1485
1665
|
// ===== organization-billing.prisma =====
|
|
1486
1666
|
model OrganizationBilling {
|
|
1487
1667
|
id String @id @default(dbgenerated("generate_prefixed_cuid('obil'::text)"))
|
|
@@ -1490,31 +1670,30 @@ model OrganizationBilling {
|
|
|
1490
1670
|
createdAt DateTime @default(now()) @map("created_at")
|
|
1491
1671
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
1492
1672
|
|
|
1493
|
-
organization Organization
|
|
1673
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
1494
1674
|
pentestSubscription PentestSubscription?
|
|
1495
1675
|
|
|
1496
1676
|
@@map("organization_billing")
|
|
1497
1677
|
}
|
|
1498
1678
|
|
|
1499
|
-
|
|
1500
1679
|
// ===== organization.prisma =====
|
|
1501
1680
|
model Organization {
|
|
1502
|
-
id
|
|
1503
|
-
name
|
|
1504
|
-
slug
|
|
1505
|
-
logo
|
|
1506
|
-
createdAt
|
|
1507
|
-
metadata
|
|
1508
|
-
onboarding
|
|
1509
|
-
website
|
|
1510
|
-
onboardingCompleted
|
|
1511
|
-
hasAccess
|
|
1512
|
-
advancedModeEnabled
|
|
1513
|
-
evidenceApprovalEnabled
|
|
1514
|
-
deviceAgentStepEnabled
|
|
1515
|
-
securityTrainingStepEnabled
|
|
1516
|
-
whistleblowerReportEnabled
|
|
1517
|
-
accessRequestFormEnabled
|
|
1681
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('org'::text)"))
|
|
1682
|
+
name String
|
|
1683
|
+
slug String @unique @default(dbgenerated("generate_prefixed_cuid('slug'::text)"))
|
|
1684
|
+
logo String?
|
|
1685
|
+
createdAt DateTime @default(now())
|
|
1686
|
+
metadata String?
|
|
1687
|
+
onboarding Onboarding?
|
|
1688
|
+
website String?
|
|
1689
|
+
onboardingCompleted Boolean @default(false)
|
|
1690
|
+
hasAccess Boolean @default(false)
|
|
1691
|
+
advancedModeEnabled Boolean @default(false)
|
|
1692
|
+
evidenceApprovalEnabled Boolean @default(false)
|
|
1693
|
+
deviceAgentStepEnabled Boolean @default(true)
|
|
1694
|
+
securityTrainingStepEnabled Boolean @default(true)
|
|
1695
|
+
whistleblowerReportEnabled Boolean @default(true)
|
|
1696
|
+
accessRequestFormEnabled Boolean @default(true)
|
|
1518
1697
|
|
|
1519
1698
|
// FleetDM
|
|
1520
1699
|
fleetDmLabelId Int?
|
|
@@ -1578,13 +1757,19 @@ model Organization {
|
|
|
1578
1757
|
organizationChart OrganizationChart?
|
|
1579
1758
|
|
|
1580
1759
|
// RBAC
|
|
1581
|
-
organizationRoles
|
|
1582
|
-
roleNotificationSettings
|
|
1760
|
+
organizationRoles OrganizationRole[]
|
|
1761
|
+
roleNotificationSettings RoleNotificationSetting[]
|
|
1762
|
+
|
|
1763
|
+
// Timeline
|
|
1764
|
+
timelineInstances TimelineInstance[]
|
|
1765
|
+
|
|
1766
|
+
// Custom frameworks / requirements authored by this org
|
|
1767
|
+
customFrameworks CustomFramework[]
|
|
1768
|
+
customRequirements CustomRequirement[]
|
|
1583
1769
|
|
|
1584
1770
|
@@index([slug])
|
|
1585
1771
|
}
|
|
1586
1772
|
|
|
1587
|
-
|
|
1588
1773
|
// ===== pentest-subscription.prisma =====
|
|
1589
1774
|
model PentestSubscription {
|
|
1590
1775
|
id String @id @default(dbgenerated("generate_prefixed_cuid('psub'::text)"))
|
|
@@ -1607,7 +1792,6 @@ model PentestSubscription {
|
|
|
1607
1792
|
@@map("pentest_subscriptions")
|
|
1608
1793
|
}
|
|
1609
1794
|
|
|
1610
|
-
|
|
1611
1795
|
// ===== policy.prisma =====
|
|
1612
1796
|
enum PolicyDisplayFormat {
|
|
1613
1797
|
EDITOR
|
|
@@ -1615,7 +1799,7 @@ enum PolicyDisplayFormat {
|
|
|
1615
1799
|
}
|
|
1616
1800
|
|
|
1617
1801
|
enum PolicyVisibility {
|
|
1618
|
-
ALL
|
|
1802
|
+
ALL // Visible to everyone in organization
|
|
1619
1803
|
DEPARTMENT // Only visible to specified departments
|
|
1620
1804
|
}
|
|
1621
1805
|
|
|
@@ -1645,6 +1829,12 @@ model Policy {
|
|
|
1645
1829
|
lastArchivedAt DateTime?
|
|
1646
1830
|
lastPublishedAt DateTime?
|
|
1647
1831
|
|
|
1832
|
+
// Sync-driven archive. Distinct from `isArchived` (which is user-initiated
|
|
1833
|
+
// archiving of a published policy). UI should hide a policy if EITHER is
|
|
1834
|
+
// set: `WHERE isArchived = false AND archivedAt IS NULL`. Rollback restores
|
|
1835
|
+
// only `archivedAt`, never touches `isArchived`.
|
|
1836
|
+
archivedAt DateTime?
|
|
1837
|
+
|
|
1648
1838
|
// Relationships
|
|
1649
1839
|
organizationId String
|
|
1650
1840
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
@@ -1659,8 +1849,10 @@ model Policy {
|
|
|
1659
1849
|
currentVersion PolicyVersion? @relation("PolicyCurrentVersion", fields: [currentVersionId], references: [id])
|
|
1660
1850
|
pendingVersionId String?
|
|
1661
1851
|
versions PolicyVersion[] @relation("PolicyVersions")
|
|
1852
|
+
findings Finding[]
|
|
1662
1853
|
|
|
1663
1854
|
@@index([organizationId])
|
|
1855
|
+
@@index([organizationId, archivedAt])
|
|
1664
1856
|
}
|
|
1665
1857
|
|
|
1666
1858
|
model PolicyVersion {
|
|
@@ -1669,8 +1861,8 @@ model PolicyVersion {
|
|
|
1669
1861
|
updatedAt DateTime @updatedAt
|
|
1670
1862
|
|
|
1671
1863
|
// Relations
|
|
1672
|
-
policyId
|
|
1673
|
-
policy
|
|
1864
|
+
policyId String
|
|
1865
|
+
policy Policy @relation("PolicyVersions", fields: [policyId], references: [id], onDelete: Cascade)
|
|
1674
1866
|
currentForPolicy Policy? @relation("PolicyCurrentVersion")
|
|
1675
1867
|
|
|
1676
1868
|
// Version details
|
|
@@ -1686,7 +1878,6 @@ model PolicyVersion {
|
|
|
1686
1878
|
@@index([createdAt])
|
|
1687
1879
|
}
|
|
1688
1880
|
|
|
1689
|
-
|
|
1690
1881
|
// ===== questionnaire.prisma =====
|
|
1691
1882
|
model Questionnaire {
|
|
1692
1883
|
id String @id @default(dbgenerated("generate_prefixed_cuid('qst'::text)"))
|
|
@@ -1751,13 +1942,68 @@ enum QuestionnaireAnswerStatus {
|
|
|
1751
1942
|
manual // Manually written/edited by user
|
|
1752
1943
|
}
|
|
1753
1944
|
|
|
1945
|
+
// ===== remediation-action.prisma =====
|
|
1946
|
+
model RemediationAction {
|
|
1947
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('rma'::text)"))
|
|
1948
|
+
checkResultId String
|
|
1949
|
+
connectionId String
|
|
1950
|
+
organizationId String
|
|
1951
|
+
initiatedById String
|
|
1952
|
+
remediationKey String
|
|
1953
|
+
resourceId String
|
|
1954
|
+
resourceType String
|
|
1955
|
+
previousState Json
|
|
1956
|
+
appliedState Json
|
|
1957
|
+
status String @default("pending")
|
|
1958
|
+
riskLevel String?
|
|
1959
|
+
acknowledgmentText String?
|
|
1960
|
+
acknowledgedAt DateTime?
|
|
1961
|
+
errorMessage String?
|
|
1962
|
+
executedAt DateTime?
|
|
1963
|
+
rolledBackAt DateTime?
|
|
1964
|
+
createdAt DateTime @default(now())
|
|
1965
|
+
updatedAt DateTime @updatedAt
|
|
1966
|
+
|
|
1967
|
+
checkResult IntegrationCheckResult @relation(fields: [checkResultId], references: [id], onDelete: Cascade)
|
|
1968
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
1969
|
+
|
|
1970
|
+
@@index([connectionId])
|
|
1971
|
+
@@index([organizationId])
|
|
1972
|
+
@@index([checkResultId])
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
// ===== remediation-batch.prisma =====
|
|
1976
|
+
model RemediationBatch {
|
|
1977
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('rmb'::text)"))
|
|
1978
|
+
connectionId String
|
|
1979
|
+
organizationId String
|
|
1980
|
+
initiatedById String
|
|
1981
|
+
triggerRunId String?
|
|
1982
|
+
status String @default("pending") // pending, running, done, cancelled
|
|
1983
|
+
findings Json @default("[]") // Array of { id, key, title, status, error? }
|
|
1984
|
+
fixed Int @default(0)
|
|
1985
|
+
skipped Int @default(0)
|
|
1986
|
+
failed Int @default(0)
|
|
1987
|
+
createdAt DateTime @default(now())
|
|
1988
|
+
updatedAt DateTime @updatedAt
|
|
1989
|
+
|
|
1990
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
1991
|
+
|
|
1992
|
+
@@index([connectionId])
|
|
1993
|
+
@@index([organizationId])
|
|
1994
|
+
@@index([status])
|
|
1995
|
+
}
|
|
1754
1996
|
|
|
1755
1997
|
// ===== requirement.prisma =====
|
|
1756
1998
|
model RequirementMap {
|
|
1757
1999
|
id String @id @default(dbgenerated("generate_prefixed_cuid('req'::text)"))
|
|
1758
2000
|
|
|
1759
|
-
requirementId
|
|
1760
|
-
|
|
2001
|
+
// Exactly one of requirementId / customRequirementId is set (enforced by DB CHECK constraint).
|
|
2002
|
+
requirementId String?
|
|
2003
|
+
requirement FrameworkEditorRequirement? @relation(fields: [requirementId], references: [id], onDelete: Cascade)
|
|
2004
|
+
|
|
2005
|
+
customRequirementId String?
|
|
2006
|
+
customRequirement CustomRequirement? @relation(fields: [customRequirementId], references: [id], onDelete: Cascade)
|
|
1761
2007
|
|
|
1762
2008
|
controlId String
|
|
1763
2009
|
control Control @relation(fields: [controlId], references: [id], onDelete: Cascade)
|
|
@@ -1765,11 +2011,17 @@ model RequirementMap {
|
|
|
1765
2011
|
frameworkInstanceId String
|
|
1766
2012
|
frameworkInstance FrameworkInstance @relation(fields: [frameworkInstanceId], references: [id], onDelete: Cascade)
|
|
1767
2013
|
|
|
2014
|
+
// Sync-driven archive — edges are framework-scoped, so these always archive
|
|
2015
|
+
// cleanly when the mapping disappears from the framework's latest version.
|
|
2016
|
+
archivedAt DateTime?
|
|
2017
|
+
|
|
1768
2018
|
@@unique([controlId, frameworkInstanceId, requirementId])
|
|
2019
|
+
@@unique([controlId, frameworkInstanceId, customRequirementId])
|
|
1769
2020
|
@@index([requirementId, frameworkInstanceId])
|
|
2021
|
+
@@index([customRequirementId, frameworkInstanceId])
|
|
2022
|
+
@@index([frameworkInstanceId, archivedAt])
|
|
1770
2023
|
}
|
|
1771
2024
|
|
|
1772
|
-
|
|
1773
2025
|
// ===== risk.prisma =====
|
|
1774
2026
|
model Risk {
|
|
1775
2027
|
// Metadata
|
|
@@ -1796,6 +2048,7 @@ model Risk {
|
|
|
1796
2048
|
assigneeId String?
|
|
1797
2049
|
assignee Member? @relation(fields: [assigneeId], references: [id])
|
|
1798
2050
|
tasks Task[]
|
|
2051
|
+
findings Finding[]
|
|
1799
2052
|
|
|
1800
2053
|
@@index([organizationId])
|
|
1801
2054
|
@@index([category])
|
|
@@ -1830,7 +2083,6 @@ enum RiskStatus {
|
|
|
1830
2083
|
archived
|
|
1831
2084
|
}
|
|
1832
2085
|
|
|
1833
|
-
|
|
1834
2086
|
// ===== secret.prisma =====
|
|
1835
2087
|
model Secret {
|
|
1836
2088
|
id String @id @default(dbgenerated("generate_prefixed_cuid('sec'::text)"))
|
|
@@ -1849,14 +2101,13 @@ model Secret {
|
|
|
1849
2101
|
@@map("secrets")
|
|
1850
2102
|
}
|
|
1851
2103
|
|
|
1852
|
-
|
|
1853
2104
|
// ===== security-penetration-test-run.prisma =====
|
|
1854
2105
|
model SecurityPenetrationTestRun {
|
|
1855
|
-
id
|
|
1856
|
-
organizationId String
|
|
1857
|
-
providerRunId
|
|
1858
|
-
createdAt
|
|
1859
|
-
updatedAt
|
|
2106
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('ptr'::text)"))
|
|
2107
|
+
organizationId String @map("organization_id")
|
|
2108
|
+
providerRunId String @map("provider_run_id")
|
|
2109
|
+
createdAt DateTime @default(now()) @map("created_at")
|
|
2110
|
+
updatedAt DateTime @updatedAt @map("updated_at")
|
|
1860
2111
|
|
|
1861
2112
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
1862
2113
|
|
|
@@ -1865,7 +2116,6 @@ model SecurityPenetrationTestRun {
|
|
|
1865
2116
|
@@map("security_penetration_test_runs")
|
|
1866
2117
|
}
|
|
1867
2118
|
|
|
1868
|
-
|
|
1869
2119
|
// ===== security-questionnaire-manual-answer.prisma =====
|
|
1870
2120
|
model SecurityQuestionnaireManualAnswer {
|
|
1871
2121
|
id String @id @default(dbgenerated("generate_prefixed_cuid('sqma'::text)"))
|
|
@@ -1896,7 +2146,6 @@ model SecurityQuestionnaireManualAnswer {
|
|
|
1896
2146
|
@@index([createdAt])
|
|
1897
2147
|
}
|
|
1898
2148
|
|
|
1899
|
-
|
|
1900
2149
|
// ===== shared.prisma =====
|
|
1901
2150
|
model ApiKey {
|
|
1902
2151
|
id String @id @default(dbgenerated("generate_prefixed_cuid('apk'::text)"))
|
|
@@ -2028,7 +2277,6 @@ enum Impact {
|
|
|
2028
2277
|
severe
|
|
2029
2278
|
}
|
|
2030
2279
|
|
|
2031
|
-
|
|
2032
2280
|
// ===== soa.prisma =====
|
|
2033
2281
|
// Statement of Applicability (SOA) Auto-complete Configuration and Answers
|
|
2034
2282
|
|
|
@@ -2092,9 +2340,9 @@ model SOADocument {
|
|
|
2092
2340
|
answeredQuestions Int @default(0) // Number of questions with answers
|
|
2093
2341
|
|
|
2094
2342
|
// Approval tracking
|
|
2095
|
-
preparedBy String
|
|
2343
|
+
preparedBy String @default("Comp AI") // Always "Comp AI"
|
|
2096
2344
|
approverId String? // Member ID who will approve this document (set when submitted for approval)
|
|
2097
|
-
approver Member?
|
|
2345
|
+
approver Member? @relation("SOADocumentApprover", fields: [approverId], references: [id], onDelete: SetNull, onUpdate: Cascade)
|
|
2098
2346
|
approvedAt DateTime? // When document was approved
|
|
2099
2347
|
|
|
2100
2348
|
// Dates
|
|
@@ -2165,37 +2413,36 @@ enum SOAAnswerStatus {
|
|
|
2165
2413
|
manual // Manually written/edited by user
|
|
2166
2414
|
}
|
|
2167
2415
|
|
|
2168
|
-
|
|
2169
2416
|
// ===== task-item.prisma =====
|
|
2170
2417
|
model TaskItem {
|
|
2171
|
-
id String
|
|
2418
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('tski'::text)"))
|
|
2172
2419
|
title String
|
|
2173
2420
|
description String?
|
|
2174
|
-
status TaskItemStatus
|
|
2175
|
-
priority TaskItemPriority
|
|
2176
|
-
|
|
2421
|
+
status TaskItemStatus @default(todo)
|
|
2422
|
+
priority TaskItemPriority @default(medium)
|
|
2423
|
+
|
|
2177
2424
|
// Polymorphic relation (like Comment and Attachment)
|
|
2178
2425
|
entityId String
|
|
2179
2426
|
entityType TaskItemEntityType
|
|
2180
|
-
|
|
2427
|
+
|
|
2181
2428
|
// Assignment (nullable)
|
|
2182
|
-
assigneeId
|
|
2183
|
-
assignee Member?
|
|
2184
|
-
|
|
2429
|
+
assigneeId String?
|
|
2430
|
+
assignee Member? @relation("TaskItemAssignee", fields: [assigneeId], references: [id], onDelete: SetNull)
|
|
2431
|
+
|
|
2185
2432
|
// Creator & Updater
|
|
2186
2433
|
createdById String
|
|
2187
|
-
createdBy Member
|
|
2434
|
+
createdBy Member @relation("TaskItemCreator", fields: [createdById], references: [id])
|
|
2188
2435
|
updatedById String?
|
|
2189
|
-
updatedBy Member?
|
|
2190
|
-
|
|
2436
|
+
updatedBy Member? @relation("TaskItemUpdater", fields: [updatedById], references: [id])
|
|
2437
|
+
|
|
2191
2438
|
// Relationships
|
|
2192
2439
|
organizationId String
|
|
2193
2440
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
2194
|
-
|
|
2441
|
+
|
|
2195
2442
|
// Dates
|
|
2196
2443
|
createdAt DateTime @default(now())
|
|
2197
2444
|
updatedAt DateTime @updatedAt
|
|
2198
|
-
|
|
2445
|
+
|
|
2199
2446
|
@@index([entityId, entityType])
|
|
2200
2447
|
@@index([organizationId])
|
|
2201
2448
|
@@index([assigneeId])
|
|
@@ -2223,18 +2470,19 @@ enum TaskItemEntityType {
|
|
|
2223
2470
|
risk
|
|
2224
2471
|
}
|
|
2225
2472
|
|
|
2226
|
-
|
|
2227
2473
|
// ===== task.prisma =====
|
|
2228
2474
|
model Task {
|
|
2229
2475
|
// Metadata
|
|
2230
|
-
id
|
|
2231
|
-
title
|
|
2232
|
-
description
|
|
2233
|
-
status
|
|
2234
|
-
automationStatus
|
|
2235
|
-
frequency
|
|
2236
|
-
|
|
2237
|
-
|
|
2476
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('tsk'::text)"))
|
|
2477
|
+
title String
|
|
2478
|
+
description String
|
|
2479
|
+
status TaskStatus @default(todo)
|
|
2480
|
+
automationStatus TaskAutomationStatus @default(AUTOMATED)
|
|
2481
|
+
frequency TaskFrequency?
|
|
2482
|
+
integrationScheduleFrequency TaskFrequency @default(daily)
|
|
2483
|
+
integrationLastRunAt DateTime?
|
|
2484
|
+
department Departments? @default(none)
|
|
2485
|
+
order Int @default(0)
|
|
2238
2486
|
|
|
2239
2487
|
// Dates
|
|
2240
2488
|
createdAt DateTime @default(now())
|
|
@@ -2256,14 +2504,19 @@ model Task {
|
|
|
2256
2504
|
browserAutomations BrowserAutomation[]
|
|
2257
2505
|
|
|
2258
2506
|
evidenceAutomationRuns EvidenceAutomationRun[]
|
|
2259
|
-
integrationCheckRuns
|
|
2260
|
-
findings
|
|
2507
|
+
integrationCheckRuns IntegrationCheckRun[]
|
|
2508
|
+
findings Finding[]
|
|
2261
2509
|
|
|
2262
2510
|
// Evidence approval
|
|
2263
2511
|
approverId String?
|
|
2264
2512
|
approver Member? @relation("TaskApprover", fields: [approverId], references: [id])
|
|
2265
2513
|
approvedAt DateTime?
|
|
2266
2514
|
previousStatus TaskStatus?
|
|
2515
|
+
|
|
2516
|
+
// Sync-driven archive — see Control.archivedAt.
|
|
2517
|
+
archivedAt DateTime?
|
|
2518
|
+
|
|
2519
|
+
@@index([organizationId, archivedAt])
|
|
2267
2520
|
}
|
|
2268
2521
|
|
|
2269
2522
|
enum TaskStatus {
|
|
@@ -2288,6 +2541,128 @@ enum TaskAutomationStatus {
|
|
|
2288
2541
|
MANUAL
|
|
2289
2542
|
}
|
|
2290
2543
|
|
|
2544
|
+
// ===== timeline.prisma =====
|
|
2545
|
+
enum TimelineStatus {
|
|
2546
|
+
DRAFT
|
|
2547
|
+
ACTIVE
|
|
2548
|
+
PAUSED
|
|
2549
|
+
COMPLETED
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
enum TimelinePhaseStatus {
|
|
2553
|
+
PENDING
|
|
2554
|
+
IN_PROGRESS
|
|
2555
|
+
COMPLETED
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
enum PhaseCompletionType {
|
|
2559
|
+
AUTO_TASKS
|
|
2560
|
+
AUTO_POLICIES
|
|
2561
|
+
AUTO_PEOPLE
|
|
2562
|
+
AUTO_FINDINGS
|
|
2563
|
+
AUTO_UPLOAD
|
|
2564
|
+
MANUAL
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
model TimelineTemplate {
|
|
2568
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('tml'::text)"))
|
|
2569
|
+
frameworkId String
|
|
2570
|
+
name String
|
|
2571
|
+
trackKey String @default("primary")
|
|
2572
|
+
cycleNumber Int
|
|
2573
|
+
templateKey String?
|
|
2574
|
+
nextTemplateKey String?
|
|
2575
|
+
createdAt DateTime @default(now())
|
|
2576
|
+
updatedAt DateTime @updatedAt
|
|
2577
|
+
|
|
2578
|
+
framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id])
|
|
2579
|
+
phases TimelinePhaseTemplate[]
|
|
2580
|
+
instances TimelineInstance[]
|
|
2581
|
+
|
|
2582
|
+
@@unique([frameworkId, trackKey, cycleNumber])
|
|
2583
|
+
// Note: Postgres treats NULLs as distinct in unique indexes, so this
|
|
2584
|
+
// constraint only enforces uniqueness among rows where templateKey is set.
|
|
2585
|
+
// That's intentional — frameworks without explicit keys (legacy defaults)
|
|
2586
|
+
// are uniquely identified by the (frameworkId, trackKey, cycleNumber)
|
|
2587
|
+
// constraint above, so multiple NULL templateKey rows are permitted.
|
|
2588
|
+
@@unique([frameworkId, templateKey])
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
model TimelinePhaseTemplate {
|
|
2592
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('tpt'::text)"))
|
|
2593
|
+
templateId String
|
|
2594
|
+
name String
|
|
2595
|
+
description String?
|
|
2596
|
+
groupLabel String?
|
|
2597
|
+
orderIndex Int
|
|
2598
|
+
defaultDurationWeeks Int
|
|
2599
|
+
completionType PhaseCompletionType @default(MANUAL)
|
|
2600
|
+
locksTimelineOnComplete Boolean @default(false)
|
|
2601
|
+
createdAt DateTime @default(now())
|
|
2602
|
+
updatedAt DateTime @updatedAt
|
|
2603
|
+
|
|
2604
|
+
template TimelineTemplate @relation(fields: [templateId], references: [id], onDelete: Cascade)
|
|
2605
|
+
phases TimelinePhase[]
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
model TimelineInstance {
|
|
2609
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('tli'::text)"))
|
|
2610
|
+
organizationId String
|
|
2611
|
+
frameworkInstanceId String
|
|
2612
|
+
templateId String
|
|
2613
|
+
trackKey String @default("primary")
|
|
2614
|
+
cycleNumber Int
|
|
2615
|
+
status TimelineStatus @default(DRAFT)
|
|
2616
|
+
startDate DateTime?
|
|
2617
|
+
pausedAt DateTime?
|
|
2618
|
+
lockedAt DateTime?
|
|
2619
|
+
lockedById String?
|
|
2620
|
+
unlockedAt DateTime?
|
|
2621
|
+
unlockedById String?
|
|
2622
|
+
unlockReason String?
|
|
2623
|
+
completedAt DateTime?
|
|
2624
|
+
createdAt DateTime @default(now())
|
|
2625
|
+
updatedAt DateTime @updatedAt
|
|
2626
|
+
|
|
2627
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
2628
|
+
frameworkInstance FrameworkInstance @relation(fields: [frameworkInstanceId], references: [id], onDelete: Cascade)
|
|
2629
|
+
template TimelineTemplate @relation(fields: [templateId], references: [id])
|
|
2630
|
+
lockedBy User? @relation("TimelineInstanceLockedBy", fields: [lockedById], references: [id])
|
|
2631
|
+
unlockedBy User? @relation("TimelineInstanceUnlockedBy", fields: [unlockedById], references: [id])
|
|
2632
|
+
phases TimelinePhase[]
|
|
2633
|
+
|
|
2634
|
+
@@unique([frameworkInstanceId, trackKey, cycleNumber])
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2637
|
+
model TimelinePhase {
|
|
2638
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('tlp'::text)"))
|
|
2639
|
+
instanceId String
|
|
2640
|
+
phaseTemplateId String?
|
|
2641
|
+
name String
|
|
2642
|
+
description String?
|
|
2643
|
+
groupLabel String?
|
|
2644
|
+
orderIndex Int
|
|
2645
|
+
status TimelinePhaseStatus @default(PENDING)
|
|
2646
|
+
startDate DateTime?
|
|
2647
|
+
endDate DateTime?
|
|
2648
|
+
durationWeeks Int
|
|
2649
|
+
completionType PhaseCompletionType @default(MANUAL)
|
|
2650
|
+
locksTimelineOnComplete Boolean @default(false)
|
|
2651
|
+
regressedAt DateTime?
|
|
2652
|
+
datesPinned Boolean @default(false)
|
|
2653
|
+
completedAt DateTime?
|
|
2654
|
+
completedById String?
|
|
2655
|
+
readyForReview Boolean @default(false)
|
|
2656
|
+
readyForReviewAt DateTime?
|
|
2657
|
+
documentUrl String?
|
|
2658
|
+
documentName String?
|
|
2659
|
+
createdAt DateTime @default(now())
|
|
2660
|
+
updatedAt DateTime @updatedAt
|
|
2661
|
+
|
|
2662
|
+
instance TimelineInstance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
|
2663
|
+
phaseTemplate TimelinePhaseTemplate? @relation(fields: [phaseTemplateId], references: [id])
|
|
2664
|
+
completedBy User? @relation(fields: [completedById], references: [id])
|
|
2665
|
+
}
|
|
2291
2666
|
|
|
2292
2667
|
// ===== trust.prisma =====
|
|
2293
2668
|
model Trust {
|
|
@@ -2542,7 +2917,6 @@ model TrustCustomLink {
|
|
|
2542
2917
|
@@index([organizationId, isActive, order])
|
|
2543
2918
|
}
|
|
2544
2919
|
|
|
2545
|
-
|
|
2546
2920
|
// ===== vendor.prisma =====
|
|
2547
2921
|
model Vendor {
|
|
2548
2922
|
id String @id @default(dbgenerated("generate_prefixed_cuid('vnd'::text)"))
|
|
@@ -2572,6 +2946,7 @@ model Vendor {
|
|
|
2572
2946
|
assignee Member? @relation(fields: [assigneeId], references: [id], onDelete: Cascade)
|
|
2573
2947
|
contacts VendorContact[]
|
|
2574
2948
|
tasks Task[]
|
|
2949
|
+
findings Finding[]
|
|
2575
2950
|
|
|
2576
2951
|
@@index([organizationId])
|
|
2577
2952
|
@@index([assigneeId])
|