Database Schema

The "depends" project persists all data in a single SQLite database file (data/depends.db by default). The schema enables multi-tenant isolation, dependency graphs, state tracking, auditing, and notifications. SQLite operates in WAL (Write-Ahead Logging) mode for better concurrency, with a 5-second busy timeout and foreign keys enabled for referential integrity.

The database supports the core-model.md: users own namespaces containing nodes (services/systems) with states (green, yellow, red), edges (dependencies), events (state changes), and notification rules. Effective states aggregate the worst state across a node and its transitive dependencies, computed on-the-fly rather than stored, as described in graph-computation.md.

Schema Initialization

The full schema appears in src/db.ts and initializes on database creation:

PRAGMA journal_mode=WAL;
PRAGMA busy_timeout=5000;
PRAGMA foreign_keys=ON;

CREATE TABLE IF NOT EXISTS tokens (
  id              INTEGER PRIMARY KEY AUTOINCREMENT,
  token_hash      TEXT NOT NULL UNIQUE,
  email           TEXT,
  legendum_token  TEXT,
  meta            TEXT DEFAULT '{}',
  created_at      TEXT NOT NULL DEFAULT (datetime('now'))
);

-- Additional tables follow (namespaces, nodes, etc.)

The createDb function executes this schema idempotently. In-memory databases support testing via createTestDb.

Table Relationships

This design ensures data isolation per user/namespace while allowing efficient queries for graphs and audits.

Tokens Table

Stores user authentication data. See authentication.md.

ColumnTypeConstraints/Notes
idINTEGERPK, AUTOINCREMENT
token_hashTEXTUNIQUE, bcrypt hash of API token
emailTEXTLowercased on signup
legendum_tokenTEXTOpaque token from Legendum billing service
metaTEXTJSON, default '{}' (extensible)
created_atTEXTISO datetime default

Namespaces Table

Projects/graphs belong to a token. IDs are lowercase alphanumeric/hyphens, max 64 chars.

ColumnTypeConstraints/Notes
ns_idINTEGERPK, AUTOINCREMENT
idTEXTNamespace name (e.g., "my-project")
token_idINTEGERFK to tokens(id)
created_atTEXTISO datetime default
UNIQUE(token_id, id)Prevents duplicate namespaces per user

CLI init derives namespace from directory name, sanitizing to valid ID.

Nodes Table

Core entities representing services/systems. States use CHECK constraint: 'green' (healthy), 'yellow' (warning), 'red' (broken). default_state sets initial state on auto-creation.

ColumnTypeConstraints/Notes
ns_idINTEGERFK to namespaces(ns_id)
idTEXTNode name (no /)
labelTEXTHuman-readable name
stateTEXTDEFAULT 'yellow', CHECK in (green,yellow,red)
default_stateTEXTCHECK in (green,yellow,red), nullable
metaTEXTJSON (e.g., {"checks": [...]})
reasonTEXTFailure explanation
solutionTEXTSuggested fix
ttlINTEGERSeconds; green states expire to yellow if last_state_write exceeds TTL
last_state_writeTEXTISO datetime of last explicit state update
state_changed_atTEXTISO datetime default
updated_atTEXTISO datetime default
PRIMARY KEY(ns_id, id)

TTL parses strings like "10m" via parseTtl (e.g., 10m → 600s). Effective state considers TTL expiry and propagates "worst" (red > yellow > green) across dependencies.

Edges Table

Directed dependencies: from_nodeto_node (A depends on B).

ColumnTypeConstraints/Notes
ns_idINTEGER
from_nodeTEXT
to_nodeTEXT
PRIMARY KEY(ns_id, from_node, to_node)
FK(ns_id,from_node)ON DELETE CASCADE
FK(ns_id,to_node)ON DELETE CASCADE

Prevents cycles on insert (project-invariants.md). Indexes: idx_edges_to_node on (ns_id, to_node) for reverse lookups.

Notification Rules Table

Triggers on state changes. See notifications.md.

ColumnTypeConstraints/Notes
ns_idINTEGERFK to namespaces(ns_id)
idTEXTRule name
watchTEXTNode ID or '*' (default)
on_stateTEXTDEFAULT 'red'
urlTEXTWebhook
emailTEXTEmail recipient
secretTEXTWebhook auth
ackINTEGERDEFAULT 0 (boolean)
ack_tokenTEXT
suppressedINTEGERDEFAULT 0 (acknowledged)
last_fired_atTEXT
CHECK(url OR email)At least one
PRIMARY KEY(ns_id, id)

Events Table

Immutable audit log of state changes. Supports events-auditing.md and CLI events.

ColumnTypeConstraints/Notes
idINTEGERPK, AUTOINCREMENT
ns_idINTEGERFK to namespaces(ns_id)
node_idTEXT
previous_stateTEXTNullable
new_stateTEXT
previous_effective_stateTEXTNullable
new_effective_stateTEXT
reasonTEXTNullable
solutionTEXTNullable
created_atTEXTISO datetime default

Indexes:

API/CLI query with limit, since, order=desc. Retained 30 days; data-purging.md auto-deletes older events hourly in server mode.

Key Behaviors and Invariants

This schema balances simplicity (single file) with scalability for thousands of nodes/events per namespace.

Recent changes