@claudebernard/web-component-fhir-utils 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -98,6 +98,18 @@ Which produces a diff shaped like this — the original request goes `on-hold` v
98
98
  }
99
99
  ```
100
100
 
101
+ ### Supersession reasons
102
+
103
+ `PriorPrescriptionReason` carries *why* the new request replaces the old one, as a `valueCode` on the
104
+ `priorPrescription` extension. Pick the one that matches the user's intent — consumers filter on it
105
+ with `hasPriorPrescriptionReason`:
106
+
107
+ | Value | Code | When |
108
+ |---|---|---|
109
+ | `PriorPrescriptionReason.DOSAGE_OVERRIDE` | `dosage-override` | Same medication, dosage changed |
110
+ | `PriorPrescriptionReason.MEDICATION_OVERRIDE` | `medication-override` | Different medication, same therapeutic intent |
111
+ | `PriorPrescriptionReason.THERAPEUTIC_ALTERNATIVE` | `therapeutic-alternative` | Substitution proposed by `bcb-therapeutic-alternative` |
112
+
101
113
  More worked examples (including the therapeutic-alternative case) are in the [Developer Portal](https://platform.claudebernard.fr/doc) guide.
102
114
 
103
115
  ## API
@@ -113,6 +125,12 @@ More worked examples (including the therapeutic-alternative case) are in the [De
113
125
  | `hasPriorPrescriptionReason(medicationRequest, reason)` | Check why a `MedicationRequest` supersedes another |
114
126
  | `PriorPrescriptionReason`, `PRIOR_PRESCRIPTION_REASON_URL`, `BCB_CODE_SYSTEM` | Shared constants |
115
127
 
128
+ ## Versioning
129
+
130
+ This package carries the version of the `fhir-monorepo` repository — one version, tag and changelog
131
+ for the whole repo. Published versions are therefore sparse: a release only reaches npm when this
132
+ package actually changed.
133
+
116
134
  ## License
117
135
 
118
136
  Copyright of Cegedim. See [LICENSE](LICENSE.md) for details.
@@ -1,5 +1,13 @@
1
1
  import type { BundleEntry, MedicationRequest } from "fhir/r5";
2
2
  import { PriorPrescriptionReason } from "../constants/prior-prescription.const";
3
+ /**
4
+ * Builds the `priorPrescription` field housing both the link back to the previous
5
+ * MedicationRequest and the `prior-prescription-reason` extension recording why it was
6
+ * superseded/modified. The single home for this shape, so consumers linking to an already-existing
7
+ * `priorPrescription.reference` (e.g. updating a MedicationRequest in place instead of superseding
8
+ * it again) stay in sync with `supersedeMedicationRequest` below.
9
+ */
10
+ export declare function buildPriorPrescription(reference: string, reason: PriorPrescriptionReason): NonNullable<MedicationRequest["priorPrescription"]>;
3
11
  /**
4
12
  * Checks whether a MedicationRequest is the result of a supersession for a
5
13
  * given reason (e.g. a dosage override, or a therapeutic-alternative swap),
@@ -1 +1 @@
1
- {"version":3,"file":"supersede-resource.d.ts","sourceRoot":"","sources":["../../src/bundle/supersede-resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAiC,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAG/G;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,EACvD,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,EACnC,MAAM,EAAE,uBAAuB,GAC9B,WAAW,EAAE,CAsBf"}
1
+ {"version":3,"file":"supersede-resource.d.ts","sourceRoot":"","sources":["../../src/bundle/supersede-resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAiC,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAG/G;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,GAAG,WAAW,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC,CAK9I;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,EACvD,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,EACnC,MAAM,EAAE,uBAAuB,GAC9B,WAAW,EAAE,CAmBf"}
@@ -1,5 +1,18 @@
1
1
  import { PRIOR_PRESCRIPTION_REASON_URL } from "../constants/prior-prescription.const";
2
2
  import { createBundleEntry } from "./create-transaction-bundle";
3
+ /**
4
+ * Builds the `priorPrescription` field housing both the link back to the previous
5
+ * MedicationRequest and the `prior-prescription-reason` extension recording why it was
6
+ * superseded/modified. The single home for this shape, so consumers linking to an already-existing
7
+ * `priorPrescription.reference` (e.g. updating a MedicationRequest in place instead of superseding
8
+ * it again) stay in sync with `supersedeMedicationRequest` below.
9
+ */
10
+ export function buildPriorPrescription(reference, reason) {
11
+ return {
12
+ reference,
13
+ extension: [{ url: PRIOR_PRESCRIPTION_REASON_URL, valueCode: reason }],
14
+ };
15
+ }
3
16
  /**
4
17
  * Checks whether a MedicationRequest is the result of a supersession for a
5
18
  * given reason (e.g. a dosage override, or a therapeutic-alternative swap),
@@ -28,10 +41,7 @@ export function supersedeMedicationRequest(original, changes, reason) {
28
41
  ...changes,
29
42
  id: crypto.randomUUID(),
30
43
  status: "active",
31
- priorPrescription: {
32
- reference: `MedicationRequest/${original.id}`,
33
- extension: [{ url: PRIOR_PRESCRIPTION_REASON_URL, valueCode: reason }],
34
- },
44
+ priorPrescription: buildPriorPrescription(`MedicationRequest/${original.id}`, reason),
35
45
  };
36
46
  return [
37
47
  createBundleEntry(onHoldOriginal, "PUT"),
@@ -1 +1 @@
1
- {"version":3,"file":"supersede-resource.js","sourceRoot":"","sources":["../../src/bundle/supersede-resource.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAA2B,MAAM,uCAAuC,CAAC;AAC/G,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,iBAAuD,EACvD,MAA+B;IAE/B,MAAM,SAAS,GAAG,iBAAiB,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,CACrE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,6BAA6B,CACjD,CAAC;IACF,OAAO,SAAS,EAAE,SAAS,KAAK,MAAM,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAA2B,EAC3B,OAAmC,EACnC,MAA+B;IAE/B,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,cAAc,GAAsB,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAE7E,MAAM,WAAW,GAAsB;QACrC,GAAG,eAAe,CAAC,QAAQ,CAAC;QAC5B,GAAG,OAAO;QACV,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,MAAM,EAAE,QAAQ;QAChB,iBAAiB,EAAE;YACjB,SAAS,EAAE,qBAAqB,QAAQ,CAAC,EAAE,EAAE;YAC7C,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,6BAA6B,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;SACvE;KACF,CAAC;IAEF,OAAO;QACL,iBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC;QACxC,iBAAiB,CAAC,WAAW,EAAE,MAAM,CAAC;KACvC,CAAC;AACJ,CAAC","sourcesContent":["import type { BundleEntry, MedicationRequest } from \"fhir/r5\";\nimport { PRIOR_PRESCRIPTION_REASON_URL, PriorPrescriptionReason } from \"../constants/prior-prescription.const\";\nimport { createBundleEntry } from \"./create-transaction-bundle\";\n\n/**\n * Checks whether a MedicationRequest is the result of a supersession for a\n * given reason (e.g. a dosage override, or a therapeutic-alternative swap),\n * as tagged by `supersedeMedicationRequest`.\n */\nexport function hasPriorPrescriptionReason(\n medicationRequest: MedicationRequest | null | undefined,\n reason: PriorPrescriptionReason,\n): boolean {\n const extension = medicationRequest?.priorPrescription?.extension?.find(\n ext => ext.url === PRIOR_PRESCRIPTION_REASON_URL,\n );\n return extension?.valueCode === reason;\n}\n\n/**\n * Standard house pattern for representing \"this MedicationRequest replaces\n * that one\" as a transaction Bundle diff: the original is put `on-hold` via\n * PUT, and a new `active` MedicationRequest is created via POST, linked back\n * through `priorPrescription` and tagged with why via the\n * `prior-prescription-reason` extension.\n *\n * Returns the two entries ready to hand to `createTransactionBundle`.\n */\nexport function supersedeMedicationRequest(\n original: MedicationRequest,\n changes: Partial<MedicationRequest>,\n reason: PriorPrescriptionReason,\n): BundleEntry[] {\n if (!original.id) {\n throw new Error(\"supersedeMedicationRequest: original MedicationRequest must have an id\");\n }\n\n const onHoldOriginal: MedicationRequest = { ...original, status: \"on-hold\" };\n\n const superseding: MedicationRequest = {\n ...structuredClone(original),\n ...changes,\n id: crypto.randomUUID(),\n status: \"active\",\n priorPrescription: {\n reference: `MedicationRequest/${original.id}`,\n extension: [{ url: PRIOR_PRESCRIPTION_REASON_URL, valueCode: reason }],\n },\n };\n\n return [\n createBundleEntry(onHoldOriginal, \"PUT\"),\n createBundleEntry(superseding, \"POST\"),\n ];\n}\n"]}
1
+ {"version":3,"file":"supersede-resource.js","sourceRoot":"","sources":["../../src/bundle/supersede-resource.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAA2B,MAAM,uCAAuC,CAAC;AAC/G,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE,MAA+B;IACvF,OAAO;QACL,SAAS;QACT,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,6BAA6B,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;KACvE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,iBAAuD,EACvD,MAA+B;IAE/B,MAAM,SAAS,GAAG,iBAAiB,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,CACrE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,6BAA6B,CACjD,CAAC;IACF,OAAO,SAAS,EAAE,SAAS,KAAK,MAAM,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAA2B,EAC3B,OAAmC,EACnC,MAA+B;IAE/B,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,cAAc,GAAsB,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAE7E,MAAM,WAAW,GAAsB;QACrC,GAAG,eAAe,CAAC,QAAQ,CAAC;QAC5B,GAAG,OAAO;QACV,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,MAAM,EAAE,QAAQ;QAChB,iBAAiB,EAAE,sBAAsB,CAAC,qBAAqB,QAAQ,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC;KACtF,CAAC;IAEF,OAAO;QACL,iBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC;QACxC,iBAAiB,CAAC,WAAW,EAAE,MAAM,CAAC;KACvC,CAAC;AACJ,CAAC","sourcesContent":["import type { BundleEntry, MedicationRequest } from \"fhir/r5\";\nimport { PRIOR_PRESCRIPTION_REASON_URL, PriorPrescriptionReason } from \"../constants/prior-prescription.const\";\nimport { createBundleEntry } from \"./create-transaction-bundle\";\n\n/**\n * Builds the `priorPrescription` field housing both the link back to the previous\n * MedicationRequest and the `prior-prescription-reason` extension recording why it was\n * superseded/modified. The single home for this shape, so consumers linking to an already-existing\n * `priorPrescription.reference` (e.g. updating a MedicationRequest in place instead of superseding\n * it again) stay in sync with `supersedeMedicationRequest` below.\n */\nexport function buildPriorPrescription(reference: string, reason: PriorPrescriptionReason): NonNullable<MedicationRequest[\"priorPrescription\"]> {\n return {\n reference,\n extension: [{ url: PRIOR_PRESCRIPTION_REASON_URL, valueCode: reason }],\n };\n}\n\n/**\n * Checks whether a MedicationRequest is the result of a supersession for a\n * given reason (e.g. a dosage override, or a therapeutic-alternative swap),\n * as tagged by `supersedeMedicationRequest`.\n */\nexport function hasPriorPrescriptionReason(\n medicationRequest: MedicationRequest | null | undefined,\n reason: PriorPrescriptionReason,\n): boolean {\n const extension = medicationRequest?.priorPrescription?.extension?.find(\n ext => ext.url === PRIOR_PRESCRIPTION_REASON_URL,\n );\n return extension?.valueCode === reason;\n}\n\n/**\n * Standard house pattern for representing \"this MedicationRequest replaces\n * that one\" as a transaction Bundle diff: the original is put `on-hold` via\n * PUT, and a new `active` MedicationRequest is created via POST, linked back\n * through `priorPrescription` and tagged with why via the\n * `prior-prescription-reason` extension.\n *\n * Returns the two entries ready to hand to `createTransactionBundle`.\n */\nexport function supersedeMedicationRequest(\n original: MedicationRequest,\n changes: Partial<MedicationRequest>,\n reason: PriorPrescriptionReason,\n): BundleEntry[] {\n if (!original.id) {\n throw new Error(\"supersedeMedicationRequest: original MedicationRequest must have an id\");\n }\n\n const onHoldOriginal: MedicationRequest = { ...original, status: \"on-hold\" };\n\n const superseding: MedicationRequest = {\n ...structuredClone(original),\n ...changes,\n id: crypto.randomUUID(),\n status: \"active\",\n priorPrescription: buildPriorPrescription(`MedicationRequest/${original.id}`, reason),\n };\n\n return [\n createBundleEntry(onHoldOriginal, \"PUT\"),\n createBundleEntry(superseding, \"POST\"),\n ];\n}\n"]}
@@ -3,6 +3,7 @@ export declare const PRIOR_PRESCRIPTION_REASON_URL = "https://platform.claudeber
3
3
  export declare const PriorPrescriptionReason: {
4
4
  readonly DOSAGE_OVERRIDE: "dosage-override";
5
5
  readonly THERAPEUTIC_ALTERNATIVE: "therapeutic-alternative";
6
+ readonly MEDICATION_OVERRIDE: "medication-override";
6
7
  };
7
8
  export type PriorPrescriptionReason = typeof PriorPrescriptionReason[keyof typeof PriorPrescriptionReason];
8
9
  //# sourceMappingURL=prior-prescription.const.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prior-prescription.const.d.ts","sourceRoot":"","sources":["../../src/constants/prior-prescription.const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,+DAA+D,CAAC;AAE5F,eAAO,MAAM,6BAA6B,yFAAyF,CAAC;AAEpI,eAAO,MAAM,uBAAuB;;;CAG1B,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,OAAO,uBAAuB,CAAC,MAAM,OAAO,uBAAuB,CAAC,CAAC"}
1
+ {"version":3,"file":"prior-prescription.const.d.ts","sourceRoot":"","sources":["../../src/constants/prior-prescription.const.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,+DAA+D,CAAC;AAE5F,eAAO,MAAM,6BAA6B,yFAAyF,CAAC;AAEpI,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,OAAO,uBAAuB,CAAC,MAAM,OAAO,uBAAuB,CAAC,CAAC"}
@@ -3,5 +3,6 @@ export const PRIOR_PRESCRIPTION_REASON_URL = "https://platform.claudebernard.fr/
3
3
  export const PriorPrescriptionReason = {
4
4
  DOSAGE_OVERRIDE: "dosage-override",
5
5
  THERAPEUTIC_ALTERNATIVE: "therapeutic-alternative",
6
+ MEDICATION_OVERRIDE: "medication-override",
6
7
  };
7
8
  //# sourceMappingURL=prior-prescription.const.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prior-prescription.const.js","sourceRoot":"","sources":["../../src/constants/prior-prescription.const.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,4DAA4D,CAAC;AAE5F,MAAM,CAAC,MAAM,6BAA6B,GAAG,sFAAsF,CAAC;AAEpI,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,eAAe,EAAE,iBAAiB;IAClC,uBAAuB,EAAE,yBAAyB;CAC1C,CAAC","sourcesContent":["export const BCB_CODE_SYSTEM = \"https://platform.claudebernard.fr/fhir/CodeSystem/bcb-code\";\n\nexport const PRIOR_PRESCRIPTION_REASON_URL = \"https://platform.claudebernard.fr/fhir/StructureDefinition/prior-prescription-reason\";\n\nexport const PriorPrescriptionReason = {\n DOSAGE_OVERRIDE: \"dosage-override\",\n THERAPEUTIC_ALTERNATIVE: \"therapeutic-alternative\",\n} as const;\n\nexport type PriorPrescriptionReason = typeof PriorPrescriptionReason[keyof typeof PriorPrescriptionReason];\n"]}
1
+ {"version":3,"file":"prior-prescription.const.js","sourceRoot":"","sources":["../../src/constants/prior-prescription.const.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,4DAA4D,CAAC;AAE5F,MAAM,CAAC,MAAM,6BAA6B,GAAG,sFAAsF,CAAC;AAEpI,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,eAAe,EAAE,iBAAiB;IAClC,uBAAuB,EAAE,yBAAyB;IAClD,mBAAmB,EAAE,qBAAqB;CAClC,CAAC","sourcesContent":["export const BCB_CODE_SYSTEM = \"https://platform.claudebernard.fr/fhir/CodeSystem/bcb-code\";\n\nexport const PRIOR_PRESCRIPTION_REASON_URL = \"https://platform.claudebernard.fr/fhir/StructureDefinition/prior-prescription-reason\";\n\nexport const PriorPrescriptionReason = {\n DOSAGE_OVERRIDE: \"dosage-override\",\n THERAPEUTIC_ALTERNATIVE: \"therapeutic-alternative\",\n MEDICATION_OVERRIDE: \"medication-override\",\n} as const;\n\nexport type PriorPrescriptionReason = typeof PriorPrescriptionReason[keyof typeof PriorPrescriptionReason];\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claudebernard/web-component-fhir-utils",
3
- "version": "1.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Shared FHIR Bundle utilities (collection/transaction bundles, prior-prescription linking) for Claude Bernard web components and their integrators.",
5
5
  "type": "module",
6
6
  "types": "dist/index.d.ts",
@@ -69,40 +69,5 @@
69
69
  "eslint-plugin-import": "2.32.0",
70
70
  "typescript": "~5.9.3",
71
71
  "vitest": "^4.0.18"
72
- },
73
- "release": {
74
- "tagFormat": "${version}",
75
- "branches": ["master"],
76
- "plugins": [
77
- "@semantic-release/commit-analyzer",
78
- "@semantic-release/release-notes-generator",
79
- "@semantic-release/changelog",
80
- [
81
- "semantic-release-replace-plugin",
82
- {
83
- "replacements": [
84
- {
85
- "files": ["package.json"],
86
- "from": "\"version\": \"\\d+\\.\\d+\\.\\d+\"",
87
- "to": "\"version\": \"${nextRelease.version}\"",
88
- "results": [
89
- {
90
- "file": "package.json",
91
- "hasChanged": true
92
- }
93
- ]
94
- }
95
- ]
96
- }
97
- ],
98
- [
99
- "@semantic-release/git",
100
- {
101
- "message": "chore(release): ${nextRelease.version} [skip ci on prod]",
102
- "assets": ["package.json", "CHANGELOG.md"]
103
- }
104
- ],
105
- "@semantic-release/gitlab"
106
- ]
107
72
  }
108
73
  }