Skip to content

Database Schema

Melvin PETIT edited this page Jun 16, 2026 · 1 revision

Database Schema

DataShield uses Prisma 7 with PostgreSQL. The schema lives in prisma/schema.prisma. All identifiers are CUIDs. Every tenant-owned row references a Company, and deletes cascade from the company down.

Entity relationships

erDiagram
  Company ||--o{ User : has
  Company ||--o{ Employee : has
  Company ||--o{ Alert : has
  Company ||--o{ DashboardPreset : has
  Company ||--o{ DirectoryConnection : has
  Company ||--o{ ApiCredential : has
  Company ||--o{ Webhook : has
  User ||--o| DashboardConfig : owns
  User ||--o{ DashboardPreset : authors
  Employee ||--o{ BreachRecord : has
  Employee ||--o{ Alert : triggers
  Breach ||--o{ BreachRecord : appears_in
  Breach ||--o{ Alert : triggers
Loading

Models

Company

Tenant root. domain is unique. Owns every other tenant-scoped entity; all relations cascade on delete.

User

email unique, hashedPassword (bcrypt), role (ADMIN | VIEWER, defaults VIEWER). Has one optional DashboardConfig, authors many DashboardPresets, and points to an activePreset (set to null on preset delete).

Employee

@@unique([email, companyId]) so the same address can exist across tenants but is unique within one. Optional department. Linked to BreachRecords and Alerts.

Breach

name unique (used as the upsert key by the scan engine). source (HIBP | MANUAL | DARK_WEB), breachDate, dataTypes string array.

BreachRecord

Join between an Employee and a Breach with the exposedData for that specific match. @@unique([employeeId, breachId]) prevents duplicate links.

Alert

Severity-scored event. severity (CRITICAL | HIGH | MEDIUM | LOW), status (OPEN | ACKNOWLEDGED | RESOLVED, defaults OPEN). Employee and breach references are nullable and set to null on delete so alert history survives.

DirectoryConnection

An identity-provider connection. type (see DirectoryType), encryptedConfig (AES-256-GCM blob), status (ACTIVE | ERROR | PENDING), plus lastSyncAt, lastSyncCount, errorMessage.

ApiCredential

A breach-provider API key. provider (see ApiProvider), encryptedKey, keyHint (display-safe suffix), status, lastUsedAt. @@unique([companyId, provider]), so one key per provider per company.

Webhook

Outbound notification target. encryptedUrl, urlHint (host only), minSeverity (defaults MEDIUM), enabled.

DashboardConfig / DashboardPreset

Per-user live layout (DashboardConfig, one per user) and saved presets (DashboardPreset, scope PERSONAL or COMPANY). Both store layout and widgets as JSON.

Enums

Enum Values
Role ADMIN, VIEWER
Severity CRITICAL, HIGH, MEDIUM, LOW
AlertStatus OPEN, ACKNOWLEDGED, RESOLVED
BreachSource HIBP, MANUAL, DARK_WEB
DirectoryType AZURE_AD, GOOGLE_WORKSPACE, LDAP, AWS_DIRECTORY, OKTA, SCIM
ApiProvider HIBP, DEHASHED, LEAKCHECK, INTELX, SNUSBASE
ConnectStatus ACTIVE, ERROR, PENDING
PresetScope PERSONAL, COMPANY

Migrations

Migrations are checked into prisma/migrations/, applied with prisma migrate deploy (npm run db:migrate). The current history:

  1. init
  2. add_dashboard_config
  3. add_preset_scope_and_active_preset
  4. add_directory_connections
  5. add_aws_directory_type
  6. add_okta_scim_directory_types
  7. add_api_credentials
  8. add_webhooks

Clone this wiki locally