@trycompai/db 1.3.18 → 1.3.19
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.map +1 -1
- package/dist/client.js +4 -1
- package/dist/schema.prisma +687 -88
- package/package.json +2 -1
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI9C,eAAO,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI9C,eAAO,MAAM,EAAE,gIAIX,CAAC"}
|
package/dist/client.js
CHANGED
|
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.db = void 0;
|
|
4
4
|
const client_1 = require("@prisma/client");
|
|
5
5
|
const globalForPrisma = global;
|
|
6
|
-
exports.db = globalForPrisma.prisma ||
|
|
6
|
+
exports.db = globalForPrisma.prisma ||
|
|
7
|
+
new client_1.PrismaClient({
|
|
8
|
+
datasourceUrl: process.env.DATABASE_URL,
|
|
9
|
+
});
|
|
7
10
|
if (process.env.NODE_ENV !== 'production')
|
|
8
11
|
globalForPrisma.prisma = exports.db;
|
package/dist/schema.prisma
CHANGED
|
@@ -7,7 +7,6 @@ generator client {
|
|
|
7
7
|
datasource db {
|
|
8
8
|
provider = "postgresql"
|
|
9
9
|
url = env("DATABASE_URL")
|
|
10
|
-
directUrl = env("DATABASE_URL")
|
|
11
10
|
extensions = [pgcrypto]
|
|
12
11
|
}
|
|
13
12
|
|
|
@@ -53,14 +52,17 @@ enum AttachmentType {
|
|
|
53
52
|
|
|
54
53
|
// ===== auth.prisma =====
|
|
55
54
|
model User {
|
|
56
|
-
id
|
|
57
|
-
name
|
|
58
|
-
email
|
|
59
|
-
emailVerified
|
|
60
|
-
image
|
|
61
|
-
createdAt
|
|
62
|
-
updatedAt
|
|
63
|
-
lastLogin
|
|
55
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('usr'::text)"))
|
|
56
|
+
name String
|
|
57
|
+
email String
|
|
58
|
+
emailVerified Boolean
|
|
59
|
+
image String?
|
|
60
|
+
createdAt DateTime @default(now())
|
|
61
|
+
updatedAt DateTime @updatedAt
|
|
62
|
+
lastLogin DateTime?
|
|
63
|
+
emailNotificationsUnsubscribed Boolean @default(false)
|
|
64
|
+
emailPreferences Json? @default("{\"policyNotifications\":true,\"taskReminders\":true,\"weeklyTaskDigest\":true,\"unassignedItemsNotifications\":true}")
|
|
65
|
+
isPlatformAdmin Boolean @default(false)
|
|
64
66
|
|
|
65
67
|
accounts Account[]
|
|
66
68
|
auditLog AuditLog[]
|
|
@@ -147,12 +149,13 @@ model Member {
|
|
|
147
149
|
|
|
148
150
|
department Departments @default(none)
|
|
149
151
|
isActive Boolean @default(true)
|
|
150
|
-
|
|
152
|
+
deactivated Boolean @default(false)
|
|
151
153
|
employeeTrainingVideoCompletion EmployeeTrainingVideoCompletion[]
|
|
152
154
|
fleetDmLabelId Int?
|
|
153
155
|
|
|
154
156
|
assignedPolicies Policy[] @relation("PolicyAssignee") // Policies where this member is an assignee
|
|
155
157
|
approvedPolicies Policy[] @relation("PolicyApprover") // Policies where this member is an approver
|
|
158
|
+
approvedSOADocuments SOADocument[] @relation("SOADocumentApprover") // SOA documents where this member is an approver
|
|
156
159
|
risks Risk[]
|
|
157
160
|
tasks Task[]
|
|
158
161
|
vendors Vendor[]
|
|
@@ -173,16 +176,17 @@ model Invitation {
|
|
|
173
176
|
expiresAt DateTime
|
|
174
177
|
inviterId String
|
|
175
178
|
user User @relation(fields: [inviterId], references: [id], onDelete: Cascade)
|
|
179
|
+
createdAt DateTime @default(now())
|
|
176
180
|
}
|
|
177
181
|
|
|
178
182
|
// This is only for the app to consume, shouldn't be enforced by DB
|
|
179
183
|
// Otherwise it won't work with Better Auth, as per https://www.better-auth.com/docs/plugins/organization#access-control
|
|
180
184
|
enum Role {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
185
|
+
owner
|
|
186
|
+
admin
|
|
187
|
+
auditor
|
|
188
|
+
employee
|
|
189
|
+
contractor
|
|
186
190
|
}
|
|
187
191
|
|
|
188
192
|
enum PolicyStatus {
|
|
@@ -392,6 +396,8 @@ model FrameworkEditorFramework {
|
|
|
392
396
|
|
|
393
397
|
requirements FrameworkEditorRequirement[]
|
|
394
398
|
frameworkInstances FrameworkInstance[]
|
|
399
|
+
soaConfigurations SOAFrameworkConfiguration[] // Multiple SOA config versions per framework
|
|
400
|
+
soaDocuments SOADocument[] // SOA documents from organizations
|
|
395
401
|
|
|
396
402
|
// Dates
|
|
397
403
|
createdAt DateTime @default(now())
|
|
@@ -485,6 +491,424 @@ model FrameworkInstance {
|
|
|
485
491
|
}
|
|
486
492
|
|
|
487
493
|
|
|
494
|
+
// ===== integration-platform.prisma =====
|
|
495
|
+
// ===== Integration Platform =====
|
|
496
|
+
// New integration platform models for scalable, config-driven integrations
|
|
497
|
+
|
|
498
|
+
/// Stores metadata about available integration providers (synced from code manifests)
|
|
499
|
+
model IntegrationProvider {
|
|
500
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('prv'::text)"))
|
|
501
|
+
/// Unique slug matching manifest ID (e.g., "github", "slack")
|
|
502
|
+
slug String @unique
|
|
503
|
+
/// Display name
|
|
504
|
+
name String
|
|
505
|
+
/// Category for grouping
|
|
506
|
+
category String
|
|
507
|
+
/// Hash of manifest for detecting changes
|
|
508
|
+
manifestHash String?
|
|
509
|
+
/// Capabilities JSON array
|
|
510
|
+
capabilities Json @default("[]")
|
|
511
|
+
/// Whether provider is active
|
|
512
|
+
isActive Boolean @default(true)
|
|
513
|
+
|
|
514
|
+
createdAt DateTime @default(now())
|
|
515
|
+
updatedAt DateTime @updatedAt
|
|
516
|
+
|
|
517
|
+
connections IntegrationConnection[]
|
|
518
|
+
|
|
519
|
+
@@index([slug])
|
|
520
|
+
@@index([category])
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/// Represents an organization's connection to an integration provider
|
|
524
|
+
model IntegrationConnection {
|
|
525
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('icn'::text)"))
|
|
526
|
+
|
|
527
|
+
/// Reference to the provider
|
|
528
|
+
providerId String
|
|
529
|
+
provider IntegrationProvider @relation(fields: [providerId], references: [id], onDelete: Cascade)
|
|
530
|
+
|
|
531
|
+
/// Organization that owns this connection
|
|
532
|
+
organizationId String
|
|
533
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
534
|
+
|
|
535
|
+
/// Connection status
|
|
536
|
+
status IntegrationConnectionStatus @default(pending)
|
|
537
|
+
|
|
538
|
+
/// Auth strategy used (oauth2, api_key, basic, jwt, custom)
|
|
539
|
+
authStrategy String
|
|
540
|
+
|
|
541
|
+
/// Reference to active credential version
|
|
542
|
+
activeCredentialVersionId String?
|
|
543
|
+
|
|
544
|
+
/// Last successful sync timestamp
|
|
545
|
+
lastSyncAt DateTime?
|
|
546
|
+
|
|
547
|
+
/// Next scheduled sync timestamp
|
|
548
|
+
nextSyncAt DateTime?
|
|
549
|
+
|
|
550
|
+
/// Custom sync cadence (cron expression), null = use default
|
|
551
|
+
syncCadence String?
|
|
552
|
+
|
|
553
|
+
/// Additional metadata (e.g., connected account info)
|
|
554
|
+
metadata Json?
|
|
555
|
+
|
|
556
|
+
/// User-configured variables for checks (collected after OAuth)
|
|
557
|
+
variables Json?
|
|
558
|
+
|
|
559
|
+
/// Error message if status is error
|
|
560
|
+
errorMessage String?
|
|
561
|
+
|
|
562
|
+
createdAt DateTime @default(now())
|
|
563
|
+
updatedAt DateTime @updatedAt
|
|
564
|
+
|
|
565
|
+
credentialVersions IntegrationCredentialVersion[]
|
|
566
|
+
runs IntegrationRun[]
|
|
567
|
+
findings IntegrationPlatformFinding[]
|
|
568
|
+
checkRuns IntegrationCheckRun[]
|
|
569
|
+
|
|
570
|
+
@@unique([providerId, organizationId])
|
|
571
|
+
@@index([organizationId])
|
|
572
|
+
@@index([providerId])
|
|
573
|
+
@@index([status])
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
enum IntegrationConnectionStatus {
|
|
577
|
+
pending // Awaiting credential setup
|
|
578
|
+
active // Connected and operational
|
|
579
|
+
error // Connection has errors
|
|
580
|
+
paused // Manually paused by user
|
|
581
|
+
disconnected // User disconnected
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/// Stores encrypted credentials with versioning for audit trail
|
|
585
|
+
model IntegrationCredentialVersion {
|
|
586
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('icv'::text)"))
|
|
587
|
+
|
|
588
|
+
/// Parent connection
|
|
589
|
+
connectionId String
|
|
590
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
591
|
+
|
|
592
|
+
/// Encrypted credential payload (JSON with encrypted fields)
|
|
593
|
+
encryptedPayload Json
|
|
594
|
+
|
|
595
|
+
/// Version number (auto-increment per connection)
|
|
596
|
+
version Int
|
|
597
|
+
|
|
598
|
+
/// Token expiration (for OAuth tokens)
|
|
599
|
+
expiresAt DateTime?
|
|
600
|
+
|
|
601
|
+
/// When this version was rotated/replaced
|
|
602
|
+
rotatedAt DateTime?
|
|
603
|
+
|
|
604
|
+
createdAt DateTime @default(now())
|
|
605
|
+
|
|
606
|
+
@@unique([connectionId, version])
|
|
607
|
+
@@index([connectionId])
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/// Records each sync/job execution for audit and debugging
|
|
611
|
+
model IntegrationRun {
|
|
612
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('irn'::text)"))
|
|
613
|
+
|
|
614
|
+
/// Parent connection
|
|
615
|
+
connectionId String
|
|
616
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
617
|
+
|
|
618
|
+
/// Type of job
|
|
619
|
+
jobType IntegrationRunJobType
|
|
620
|
+
|
|
621
|
+
/// Execution status
|
|
622
|
+
status IntegrationRunStatus @default(pending)
|
|
623
|
+
|
|
624
|
+
/// Timestamps
|
|
625
|
+
startedAt DateTime?
|
|
626
|
+
completedAt DateTime?
|
|
627
|
+
|
|
628
|
+
/// Duration in milliseconds
|
|
629
|
+
durationMs Int?
|
|
630
|
+
|
|
631
|
+
/// Number of findings from this run
|
|
632
|
+
findingsCount Int @default(0)
|
|
633
|
+
|
|
634
|
+
/// Error details if failed
|
|
635
|
+
error Json?
|
|
636
|
+
|
|
637
|
+
/// Additional metadata (trigger source, cursor, etc.)
|
|
638
|
+
metadata Json?
|
|
639
|
+
|
|
640
|
+
createdAt DateTime @default(now())
|
|
641
|
+
|
|
642
|
+
findings IntegrationPlatformFinding[]
|
|
643
|
+
|
|
644
|
+
@@index([connectionId])
|
|
645
|
+
@@index([status])
|
|
646
|
+
@@index([createdAt])
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
enum IntegrationRunJobType {
|
|
650
|
+
full_sync
|
|
651
|
+
delta_sync
|
|
652
|
+
webhook
|
|
653
|
+
manual
|
|
654
|
+
test_connection
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
enum IntegrationRunStatus {
|
|
658
|
+
pending
|
|
659
|
+
running
|
|
660
|
+
success
|
|
661
|
+
failed
|
|
662
|
+
cancelled
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/// Stores findings/results from integration syncs
|
|
666
|
+
model IntegrationPlatformFinding {
|
|
667
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('ipf'::text)"))
|
|
668
|
+
|
|
669
|
+
/// Parent run (optional - webhooks may not have runs)
|
|
670
|
+
runId String?
|
|
671
|
+
run IntegrationRun? @relation(fields: [runId], references: [id], onDelete: SetNull)
|
|
672
|
+
|
|
673
|
+
/// Parent connection
|
|
674
|
+
connectionId String
|
|
675
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
676
|
+
|
|
677
|
+
/// Resource classification
|
|
678
|
+
resourceType String
|
|
679
|
+
resourceId String
|
|
680
|
+
|
|
681
|
+
/// Finding details
|
|
682
|
+
title String
|
|
683
|
+
description String?
|
|
684
|
+
|
|
685
|
+
/// Severity level
|
|
686
|
+
severity IntegrationFindingSeverity @default(info)
|
|
687
|
+
|
|
688
|
+
/// Finding status
|
|
689
|
+
status IntegrationFindingStatus @default(open)
|
|
690
|
+
|
|
691
|
+
/// Remediation guidance
|
|
692
|
+
remediation String?
|
|
693
|
+
|
|
694
|
+
/// Raw payload from provider
|
|
695
|
+
rawPayload Json?
|
|
696
|
+
|
|
697
|
+
createdAt DateTime @default(now())
|
|
698
|
+
updatedAt DateTime @updatedAt
|
|
699
|
+
|
|
700
|
+
@@index([connectionId])
|
|
701
|
+
@@index([runId])
|
|
702
|
+
@@index([resourceType, resourceId])
|
|
703
|
+
@@index([severity])
|
|
704
|
+
@@index([status])
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
enum IntegrationFindingSeverity {
|
|
708
|
+
info
|
|
709
|
+
low
|
|
710
|
+
medium
|
|
711
|
+
high
|
|
712
|
+
critical
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
enum IntegrationFindingStatus {
|
|
716
|
+
open
|
|
717
|
+
resolved
|
|
718
|
+
ignored
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/// Stores OAuth state for CSRF protection during OAuth flow
|
|
722
|
+
model IntegrationOAuthState {
|
|
723
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('ios'::text)"))
|
|
724
|
+
|
|
725
|
+
/// Random state parameter
|
|
726
|
+
state String @unique
|
|
727
|
+
|
|
728
|
+
/// Provider slug
|
|
729
|
+
providerSlug String
|
|
730
|
+
|
|
731
|
+
/// Organization initiating the OAuth
|
|
732
|
+
organizationId String
|
|
733
|
+
|
|
734
|
+
/// User initiating the OAuth
|
|
735
|
+
userId String
|
|
736
|
+
|
|
737
|
+
/// PKCE code verifier (if using PKCE)
|
|
738
|
+
codeVerifier String?
|
|
739
|
+
|
|
740
|
+
/// Redirect URL after OAuth completes
|
|
741
|
+
redirectUrl String?
|
|
742
|
+
|
|
743
|
+
/// Expiration timestamp
|
|
744
|
+
expiresAt DateTime
|
|
745
|
+
|
|
746
|
+
createdAt DateTime @default(now())
|
|
747
|
+
|
|
748
|
+
@@index([state])
|
|
749
|
+
@@index([expiresAt])
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/// Stores organization-level OAuth app credentials
|
|
753
|
+
/// Allows orgs (especially self-hosters) to use their own OAuth apps
|
|
754
|
+
model IntegrationOAuthApp {
|
|
755
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('ioa'::text)"))
|
|
756
|
+
|
|
757
|
+
/// Provider slug (e.g., "github", "slack")
|
|
758
|
+
providerSlug String
|
|
759
|
+
|
|
760
|
+
/// Organization that owns this OAuth app config
|
|
761
|
+
organizationId String
|
|
762
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
763
|
+
|
|
764
|
+
/// Encrypted client ID
|
|
765
|
+
encryptedClientId Json
|
|
766
|
+
|
|
767
|
+
/// Encrypted client secret
|
|
768
|
+
encryptedClientSecret Json
|
|
769
|
+
|
|
770
|
+
/// Optional: custom scopes (overrides manifest defaults)
|
|
771
|
+
customScopes String[]
|
|
772
|
+
|
|
773
|
+
/// Provider-specific settings (e.g., Rippling app name for authorize URL)
|
|
774
|
+
/// Stored as JSON: { "appName": "compai533c" }
|
|
775
|
+
customSettings Json?
|
|
776
|
+
|
|
777
|
+
/// Whether this config is active
|
|
778
|
+
isActive Boolean @default(true)
|
|
779
|
+
|
|
780
|
+
createdAt DateTime @default(now())
|
|
781
|
+
updatedAt DateTime @updatedAt
|
|
782
|
+
|
|
783
|
+
@@unique([providerSlug, organizationId])
|
|
784
|
+
@@index([organizationId])
|
|
785
|
+
@@index([providerSlug])
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
/// Records check runs linked to tasks for compliance verification
|
|
789
|
+
model IntegrationCheckRun {
|
|
790
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('icr'::text)"))
|
|
791
|
+
|
|
792
|
+
/// Parent connection
|
|
793
|
+
connectionId String
|
|
794
|
+
connection IntegrationConnection @relation(fields: [connectionId], references: [id], onDelete: Cascade)
|
|
795
|
+
|
|
796
|
+
/// Task being verified (optional - checks can run without a task)
|
|
797
|
+
taskId String?
|
|
798
|
+
task Task? @relation(fields: [taskId], references: [id], onDelete: SetNull)
|
|
799
|
+
|
|
800
|
+
/// Check ID from the manifest
|
|
801
|
+
checkId String
|
|
802
|
+
|
|
803
|
+
/// Check name (denormalized for display)
|
|
804
|
+
checkName String
|
|
805
|
+
|
|
806
|
+
/// Execution status
|
|
807
|
+
status IntegrationRunStatus @default(pending)
|
|
808
|
+
|
|
809
|
+
/// Timestamps
|
|
810
|
+
startedAt DateTime?
|
|
811
|
+
completedAt DateTime?
|
|
812
|
+
|
|
813
|
+
/// Duration in milliseconds
|
|
814
|
+
durationMs Int?
|
|
815
|
+
|
|
816
|
+
/// Summary counts
|
|
817
|
+
totalChecked Int @default(0)
|
|
818
|
+
passedCount Int @default(0)
|
|
819
|
+
failedCount Int @default(0)
|
|
820
|
+
|
|
821
|
+
/// Error message if failed
|
|
822
|
+
errorMessage String?
|
|
823
|
+
|
|
824
|
+
/// Full execution logs (JSON array)
|
|
825
|
+
logs Json?
|
|
826
|
+
|
|
827
|
+
createdAt DateTime @default(now())
|
|
828
|
+
|
|
829
|
+
/// Results from this check run
|
|
830
|
+
results IntegrationCheckResult[]
|
|
831
|
+
|
|
832
|
+
@@index([connectionId])
|
|
833
|
+
@@index([taskId])
|
|
834
|
+
@@index([checkId])
|
|
835
|
+
@@index([status])
|
|
836
|
+
@@index([createdAt])
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/// Stores individual results (pass/fail) from check runs
|
|
840
|
+
model IntegrationCheckResult {
|
|
841
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('icx'::text)"))
|
|
842
|
+
|
|
843
|
+
/// Parent check run
|
|
844
|
+
checkRunId String
|
|
845
|
+
checkRun IntegrationCheckRun @relation(fields: [checkRunId], references: [id], onDelete: Cascade)
|
|
846
|
+
|
|
847
|
+
/// Whether this result is a pass or fail
|
|
848
|
+
passed Boolean
|
|
849
|
+
|
|
850
|
+
/// Resource classification
|
|
851
|
+
resourceType String
|
|
852
|
+
resourceId String
|
|
853
|
+
|
|
854
|
+
/// Result details
|
|
855
|
+
title String
|
|
856
|
+
description String?
|
|
857
|
+
|
|
858
|
+
/// Severity (for failures)
|
|
859
|
+
severity IntegrationFindingSeverity?
|
|
860
|
+
|
|
861
|
+
/// Remediation guidance (for failures)
|
|
862
|
+
remediation String?
|
|
863
|
+
|
|
864
|
+
/// Evidence/proof (JSON - API response data)
|
|
865
|
+
evidence Json?
|
|
866
|
+
|
|
867
|
+
/// When this evidence was collected
|
|
868
|
+
collectedAt DateTime @default(now())
|
|
869
|
+
|
|
870
|
+
@@index([checkRunId])
|
|
871
|
+
@@index([passed])
|
|
872
|
+
@@index([resourceType, resourceId])
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/// Stores platform-wide OAuth app credentials
|
|
876
|
+
/// Used by platform operators to provide default OAuth apps for all users
|
|
877
|
+
model IntegrationPlatformCredential {
|
|
878
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('ipc'::text)"))
|
|
879
|
+
|
|
880
|
+
/// Provider slug (e.g., "github", "slack") - unique per platform
|
|
881
|
+
providerSlug String @unique
|
|
882
|
+
|
|
883
|
+
/// Encrypted client ID
|
|
884
|
+
encryptedClientId Json
|
|
885
|
+
|
|
886
|
+
/// Encrypted client secret
|
|
887
|
+
encryptedClientSecret Json
|
|
888
|
+
|
|
889
|
+
/// Optional: custom scopes (overrides manifest defaults)
|
|
890
|
+
customScopes String[]
|
|
891
|
+
|
|
892
|
+
/// Provider-specific settings (e.g., Rippling app name for authorize URL)
|
|
893
|
+
/// Stored as JSON: { "appName": "compai533c" }
|
|
894
|
+
customSettings Json?
|
|
895
|
+
|
|
896
|
+
/// Whether this credential is active
|
|
897
|
+
isActive Boolean @default(true)
|
|
898
|
+
|
|
899
|
+
/// Who created this credential
|
|
900
|
+
createdById String?
|
|
901
|
+
|
|
902
|
+
/// Who last updated this credential
|
|
903
|
+
updatedById String?
|
|
904
|
+
|
|
905
|
+
createdAt DateTime @default(now())
|
|
906
|
+
updatedAt DateTime @updatedAt
|
|
907
|
+
|
|
908
|
+
@@index([providerSlug])
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
|
|
488
912
|
// ===== integration.prisma =====
|
|
489
913
|
model Integration {
|
|
490
914
|
id String @id @default(dbgenerated("generate_prefixed_cuid('int'::text)"))
|
|
@@ -522,15 +946,15 @@ model IntegrationResult {
|
|
|
522
946
|
|
|
523
947
|
// ===== knowledge-base-document.prisma =====
|
|
524
948
|
model KnowledgeBaseDocument {
|
|
525
|
-
id
|
|
526
|
-
name
|
|
527
|
-
description
|
|
528
|
-
s3Key
|
|
529
|
-
fileType
|
|
530
|
-
fileSize
|
|
949
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('kbd'::text)"))
|
|
950
|
+
name String // Original filename
|
|
951
|
+
description String? // Optional user description/notes
|
|
952
|
+
s3Key String // S3 storage key (e.g., "org123/knowledge-base-documents/timestamp-file.pdf")
|
|
953
|
+
fileType String // MIME type (e.g., "application/pdf")
|
|
954
|
+
fileSize Int // File size in bytes
|
|
531
955
|
processingStatus KnowledgeBaseDocumentProcessingStatus @default(pending) // Track indexing status
|
|
532
|
-
processedAt
|
|
533
|
-
triggerRunId
|
|
956
|
+
processedAt DateTime? // When indexing completed
|
|
957
|
+
triggerRunId String? // Trigger.dev run ID for tracking processing progress
|
|
534
958
|
|
|
535
959
|
// Dates
|
|
536
960
|
createdAt DateTime @default(now())
|
|
@@ -547,14 +971,13 @@ model KnowledgeBaseDocument {
|
|
|
547
971
|
}
|
|
548
972
|
|
|
549
973
|
enum KnowledgeBaseDocumentProcessingStatus {
|
|
550
|
-
pending
|
|
551
|
-
processing
|
|
552
|
-
completed
|
|
553
|
-
failed
|
|
974
|
+
pending // Uploaded but not yet processed/indexed
|
|
975
|
+
processing // Currently being processed/indexed
|
|
976
|
+
completed // Successfully indexed in vector database
|
|
977
|
+
failed // Processing failed
|
|
554
978
|
}
|
|
555
979
|
|
|
556
980
|
|
|
557
|
-
|
|
558
981
|
// ===== onboarding.prisma =====
|
|
559
982
|
model Onboarding {
|
|
560
983
|
organizationId String @id
|
|
@@ -594,28 +1017,39 @@ model Organization {
|
|
|
594
1017
|
fleetDmLabelId Int?
|
|
595
1018
|
isFleetSetupCompleted Boolean @default(false)
|
|
596
1019
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
1020
|
+
// Employee sync provider (e.g., 'google-workspace', 'rippling')
|
|
1021
|
+
// When set, the scheduled sync will only use this provider
|
|
1022
|
+
employeeSyncProvider String?
|
|
1023
|
+
|
|
1024
|
+
apiKeys ApiKey[]
|
|
1025
|
+
auditLog AuditLog[]
|
|
1026
|
+
controls Control[]
|
|
1027
|
+
frameworkInstances FrameworkInstance[]
|
|
1028
|
+
integrations Integration[]
|
|
1029
|
+
invitations Invitation[]
|
|
1030
|
+
members Member[]
|
|
1031
|
+
policy Policy[]
|
|
1032
|
+
risk Risk[]
|
|
1033
|
+
vendors Vendor[]
|
|
1034
|
+
tasks Task[]
|
|
1035
|
+
comments Comment[]
|
|
1036
|
+
attachments Attachment[]
|
|
1037
|
+
trust Trust[]
|
|
1038
|
+
context Context[]
|
|
1039
|
+
secrets Secret[]
|
|
1040
|
+
trustAccessRequests TrustAccessRequest[]
|
|
1041
|
+
trustNdaAgreements TrustNDAAgreement[]
|
|
1042
|
+
trustDocuments TrustDocument[]
|
|
1043
|
+
trustResources TrustResource[] @relation("OrganizationTrustResources")
|
|
1044
|
+
knowledgeBaseDocuments KnowledgeBaseDocument[]
|
|
1045
|
+
questionnaires Questionnaire[]
|
|
618
1046
|
securityQuestionnaireManualAnswers SecurityQuestionnaireManualAnswer[]
|
|
1047
|
+
soaDocuments SOADocument[]
|
|
1048
|
+
primaryColor String?
|
|
1049
|
+
|
|
1050
|
+
// Integration Platform
|
|
1051
|
+
integrationConnections IntegrationConnection[]
|
|
1052
|
+
integrationOAuthApps IntegrationOAuthApp[]
|
|
619
1053
|
|
|
620
1054
|
@@index([slug])
|
|
621
1055
|
}
|
|
@@ -665,15 +1099,16 @@ model Policy {
|
|
|
665
1099
|
|
|
666
1100
|
// ===== questionnaire.prisma =====
|
|
667
1101
|
model Questionnaire {
|
|
668
|
-
id
|
|
669
|
-
filename
|
|
670
|
-
s3Key
|
|
671
|
-
fileType
|
|
672
|
-
fileSize
|
|
673
|
-
status
|
|
674
|
-
parsedAt
|
|
675
|
-
totalQuestions
|
|
676
|
-
answeredQuestions Int
|
|
1102
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('qst'::text)"))
|
|
1103
|
+
filename String // Original filename
|
|
1104
|
+
s3Key String // S3 storage key for the uploaded file
|
|
1105
|
+
fileType String // MIME type (e.g., "application/pdf")
|
|
1106
|
+
fileSize Int // File size in bytes
|
|
1107
|
+
status QuestionnaireStatus @default(parsing) // Parsing status
|
|
1108
|
+
parsedAt DateTime? // When parsing completed
|
|
1109
|
+
totalQuestions Int @default(0) // Total number of questions parsed
|
|
1110
|
+
answeredQuestions Int @default(0) // Number of questions with answers
|
|
1111
|
+
source String @default("internal") // Source of the questionnaire: 'internal' (from app) or 'external' (from trust portal)
|
|
677
1112
|
|
|
678
1113
|
// Dates
|
|
679
1114
|
createdAt DateTime @default(now())
|
|
@@ -681,24 +1116,25 @@ model Questionnaire {
|
|
|
681
1116
|
|
|
682
1117
|
// Relationships
|
|
683
1118
|
organizationId String
|
|
684
|
-
organization Organization
|
|
1119
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
685
1120
|
questions QuestionnaireQuestionAnswer[]
|
|
686
1121
|
manualAnswers SecurityQuestionnaireManualAnswer[] // Manual answers saved from this questionnaire
|
|
687
1122
|
|
|
688
1123
|
@@index([organizationId])
|
|
689
1124
|
@@index([organizationId, createdAt])
|
|
690
1125
|
@@index([status])
|
|
1126
|
+
@@index([source])
|
|
691
1127
|
}
|
|
692
1128
|
|
|
693
1129
|
model QuestionnaireQuestionAnswer {
|
|
694
|
-
id
|
|
695
|
-
question
|
|
696
|
-
answer
|
|
697
|
-
status
|
|
698
|
-
questionIndex
|
|
699
|
-
sources
|
|
700
|
-
generatedAt
|
|
701
|
-
updatedBy
|
|
1130
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('qqa'::text)"))
|
|
1131
|
+
question String // The question text
|
|
1132
|
+
answer String? // The answer (nullable if not provided in file or not generated yet)
|
|
1133
|
+
status QuestionnaireAnswerStatus @default(untouched) // Answer status
|
|
1134
|
+
questionIndex Int // Order/index of the question in the questionnaire
|
|
1135
|
+
sources Json? // Sources used for generated answers (array of source objects)
|
|
1136
|
+
generatedAt DateTime? // When answer was generated (if status is generated)
|
|
1137
|
+
updatedBy String? // User ID who last updated the answer (if manual)
|
|
702
1138
|
|
|
703
1139
|
// Dates
|
|
704
1140
|
createdAt DateTime @default(now())
|
|
@@ -714,19 +1150,18 @@ model QuestionnaireQuestionAnswer {
|
|
|
714
1150
|
}
|
|
715
1151
|
|
|
716
1152
|
enum QuestionnaireStatus {
|
|
717
|
-
parsing
|
|
718
|
-
completed
|
|
719
|
-
failed
|
|
1153
|
+
parsing // Currently being parsed
|
|
1154
|
+
completed // Successfully parsed
|
|
1155
|
+
failed // Parsing failed
|
|
720
1156
|
}
|
|
721
1157
|
|
|
722
1158
|
enum QuestionnaireAnswerStatus {
|
|
723
|
-
untouched
|
|
724
|
-
generated
|
|
725
|
-
manual
|
|
1159
|
+
untouched // No answer yet (empty or not generated)
|
|
1160
|
+
generated // AI generated answer
|
|
1161
|
+
manual // Manually written/edited by user
|
|
726
1162
|
}
|
|
727
1163
|
|
|
728
1164
|
|
|
729
|
-
|
|
730
1165
|
// ===== requirement.prisma =====
|
|
731
1166
|
model RequirementMap {
|
|
732
1167
|
id String @id @default(dbgenerated("generate_prefixed_cuid('req'::text)"))
|
|
@@ -827,36 +1262,35 @@ model Secret {
|
|
|
827
1262
|
|
|
828
1263
|
// ===== security-questionnaire-manual-answer.prisma =====
|
|
829
1264
|
model SecurityQuestionnaireManualAnswer {
|
|
830
|
-
id
|
|
831
|
-
question
|
|
832
|
-
answer
|
|
833
|
-
tags
|
|
834
|
-
|
|
1265
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('sqma'::text)"))
|
|
1266
|
+
question String // The question text
|
|
1267
|
+
answer String // The answer text (required for saved answers)
|
|
1268
|
+
tags String[] @default([]) // Optional tags for categorization
|
|
1269
|
+
|
|
835
1270
|
// Optional reference to original questionnaire (for tracking)
|
|
836
1271
|
sourceQuestionnaireId String?
|
|
837
1272
|
sourceQuestionnaire Questionnaire? @relation(fields: [sourceQuestionnaireId], references: [id], onDelete: SetNull)
|
|
838
|
-
|
|
1273
|
+
|
|
839
1274
|
// User who created/updated this answer
|
|
840
|
-
createdBy
|
|
841
|
-
updatedBy
|
|
842
|
-
|
|
1275
|
+
createdBy String? // User ID
|
|
1276
|
+
updatedBy String? // User ID
|
|
1277
|
+
|
|
843
1278
|
// Dates
|
|
844
1279
|
createdAt DateTime @default(now())
|
|
845
1280
|
updatedAt DateTime @updatedAt
|
|
846
|
-
|
|
1281
|
+
|
|
847
1282
|
// Relationships
|
|
848
1283
|
organizationId String
|
|
849
1284
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
850
|
-
|
|
1285
|
+
|
|
1286
|
+
@@unique([organizationId, question]) // Prevent duplicate questions per organization
|
|
851
1287
|
@@index([organizationId])
|
|
852
1288
|
@@index([organizationId, question])
|
|
853
1289
|
@@index([tags])
|
|
854
1290
|
@@index([createdAt])
|
|
855
|
-
@@unique([organizationId, question]) // Prevent duplicate questions per organization
|
|
856
1291
|
}
|
|
857
1292
|
|
|
858
1293
|
|
|
859
|
-
|
|
860
1294
|
// ===== shared.prisma =====
|
|
861
1295
|
model ApiKey {
|
|
862
1296
|
id String @id @default(dbgenerated("generate_prefixed_cuid('apk'::text)"))
|
|
@@ -965,6 +1399,143 @@ enum Impact {
|
|
|
965
1399
|
}
|
|
966
1400
|
|
|
967
1401
|
|
|
1402
|
+
// ===== soa.prisma =====
|
|
1403
|
+
// Statement of Applicability (SOA) Auto-complete Configuration and Answers
|
|
1404
|
+
|
|
1405
|
+
model SOAFrameworkConfiguration {
|
|
1406
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('soa_cfg'::text)"))
|
|
1407
|
+
frameworkId String
|
|
1408
|
+
framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id], onDelete: Cascade)
|
|
1409
|
+
|
|
1410
|
+
// Configuration versioning - allows multiple configurations per framework
|
|
1411
|
+
version Int @default(1) // Version number for this configuration (increments when config changes)
|
|
1412
|
+
isLatest Boolean @default(true) // Whether this is the latest configuration version
|
|
1413
|
+
|
|
1414
|
+
// Column definitions for SOA structure (template used when creating new documents)
|
|
1415
|
+
columns Json // Array of { name: string, type: string } objects
|
|
1416
|
+
// Example: [{ name: "Control ID", type: "string" }, { name: "Control Name", type: "string" }, { name: "Applicable", type: "boolean" }, { name: "Justification", type: "text" }]
|
|
1417
|
+
|
|
1418
|
+
// Predefined questions for this framework
|
|
1419
|
+
// Documents reference a specific configuration version via SOADocument.configurationId
|
|
1420
|
+
// Old documents keep their old config version, new documents use new config version
|
|
1421
|
+
questions Json // Array of question objects with unique IDs
|
|
1422
|
+
// Example: [{ id: "A.5.1.1", text: "Is this control applicable?", columnMapping: "Applicable", controlId: "A.5.1.1" }, ...]
|
|
1423
|
+
// IMPORTANT: question.id must be unique and stable - this is what SOAAnswer.questionId references
|
|
1424
|
+
|
|
1425
|
+
// Dates
|
|
1426
|
+
createdAt DateTime @default(now())
|
|
1427
|
+
updatedAt DateTime @updatedAt
|
|
1428
|
+
|
|
1429
|
+
// Relationships
|
|
1430
|
+
documents SOADocument[]
|
|
1431
|
+
|
|
1432
|
+
@@unique([frameworkId, version]) // Prevent duplicate configuration versions
|
|
1433
|
+
@@index([frameworkId])
|
|
1434
|
+
@@index([frameworkId, version])
|
|
1435
|
+
@@index([frameworkId, isLatest])
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
model SOADocument {
|
|
1439
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('soa_doc'::text)"))
|
|
1440
|
+
|
|
1441
|
+
// Framework and organization context
|
|
1442
|
+
frameworkId String
|
|
1443
|
+
framework FrameworkEditorFramework @relation(fields: [frameworkId], references: [id], onDelete: Cascade)
|
|
1444
|
+
organizationId String
|
|
1445
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
1446
|
+
|
|
1447
|
+
// Configuration reference - references a specific SOAFrameworkConfiguration version
|
|
1448
|
+
// Each document version can use a different configuration version
|
|
1449
|
+
// Old documents keep their old config, new documents use new config
|
|
1450
|
+
configurationId String
|
|
1451
|
+
configuration SOAFrameworkConfiguration @relation(fields: [configurationId], references: [id], onDelete: Cascade)
|
|
1452
|
+
|
|
1453
|
+
// Document versioning
|
|
1454
|
+
version Int @default(1) // Version number for this document (increments yearly)
|
|
1455
|
+
isLatest Boolean @default(true) // Whether this is the latest version
|
|
1456
|
+
|
|
1457
|
+
// Document status
|
|
1458
|
+
status SOADocumentStatus @default(draft) // draft, in_progress, completed
|
|
1459
|
+
|
|
1460
|
+
// Document metadata
|
|
1461
|
+
totalQuestions Int @default(0) // Total number of questions in this document
|
|
1462
|
+
answeredQuestions Int @default(0) // Number of questions with answers
|
|
1463
|
+
|
|
1464
|
+
// Approval tracking
|
|
1465
|
+
preparedBy String @default("Comp AI") // Always "Comp AI"
|
|
1466
|
+
approverId String? // Member ID who will approve this document (set when submitted for approval)
|
|
1467
|
+
approver Member? @relation("SOADocumentApprover", fields: [approverId], references: [id], onDelete: SetNull, onUpdate: Cascade)
|
|
1468
|
+
approvedAt DateTime? // When document was approved
|
|
1469
|
+
|
|
1470
|
+
// Dates
|
|
1471
|
+
completedAt DateTime? // When document was completed
|
|
1472
|
+
createdAt DateTime @default(now())
|
|
1473
|
+
updatedAt DateTime @updatedAt
|
|
1474
|
+
|
|
1475
|
+
// Relationships
|
|
1476
|
+
answers SOAAnswer[]
|
|
1477
|
+
|
|
1478
|
+
@@unique([frameworkId, organizationId, version]) // Prevent duplicate versions
|
|
1479
|
+
@@index([frameworkId, organizationId])
|
|
1480
|
+
@@index([frameworkId, organizationId, version])
|
|
1481
|
+
@@index([frameworkId, organizationId, isLatest])
|
|
1482
|
+
@@index([configurationId])
|
|
1483
|
+
@@index([status])
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
model SOAAnswer {
|
|
1487
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('soa_ans'::text)"))
|
|
1488
|
+
|
|
1489
|
+
// Document context (replaces direct framework/organization link)
|
|
1490
|
+
documentId String
|
|
1491
|
+
document SOADocument @relation(fields: [documentId], references: [id], onDelete: Cascade)
|
|
1492
|
+
|
|
1493
|
+
// Question reference - references question.id from SOADocument.configuration.questions
|
|
1494
|
+
// References the specific configuration version that the document uses
|
|
1495
|
+
// If config changes, old documents still reference their old config version
|
|
1496
|
+
questionId String // Must match a question.id from SOADocument.configuration.questions
|
|
1497
|
+
|
|
1498
|
+
// Answer data - simple text answer
|
|
1499
|
+
answer String? // Text answer (nullable if not generated yet)
|
|
1500
|
+
|
|
1501
|
+
// Answer metadata
|
|
1502
|
+
status SOAAnswerStatus @default(untouched) // untouched, generated, manual
|
|
1503
|
+
sources Json? // Sources used for generated answers (similar to questionnaire)
|
|
1504
|
+
generatedAt DateTime? // When answer was generated
|
|
1505
|
+
|
|
1506
|
+
// Answer versioning (within the document)
|
|
1507
|
+
answerVersion Int @default(1) // Version number for this specific answer
|
|
1508
|
+
isLatestAnswer Boolean @default(true) // Whether this is the latest version of this answer
|
|
1509
|
+
|
|
1510
|
+
// User tracking
|
|
1511
|
+
createdBy String? // User ID who created this answer
|
|
1512
|
+
updatedBy String? // User ID who last updated this answer
|
|
1513
|
+
|
|
1514
|
+
// Dates
|
|
1515
|
+
createdAt DateTime @default(now())
|
|
1516
|
+
updatedAt DateTime @updatedAt
|
|
1517
|
+
|
|
1518
|
+
@@unique([documentId, questionId, answerVersion]) // Prevent duplicate answer versions
|
|
1519
|
+
@@index([documentId])
|
|
1520
|
+
@@index([documentId, questionId])
|
|
1521
|
+
@@index([documentId, questionId, isLatestAnswer])
|
|
1522
|
+
@@index([status])
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
enum SOADocumentStatus {
|
|
1526
|
+
draft // Document is being created/edited
|
|
1527
|
+
in_progress // Document is being generated
|
|
1528
|
+
needs_review // Document is submitted for approval
|
|
1529
|
+
completed // Document is complete and approved
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
enum SOAAnswerStatus {
|
|
1533
|
+
untouched // No answer yet (not generated)
|
|
1534
|
+
generated // AI generated answer
|
|
1535
|
+
manual // Manually written/edited by user
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
|
|
968
1539
|
// ===== task.prisma =====
|
|
969
1540
|
model Task {
|
|
970
1541
|
// Metadata
|
|
@@ -994,7 +1565,8 @@ model Task {
|
|
|
994
1565
|
risks Risk[]
|
|
995
1566
|
evidenceAutomations EvidenceAutomation[]
|
|
996
1567
|
|
|
997
|
-
EvidenceAutomationRun
|
|
1568
|
+
EvidenceAutomationRun EvidenceAutomationRun[]
|
|
1569
|
+
integrationCheckRuns IntegrationCheckRun[]
|
|
998
1570
|
}
|
|
999
1571
|
|
|
1000
1572
|
enum TaskStatus {
|
|
@@ -1067,6 +1639,33 @@ enum FrameworkStatus {
|
|
|
1067
1639
|
compliant
|
|
1068
1640
|
}
|
|
1069
1641
|
|
|
1642
|
+
enum TrustFramework {
|
|
1643
|
+
iso_27001
|
|
1644
|
+
iso_42001
|
|
1645
|
+
gdpr
|
|
1646
|
+
hipaa
|
|
1647
|
+
soc2_type1
|
|
1648
|
+
soc2_type2
|
|
1649
|
+
pci_dss
|
|
1650
|
+
nen_7510
|
|
1651
|
+
iso_9001
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
model TrustResource {
|
|
1655
|
+
id String @id @default(dbgenerated("generate_prefixed_cuid('tcr'::text)"))
|
|
1656
|
+
organizationId String
|
|
1657
|
+
organization Organization @relation("OrganizationTrustResources", fields: [organizationId], references: [id], onDelete: Cascade)
|
|
1658
|
+
framework TrustFramework
|
|
1659
|
+
s3Key String
|
|
1660
|
+
fileName String
|
|
1661
|
+
fileSize Int
|
|
1662
|
+
createdAt DateTime @default(now())
|
|
1663
|
+
updatedAt DateTime @updatedAt
|
|
1664
|
+
|
|
1665
|
+
@@unique([organizationId, framework])
|
|
1666
|
+
@@index([organizationId])
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1070
1669
|
model TrustAccessRequest {
|
|
1071
1670
|
id String @id @default(dbgenerated("generate_prefixed_cuid('tar'::text)"))
|
|
1072
1671
|
organizationId String
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trycompai/db",
|
|
3
3
|
"description": "Database package with Prisma client and schema for Comp AI",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.19",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@prisma/client": "^6.13.0",
|
|
7
7
|
"dotenv": "^16.4.5",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"check-types": "tsc --noEmit",
|
|
39
39
|
"db:generate": "prisma generate",
|
|
40
40
|
"db:migrate": "prisma migrate dev",
|
|
41
|
+
"db:migrate:reset": "prisma migrate reset",
|
|
41
42
|
"db:push": "prisma db push",
|
|
42
43
|
"db:seed": "bun prisma/seed/seed.ts",
|
|
43
44
|
"db:studio": "prisma studio",
|