Skip to main content

Traceo Database Schema

This document defines the PostgreSQL database schema for Traceo, designed for multi-tenant SaaS deployment with Supabase.

Design Principles

PrincipleImplementation
Multi-tenancyRow-Level Security (RLS) on workspace_id
Primary KeysUUID v7 (sortable, distributed-safe)
Timestampstimestamptz (timezone-aware)
Flexible DataJSONB for metadata and extensible fields
Audit TrailFull versioning with change tracking
Soft Deletesdeleted_at column where applicable

Entity Relationship Diagram

┌─────────────┐       ┌─────────────────┐       ┌──────────────────┐
│   tenants   │──────<│   workspaces    │──────<│      users       │
└─────────────┘       └─────────────────┘       └──────────────────┘
                              │                          │
                              │                          │
              ┌───────────────┼───────────────┐          │
              │               │               │          │
              ▼               ▼               ▼          ▼
      ┌──────────────┐ ┌─────────────┐ ┌────────────┐ ┌────────────┐
      │ requirements │ │ingestion_  │ │mcp_sessions│ │audit_logs  │
      └──────────────┘ │   jobs     │ └────────────┘ └────────────┘
              │        └─────────────┘
              │               │
      ┌───────┴───────┐       │
      │               │       ▼
      ▼               ▼  ┌────────────┐
┌──────────────┐ ┌──────────────────┐
│relationships │ │requirement_      │ │job_issues  │
└──────────────┘ │   versions       │ └────────────┘
                 └──────────────────┘

Tables

Core Multi-Tenancy

tenants

Top-level organization entity for multi-tenant isolation.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()Tenant identifier
nametextNOT NULLOrganization name
slugtextUNIQUE, NOT NULLURL-safe identifier
settingsjsonbDEFAULT '{}'Tenant-level settings
plantextDEFAULT 'free'Subscription plan
created_attimestamptzDEFAULT now()Creation timestamp
updated_attimestamptzDEFAULT now()Last update

workspaces

Isolated workspace within a tenant. Primary RLS boundary.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()Workspace identifier
tenant_iduuidFK → tenants, NOT NULLParent tenant
nametextNOT NULLWorkspace name
slugtextNOT NULLURL-safe identifier
descriptiontextWorkspace description
settingsjsonbDEFAULT '{}'Workspace settings
created_attimestamptzDEFAULT now()Creation timestamp
updated_attimestamptzDEFAULT now()Last update
Unique Constraint: (tenant_id, slug)

users

User accounts linked to Supabase Auth.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()User identifier
workspace_iduuidFK → workspaces, NOT NULLPrimary workspace
supabase_uiduuidUNIQUE, NOT NULLSupabase Auth user ID
emailtextNOT NULLEmail address
display_nametextDisplay name
roletextNOT NULL, DEFAULT 'member'Role: owner, admin, member, viewer
settingsjsonbDEFAULT '{}'User preferences
created_attimestamptzDEFAULT now()Creation timestamp
updated_attimestamptzDEFAULT now()Last update
last_login_attimestamptzLast login timestamp

Requirements Management

requirements

Core requirements table with full traceability support.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()Internal identifier
workspace_iduuidFK → workspaces, NOT NULLWorkspace scope
external_idtextNOT NULLHuman-readable ID (e.g., BR-001)
titletextNOT NULLRequirement title
descriptiontextFull description
typerequirement_typeNOT NULLEnum: business, functional, etc.
classificationrequirement_classification5-layer hierarchy level
statusrequirement_statusNOT NULL, DEFAULT 'draft'Lifecycle status
priorityrequirement_priorityDEFAULT 'P2-medium'Priority level
acceptance_criteriajsonbDEFAULT '[]'List of acceptance criteria
success_criteriajsonbDEFAULT '[]'Business success metrics
stakeholdersjsonbDEFAULT '{}'Stakeholder information
metadatajsonbDEFAULT '{}'Extensible metadata
versionintegerNOT NULL, DEFAULT 1Current version number
created_byuuidFK → usersCreator
updated_byuuidFK → usersLast updater
created_attimestamptzDEFAULT now()Creation timestamp
updated_attimestamptzDEFAULT now()Last update
deleted_attimestamptzSoft delete timestamp
Unique Constraint: (workspace_id, external_id) WHERE deleted_at IS NULL

relationships

Traceability relationships between requirements.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()Relationship identifier
workspace_iduuidFK → workspaces, NOT NULLWorkspace scope
source_iduuidFK → requirements, NOT NULLSource requirement
target_iduuidFK → requirements, NOT NULLTarget requirement
relationship_typerelationship_typeNOT NULLType of relationship
metadatajsonbDEFAULT '{}'Additional context
created_byuuidFK → usersCreator
created_attimestamptzDEFAULT now()Creation timestamp
Unique Constraint: (source_id, target_id, relationship_type) Check Constraint: source_id != target_id

requirement_versions

