Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Data Model

Both DPGs use PostgreSQL as their system of record (via Drizzle ORM) and Redis for caching, sessions and queues. They can run on the same PostgreSQL and Redis servers, but each DPG owns its own database and they do not share tables.

The Signals database is organised around the item/action/event primitives:

EntityWhat it holds
ItemsVersioned, schema-typed records keyed by item_type (e.g. profile_1.0). Item tables are partitioned so that high-volume reads can prune to relevant partitions.
Schema registryThe schemas that define networks and item types. Schemas are fetched and cached at the inter-instance read layer.
Actions & eventsInteractions between items and their structured results.
OrganisationsCarries a type column (network_service | aggregator | voice) that gates what each org may do (for example, only network_service orgs may upsert aggregators).

How the item/action/event primitives relate:

An item-type schema types many items (1—n); items interact via actions (1—n); each action produces events as structured results (1—n)

Always query through the partition-aware helpers in @dpg/database; a query against the parent table without a partition key scans all partitions.

Schema files live in apps/api/db/postgres/schema/. Migrations are generated, never hand-edited — regenerate with pnpm db:generate:api. A bundled schema.sql is produced and verified with pnpm schema:bundle / pnpm schema:bundle:check.

The Aggregator database (Drizzle, owned by apps/api) holds:

EntityWhat it holds
AggregatorsRegistration state, approval status, profile data.
ParticipantsOnboarded individuals/enterprises destined to become Signals items.
Bulk jobsUpload batches and per-row processing state for the worker.
Registration links & metricsShareable links and their roll-ups.

db-schema is the single source of truth; apps import table definitions from it. Migrations are generated with pnpm --filter @aggregator-dpg/api db:generate and applied with db:migrate.

  • Schema-typed, never freeform. An item’s structure is governed by its item_type schema; clients cannot invent fields.
  • Backend-owned identity fields. item_instance_url and item_schema_url are generated server-side.
  • Configuration as code. No domain- or environment-specific value is hardcoded. Values load once at startup from config loaders or environment variables, and each network’s schemas live in their own folder (see Configuration).