Skip to content

Commit 62bdad2

Browse files
committed
0.10.1 — eventToShortText: generalize formatDatasource for treatment + procedure
formatDatasource() previously only recognized medication's {drug, intake} shape (or the legacy flat shape). Newly added treatment-coded ({regimen, count?, notes?}) and procedure-coded ({procedure, count?, findings?, notes?}) events fell through to the JSON.stringify fallback and rendered the entire content blob in the diary. This change resolves the coded value across known shapes (drug / regimen / procedure) and falls back to the first object property that carries a `label`. Modality-specific extras append in the same `— …` suffix: - medication intake (doseValue, doseUnit, route) — preserved - count > 1 → "×N" - procedure findings[].label (first 1–2) - truncated notes All 50 existing tests still pass.
1 parent 6c05131 commit 62bdad2

3 files changed

Lines changed: 48 additions & 9 deletions

File tree

CHANGELOG.md

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

33
## [Unreleased]
44

5+
## [0.10.1] - 2026-05-01
6+
7+
### Fixed
8+
- **`eventToShortText` / `formatDatasource`** — generalized so newly added datasource-search items (`treatment/coded-v1` with `regimen`, `procedure/coded-v1` with `procedure`) produce a clean human label instead of a raw JSON dump. The function now resolves the coded value across known shapes (`drug` / `regimen` / `procedure`) and falls back to the first object property carrying a `label`. Appends `×count` when count > 1, the first 1–2 `findings[].label` entries (procedure), and a truncated `notes` string. Existing medication intake (`doseValue` + `doseUnit` + `route`) handling preserved; all 50 existing tests still pass.
9+
510
## [0.10.0] - 2026-04-30
611

712
### Added (plan 46 — context-via-substream resolution + new public API)

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.10.0",
3+
"version": "0.10.1",
44
"description": "Health Data Safe - Library",
55
"type": "module",
66
"engines": {

ts/HDSModel/eventToShortText.ts

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,27 +218,61 @@ function formatSelect (event: any, content: any, itemDef: any): string {
218218
function formatDatasource (content: any): string | null {
219219
if (!content || typeof content !== 'object') return String(content);
220220

221-
// medication/coded-v1: {drug: {label}, intake: {doseValue, doseUnit, route}}
222-
// legacy flat: {label, codes, doseValue, doseUnit, route}
223-
const label = content.drug?.label || content.label;
221+
// Resolve the coded value object across shapes:
222+
// medication/coded-v1 → {drug: {label, codes, ...}, intake: {...}}
223+
// treatment/coded-v1 → {regimen: {label, codes, ...}, count?, notes?}
224+
// procedure/coded-v1 → {procedure: {label, codes, ...}, count?, findings?, notes?}
225+
// medication legacy → {label, codes, doseValue, doseUnit, route}
226+
// generic datasource → any object with a property whose value carries a `label`
227+
let datasourceObj: any = content.drug ?? content.regimen ?? content.procedure;
228+
if (!datasourceObj && content.label) datasourceObj = content; // legacy flat
229+
if (!datasourceObj) {
230+
for (const v of Object.values(content)) {
231+
if (v && typeof v === 'object' && (v as any).label !== undefined) {
232+
datasourceObj = v;
233+
break;
234+
}
235+
}
236+
}
237+
238+
const label = datasourceObj?.label;
224239
let text: string;
225240
if (label) {
226-
text = typeof label === 'string' ? label : (localizeText(label) || JSON.stringify(content));
241+
text = typeof label === 'string' ? label : (localizeText(label) || JSON.stringify(datasourceObj));
227242
} else {
228243
text = JSON.stringify(content);
229244
}
230245

231-
const intake = content.intake || content;
232246
const parts: string[] = [];
233-
if (intake.doseValue) {
247+
248+
// Medication intake (new {drug, intake} OR legacy flat with doseValue at top level)
249+
const intake = content.intake || (datasourceObj === content ? content : null);
250+
if (intake?.doseValue) {
234251
const unitLabel = intake.doseUnit
235252
? intake.doseUnit.replace(/^dose\//, '').replace(/^(mass|volume)\//, '')
236253
: '';
237254
parts.push(`${intake.doseValue} ${unitLabel}`.trim());
238255
}
239-
if (intake.route) parts.push(intake.route);
240-
if (parts.length > 0) text += ' — ' + parts.join(', ');
256+
if (intake?.route) parts.push(intake.route);
241257

258+
// Treatment / procedure scalars (sibling fields on the event content)
259+
if (typeof content.count === 'number' && content.count > 1) {
260+
parts.push(${content.count}`);
261+
}
262+
if (Array.isArray(content.findings) && content.findings.length > 0) {
263+
const labels = content.findings.slice(0, 2).map((f: any) => {
264+
if (typeof f === 'string') return f;
265+
if (f?.label) return typeof f.label === 'string' ? f.label : (localizeText(f.label) || null);
266+
return null;
267+
}).filter(Boolean);
268+
if (labels.length > 0) parts.push(labels.join(', '));
269+
}
270+
if (typeof content.notes === 'string' && content.notes.trim() !== '') {
271+
const n = content.notes.trim();
272+
parts.push(n.length > 30 ? n.slice(0, 30) + '...' : n);
273+
}
274+
275+
if (parts.length > 0) text += ' — ' + parts.join(', ');
242276
return text;
243277
}
244278

0 commit comments

Comments
 (0)