Full version history for requirements.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()Version identifier
requirement_iduuidFK → requirements, NOT NULLParent requirement
versionintegerNOT NULLVersion number
snapshotjsonbNOT NULLFull requirement state
changesjsonbDEFAULT '{}'Diff from previous version
change_reasontextReason for change
changed_byuuidFK → usersUser who made change
created_attimestamptzDEFAULT now()Version timestamp
Unique Constraint: (requirement_id, version)

Ingestion Pipeline

ingestion_jobs

Track CSV/file ingestion jobs.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()Job identifier
workspace_iduuidFK → workspaces, NOT NULLWorkspace scope
statusjob_statusNOT NULL, DEFAULT 'pending'Job status
source_typetextNOT NULLSource: csv, excel, yaml
source_filenametextNOT NULLOriginal filename
source_size_bytesbigintFile size
total_rowsintegerTotal rows to process
processed_rowsintegerDEFAULT 0Rows processed
created_rowsintegerDEFAULT 0New requirements created
updated_rowsintegerDEFAULT 0Requirements updated
error_rowsintegerDEFAULT 0Rows with errors
optionsjsonbDEFAULT '{}'Job options
resultjsonbFinal result summary
created_byuuidFK → usersUser who started job
started_attimestamptzProcessing start time
completed_attimestamptzProcessing end time
created_attimestamptzDEFAULT now()Job creation time

job_issues

Issues encountered during ingestion.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()Issue identifier
job_iduuidFK → ingestion_jobs, NOT NULLParent job
severitytextNOT NULLerror, warning, info
issue_typetextNOT NULLCategory of issue
messagetextNOT NULLHuman-readable message
row_numberintegerCSV row number
column_nametextColumn that caused issue
raw_valuetextOriginal value
created_attimestamptzDEFAULT now()Issue timestamp

Session & Audit

mcp_sessions

Track MCP protocol sessions for analytics.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()Session identifier
workspace_iduuidFK → workspaces, NOT NULLWorkspace scope
user_iduuidFK → usersAssociated user
client_infojsonbDEFAULT '{}'Client metadata
tool_callsintegerDEFAULT 0Number of tool calls
requirements_createdintegerDEFAULT 0Requirements created
requirements_updatedintegerDEFAULT 0Requirements updated
started_attimestamptzDEFAULT now()Session start
ended_attimestamptzSession end
last_activity_attimestamptzDEFAULT now()Last activity

audit_logs

Comprehensive audit trail for compliance.
ColumnTypeConstraintsDescription
iduuidPK, DEFAULT gen_random_uuid()Log identifier
workspace_iduuidFK → workspaces, NOT NULLWorkspace scope
user_iduuidFK → usersActing user
actiontextNOT NULLAction: create, update, delete, export
resource_typetextNOT NULLTable/entity name
resource_iduuidAffected resource
changesjsonbDEFAULT '{}'Before/after snapshot
ip_addressinetClient IP
user_agenttextClient user agent
created_attimestamptzDEFAULT now()Log timestamp

Enum Types

-- Requirement type classifications
CREATE TYPE requirement_type AS ENUM (
    'business_requirement',
    'functional_requirement',
    'non_functional_requirement',
    'system_requirement',
    'implementation_requirement',
    'verification_requirement'
);

-- 5-layer hierarchy classifications
CREATE TYPE requirement_classification AS ENUM (
    'L1-Strategic',
    'L2-Functional',
    'L2-Performance',
    'L3-System',
    'L4-Implementation',
    'L4-Verification'
);

-- Requirement priority levels
CREATE TYPE requirement_priority AS ENUM (
    'P0-critical',
    'P1-high',
    'P2-medium',
    'P3-low'
);

-- Requirement status lifecycle
CREATE TYPE requirement_status AS ENUM (
    'draft',
    'candidate',
    'approved',
    'active',
    'implemented',
    'verified',
    'deprecated'
);

-- 6-category traceability relationship types
CREATE TYPE relationship_type AS ENUM (
    'implements',
    'satisfies',
    'decomposes_into',
    'supports',
    'depends_on',
    'conflicts_with',
    'relates_to',
    'verified_by',
    'validates',
    'constrains',
    'constrained_by',
    'affects',
    'affected_by',
    'realized_by',
    'implemented_by'
);

-- Ingestion job status
CREATE TYPE job_status AS ENUM (
    'pending',
    'processing',
    'completed',
    'failed',
    'cancelled'
);

Row-Level Security (RLS)

All tables containing workspace data enforce RLS. The core pattern:
-- Users can only access their workspace's data
CREATE POLICY "workspace_isolation" ON requirements
  FOR ALL
  USING (
    workspace_id IN (
      SELECT workspace_id FROM users 
      WHERE supabase_uid = auth.uid()
    )
  );
See migrations/002_rls_policies.sql for complete RLS implementation.

Indexes

