The DHIS2 formats¶
The pack contributes three JSON Schema formats. In JSON Schema format is an annotation that
asserts nothing on its own; dirigent's engine always hands its validator a checker, so a
format written in a schema this instance holds is enforced. Every format an installed pack
contributes joins the engine's own in that checker.
| Format | A string that is | Examples |
|---|---|---|
dhis2-uid |
a DHIS2 UID: one letter, then ten alphanumerics | ImspTQPwCqd, BfMAe6Itzgt |
dhis2-period |
a DHIS2 ISO period of one of the common types | 2026, 202601, 20260115, 2026Q1, 2026W03 |
dhis2-code |
a DHIS2 code: one to fifty characters, not padded, on one line | DE_359596, OU_222702, ANC 1st visit |
A format only ever narrows a string: a value of the wrong type is caught by type, and the
checker speaks only once the value is already a string. So a field written
{"type": ["string", "null"], "format": "dhis2-uid"} admits null and holds every string to
the format, the way the draft's own formats behave.
dhis2-uid¶
Eleven characters: [A-Za-z][A-Za-z0-9]{10}, matched whole. ImspTQPwCqd passes; a
ten-character string, a leading digit, and a UID with a hyphen in it are all refused.
dhis2-period¶
The common DHIS2 ISO period types, matched whole:
| Type | Shape | Example |
|---|---|---|
| Yearly | YYYY |
2026 |
| Monthly | YYYYMM |
202601 |
| Daily | YYYYMMDD |
20260115 |
| Quarterly | YYYYQn |
2026Q1 |
| Weekly | YYYYWn, zero-padded or not |
2026W3, 2026W03 |
The month, day, quarter and week numbers are bounded, so 202613 and 2026Q5 are refused.
The rarer period types are not covered: bi-weekly (YYYYBiWn), the weekly variants that start
on another day (YYYYWedWn, YYYYThuWn, YYYYSatWn, YYYYSunWn), bi-monthly (YYYYMMB),
six-monthly (YYYYSn), and the financial-year variants (YYYYApril, YYYYJuly, YYYYOct). A
schema that has to accept one of those uses pattern rather than this format.
dhis2-code¶
The code property every identifiable object in DHIS2 carries, and the key idScheme=CODE
addresses it by. DHIS2 caps a code at fifty characters and puts no character class on it, so
neither does this format: one to fifty characters, with no whitespace at either end and no
line break, matched whole. DE_359596, OU-222702 and ANC 1st visit all pass; an empty
string, a padded DE_359596, and a fifty-one-character string are refused.
An instance that keeps its codes to a house convention, say upper-case letters, digits and
underscores, writes that as a pattern beside the format. The format holds what DHIS2
itself holds; the convention is the schema author's.
Using one in a schema¶
Write the format beside the type, the way any other format is written:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "dhis2-data-value-set",
"title": "DHIS2 data value set",
"type": "object",
"required": ["dataValues"],
"properties": {
"dataSet": { "type": "string", "format": "dhis2-uid" },
"period": { "type": "string", "format": "dhis2-period" },
"orgUnit": { "type": "string", "format": "dhis2-uid" },
"dataValues": {
"type": "array",
"items": {
"type": "object",
"required": ["dataElement", "value"],
"properties": {
"dataElement": { "type": "string", "format": "dhis2-uid" },
"period": { "type": "string", "format": "dhis2-period" },
"value": { "type": "string" }
}
}
}
}
}
That schema is examples/schemas/dhis2-data-value-set.json. Apply it on
its own, then gate a step on it by code:
steps:
check:
block: validate.schema
config:
schema: dhis2-data-value-set
input: ${steps.export.output.body}
A schema is also what a pipeline's parameters are declared with, so a parameter written
format: dhis2-uid refuses a bad org unit when the run is submitted rather than when the call
is made.
Portability¶
A format no installed pack contributes stays a passing annotation: the value is valid, just unchecked. So the same schema asserts on an instance that has this pack and passes on one that does not, and a schema written against DHIS2 is not a schema only a DHIS2 instance can hold.