Skip to content

Schema-Driven Model

Blue Dots is schema-driven end to end. Schemas define what an instance stores, exchanges and renders. A new domain, participant type or form ships by adding or editing schema files.

  • Domain schema (network.json) — defines a domain (the code calls a domain a network), for example blue_dot for jobs or the Yellow Dot education domain. It lists the domain’s participant types (the code’s domains field), item types, actions and events.
  • Item schemas (item_type) — versioned types such as profile_1.0. An item’s item_type always points at one of these; freeform records are not allowed.
  • Form schemas — JSON schemas that drive the UI. The Signals UI renders forms and cards from item schemas; the Aggregator portal uses RJSF (React JSON Schema Form) so non-engineers can evolve registration and profile forms.
  1. Interoperability. Two instances in the same domain load the same network.json, so they agree on structure. That shared structure is what lets one instance search another.
  2. Evolvability. Versioned item_types (e.g. profile_1.0 → profile_1.1) let the model change without breaking peers.
  3. No-code domain changes. Product and program teams can add fields or new forms by editing schemas/config, not code.
FreeformSchema-typed
Record structureFreeform records with no agreed structureEvery item’s item_type points at a versioned schema (e.g. profile_1.0)
InteroperabilityInstances have no shared structure, so inter-instance discovery is not possibleInstances in the same domain load the same network.json, so they can search each other
EvolvabilityChanging the model risks breaking peersVersioned item_types (profile_1.0 → profile_1.1) evolve without breaking peers
Domain changesA new domain or form means touching application codeTeams ship fields and forms by editing schemas/config — no code changes

Each domain is a folder under examples/schemas/ in the Signals DPG repository. Today there are four: blue_dot (jobs), yellow_dot (education), purple_dot (persons with disabilities) and orange_dot (tourism). The list of domains, their participant types and their status is on Domains, Participant Types & Instances.

The network.json in each folder is the minimum standard for a blue dot in that domain: the list of fields every one of them must have, so any organisation that uses it can share and find blue dots with others. The minimum standards are published for Blue (jobs), Yellow (education), Purple (disability) and Orange (tourism). Pink, Green and Brown have no minimum standard yet.

A domain folder holds:

  • network.json: the domain’s id, its participant types, item types and actions.
  • consent.json: the consent text participants accept (terms, privacy, profile and action consent).
  • messages.properties: optional overrides for the email copy.
  • Brand sub-folders: a brand is a UI and copy skin over the domain. It does not change the schema.

A deployment runs one domain. It chooses it with settings, not code: which network.json to load, which participant types to serve, and which domain id the UI shows. The setup guides list the exact variables: Signals DPG Setup for local runs and AWS Infrastructure Setup for a cluster.

The same profile_1.0 has different fields in each domain. A seeker profile in the Blue Dot (jobs) domain and a student profile in the Yellow Dot domain are both profile_1.0, but each domain’s network.json defines its own fields.

Some fields are authoritative and server-generated; clients must never set them:

  • item_instance_url — where an item lives.
  • item_schema_url — the schema it conforms to.

Schema-driven design is paired with strict configuration discipline:

  • All env vars are declared in one place (the Signals packages/config Zod schema; the Aggregator config loader). Ad-hoc process.env reads are not allowed.
  • In Signals, adding an env var means changing two places together: the Zod schema and turbo.json’s globalPassThroughEnv, or the value won’t reach filtered tasks.
  • Per-environment values are set as environment variables: in .env files locally, and through the Helm values in bluedots-automation on a cluster.