Skip to main content

Schema Conventions

Every table follows these conventions:

ConventionRuleExample
Primary keyid, UUID v4 as TEXT (SQLite) or UUID (PostgreSQL)id TEXT PRIMARY KEY
Timestampscreated_at, updated_at — UTC, never nullcreated_at TEXT NOT NULL
Soft deletedeleted_at — nullable, for audit-sensitive recordsdeleted_at TEXT
Foreign keys{entity}_idrealm_id, user_id, engine_id
Indexesidx_{table}_{columns}idx_secrets_realm_key
Unique constraintsuq_{table}_{columns}uq_realms_user_slug
Check constraintschk_{table}_{rule}chk_leases_ttl_positive
Booleansis_ prefixis_active, is_revoked
EnumsTEXT with CHECK constraint (SQLite) or custom type (PG)status TEXT CHECK(status IN (...))

Soft Delete vs Hard Delete

  • Soft delete (set deleted_at): realms, secrets, engines, policies, leases, users
  • Hard delete (remove row): sessions, nonces, expired tokens, migration tracking
  • All queries on soft-deletable tables MUST include WHERE deleted_at IS NULL unless explicitly querying deleted records.

Timestamp Format

  • SQLite: ISO 8601 string 2026-04-01T12:00:00Z (always UTC)
  • PostgreSQL: TIMESTAMPTZ (always UTC)
  • Application code: time.Now().UTC() — never local time