DPG is a network-aware backend for publishing, validating, discovering, and interacting with schema-typed items across many independent instances.
The core model is:
- a network defines the shared contract
- a domain defines a role inside that network
- an instance serves one or more domains
- an item is a versioned schema-typed record
- an action is an interaction between items
- an event is the structured result of that action
This repository contains the current DPG API runtime, schema-driven UI app, docs site, example network schemas, and shared packages.
apps/api: Fastify API runtimeapps/docs: documentation siteapps/ui: schema-driven React UI for browsing domains, creating items, and triggering actionsexamples/schemas: example network definitions such asyellow_dotandblue_dotexamples/api: example request payloads in Markdownpackages/config: env parsing and network config loadingpackages/database: database helpers and partitioningpackages/schemas: API request schemas and network schema parsingpackages/auth: auth integrationpackages/notification: notification service client for OTP and outbound messagespackages/match_score: match score service client for item comparison
Main route groups:
/api/v1/item/api/v1/action/api/v1/event/api/v1/network
Important behavior:
POST /api/v1/item/createcreates an item on the current instanceGET /api/v1/item/fetchfetches items from the current instance onlyGET /api/v1/network/item/fetchperforms inter-instance fetch for a network/domainGET /api/v1/network/schema/:network/:domain/:itemTypereturns one concrete item schemaGET /api/v1/network/schemasreturns cached schemas known to the instancePOST /api/v1/network/refetch_schemasrefreshes schema cache
Item typing is schema-driven. item_type is not arbitrary; it should be a schema identifier defined by the network, for example profile_1.0 or profile_1.1.
The UI app lives in apps/ui. It is a React 19 + Vite frontend that renders pages from network and item schemas instead of hard-coding per-domain forms and cards.
Source: apps/ui on GitHub. Documentation: /apps/ui in the docs app.
Current UI responsibilities:
- browse items by domain
- create and edit schema-driven profiles
- render public item cards
- trigger action flows
- show map-based views through a pluggable map provider layer
UI runtime envs:
VITE_API_URL: base URL of the API appVITE_MAP_PROVIDER: active map provider, defaultleafletVITE_GEOCODING_API_URL: optional geocoding override
pnpm installStart from .env.example and set at least:
INSTANCE_ENV="development"
API_DOMAIN="http://localhost"
API_PORT="2742"
SERVED_DOMAINS="yellow_dot/student"
NETWORK_CONFIG_SOURCE="local"
NETWORK_CONFIG_LOCAL_FILE="examples/schemas/yellow_dot/network.json"
POSTGRES_HOST="127.0.0.1"
POSTGRES_PORT="5432"
REDIS_HOST="127.0.0.1"
REDIS_PORT="5555"For remote network configs, use:
NETWORK_CONFIG_SOURCE="remote"
NETWORK_CONFIG_URLS="yellow_dot=https://registry.example.com/schemas/yellow_dot/network.json"Or use SCHEMA_REGISTRY_URL with either:
- one base URL
- comma-separated
network=urlmappings
docker compose up -d db redispnpm db:migrate:apipnpm dev:apiTo run the API itself as a container against the Compose PostgreSQL and Redis services:
docker compose up -d db redis
DOCKER_NETWORK=dpg_internal pnpm docker:apiOptional:
pnpm dev:docsTo run the UI app:
pnpm dev:uiTypical local UI env:
VITE_API_URL="http://localhost:2742"
VITE_MAP_PROVIDER="leaflet"pnpm dev:apipnpm build:apipnpm preview:apipnpm start:apipnpm db:pull:apipnpm db:push:apipnpm db:generate:apipnpm db:migrate:apipnpm db:studio:apipnpm dev:docspnpm build:docspnpm dev:uipnpm build:uipnpm preview:ui
Local schema examples:
examples/schemas/yellow_dot/network.jsonexamples/schemas/blue_dot/network.json
API payload examples:
examples/api/yellow_dot.mdexamples/api/blue_dot.md
DPG treats notification delivery and match scoring as replaceable service integrations behind package-level clients.
- Notification service: dhiway/notification-service
- Match score service client:
packages/match_score
DPG uses two fetch paths:
GET /api/v1/item/fetch: instance-local fetch, intended for local reads such as a user's own items; cached briefly in RedisGET /api/v1/network/item/fetch: inter-instance fetch, which performs count-first discovery, selects only relevant peer instances, then fetches the required slices and caches the result in Redis
The full documentation lives in apps/docs. A good reading order is:
apps/docs/src/content/docs/index.mdapps/docs/src/content/docs/concepts/vocabulary.mdapps/docs/src/content/docs/concepts/architecture.mdapps/docs/src/content/docs/getting-started.mdapps/docs/src/content/docs/environment.mdapps/docs/src/content/docs/schemas/authoring.mdapps/docs/src/content/docs/apps/api.mdapps/docs/src/content/docs/apps/ui.md
The docs cover:
- vocabulary and architecture
- local setup, Docker, Dokploy, and Nixpacks hosting
- single-instance and multi-instance deployment
- schema authoring and versioning
- API behavior
- onboarding new networks and domains
item_typevalues should come from the network schema, not from freeform client input.- The backend generates
item_instance_urlanditem_schema_urlduring item creation. - Inter-instance schema fetching and caching are part of the network layer, not the item-local layer.