Add a Jurisdiction
Who this is for: onboarding a new country/regulatory market — its frameworks, document set, and reporting scheme — using the platform’s existing data model, without touching core schema.
Every claim below traces to Master Data Registry, the authoritative schema/design doc for this area. If the two disagree, that document wins.
Why this is a data change, not a migration
The governing rule (Master Data Registry §2): anything true in every jurisdiction lives in core
schema (learner, catalog_entry, enrolment, outcome, issuer); anything true only under one
country’s regulation lives in data — rows in the jurisdiction/framework/code-set/scheme-mapping
layer. Onboarding a new market should never need a schema migration; if a step below seems to
require one, stop and re-check against §2 before writing one.
Steps
1. Add the jurisdiction row
catalog.jurisdiction: jurisdiction_code (ISO 3166-1/2, e.g. IE, AU-QLD), name,
regulator_name, status (DRAFT initially). Keep it DRAFT until the steps below are seeded —
that status exists specifically so a partially-configured market isn’t live.
2. Add its qualification framework, if it has a numbered levels structure
catalog.qualification_framework / framework_level. Not every country has one — the US, Canada,
and Singapore don’t, and nothing is seeded for them; don’t invent a framework structure a country
doesn’t actually have. If the framework has non-standard steps (starts at 0, has half-levels),
store the ordered steps as-is with the official level in the label — don’t renumber to fit other
frameworks’ conventions.
3. Add its identity documents and licences
catalog.catalog_entry with entry_type = IDENTITY_DOCUMENT or LICENSE, named per that
jurisdiction’s own convention (<JURISDICTION>_<DOCUMENT>, e.g. IE_PASSPORT). These exist
specifically so the Custodian review picker and extraction-time suggestion search can offer them
by name; skipping this step means a custodian reviewer in your new market has nothing to select
for a document type that should exist.
Only mark an entry never_expires if it’s a genuine lifetime record (civil-status, citizenship, a
lifetime national ID number) — everything else (passports, licences, permits) leaves validity
unset so the document’s own printed expiry governs.
4. Add its code sets
catalog.code_set / code_value, one row per jurisdiction-specific enum value (delivery mode,
funding source, outcome result, identifier type, external register). Every vocabulary here is
data, never a CHECK constraint on a core table — this is the mechanism that makes step 1’s “no
migration needed” claim actually hold.
5. Add its regulatory scheme and field mappings, if it has a reporting/export obligation
catalog.regulatory_scheme (scheme_code, kind: REPORTING or IDENTITY_VERIFICATION) plus
scheme_field_map rows mapping core columns to that scheme’s export fields, using one of four
source_kind strategies: FIELD_PATH, CONSTANT, CODE_LOOKUP, CONCAT. Adding a fifth strategy
later is additive (a new FieldMapResolver implementation) — don’t add one preemptively if the
four already cover your scheme.
6. Register the jurisdiction’s learner identifier type, if it has a national ID scheme
code_set('LEARNER_ID_TYPE') (e.g. a new value alongside USI, NSN). The identifier value
itself is encrypted at rest with its own master key — nothing to configure per-jurisdiction there,
it’s already generic.
7. Flip the jurisdiction to ACTIVE
Once steps 1–6 are seeded and reviewed, update catalog.jurisdiction.status to ACTIVE. Issuers
can now register scheme registrations (catalog.issuer_scheme_registration) against this
jurisdiction, and the catalog/learner registration-to-issuance flow starts working for it.
What you’re deliberately not doing
Writing a new export job class, a new Program Catalog endpoint, or a schema migration. If any of those seem necessary, the jurisdiction you’re onboarding likely needs a genuinely new mechanism (not just new data) — that’s a design conversation against Master Data Registry itself, not a checklist item here.
Precedent to copy from
Master Data Registry §4’s seed data already covers AU, US, GB, IN, CA, SG, AE, NZ, EU, DE, and FR
(V2__seed_data.sql, Parts 1, 3, and 4) — read the seed rows for a market close to yours before
writing new ones from scratch.