Performance indexes are defined in migrations/003_indexes.sql:
TableIndexColumnsType
requirementsidx_requirements_workspaceworkspace_idB-tree
requirementsidx_requirements_external_idworkspace_id, external_idB-tree
requirementsidx_requirements_typeworkspace_id, typeB-tree
requirementsidx_requirements_statusworkspace_id, statusB-tree
requirementsidx_requirements_searchtitle, descriptionGIN (full-text)
relationshipsidx_relationships_sourcesource_idB-tree
relationshipsidx_relationships_targettarget_idB-tree
relationshipsidx_relationships_typerelationship_typeB-tree
audit_logsidx_audit_workspace_timeworkspace_id, created_at DESCB-tree
ingestion_jobsidx_jobs_workspace_statusworkspace_id, statusB-tree

JSONB Column Schemas

requirements.acceptance_criteria

[
  {
    "id": "AC-001",
    "description": "User can log in with email/password",
    "status": "verified",
    "test_ref": ["TC-AUTH-001", "TC-AUTH-002"]
  }
]

requirements.success_criteria

[
  {
    "metric": "API Response Time (P95)",
    "target": "<50ms",
    "current": "45ms",
    "status": "target_met",
    "business_impact": "Improved user experience",
    "measurement_method": "Prometheus monitoring"
  }
]

requirements.stakeholders

{
  "business_owner": "Jane Smith",
  "technical_owner": "John Doe",
  "approvers": ["VP Engineering", "Product Lead"],
  "code_reviewers": ["senior-dev-1", "senior-dev-2"]
}

Ariel Tables

Ariel baseline management tables are created by migrations/005_ariel_baselines.sql. All tables use RLS policies scoped to workspace_id.

ariel_baselines

Stores baseline metadata. Each baseline belongs to a workspace and follows a lifecycle: draftfrozensuperseded or archived.
ColumnTypeDescription
idUUIDPrimary key
workspace_idUUIDFK → workspaces.id
baseline_idTEXTHuman-readable ID (e.g., BL-ARCH-001)
nameTEXTDisplay name
versionTEXTSemantic version (default 1.0.0)
statusbaseline_statusdraft, frozen, superseded, archived
authorTEXTCreator identifier
descriptionTEXTOptional description
domainTEXTClassification domain
frozen_atTIMESTAMPTZWhen the baseline was frozen
git_refTEXTGit commit SHA at freeze time
parent_baselineTEXTID of the baseline this supersedes
created_atTIMESTAMPTZRow creation time
updated_atTIMESTAMPTZLast update time
Unique constraint: (workspace_id, baseline_id)

ariel_configuration_items

Configuration items (CIs) belonging to a baseline. Each CI references a document, code snippet, or diagram.
ColumnTypeDescription
idUUIDPrimary key
baseline_idUUIDFK → ariel_baselines.id (CASCADE)
typeTEXTCI type: doc, snippet, diagram, spec, test
refTEXTFile path or reference
hashTEXTSHA-256 content hash (set on freeze)
metadataJSONBAdditional metadata
created_atTIMESTAMPTZRow creation time
Unique constraint: (baseline_id, type, ref)

ariel_traceo_references

Links between baseline CIs and Traceo requirements. Created during sync.
ColumnTypeDescription
idUUIDPrimary key
baseline_idUUIDFK → ariel_baselines.id (CASCADE)
traceo_idTEXTTraceo requirement ID (e.g., SR-ARCH-001)
relationshipTEXTLink type: implements, satisfies, traces_to, derived_from
created_atTIMESTAMPTZRow creation time
Unique constraint: (baseline_id, traceo_id, relationship)

ariel_sync_history

Audit log of sync operations between Ariel baselines and Traceo requirements.
ColumnTypeDescription
idUUIDPrimary key
workspace_idUUIDFK → workspaces.id
baseline_idTEXTBaseline that was synced
directionTEXTbaseline_to_traceo or traceo_to_baseline
statusTEXTstarted, completed, failed
detailsJSONBSync results, error info, counts
created_atTIMESTAMPTZWhen the sync occurred

RLS Policies

All Ariel tables enforce workspace isolation via RLS:
  • SELECT: Users can only read rows matching their workspace_id (via auth.uid())
  • INSERT: workspace_id must match the user’s workspace
  • UPDATE/DELETE: Only rows in the user’s workspace can be modified

Indexes

Key indexes for query performance:
  • ariel_baselines: (workspace_id, status), (workspace_id, domain), (workspace_id) WHERE status = 'frozen'
  • ariel_configuration_items: (baseline_id), (type, ref)
  • ariel_traceo_references: (baseline_id), (traceo_id)
  • ariel_sync_history: (workspace_id, created_at DESC), (baseline_id)

Migration Strategy

  1. Initial Schema (001_initial_schema.sql): Creates all tables and types
  2. RLS Policies (002_rls_policies.sql): Enables security policies
  3. Indexes (003_indexes.sql): Adds performance indexes
  4. Future Migrations: Incremental changes with rollback support
  5. Ariel Baselines (005_ariel_baselines.sql): Ariel baseline management tables with RLS
See /migrations/README.md for migration procedures.