@trycompai/db 1.3.19-canary.3 → 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.
@@ -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,gIAA+C,CAAC"}
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 || new client_1.PrismaClient();
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;
File without changes
@@ -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
 
@@ -63,6 +62,7 @@ model User {
63
62
  lastLogin DateTime?
64
63
  emailNotificationsUnsubscribed Boolean @default(false)
65
64
  emailPreferences Json? @default("{\"policyNotifications\":true,\"taskReminders\":true,\"weeklyTaskDigest\":true,\"unassignedItemsNotifications\":true}")
65
+ isPlatformAdmin Boolean @default(false)
66
66
 
67
67
  accounts Account[]
68
68
  auditLog AuditLog[]
@@ -491,6 +491,424 @@ model FrameworkInstance {
491
491
  }
492
492
 
493
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
+
494
912
  // ===== integration.prisma =====
495
913
  model Integration {
496
914
  id String @id @default(dbgenerated("generate_prefixed_cuid('int'::text)"))
@@ -599,6 +1017,10 @@ model Organization {
599
1017
  fleetDmLabelId Int?
600
1018
  isFleetSetupCompleted Boolean @default(false)
601
1019
 
1020
+ // Employee sync provider (e.g., 'google-workspace', 'rippling')
1021
+ // When set, the scheduled sync will only use this provider
1022
+ employeeSyncProvider String?
1023
+
602
1024
  apiKeys ApiKey[]
603
1025
  auditLog AuditLog[]
604
1026
  controls Control[]
@@ -624,6 +1046,11 @@ model Organization {
624
1046
  securityQuestionnaireManualAnswers SecurityQuestionnaireManualAnswer[]
625
1047
  soaDocuments SOADocument[]
626
1048
  primaryColor String?
1049
+
1050
+ // Integration Platform
1051
+ integrationConnections IntegrationConnection[]
1052
+ integrationOAuthApps IntegrationOAuthApp[]
1053
+
627
1054
  @@index([slug])
628
1055
  }
629
1056
 
@@ -681,6 +1108,7 @@ model Questionnaire {
681
1108
  parsedAt DateTime? // When parsing completed
682
1109
  totalQuestions Int @default(0) // Total number of questions parsed
683
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)
684
1112
 
685
1113
  // Dates
686
1114
  createdAt DateTime @default(now())
@@ -695,6 +1123,7 @@ model Questionnaire {
695
1123
  @@index([organizationId])
696
1124
  @@index([organizationId, createdAt])
697
1125
  @@index([status])
1126
+ @@index([source])
698
1127
  }
699
1128
 
700
1129
  model QuestionnaireQuestionAnswer {
@@ -1136,7 +1565,8 @@ model Task {
1136
1565
  risks Risk[]
1137
1566
  evidenceAutomations EvidenceAutomation[]
1138
1567
 
1139
- EvidenceAutomationRun EvidenceAutomationRun[]
1568
+ EvidenceAutomationRun EvidenceAutomationRun[]
1569
+ integrationCheckRuns IntegrationCheckRun[]
1140
1570
  }
1141
1571
 
1142
1572
  enum TaskStatus {
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.19-canary.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",