Skip to content
zublms
Documentation
Documentation/Engineering handbook

Engineering handbook · PostgreSQL 18

Know the data.
Understand the relationships.

A browsable schema map and complete field reference, generated from migrations in an empty disposable database. No customer records are included.

120 tables882 columns176 foreign keys55 schema version
A source snapshot, not a live database browser.

Includes application, Goose and River tables. Keycloak’s internal identity database, OpenBao storage and object contents are outside this schema. A stored table does not establish a completed product feature. JSONB contracts and associations without foreign keys require the owning Go service and API documentation.

Explore the relationships

Choose a domain to keep the graph readable. Cross-domain tables appear as context. Key fields are shown here; every field and SQL definition is available below.

Entity relationships

Catalogue & publishing

21 owned tables, with their outgoing foreign keys and immediate referenced tables.

Open SVG ↗
Catalogue & publishing. Read the explanation and editable diagram source below.
Overview · use Actual size to read small labels SVGMermaid source
How to read this diagram & source references
  • Only declared foreign keys form relationships. Missing lines do not prove that no application-level relationship exists.
  • PK/FK/UK mark participation in primary, foreign and unique constraints; composite keys apply to the whole column set. Full definitions are in the dictionary.
  • Crow’s feet show zero-or-many; a circle with a bar shows zero-or-one. Nullable child keys permit an absent parent. Solid lines identify keys contained in the child primary key; dashed lines are non-identifying.
  • Diagrams show key columns and a compact selection of fields. External tables are included for context; the dictionary contains every column.

Source references in the repository:

  • migrations/00009_drafts.sql
  • migrations/00010_course_versions.sql
  • migrations/00011_enrolments.sql
  • migrations/00012_quarantine.sql
  • migrations/00017_media_renditions.sql
  • migrations/00020_refresher_schedule.sql
  • migrations/00027_scorm_packages.sql
  • migrations/00030_dispatch_destinations.sql
  • migrations/00035_native_workspace.sql
  • migrations/00043_course_bookmarks.sql
  • migrations/00053_collections_pathways.sql
  • migrations/00046_course_builder.sql
  • migrations/00014_quiz_attempts.sql
  • migrations/00045_experience.sql
  • migrations/00049_learning_packages.sql
  • migrations/00028_scorm_launch_registrations.sql
  • migrations/00031_dispatch_registrations.sql
  • migrations/00036_workspace_command_results.sql
  • migrations/00054_people_directory.sql

The downloadable Mermaid file provides a text representation of every node and connection.

Data dictionary

Search table names, purposes or column names. Select a table to inspect its exact structure. Table links are shareable.

120 of 120 tables

Catalogue & publishing

courses

Mutable course drafts and authoring metadata.

5 columnsRLS enabledForced RLS yes
Columns, types and defaults
Column / keysSQL typeNullableDefault
organisation_idPK · FKuuidNo—
idPKuuidNo—
titletextNo—
revisionbigintNo1
metadatajsonbNo'{}'::jsonb
Relationships · 1 outgoing · 12 incoming

organisation_id → organisations (id)

Referenced by collection_courses: organisation_id + course_id

Referenced by course_bookmarks: organisation_id + course_id

Referenced by course_draft_assets: organisation_id + course_id

Referenced by course_draft_renditions: organisation_id + course_id

Referenced by course_versions: organisation_id + course_id

Referenced by dispatch_deployments: organisation_id + course_id

Referenced by enrolments: organisation_id + course_id

Referenced by modules: organisation_id + course_id

Referenced by pathway_course_links: organisation_id + course_id

Referenced by pathway_version_courses: organisation_id + course_id

Referenced by refresher_rules: organisation_id + course_id

Referenced by scorm_packages: organisation_id + course_id

Constraints & indexes

Composite uniqueness applies to the entire key. Partial indexes apply only when their predicate holds. NOT NULL appears in the column table above.

courses_organisation_fk
FOREIGN KEY (organisation_id) REFERENCES organisations(id)
courses_pkey
PRIMARY KEY (organisation_id, id)
courses_revision_positive
CHECK ((revision > 0))
courses_title_present
CHECK (((title = btrim(title)) AND (title <> ''::text)))
CREATE UNIQUE INDEX courses_pkey ON public.courses USING btree (organisation_id, id)
Row security & triggers
courses_isolation

ALL · PERMISSIVE · roles: public

USING (organisation_id = (NULLIF(current_setting('app.organisation_id'::text, true), ''::text))::uuid)
WITH CHECK (organisation_id = (NULLIF(current_setting('app.organisation_id'::text, true), ''::text))::uuid)

No user-defined triggers.

Migration references

Files mentioning this table, including later alterations; these are provenance pointers, not a replacement for the migration ledger.

  • migrations/00009_drafts.sql
  • migrations/00010_course_versions.sql
  • migrations/00011_enrolments.sql
  • migrations/00012_quarantine.sql
  • migrations/00017_media_renditions.sql
  • migrations/00020_refresher_schedule.sql
  • migrations/00027_scorm_packages.sql
  • migrations/00030_dispatch_destinations.sql
  • migrations/00035_native_workspace.sql
  • migrations/00043_course_bookmarks.sql
  • migrations/00053_collections_pathways.sql
All domain ER diagrams

Enums and views

river_job_state

available · cancelled · completed · discarded · pending · retryable · running · scheduled

0 SQL views in this schema snapshot.

Reading the model correctly

  • Tenant boundary: many keys pair organisation_id with an entity ID. Follow the full composite foreign key. Row-security policy details show how tenant context is enforced.
  • Stable learning: editable courses/modules/activities and immutable course_version_* snapshots have different lifecycles. Enrolments reference a published version.
  • Packages: learning_packages and related tables back the integrated library/player. Older scorm_* tables and dispatch_* foundations remain separately documented; they do not imply SCORM 2004 or complete hosted distribution.
  • Objects and jobs: PostgreSQL stores metadata and delivery state, not all file bytes. River coordinates jobs; queue tables are not tenant content APIs.
  • Security metadata: hashes, encrypted fields and key references are schema attributes. This page contains no actual tokens, secrets, passwords or user records.

Reproduce and keep it current

From the repository root, run the schema exporter only with a local Docker engine. It creates and removes its own temporary PostgreSQL container, refuses remote Docker contexts and never accepts an existing database URL.

python3 scripts/docs/generate-schema.py
npm run docs:diagrams --prefix web
npm run docs:check --prefix web

The final command checks migration/dependency fingerprints and generated asset hashes without Docker. Regeneration needs the pinned Mermaid development dependency and a Playwright browser. See docs/technical-diagrams.md for the maintenance contract.

See system components and UML

Documentation reviewed 3 November 2026 · Current implementation snapshot

Need account help? Contact your company administrator. Planning a rollout? Talk to us.