Data Model
The HDS data model defines all health data items, their types, streams, and relationships.
Structure
Section titled “Structure”- Items — individual data points (body-weight, body-height, bleeding, medication, treatment, procedure, etc.)
- Streams — hierarchical categories (body, fertility, medication, treatment, procedure, profile, …)
- Event types — Pryv event type definitions with JSON schemas
- Datasources — external data sources (medication, treatment, procedure databases)
Item Types
Section titled “Item Types”number— numeric values with optional unit variations (kg/lb, m/ft)select— single choice from optionscheckbox— boolean (activity/plain events)text— free textdate— date valuescomposite— nested object fieldsdatasource-search— search external datasources (medications, treatments, procedures)
Context-via-substream (D3 mechanic)
Section titled “Context-via-substream (D3 mechanic)”Items registered at a parent stream (e.g. treatment-coded at treatment) can be reused under a descendant stream (treatment-fertility) by passing a context to the form section. forEvent() walks parent streams to resolve the original itemDef, keeping a single coded surface across multiple medical subdomains. See data-model/documentation/TREATMENT-PROCEDURE.md.
App-level qualifiers & context (what HDS deliberately does not model)
Section titled “App-level qualifiers & context (what HDS deliberately does not model)”The root data model standardizes concepts that have cross-app machine-interoperability value. It does not try to encode every possible qualifier or circumstance on an observation — those are often specific to one application’s interpretation, and forcing them into the shared model would bloat it without a consumer that reads them.
Examples of app-level data: the situation of a symptom (e.g. pelvic pain graded by “on bowel movement”, “at ovulation”, “on a full bladder”), a lab draw’s sample context, or a “recorded from memory / date approximate” marker on a recalled history event. The measurement itself (ratio/* severity, pregnancy/detailed, a lab value) is modelled; the extra qualifier around it is the app’s.
Recommended pattern when your app needs to attach such data to an event:
clientData— for your app’s own structured use. This is the correct home precisely because HDS makes no interoperability claim about it:clientDatais documented for app-owned, non-authoritative data (its one standardized use in the model is therelatedcross-reference to other events). Do not put root-model authoritative data here.event.description— a short human-readable string (e.g. “pelvic pain, on bowel movement”, “prior miscarriage — date reported from memory”). This gives cross-app human visibility: any other HDS app, dashboard, or clinician view renders it, so the context isn’t lost even though it isn’t machine-structured.
Recalled history. Keep writing one event per occurrence (counts stay COUNT(events); do not revive deprecated aggregate-count items), set event.time to the intake date rather than a fabricated one, and mark it recalled via the pattern above. This maps cleanly to FHIR data-absent-reason: unknown on export.
When it should become root-model. The bar is a second application needing to machine-read the same qualifier across apps. At that point it graduates into the shared model — most likely as a coded circumstance axis in the event’s secondary streamIds (the tags/ mechanism), which keeps the measurement on its shared interoperability surface while adding the qualifier as a separate coded, multi-valued dimension. Until then, keep it app-level. (Background: site-agents #4.)
Published
Section titled “Published”The compiled model is served at model.datasafe.dev.