Database Schema

Complete schema documentation with realms, signals, clusters, and synthesis.

Schema Overview

Autonomy's database schema is designed with three core principles:

  • Epistemic integrity — The schema enforces truth about data ownership and relationships
  • Multi-tenant isolation — Every entity belongs to a realm, enforced by foreign keys
  • Extensibility — JSON fields allow flexible metadata without schema migrations

Core Models

users

User accounts with authentication and role-based access control.

user_idString (ULID) - Primary key
user_emailString - Unique
user_passwordString - Hashed (bcrypt)
user_nameString? - Optional display name
user_roleString - OWNER, SANCTUM, GUEST
is_ownerBoolean - System owner flag

realms

Sovereign territories for signals. Multi-tenant data isolation.

realm_idString (ULID) - Primary key
user_idString - Foreign key to users
realm_typeString - PRIVATE, PUBLIC, SHARED
realm_nameString - Display name
realm_descriptionString? - Optional description
flag_registryBoolean - Listed in public registry?

realms_users

Many-to-many relationship for realm membership with roles.

realm_idString - Foreign key to realms
user_idString - Foreign key to users
user_roleString - OWNER, CONTRIBUTOR, OBSERVER

Future feature for shared realm collaboration

signals

Atomic units of lived data with geospatial and embedding support.

signal_idString (ULID) - Primary key
realm_idString - Foreign key to realms (REQUIRED)
signal_typeString - TEXT, PHOTO, VIDEO, AUDIO, etc.
signal_titleString - Brief title
signal_descriptionString? - Longer description
signal_visibilityString - PUBLIC, PRIVATE, SANCTUM, SHARED
signal_locationPoint? - PostGIS point (PostgreSQL)
signal_latitudeFloat? - Latitude (MySQL)
signal_longitudeFloat? - Longitude (MySQL)
signal_metadataJSON? - Structured metadata
signal_payloadJSON? - Full content data
signal_tagsJSON? - Array of tags
signal_embeddingVector? - pgvector embedding
stamp_createdDateTime - When created in system
stamp_importedDateTime? - When originally captured

clusters

Hierarchical groupings of signals.

cluster_idString (ULID) - Primary key
realm_idString - Foreign key to realms (REQUIRED)
parent_cluster_idString? - Foreign key to clusters (self-reference)
cluster_nameString - Display name
cluster_descriptionString? - Description
cluster_typeString - TEMPORAL, SPATIAL, THEMATIC, etc.
cluster_metadataJSON? - Structured metadata
cluster_payloadJSON? - Full cluster data
cluster_tagsJSON? - Array of tags
cluster_annotationsJSON? - User notes

clusters_signals

Many-to-many relationship between clusters and signals with positioning.

cluster_idString - Foreign key to clusters
signal_idString - Foreign key to signals
positionInt? - Order within cluster

synthesis

Polymorphic AI analysis layer (attaches to signals or clusters).

synthesis_idString (ULID) - Primary key
realm_idString - Foreign key to realms (REQUIRED)
polymorphic_typeString - "Signal" or "Cluster"
polymorphic_idString - ID of target entity
synthesis_typeString - METADATA or REFLECTION
synthesis_subtypeString - SURFACE/STRUCTURE/PATTERNS or MIRROR/MYTH/NARRATIVE
synthesis_depthInt - Processing depth level
synthesis_contentJSON? - Generated synthesis
synthesis_annotationsJSON? - User notes
synthesis_historyJSON? - Audit trail
synthesis_errorsJSON? - Processing errors
synthesis_sourceString? - AI model used

Key Relationships

users
  └─ realms (one-to-many)
       └─ signals (one-to-many)
       └─ clusters (one-to-many)
            └─ clusters_signals (many-to-many with signals)
       └─ synthesis (one-to-many)
            └─ polymorphic to signals OR clusters

realms
  └─ realms_users (many-to-many with users)

clusters
  └─ parent_cluster (self-referencing for hierarchies)

Foreign Key Constraints

All foreign keys cascade on delete, ensuring data integrity:

  • Deleting a realm → Deletes all signals, clusters, and synthesis in that realm
  • Deleting a cluster → Removes cluster-signal associations (signals remain)
  • Deleting a signal → Removes cluster-signal associations
  • Deleting a user → Deletes all their owned realms (cascade)

ULID Identifiers

All primary keys use ULID (Universally Unique Lexicographically Sortable Identifier):

  • 26 characters long
  • Timestamp-based prefix (sortable by creation time)
  • Unique across distributed systems
  • URL-safe (no special characters)
01HQXYZ123ABC456DEF789GHI0

Optional Database Features

PostGIS (PostgreSQL)

Geospatial extension for location-based queries:

  • • Distance calculations
  • • Radius searches
  • • Spatial indexing
  • • Geometric operations

pgvector (PostgreSQL)

Vector similarity search for embeddings:

  • • Semantic search across signals
  • • Find similar content
  • • Cluster by meaning
  • • Vector indexing

Schema Generation

The schema is generated from TypeScript schema definitions using a custom generator:

npm run db:generate-schema

This creates schema.prisma which Prisma uses to generate TypeScript types and database migrations.

Benefits:

  • Type-safe schema definitions
  • Single source of truth in TypeScript
  • Automatic Prisma client generation
  • Database-agnostic (supports PostgreSQL and MySQL)

Database Migrations

Migration Workflow

  1. 1. Modify schema in lib/db/schemas/
  2. 2. Run npm run db:generate-schema
  3. 3. Review generated schema.prisma
  4. 4. Run npx prisma migrate dev --name description_of_change
  5. 5. Commit migration files to version control

Related Documentation