Skip to content

Commit 3b46b93

Browse files
committed
feat: HDSModelOverload — apps can extend the data-model at init time
Adds an optional overload payload to HDSModel.load() / initHDSModel() that deep-merges into modelData before deepFreeze. Apps can add new itemDefs, streams, eventTypes, settings, datasources, appStreams, and refine translations or default repeatable values without forking data-model. Forbidden mutations (parentId of an existing stream, schema of an existing eventType, type/streamId/eventType of an existing item, etc.) throw HDSLibError listing every violation. extractOverloadAsDefinitions() converts an overload back into a {filepath: content} map matching data-model/data-model/definitions/ layout so apps can dump their overload to disk and open a PR upstream. Browser-safe, no fs, no deps. 35 new tests, all passing. Bump 0.5.0 -> 0.6.0. Plan 34 done.
1 parent f08a16a commit 3b46b93

9 files changed

Lines changed: 908 additions & 8 deletions

AppTemplates.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,60 @@ Accept current request
141141
Revoke current request
142142

143143
#### collectorClient.refuse()
144-
Refuse current request
144+
Refuse current request
145+
146+
## Overloading the data model
147+
148+
Apps can extend the shared HDS data-model at init time without forking `data-model`. Pass an `HDSModelOverload` to `initHDSModel()`:
149+
150+
```js
151+
import { initHDSModel, extractOverloadAsDefinitions } from 'hds-lib';
152+
153+
const overload = {
154+
// Add brand new items
155+
items: {
156+
'mood-happy': {
157+
version: 'v1',
158+
label: { en: 'Happy', fr: 'Heureux' },
159+
description: { en: 'Feeling happy' },
160+
streamId: 'mood-happy',
161+
eventType: 'activity/plain',
162+
type: 'checkbox',
163+
repeatable: 'unlimited'
164+
},
165+
// Refine an existing item: add a translation, override repeatable
166+
'body-weight': {
167+
label: { fr: 'Poids' },
168+
repeatable: 'P1D'
169+
}
170+
},
171+
// Add new streams (must hang under an existing parent — or be a new root)
172+
streams: [
173+
{ id: 'mood', name: 'Mood', parentId: null, children: [
174+
{ id: 'mood-happy', name: 'Happy' }
175+
]}
176+
],
177+
// App-specific settings, eventTypes, datasources, appStreams also supported
178+
settings: {
179+
fontSize: { eventType: 'settings/font-size', type: 'number', default: 14 }
180+
}
181+
};
182+
183+
await initHDSModel({ overload });
184+
```
185+
186+
The overload is **validated** before merging — attempting to change the `parentId` of an existing stream, the `type`/schema of an existing eventType, or the `type`/`streamId`/`eventType` of an existing item throws `HDSLibError` listing every violation.
187+
188+
To later contribute your overload upstream, dump it to `data-model/data-model/definitions/`-shaped files:
189+
190+
```js
191+
import { writeFileSync, mkdirSync } from 'node:fs';
192+
import { dirname } from 'node:path';
193+
const files = extractOverloadAsDefinitions(overload);
194+
for (const [path, content] of Object.entries(files)) {
195+
mkdirSync(dirname(`./out/${path}`), { recursive: true });
196+
writeFileSync(`./out/${path}`, content);
197+
}
198+
```
199+
200+
Note: runtime overload validation only enforces the policy table (no AJV schema). For full schema validation, run `data-model/data-model/src/schemas/items.js` AJV against your overload at build time.

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
## [Unreleased]
44

5+
### Added
6+
- `HDSModelOverload` — apps can extend the shared HDS data-model at init time with their own itemDefs, streams, eventTypes, settings, datasources, or appStreams, plus refine translations and default `repeatable` values.
7+
- `HDSModel.load(url, overload?)` — merges the overload (after policy validation) before freezing.
8+
- `initHDSModel({ overload })` — same hook on the singleton init.
9+
- `extractOverloadAsDefinitions(overload)` — converts an overload back into a `{ filepath: content }` map matching the layout under `data-model/data-model/definitions/`, so apps can dump their overload to disk and open a PR upstream. Browser-safe (no `fs`).
10+
- Forbidden mutations (changing `parentId` of an existing stream, `type`/schema of an existing eventType, `type`/`streamId`/`eventType` of an existing item, etc.) throw `HDSLibError` listing every violation.
11+
512
## [0.5.0] - 2026-04-02
613

714
### Added

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hds-lib",
3-
"version": "0.5.0",
3+
"version": "0.6.0",
44
"description": "Health Data Safe - Library",
55
"type": "module",
66
"engines": {

0 commit comments

Comments
 (0)