@trycompai/db 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/schema.prisma +300 -34
  2. package/package.json +1 -1
@@ -38,6 +38,7 @@ enum AttachmentEntityType {
38
38
  comment
39
39
  trust_nda
40
40
  task_item
41
+ background_check
41
42
  }
42
43
 
43
44
  enum AttachmentType {
@@ -169,6 +170,7 @@ model Member {
169
170
  jobTitle String?
170
171
  isActive Boolean @default(true)
171
172
  deactivated Boolean @default(false)
173
+ backgroundCheckExempt Boolean @default(false)
172
174
  externalUserId String?
173
175
  externalUserSource String?
174
176
  employeeTrainingVideoCompletion EmployeeTrainingVideoCompletion[]
@@ -194,6 +196,7 @@ model Member {
194
196
  performedFrameworkSyncOperations FrameworkSyncOperation[] @relation("FrameworkSyncOperationPerformer")
195
197
  approvedTasks Task[] @relation("TaskApprover")
196
198
  devices Device[]
199
+ backgroundCheckRequests BackgroundCheckRequest[]
197
200
  }
198
201
 
199
202
  model Invitation {
@@ -343,6 +346,71 @@ model EvidenceAutomation {
343
346
  @@index([taskId])
344
347
  }
345
348
 
349
+ // ===== background-check.prisma =====
350
+ model BackgroundCheckRequest {
351
+ id String @id @default(dbgenerated("generate_prefixed_cuid('bcr'::text)"))
352
+ organizationId String
353
+ memberId String
354
+ employeeEmail String
355
+ employeeName String
356
+ requesterNotes String?
357
+ identityBackgroundCheckId String? @unique
358
+ candidateUrl String?
359
+ status BackgroundCheckStatus @default(invited)
360
+ identityStatus String?
361
+ employmentStatus String?
362
+ referenceStatus String?
363
+ rightToWorkStatus String?
364
+ adjudicationStatus String?
365
+ stripePaymentIntentId String?
366
+ stripePaymentStatus String?
367
+ stripeRefundId String?
368
+ stripeAmountCents Int?
369
+ stripeCurrency String?
370
+ lastWebhookEventId String?
371
+ lastSyncedAt DateTime?
372
+ reportSnapshot Json?
373
+ reportSyncedAt DateTime?
374
+ createdAt DateTime @default(now())
375
+ updatedAt DateTime @updatedAt
376
+
377
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
378
+ member Member @relation(fields: [memberId], references: [id], onDelete: Cascade)
379
+ webhookEvents BackgroundCheckWebhookEvent[]
380
+
381
+ @@unique([organizationId, memberId])
382
+ @@index([organizationId])
383
+ @@index([memberId])
384
+ @@index([status])
385
+ @@map("background_check_requests")
386
+ }
387
+
388
+ model BackgroundCheckWebhookEvent {
389
+ id String @id @default(dbgenerated("generate_prefixed_cuid('bcw'::text)"))
390
+ eventId String @unique
391
+ eventType String
392
+ backgroundCheckRequestId String?
393
+ identityBackgroundCheckId String?
394
+ payload Json
395
+ processedAt DateTime @default(now())
396
+
397
+ backgroundCheckRequest BackgroundCheckRequest? @relation(fields: [backgroundCheckRequestId], references: [id], onDelete: SetNull)
398
+
399
+ @@index([backgroundCheckRequestId])
400
+ @@index([identityBackgroundCheckId])
401
+ @@map("background_check_webhook_events")
402
+ }
403
+
404
+ enum BackgroundCheckStatus {
405
+ invited
406
+ in_progress
407
+ in_review
408
+ completed
409
+ completed_with_flags
410
+ failed
411
+ cancelled
412
+ }
413
+
346
414
  // ===== browserbase-context.prisma =====
347
415
  /// Stores Browserbase context IDs for browser-based automation
348
416
  /// One context per organization - shared like a normal browser
@@ -748,6 +816,21 @@ model EvidenceSubmission {
748
816
  @@index([submittedById, status])
749
817
  }
750
818
 
819
+ model EvidenceFormSetting {
820
+ id String @id @default(dbgenerated("generate_prefixed_cuid('efs'::text)"))
821
+ organizationId String
822
+ formType EvidenceFormType
823
+ isNotRelevant Boolean @default(false)
824
+ createdAt DateTime @default(now())
825
+ updatedAt DateTime @updatedAt
826
+
827
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
828
+
829
+ @@unique([organizationId, formType])
830
+ @@index([organizationId])
831
+ @@index([organizationId, isNotRelevant])
832
+ }
833
+
751
834
  // ===== finding.prisma =====
752
835
  enum FindingType {
753
836
  soc2
@@ -1664,18 +1747,146 @@ model OrganizationChart {
1664
1747
 
1665
1748
  // ===== organization-billing.prisma =====
1666
1749
  model OrganizationBilling {
1667
- id String @id @default(dbgenerated("generate_prefixed_cuid('obil'::text)"))
1668
- organizationId String @unique @map("organization_id")
1669
- stripeCustomerId String @map("stripe_customer_id")
1670
- createdAt DateTime @default(now()) @map("created_at")
1671
- updatedAt DateTime @updatedAt @map("updated_at")
1750
+ id String @id @default(dbgenerated("generate_prefixed_cuid('obil'::text)"))
1751
+ organizationId String @unique @map("organization_id")
1752
+ stripeCustomerId String @map("stripe_customer_id")
1753
+ stripePaymentMethodId String? @map("stripe_payment_method_id")
1754
+ paymentMethodUpdatedAt DateTime? @map("payment_method_updated_at")
1755
+ createdAt DateTime @default(now()) @map("created_at")
1756
+ updatedAt DateTime @updatedAt @map("updated_at")
1672
1757
 
1673
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1674
- pentestSubscription PentestSubscription?
1758
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1675
1759
 
1676
1760
  @@map("organization_billing")
1677
1761
  }
1678
1762
 
1763
+ model OrganizationBillingSubscription {
1764
+ id String @id @default(dbgenerated("generate_prefixed_cuid('obs'::text)"))
1765
+ organizationId String @map("organization_id")
1766
+ skuKey String @map("sku_key")
1767
+ stripeSubscriptionId String @map("stripe_subscription_id")
1768
+ stripeSubscriptionItemId String @map("stripe_subscription_item_id")
1769
+ stripePriceId String @map("stripe_price_id")
1770
+ stripeStatus String @map("stripe_status")
1771
+ currentPeriodStart DateTime? @map("current_period_start")
1772
+ currentPeriodEnd DateTime? @map("current_period_end")
1773
+ includedQuantity Int @map("included_quantity")
1774
+ usedQuantity Int @default(0) @map("used_quantity")
1775
+ cancelAtPeriodEnd Boolean @default(false) @map("cancel_at_period_end")
1776
+ canceledAt DateTime? @map("canceled_at")
1777
+ createdAt DateTime @default(now()) @map("created_at")
1778
+ updatedAt DateTime @updatedAt @map("updated_at")
1779
+
1780
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1781
+
1782
+ @@unique([organizationId, skuKey])
1783
+ @@unique([stripeSubscriptionId, stripeSubscriptionItemId], map: "org_billing_subs_stripe_sub_item_key")
1784
+ @@index([organizationId])
1785
+ @@index([stripeSubscriptionId])
1786
+ @@index([skuKey])
1787
+ @@map("organization_billing_subscriptions")
1788
+ }
1789
+
1790
+ model BillingUsageEvent {
1791
+ id String @id @default(dbgenerated("generate_prefixed_cuid('bue'::text)"))
1792
+ organizationId String @map("organization_id")
1793
+ skuKey String @map("sku_key")
1794
+ eventType String @map("event_type")
1795
+ quantity Int
1796
+ sourceResourceId String? @map("source_resource_id")
1797
+ idempotencyKey String @unique @map("idempotency_key")
1798
+ stripeEventId String? @map("stripe_event_id")
1799
+ stripeInvoiceId String? @map("stripe_invoice_id")
1800
+ stripeSubscriptionItemId String? @map("stripe_subscription_item_id")
1801
+ periodStart DateTime? @map("period_start")
1802
+ periodEnd DateTime? @map("period_end")
1803
+ createdAt DateTime @default(now()) @map("created_at")
1804
+
1805
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1806
+
1807
+ @@index([organizationId, skuKey])
1808
+ @@index([stripeEventId])
1809
+ @@index([stripeInvoiceId])
1810
+ @@map("billing_usage_events")
1811
+ }
1812
+
1813
+ model StripeWebhookEvent {
1814
+ id String @id @default(dbgenerated("generate_prefixed_cuid('swe'::text)"))
1815
+ stripeEventId String @unique @map("stripe_event_id")
1816
+ eventType String @map("event_type")
1817
+ payload Json
1818
+ status String @default("processed")
1819
+ error String?
1820
+ processedAt DateTime @default(now()) @map("processed_at")
1821
+ createdAt DateTime @default(now()) @map("created_at")
1822
+
1823
+ @@index([eventType])
1824
+ @@index([status])
1825
+ @@map("stripe_webhook_events")
1826
+ }
1827
+
1828
+ model BillingAuditEvent {
1829
+ id String @id @default(dbgenerated("generate_prefixed_cuid('bae'::text)"))
1830
+ organizationId String @map("organization_id")
1831
+ eventType String @map("event_type")
1832
+ skuKey String? @map("sku_key")
1833
+ stripeEventId String? @map("stripe_event_id")
1834
+ metadata Json?
1835
+ createdAt DateTime @default(now()) @map("created_at")
1836
+
1837
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1838
+
1839
+ @@index([organizationId])
1840
+ @@index([stripeEventId])
1841
+ @@index([skuKey])
1842
+ @@map("billing_audit_events")
1843
+ }
1844
+
1845
+ model BillingCreditBalance {
1846
+ id String @id @default(dbgenerated("generate_prefixed_cuid('bcb'::text)"))
1847
+ organizationId String @map("organization_id")
1848
+ productKey String @map("product_key")
1849
+ skuKey String? @map("sku_key")
1850
+ balance Int @default(0)
1851
+ totalGranted Int @default(0) @map("total_granted")
1852
+ totalConsumed Int @default(0) @map("total_consumed")
1853
+ totalRefunded Int @default(0) @map("total_refunded")
1854
+ lastSource String @default("manual") @map("last_source")
1855
+ createdAt DateTime @default(now()) @map("created_at")
1856
+ updatedAt DateTime @updatedAt @map("updated_at")
1857
+
1858
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1859
+ events BillingCreditEvent[]
1860
+
1861
+ @@index([organizationId, productKey])
1862
+ @@map("billing_credit_balances")
1863
+ }
1864
+
1865
+ model BillingCreditEvent {
1866
+ id String @id @default(dbgenerated("generate_prefixed_cuid('bce'::text)"))
1867
+ organizationId String @map("organization_id")
1868
+ balanceId String @map("balance_id")
1869
+ productKey String @map("product_key")
1870
+ skuKey String? @map("sku_key")
1871
+ eventType String @map("event_type")
1872
+ quantity Int
1873
+ source String
1874
+ note String?
1875
+ adminUserId String? @map("admin_user_id")
1876
+ sourceResourceId String? @map("source_resource_id")
1877
+ linkedEventId String? @map("linked_event_id")
1878
+ idempotencyKey String @unique @map("idempotency_key")
1879
+ createdAt DateTime @default(now()) @map("created_at")
1880
+
1881
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1882
+ balance BillingCreditBalance @relation(fields: [balanceId], references: [id], onDelete: Cascade)
1883
+
1884
+ @@index([organizationId, productKey])
1885
+ @@index([sourceResourceId])
1886
+ @@index([linkedEventId])
1887
+ @@map("billing_credit_events")
1888
+ }
1889
+
1679
1890
  // ===== organization.prisma =====
1680
1891
  model Organization {
1681
1892
  id String @id @default(dbgenerated("generate_prefixed_cuid('org'::text)"))
@@ -1692,6 +1903,7 @@ model Organization {
1692
1903
  evidenceApprovalEnabled Boolean @default(false)
1693
1904
  deviceAgentStepEnabled Boolean @default(true)
1694
1905
  securityTrainingStepEnabled Boolean @default(true)
1906
+ backgroundCheckStepEnabled Boolean @default(true)
1695
1907
  whistleblowerReportEnabled Boolean @default(true)
1696
1908
  accessRequestFormEnabled Boolean @default(true)
1697
1909
 
@@ -1718,6 +1930,7 @@ model Organization {
1718
1930
  comments Comment[]
1719
1931
  attachments Attachment[]
1720
1932
  evidenceSubmissions EvidenceSubmission[]
1933
+ evidenceFormSettings EvidenceFormSetting[]
1721
1934
  trust Trust[]
1722
1935
  context Context[]
1723
1936
  secrets Secret[]
@@ -1739,9 +1952,16 @@ model Organization {
1739
1952
  integrationOAuthApps IntegrationOAuthApp[]
1740
1953
  integrationSyncLogs IntegrationSyncLog[]
1741
1954
 
1742
- // Pentest Subscription
1743
- pentestSubscription PentestSubscription?
1744
- billing OrganizationBilling?
1955
+ // Pentest credits — wallet of run-credits an org can spend.
1956
+ // Source of credits (trial / future Stripe subscription / top-up)
1957
+ // is metadata on the row; balance is unified.
1958
+ pentestCredits PentestCredits?
1959
+ billing OrganizationBilling?
1960
+ billingSubscriptions OrganizationBillingSubscription[]
1961
+ billingUsageEvents BillingUsageEvent[]
1962
+ billingAuditEvents BillingAuditEvent[]
1963
+ billingCreditBalances BillingCreditBalance[]
1964
+ billingCreditEvents BillingCreditEvent[]
1745
1965
 
1746
1966
  // Browser Automation
1747
1967
  browserbaseContext BrowserbaseContext?
@@ -1753,6 +1973,9 @@ model Organization {
1753
1973
  // Device Agent
1754
1974
  devices Device[]
1755
1975
 
1976
+ // Background Checks
1977
+ backgroundCheckRequests BackgroundCheckRequest[]
1978
+
1756
1979
  // Org Chart
1757
1980
  organizationChart OrganizationChart?
1758
1981
 
@@ -1770,26 +1993,51 @@ model Organization {
1770
1993
  @@index([slug])
1771
1994
  }
1772
1995
 
1773
- // ===== pentest-subscription.prisma =====
1774
- model PentestSubscription {
1775
- id String @id @default(dbgenerated("generate_prefixed_cuid('psub'::text)"))
1776
- organizationId String @unique @map("organization_id")
1777
- organizationBillingId String @unique @map("organization_billing_id")
1778
- stripeSubscriptionId String @map("stripe_subscription_id")
1779
- stripePriceId String @map("stripe_price_id")
1780
- stripeOveragePriceId String? @map("stripe_overage_price_id")
1781
- status String @default("active") // active | cancelled | past_due
1782
- includedRunsPerPeriod Int @default(3) @map("included_runs_per_period")
1783
- currentPeriodStart DateTime @map("current_period_start")
1784
- currentPeriodEnd DateTime @map("current_period_end")
1785
- createdAt DateTime @default(now()) @map("created_at")
1786
- updatedAt DateTime @updatedAt @map("updated_at")
1787
-
1788
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
1789
- organizationBilling OrganizationBilling @relation(fields: [organizationBillingId], references: [id])
1996
+ // ===== pentest-credits.prisma =====
1997
+ /// Pentest credit wallet — one row per organization, holding the org's
1998
+ /// current quota for penetration test runs.
1999
+ ///
2000
+ /// `balance` is the operative number: decremented atomically when a run is
2001
+ /// created, granted by trial bootstrap, future Stripe subscription renewals,
2002
+ /// future top-up purchases, etc. The wallet does not differentiate by
2003
+ /// source — credits are credits. The most recent grant source is recorded
2004
+ /// for support visibility, not for spend logic.
2005
+ ///
2006
+ /// For a full audit trail of every grant/consume, a future
2007
+ /// `pentest_credit_entries` ledger table can be layered in. v1 sticks with
2008
+ /// running totals (`totalGranted` / `totalConsumed`) for simplicity.
2009
+ model PentestCredits {
2010
+ id String @id @default(dbgenerated("generate_prefixed_cuid('pcr'::text)"))
2011
+ organizationId String @unique @map("organization_id")
2012
+
2013
+ /// Spendable balance. Never negative.
2014
+ /// Enforced both in code (atomic `updateMany WHERE balance > 0` in
2015
+ /// PentestCreditsService.debitOrThrow) AND at the DB level via a
2016
+ /// CHECK constraint added in migration
2017
+ /// `20260429120000_pentest_credits_balance_check`. Prisma's schema
2018
+ /// DSL doesn't currently support CHECK constraints, hence the
2019
+ /// SQL-only migration.
2020
+ balance Int @default(0)
2021
+
2022
+ /// Lifetime totals — useful for analytics and "why do I have N credits?"
2023
+ /// support questions without needing a full ledger.
2024
+ totalGranted Int @default(0) @map("total_granted")
2025
+ totalConsumed Int @default(0) @map("total_consumed")
2026
+
2027
+ /// Where the most recent grant came from. Free-form string so v2 can add
2028
+ /// new sources (`subscription`, `topup`, `promo`, `refund`, …) without a
2029
+ /// schema change. `trial` is the v1 default.
2030
+ lastGrantSource String @default("trial") @map("last_grant_source")
2031
+
2032
+ createdAt DateTime @default(now()) @map("created_at")
2033
+ updatedAt DateTime @updatedAt @map("updated_at")
1790
2034
 
1791
- @@index([organizationId])
1792
- @@map("pentest_subscriptions")
2035
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
2036
+
2037
+ // No explicit @@index([organizationId]) — `@unique` on organizationId
2038
+ // already creates a btree index, and a duplicate would just consume
2039
+ // disk + write amplification with no read benefit.
2040
+ @@map("pentest_credits")
1793
2041
  }
1794
2042
 
1795
2043
  // ===== policy.prisma =====
@@ -2117,11 +2365,25 @@ model Secret {
2117
2365
 
2118
2366
  // ===== security-penetration-test-run.prisma =====
2119
2367
  model SecurityPenetrationTestRun {
2120
- id String @id @default(dbgenerated("generate_prefixed_cuid('ptr'::text)"))
2121
- organizationId String @map("organization_id")
2122
- providerRunId String @map("provider_run_id")
2123
- createdAt DateTime @default(now()) @map("created_at")
2124
- updatedAt DateTime @updatedAt @map("updated_at")
2368
+ id String @id @default(dbgenerated("generate_prefixed_cuid('ptr'::text)"))
2369
+ organizationId String @map("organization_id")
2370
+ providerRunId String @map("provider_run_id")
2371
+ billingUsageSourceId String? @map("billing_usage_source_id")
2372
+ createdAt DateTime @default(now()) @map("created_at")
2373
+ updatedAt DateTime @updatedAt @map("updated_at")
2374
+
2375
+ /// Set the first time we refund this run's credit (e.g. on
2376
+ /// `pentest.failed` / `pentest.cancelled` webhooks). Used to make the
2377
+ /// refund idempotent — webhook redelivery cannot double-credit because
2378
+ /// the second attempt sees a non-null value here.
2379
+ creditRefundedAt DateTime? @map("credit_refunded_at")
2380
+
2381
+ /// Set the first time we write a `pentest_completed` audit-log entry
2382
+ /// for this run. Webhook redelivery would otherwise create duplicate
2383
+ /// rows in `audit_log` because Maced retries `pentest.completed` on
2384
+ /// transient delivery failures. The atomic claim on this column
2385
+ /// guarantees one audit row per run regardless of retry count.
2386
+ completedAuditAt DateTime? @map("completed_audit_at")
2125
2387
 
2126
2388
  organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
2127
2389
 
@@ -2216,6 +2478,7 @@ enum AuditLogEntityType {
2216
2478
  integration
2217
2479
  trust
2218
2480
  finding
2481
+ pentest
2219
2482
  }
2220
2483
 
2221
2484
  enum EvidenceFormType {
@@ -2699,6 +2962,7 @@ model Trust {
2699
2962
  soc2 Boolean @default(false)
2700
2963
  soc2type1 Boolean @default(false)
2701
2964
  soc2type2 Boolean @default(false)
2965
+ soc3 Boolean @default(false)
2702
2966
  iso27001 Boolean @default(false)
2703
2967
  iso42001 Boolean @default(false)
2704
2968
  nen7510 Boolean @default(false)
@@ -2710,6 +2974,7 @@ model Trust {
2710
2974
  soc2_status FrameworkStatus @default(started)
2711
2975
  soc2type1_status FrameworkStatus @default(started)
2712
2976
  soc2type2_status FrameworkStatus @default(started)
2977
+ soc3_status FrameworkStatus @default(started)
2713
2978
  iso27001_status FrameworkStatus @default(started)
2714
2979
  iso42001_status FrameworkStatus @default(started)
2715
2980
  nen7510_status FrameworkStatus @default(started)
@@ -2750,6 +3015,7 @@ enum TrustFramework {
2750
3015
  hipaa
2751
3016
  soc2_type1
2752
3017
  soc2_type2
3018
+ soc3
2753
3019
  pci_dss
2754
3020
  nen_7510
2755
3021
  iso_9001
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": "2.1.0",
4
+ "version": "2.1.1",
5
5
  "dependencies": {
6
6
  "@prisma/adapter-pg": "7.6.0",
7
7
  "@prisma/client": "7.6.0",