@fuego-systems/core 0.1.14 → 0.1.16

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.
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MANDATORY_ADDON_OVERRIDE_ACTION_ID = void 0;
3
4
  exports.isProtocolGroup = isProtocolGroup;
4
5
  exports.getProtocolActions = getProtocolActions;
5
6
  exports.getDefaultProtocol = getDefaultProtocol;
@@ -9,7 +10,28 @@ exports.buildProtocolGroup = buildProtocolGroup;
9
10
  exports.configureProtocolGroup = configureProtocolGroup;
10
11
  exports.resolveProtocolSelection = resolveProtocolSelection;
11
12
  exports.readProtocolSelection = readProtocolSelection;
13
+ exports.readMandatoryAddonOverrides = readMandatoryAddonOverrides;
14
+ exports.resolveVariantMandatoryAddons = resolveVariantMandatoryAddons;
12
15
  const constants_1 = require("./constants");
16
+ /**
17
+ * `action.id` of the per-variant group that overrides the order-set PD's
18
+ * default mandatory add-ons (the tipo-3 `getMandatoryAddonIds` path). It lives
19
+ * as a direct child of a protocol-group variant action, kept structurally
20
+ * separate from the variant's own add-on sub-actions (the tipo-2
21
+ * `resolveProtocolSelection` path) so the two never conflate. Its group node
22
+ * carries no `definitionCanonical`, so `resolveProtocolSelection`,
23
+ * `getProtocolActions` and friends skip it and never descend into it.
24
+ */
25
+ exports.MANDATORY_ADDON_OVERRIDE_ACTION_ID = 'mandatory-addons';
26
+ /**
27
+ * FHIR-standard ActionType code system. Each override sub-action carries a
28
+ * `type.coding` from this system: `create` = add the add-on to the variant's
29
+ * mandatory set, `remove` = drop a PD-default mandatory add-on. `requiredBehavior`
30
+ * is not used for this because FHIR's value set has no "exclude" member.
31
+ */
32
+ const ACTION_TYPE_SYSTEM = 'http://terminology.hl7.org/CodeSystem/action-type';
33
+ const ACTION_TYPE_ADD = 'create';
34
+ const ACTION_TYPE_REMOVE = 'remove';
13
35
  // ─── Detection ───────────────────────────────────────────────────────────────
14
36
  /**
15
37
  * Returns `true` if the PlanDefinition is a protocol-group (wrapping multiple concrete PDs).
@@ -85,12 +107,14 @@ function getProtocolGroupHealthcareServiceReference(pd) {
85
107
  function buildProtocolGroup(title, entries, existingId, hsReference) {
86
108
  const actions = entries.map((e) => {
87
109
  var _a;
88
- const subActions = ((_a = e.addons) !== null && _a !== void 0 ? _a : []).map((addon) => buildAction(addon.id, addon.display, addon.ref, addon.code, addon.duration, addon.question, addon.label, addon.mandatory));
89
- const action = buildAction(e.isDefault ? 'default' : e.id, e.display, e.ref, e.code, e.duration, e.question, e.label);
110
+ const subActions = ((_a = e.addons) !== null && _a !== void 0 ? _a : []).map((addon) => buildAction(addon.id, addon.display, addon.ref, addon.code, addon.duration, addon.question, addon.label, addon.mandatory, addon.praId));
111
+ const action = buildAction(e.isDefault ? 'default' : e.id, e.display, e.ref, e.code, e.duration, e.question, e.label, undefined, e.praId);
90
112
  // Top-level actions use exactly-one selection behavior
91
113
  action.selectionBehavior = 'exactly-one';
92
- if (subActions.length > 0) {
93
- action.action = subActions;
114
+ const overrideGroup = buildMandatoryAddonOverrideGroup(e.mandatoryAddonOverrides);
115
+ const childActions = overrideGroup ? [...subActions, overrideGroup] : subActions;
116
+ if (childActions.length > 0) {
117
+ action.action = childActions;
94
118
  // When an action has sub-actions (addons), they use `any` grouping
95
119
  action.groupingBehavior = 'logical-group';
96
120
  }
@@ -151,8 +175,12 @@ function configureProtocolGroup(pd, selection) {
151
175
  const isSelected = a.id === selection.actionId;
152
176
  const subActions = ((_a = a.action) !== null && _a !== void 0 ? _a : []).map((sub) => {
153
177
  var _a;
178
+ // The mandatory-addons override group is server-side configuration,
179
+ // not a selectable addon — never stamp it as prechecked, even if a
180
+ // (buggy) caller passes its id among the addonIds.
181
+ const isOverrideGroup = sub.id === exports.MANDATORY_ADDON_OVERRIDE_ACTION_ID;
154
182
  const isMandatory = sub.requiredBehavior === 'must';
155
- const isOn = isSelected && (isMandatory || addonSet.has((_a = sub.id) !== null && _a !== void 0 ? _a : ''));
183
+ const isOn = isSelected && !isOverrideGroup && (isMandatory || addonSet.has((_a = sub.id) !== null && _a !== void 0 ? _a : ''));
156
184
  return {
157
185
  ...sub,
158
186
  precheckBehavior: isOn ? 'yes' : 'no'
@@ -224,7 +252,7 @@ function readProtocolSelection(pd) {
224
252
  if (prechecked === null || prechecked === void 0 ? void 0 : prechecked.id) {
225
253
  const addonIds = ((_b = prechecked.action) !== null && _b !== void 0 ? _b : [])
226
254
  .filter((sub) => {
227
- if (!sub.id) {
255
+ if (!sub.id || sub.id === exports.MANDATORY_ADDON_OVERRIDE_ACTION_ID) {
228
256
  return false;
229
257
  }
230
258
  if (sub.requiredBehavior === 'must') {
@@ -250,6 +278,12 @@ function getActionServiceCode(action) {
250
278
  .find((c) => c.system === constants_1.SERVICE_TYPE_SYSTEM);
251
279
  return (_b = coding === null || coding === void 0 ? void 0 : coding.code) !== null && _b !== void 0 ? _b : '';
252
280
  }
281
+ function getActionPraId(action) {
282
+ var _a, _b;
283
+ return (_b = ((_a = action.code) !== null && _a !== void 0 ? _a : [])
284
+ .flatMap((cc) => { var _a; return (_a = cc.coding) !== null && _a !== void 0 ? _a : []; })
285
+ .find((c) => c.system === constants_1.EGES_PRACTICA_SYSTEM)) === null || _b === void 0 ? void 0 : _b.code;
286
+ }
253
287
  function precheckToBool(value) {
254
288
  if (value === 'yes') {
255
289
  return true;
@@ -262,7 +296,7 @@ function precheckToBool(value) {
262
296
  function extractActionInfo(a, isDefault) {
263
297
  var _a, _b, _c, _d, _e, _f;
264
298
  const subActions = ((_a = a.action) !== null && _a !== void 0 ? _a : [])
265
- .filter((sub) => Boolean(sub.definitionCanonical))
299
+ .filter((sub) => Boolean(sub.definitionCanonical) && sub.id !== exports.MANDATORY_ADDON_OVERRIDE_ACTION_ID)
266
300
  .map((sub) => extractActionInfo(sub, false));
267
301
  return {
268
302
  actionId: (_b = a.id) !== null && _b !== void 0 ? _b : '',
@@ -272,20 +306,125 @@ function extractActionInfo(a, isDefault) {
272
306
  protocolRef: a.definitionCanonical,
273
307
  protocolDisplay: (_f = a.title) !== null && _f !== void 0 ? _f : '',
274
308
  protocolCode: getActionServiceCode(a),
309
+ praId: getActionPraId(a),
275
310
  duration: a.timingDuration,
276
311
  prechecked: precheckToBool(a.precheckBehavior),
277
312
  mandatory: a.requiredBehavior === 'must' ? true : undefined,
278
- addons: subActions
313
+ addons: subActions,
314
+ mandatoryAddonOverrides: readMandatoryAddonOverrides(a)
315
+ };
316
+ }
317
+ /**
318
+ * Reads the per-variant mandatory-addon overrides out of a variant action's
319
+ * `mandatory-addons` group. Returns `[]` when the variant declares none.
320
+ *
321
+ * @param variantAction - a protocol-group top-level variant action
322
+ * @returns the variant's mandatory-addon overrides (empty when none)
323
+ */
324
+ function readMandatoryAddonOverrides(variantAction) {
325
+ var _a, _b;
326
+ const group = ((_a = variantAction.action) !== null && _a !== void 0 ? _a : []).find((sub) => sub.id === exports.MANDATORY_ADDON_OVERRIDE_ACTION_ID);
327
+ const result = [];
328
+ for (const sub of (_b = group === null || group === void 0 ? void 0 : group.action) !== null && _b !== void 0 ? _b : []) {
329
+ if (!sub.definitionCanonical) {
330
+ continue;
331
+ }
332
+ const action = overrideActionFromActionType(sub);
333
+ if (!action) {
334
+ continue;
335
+ }
336
+ result.push(sub.title !== undefined
337
+ ? { ref: sub.definitionCanonical, action, display: sub.title }
338
+ : { ref: sub.definitionCanonical, action });
339
+ }
340
+ return result;
341
+ }
342
+ /**
343
+ * Resolves the effective mandatory add-on canonicals for a selected variant:
344
+ * the order-set PD defaults, plus the variant's `'add'` overrides, minus its
345
+ * `'remove'` overrides. Order-set defaults and overrides are matched by exact
346
+ * canonical string. Deduplicated; input order of the defaults is preserved,
347
+ * with any added canonicals appended.
348
+ *
349
+ * @param defaultRefs - canonicals of the order-set PD's default mandatory add-ons
350
+ * @param variantAction - the selected protocol-group variant action, or undefined
351
+ * @returns the resolved set of mandatory add-on canonicals
352
+ */
353
+ function resolveVariantMandatoryAddons(defaultRefs, variantAction) {
354
+ const resolved = new Set(defaultRefs);
355
+ if (variantAction) {
356
+ for (const override of readMandatoryAddonOverrides(variantAction)) {
357
+ if (override.action === 'add') {
358
+ resolved.add(override.ref);
359
+ }
360
+ else {
361
+ resolved.delete(override.ref);
362
+ }
363
+ }
364
+ }
365
+ return Array.from(resolved);
366
+ }
367
+ /**
368
+ * Maps an override sub-action's `type.coding` (ActionType) back to add/remove.
369
+ *
370
+ * @param sub - an override group sub-action
371
+ * @returns `'add'` for `create`, `'remove'` for `remove`, else undefined
372
+ */
373
+ function overrideActionFromActionType(sub) {
374
+ var _a, _b, _c;
375
+ const code = (_c = ((_b = (_a = sub.type) === null || _a === void 0 ? void 0 : _a.coding) !== null && _b !== void 0 ? _b : []).find((c) => c.system === ACTION_TYPE_SYSTEM)) === null || _c === void 0 ? void 0 : _c.code;
376
+ if (code === ACTION_TYPE_ADD) {
377
+ return 'add';
378
+ }
379
+ if (code === ACTION_TYPE_REMOVE) {
380
+ return 'remove';
381
+ }
382
+ return undefined;
383
+ }
384
+ /**
385
+ * Builds the `mandatory-addons` override group child for a variant, or returns
386
+ * `undefined` when the variant declares no overrides. Each override becomes a
387
+ * sub-action referencing the add-on's canonical, with `requiredBehavior`
388
+ * `'must'` (add) or `'prohibited'` (remove).
389
+ *
390
+ * @param overrides - the variant's mandatory-addon overrides (may be undefined)
391
+ * @returns the override group action, or undefined when there are no overrides
392
+ */
393
+ function buildMandatoryAddonOverrideGroup(overrides) {
394
+ if (!overrides || overrides.length === 0) {
395
+ return undefined;
396
+ }
397
+ return {
398
+ id: exports.MANDATORY_ADDON_OVERRIDE_ACTION_ID,
399
+ title: 'Adicionales obligatorios (override por variante)',
400
+ selectionBehavior: 'any',
401
+ action: overrides.map((o) => {
402
+ const sub = {
403
+ definitionCanonical: o.ref,
404
+ type: {
405
+ coding: [{ system: ACTION_TYPE_SYSTEM, code: o.action === 'add' ? ACTION_TYPE_ADD : ACTION_TYPE_REMOVE }]
406
+ }
407
+ };
408
+ if (o.display) {
409
+ sub.title = o.display;
410
+ }
411
+ return sub;
412
+ })
279
413
  };
280
414
  }
281
- function buildAction(id, title, ref, code, duration, question, labelOverride, mandatory) {
415
+ function buildAction(id, title, ref, code, duration, question, labelOverride, mandatory, praId) {
282
416
  const action = {
283
417
  id,
284
418
  title,
285
419
  definitionCanonical: ref
286
420
  };
287
- if (code) {
288
- action.code = [{ coding: [{ system: constants_1.SERVICE_TYPE_SYSTEM, code }] }];
421
+ if (code || praId) {
422
+ action.code = [{
423
+ coding: [
424
+ ...(code ? [{ system: constants_1.SERVICE_TYPE_SYSTEM, code }] : []),
425
+ ...(praId ? [{ system: constants_1.EGES_PRACTICA_SYSTEM, code: praId }] : [])
426
+ ]
427
+ }];
289
428
  }
290
429
  if (duration) {
291
430
  action.timingDuration = duration;
@@ -1 +1 @@
1
- {"version":3,"file":"plan-definition-group.js","sourceRoot":"","sources":["../src/plan-definition-group.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Duration, PlanDefinition, PlanDefinitionAction } from '@medplum/fhirtypes'\nimport { PD_HEALTHCARE_SERVICE_EXTENSION_URL, PD_TYPE_PROTOCOL_GROUP, PD_TYPE_SYSTEM, SERVICE_TYPE_SYSTEM } from './constants'\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Information about a single action inside a protocol-group PD. */\nexport interface ProtocolActionInfo {\n readonly actionId: string\n readonly isDefault: boolean\n /** Short label for the variant (e.g. \"Helicoidal\") */\n readonly label: string\n /** User-facing question to select this variant */\n readonly question: string\n readonly protocolRef: string\n readonly protocolDisplay: string\n readonly protocolCode: string\n readonly duration?: Duration\n /**\n * Whether this action is pre-selected in a **configured** protocol-group.\n * Set by {@link configureProtocolGroup} via FHIR `precheckBehavior`.\n * `undefined` means the PD has not been configured (use `isDefault` as fallback).\n */\n readonly prechecked?: boolean\n /**\n * Only meaningful on addon (sub-action) entries. When `true`, the addon is\n * always included whenever its parent action is selected — it is not shown\n * as a togglable option in the consumer UI. Encoded in FHIR as\n * `PlanDefinitionAction.requiredBehavior === 'must'`.\n */\n readonly mandatory?: boolean\n /** Optional sub-actions (addons) with `any` selection behavior. */\n readonly addons: readonly ProtocolActionInfo[]\n}\n\n/** Entry used to build a protocol-group PD action. */\nexport interface ProtocolGroupActionEntry {\n readonly id: string\n readonly isDefault: boolean\n readonly label: string\n readonly question: string\n readonly ref: string\n readonly display: string\n readonly code: string\n readonly duration?: Duration\n /**\n * Only meaningful on addon entries. When `true`, the addon is always\n * included with the parent action and is hidden from the consumer UI.\n */\n readonly mandatory?: boolean\n /** Optional sub-action entries (addons). */\n readonly addons?: readonly ProtocolGroupActionEntry[]\n}\n\n// ─── Backward-compat aliases ────────────────────────────────────────────────\n\n/** @deprecated Use {@link ProtocolActionInfo} instead. */\nexport type ProtocolVariantInfo = ProtocolActionInfo\n\n/** @deprecated Use {@link ProtocolActionInfo} instead. */\nexport interface ProtocolDefaultInfo {\n readonly ref: string\n readonly display: string\n readonly code: string\n readonly duration?: Duration\n}\n\n// ─── Detection ───────────────────────────────────────────────────────────────\n\n/**\n * Returns `true` if the PlanDefinition is a protocol-group (wrapping multiple concrete PDs).\n *\n * @param pd - the PlanDefinition to check\n * @returns whether the PlanDefinition is a protocol-group\n */\nexport function isProtocolGroup (pd: PlanDefinition): boolean {\n return (pd.type?.coding ?? []).some(\n (c) => c.system === PD_TYPE_SYSTEM && c.code === PD_TYPE_PROTOCOL_GROUP\n )\n}\n\n// ─── Extraction ──────────────────────────────────────────────────────────────\n\n/**\n * Extracts all protocol actions from a protocol-group PD (preserving order).\n *\n * @param pd - the protocol-group PlanDefinition\n * @returns array of action info objects (the one with `isDefault === true` is the default)\n */\nexport function getProtocolActions (pd: PlanDefinition): ProtocolActionInfo[] {\n return (pd.action ?? [])\n .filter((a): a is PlanDefinitionAction & { definitionCanonical: string } =>\n Boolean(a.definitionCanonical)\n )\n .map((a) => extractActionInfo(a, a.id === 'default'))\n}\n\n/**\n * Extracts the default protocol action from a protocol-group PD.\n *\n * @param pd - the protocol-group PlanDefinition\n * @returns the default protocol info, or undefined if not found\n */\nexport function getDefaultProtocol (pd: PlanDefinition): ProtocolDefaultInfo | undefined {\n const action = (pd.action ?? []).find((a) => a.id === 'default')\n if (!action?.definitionCanonical) { return undefined }\n return {\n ref: action.definitionCanonical,\n display: action.title ?? '',\n code: getActionServiceCode(action),\n duration: action.timingDuration\n }\n}\n\n/**\n * Extracts the non-default variant actions from a protocol-group PD.\n *\n * @param pd - the protocol-group PlanDefinition\n * @returns array of variant info objects\n */\nexport function getProtocolVariants (pd: PlanDefinition): ProtocolActionInfo[] {\n return getProtocolActions(pd).filter((a) => !a.isDefault)\n}\n\n/**\n * Extracts the HealthcareService reference linked to a protocol-group PD.\n *\n * @param pd - the PlanDefinition to inspect\n * @returns the referenced HealthcareService, if present\n */\nexport function getProtocolGroupHealthcareServiceReference (pd: PlanDefinition): string | undefined {\n return pd.extension?.find((e) => e.url === PD_HEALTHCARE_SERVICE_EXTENSION_URL)?.valueReference?.reference\n}\n\n// ─── Construction ────────────────────────────────────────────────────────────\n\n/**\n * Builds a protocol-group PlanDefinition resource.\n *\n * @param title - human-readable title for the group (e.g. \"TAC de hombro — Protocolos\")\n * @param entries - protocol action entries (at least one should have `isDefault: true`)\n * @param existingId - optional ID to reuse when updating an existing group PD\n * @param hsReference - optional HealthcareService reference stored on the group PD\n * @returns the constructed protocol-group PlanDefinition\n */\nexport function buildProtocolGroup (\n title: string,\n entries: readonly ProtocolGroupActionEntry[],\n existingId?: string,\n hsReference?: string\n): PlanDefinition {\n const actions: PlanDefinitionAction[] = entries.map((e) => {\n const subActions = (e.addons ?? []).map((addon) =>\n buildAction(\n addon.id,\n addon.display,\n addon.ref,\n addon.code,\n addon.duration,\n addon.question,\n addon.label,\n addon.mandatory\n )\n )\n\n const action = buildAction(\n e.isDefault ? 'default' : e.id,\n e.display,\n e.ref,\n e.code,\n e.duration,\n e.question,\n e.label\n )\n\n // Top-level actions use exactly-one selection behavior\n action.selectionBehavior = 'exactly-one'\n\n if (subActions.length > 0) {\n action.action = subActions\n // When an action has sub-actions (addons), they use `any` grouping\n action.groupingBehavior = 'logical-group'\n }\n\n return action\n })\n\n const pd: PlanDefinition = {\n resourceType: 'PlanDefinition',\n status: 'active',\n title,\n type: {\n coding: [{ system: PD_TYPE_SYSTEM, code: PD_TYPE_PROTOCOL_GROUP }]\n },\n action: actions\n }\n\n if (hsReference) {\n pd.extension = [\n {\n url: PD_HEALTHCARE_SERVICE_EXTENSION_URL,\n valueReference: { reference: hsReference }\n }\n ]\n }\n\n if (existingId) {\n pd.id = existingId\n }\n\n return pd\n}\n\n// ─── Selection / Configuration ──────────────────────────────────────────────\n\n/**\n * A user's selection within a protocol-group PlanDefinition.\n *\n * Represents the patient's choices when configuring a HealthcareService:\n * one main action (from the `exactly-one` selection) plus zero or more\n * addon sub-actions.\n */\nexport interface ProtocolSelection {\n /** The `action.id` of the chosen top-level action. */\n readonly actionId: string\n /** The `action.id`s of toggled-on addon sub-actions within the selected action. */\n readonly addonIds: readonly string[]\n}\n\n/** Resolved booking parameters for a single protocol action. */\nexport interface ResolvedProtocolAction {\n /** The `definitionCanonical` reference to the order-set PlanDefinition. */\n readonly protocolRef: string\n /** The service-type code for slot searching / billing. */\n readonly serviceType: string\n /** Estimated duration for this action. */\n readonly duration?: Duration\n}\n\n/** Fully resolved booking parameters produced by {@link resolveProtocolSelection}. */\nexport interface ResolvedProtocol {\n /** Resolved main action. */\n readonly main: ResolvedProtocolAction\n /** Resolved addon actions (empty when none selected). */\n readonly addons: readonly ResolvedProtocolAction[]\n}\n\n/**\n * Returns a **configured** copy of a protocol-group PlanDefinition by stamping\n * `precheckBehavior` on every action according to the given selection.\n *\n * - The selected top-level action gets `precheckBehavior: \"yes\"`, all others `\"no\"`.\n * - Within the selected action, each addon sub-action is stamped according to\n * whether its id appears in `selection.addonIds`. **Mandatory addons**\n * (`requiredBehavior === 'must'`) are always stamped `\"yes\"` regardless of\n * the caller-provided ids.\n * - Unselected top-level actions have all their sub-actions stamped as `\"no\"`.\n *\n * The returned PD is a shallow copy — the original is never mutated.\n *\n * @param pd - a protocol-group PlanDefinition\n * @param selection - the user's action + addon selection\n * @returns a new PlanDefinition with `precheckBehavior` set on every action\n * @throws if the selected `actionId` is not found in the PD\n */\nexport function configureProtocolGroup (\n pd: PlanDefinition,\n selection: ProtocolSelection\n): PlanDefinition {\n const actions = pd.action ?? []\n const found = actions.some((a) => a.id === selection.actionId)\n if (!found) {\n throw new Error(`Action \"${selection.actionId}\" not found in protocol-group PlanDefinition`)\n }\n\n const addonSet = new Set(selection.addonIds)\n\n return {\n ...pd,\n action: actions.map((a) => {\n const isSelected = a.id === selection.actionId\n const subActions = (a.action ?? []).map((sub) => {\n const isMandatory = sub.requiredBehavior === 'must'\n const isOn = isSelected && (isMandatory || addonSet.has(sub.id ?? ''))\n return {\n ...sub,\n precheckBehavior: isOn ? 'yes' as const : 'no' as const\n }\n })\n\n return {\n ...a,\n precheckBehavior: isSelected ? 'yes' as const : 'no' as const,\n ...(a.action ? { action: subActions } : {})\n }\n })\n }\n}\n\n/**\n * Resolves a protocol-group PlanDefinition + selection into concrete booking\n * parameters (service-type codes, definitionCanonical references, durations).\n *\n * @param pd - a protocol-group PlanDefinition\n * @param selection - the user's action + addon selection\n * @returns the resolved main + addon protocol references and codes\n * @throws if the selected `actionId` is not found in the PD\n */\nexport function resolveProtocolSelection (\n pd: PlanDefinition,\n selection: ProtocolSelection\n): ResolvedProtocol {\n const actions = pd.action ?? []\n const selected = actions.find((a) => a.id === selection.actionId)\n if (!selected?.definitionCanonical) {\n throw new Error(`Action \"${selection.actionId}\" not found in protocol-group PlanDefinition`)\n }\n\n const addonSet = new Set(selection.addonIds)\n const resolvedAddons: ResolvedProtocolAction[] = (selected.action ?? [])\n .filter((sub): sub is PlanDefinitionAction & { definitionCanonical: string; id: string } => {\n if (!sub.id || !sub.definitionCanonical) { return false }\n const isMandatory = sub.requiredBehavior === 'must'\n return isMandatory || addonSet.has(sub.id)\n })\n .map((sub) => ({\n protocolRef: sub.definitionCanonical,\n serviceType: getActionServiceCode(sub),\n duration: sub.timingDuration\n }))\n\n return {\n main: {\n protocolRef: selected.definitionCanonical,\n serviceType: getActionServiceCode(selected),\n duration: selected.timingDuration\n },\n addons: resolvedAddons\n }\n}\n\n/**\n * Reads the current selection from a **configured** protocol-group PlanDefinition\n * (one whose actions have been stamped with `precheckBehavior` via\n * {@link configureProtocolGroup}).\n *\n * Falls back to `id === \"default\"` with mandatory addons of that default\n * action when no action has `precheckBehavior: \"yes\"`.\n *\n * @param pd - a (possibly configured) protocol-group PlanDefinition\n * @returns the selection encoded in the PD, or the default selection\n */\nexport function readProtocolSelection (pd: PlanDefinition): ProtocolSelection {\n const actions = pd.action ?? []\n\n // Look for an action explicitly marked as prechecked\n const prechecked = actions.find((a) => a.precheckBehavior === 'yes')\n if (prechecked?.id) {\n const addonIds = (prechecked.action ?? [])\n .filter((sub): sub is PlanDefinitionAction & { id: string } => {\n if (!sub.id) { return false }\n if (sub.requiredBehavior === 'must') { return true }\n return sub.precheckBehavior === 'yes'\n })\n .map((sub) => sub.id)\n return { actionId: prechecked.id, addonIds }\n }\n\n // Fallback: default action with its mandatory addons (if any)\n const defaultAction = actions.find((a) => a.id === 'default') ?? actions[0]\n const mandatoryAddonIds = (defaultAction?.action ?? [])\n .filter((sub): sub is PlanDefinitionAction & { id: string } =>\n Boolean(sub.id) && sub.requiredBehavior === 'must'\n )\n .map((sub) => sub.id)\n return { actionId: defaultAction?.id ?? '', addonIds: mandatoryAddonIds }\n}\n\n// ─── Internal helpers ───────────────────────────────────────────────────────\n\nfunction getActionServiceCode (action: PlanDefinitionAction): string {\n const coding = (action.code ?? [])\n .flatMap((cc) => cc.coding ?? [])\n .find((c) => c.system === SERVICE_TYPE_SYSTEM)\n return coding?.code ?? ''\n}\n\nfunction precheckToBool (value: string | undefined): boolean | undefined {\n if (value === 'yes') { return true }\n if (value === 'no') { return false }\n return undefined\n}\n\nfunction extractActionInfo (a: PlanDefinitionAction & { definitionCanonical: string }, isDefault: boolean): ProtocolActionInfo {\n const subActions = (a.action ?? [])\n .filter((sub): sub is PlanDefinitionAction & { definitionCanonical: string } =>\n Boolean(sub.definitionCanonical)\n )\n .map((sub) => extractActionInfo(sub, false))\n\n return {\n actionId: a.id ?? '',\n isDefault,\n label: a.textEquivalent ?? a.title ?? '',\n question: a.description ?? '',\n protocolRef: a.definitionCanonical,\n protocolDisplay: a.title ?? '',\n protocolCode: getActionServiceCode(a),\n duration: a.timingDuration,\n prechecked: precheckToBool(a.precheckBehavior),\n mandatory: a.requiredBehavior === 'must' ? true : undefined,\n addons: subActions\n }\n}\n\nfunction buildAction (\n id: string,\n title: string,\n ref: string,\n code: string,\n duration?: Duration,\n question?: string,\n labelOverride?: string,\n mandatory?: boolean\n): PlanDefinitionAction {\n const action: PlanDefinitionAction = {\n id,\n title,\n definitionCanonical: ref\n }\n if (code) {\n action.code = [{ coding: [{ system: SERVICE_TYPE_SYSTEM, code }] }]\n }\n if (duration) {\n action.timingDuration = duration\n }\n if (question) {\n action.description = question\n }\n if (labelOverride) {\n action.textEquivalent = labelOverride\n }\n if (mandatory) {\n action.requiredBehavior = 'must'\n }\n return action\n}\n"]}
1
+ {"version":3,"file":"plan-definition-group.js","sourceRoot":"","sources":["../src/plan-definition-group.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Duration, PlanDefinition, PlanDefinitionAction } from '@medplum/fhirtypes'\nimport { EGES_PRACTICA_SYSTEM, PD_HEALTHCARE_SERVICE_EXTENSION_URL, PD_TYPE_PROTOCOL_GROUP, PD_TYPE_SYSTEM, SERVICE_TYPE_SYSTEM } from './constants'\n\n/**\n * `action.id` of the per-variant group that overrides the order-set PD's\n * default mandatory add-ons (the tipo-3 `getMandatoryAddonIds` path). It lives\n * as a direct child of a protocol-group variant action, kept structurally\n * separate from the variant's own add-on sub-actions (the tipo-2\n * `resolveProtocolSelection` path) so the two never conflate. Its group node\n * carries no `definitionCanonical`, so `resolveProtocolSelection`,\n * `getProtocolActions` and friends skip it and never descend into it.\n */\nexport const MANDATORY_ADDON_OVERRIDE_ACTION_ID = 'mandatory-addons'\n\n/**\n * FHIR-standard ActionType code system. Each override sub-action carries a\n * `type.coding` from this system: `create` = add the add-on to the variant's\n * mandatory set, `remove` = drop a PD-default mandatory add-on. `requiredBehavior`\n * is not used for this because FHIR's value set has no \"exclude\" member.\n */\nconst ACTION_TYPE_SYSTEM = 'http://terminology.hl7.org/CodeSystem/action-type'\nconst ACTION_TYPE_ADD = 'create'\nconst ACTION_TYPE_REMOVE = 'remove'\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/**\n * How a variant alters one order-set default mandatory add-on:\n * - `'add'` forces the add-on mandatory for this variant even if the order-set\n * PD marks it optional (or does not list it as mandatory).\n * - `'remove'` drops an add-on that the order-set PD marks mandatory by default.\n */\nexport type MandatoryAddonOverrideAction = 'add' | 'remove'\n\n/**\n * A single per-variant override of the order-set's default mandatory add-on set\n * (the tipo-3 path). Referenced by the add-on's `ActivityDefinition` canonical\n * (`${EGES_PRACTICA_SYSTEM}/{pra_id}`) — the same canonical the order-set PD\n * uses — so add/remove resolve by exact canonical match against the defaults.\n */\nexport interface MandatoryAddonOverride {\n /** Add-on `ActivityDefinition` canonical, e.g. `${EGES_PRACTICA_SYSTEM}/{pra_id}`. */\n readonly ref: string\n /** Whether the variant adds or removes this add-on relative to the PD default. */\n readonly action: MandatoryAddonOverrideAction\n /** Optional human label, for the admin editor. */\n readonly display?: string\n}\n\n/** Information about a single action inside a protocol-group PD. */\nexport interface ProtocolActionInfo {\n readonly actionId: string\n readonly isDefault: boolean\n /** Short label for the variant (e.g. \"Helicoidal\") */\n readonly label: string\n /** User-facing question to select this variant */\n readonly question: string\n readonly protocolRef: string\n readonly protocolDisplay: string\n readonly protocolCode: string\n /**\n * EGES pra_id of the referenced práctica, when stamped on the action's\n * `code[]` (an `EGES_PRACTICA_SYSTEM` coding alongside the service-type\n * coding). Persisted by {@link buildProtocolGroup} so admin UIs can show\n * the id without re-reading each order-set PD.\n */\n readonly praId?: string\n readonly duration?: Duration\n /**\n * Whether this action is pre-selected in a **configured** protocol-group.\n * Set by {@link configureProtocolGroup} via FHIR `precheckBehavior`.\n * `undefined` means the PD has not been configured (use `isDefault` as fallback).\n */\n readonly prechecked?: boolean\n /**\n * Only meaningful on addon (sub-action) entries. When `true`, the addon is\n * always included whenever its parent action is selected — it is not shown\n * as a togglable option in the consumer UI. Encoded in FHIR as\n * `PlanDefinitionAction.requiredBehavior === 'must'`.\n */\n readonly mandatory?: boolean\n /** Optional sub-actions (addons) with `any` selection behavior. */\n readonly addons: readonly ProtocolActionInfo[]\n /**\n * Per-variant overrides of the order-set's default mandatory add-on set\n * (tipo-3 path). Empty when the variant inherits the PD defaults unchanged.\n * Only meaningful on top-level variant entries.\n */\n readonly mandatoryAddonOverrides: readonly MandatoryAddonOverride[]\n}\n\n/** Entry used to build a protocol-group PD action. */\nexport interface ProtocolGroupActionEntry {\n readonly id: string\n readonly isDefault: boolean\n readonly label: string\n readonly question: string\n readonly ref: string\n readonly display: string\n readonly code: string\n /** EGES pra_id of the referenced práctica, stamped on the action's `code[]`. */\n readonly praId?: string\n readonly duration?: Duration\n /**\n * Only meaningful on addon entries. When `true`, the addon is always\n * included with the parent action and is hidden from the consumer UI.\n */\n readonly mandatory?: boolean\n /** Optional sub-action entries (addons). */\n readonly addons?: readonly ProtocolGroupActionEntry[]\n /**\n * Per-variant overrides of the order-set's default mandatory add-on set\n * (tipo-3 path). Only meaningful on top-level variant entries; ignored on\n * addon entries.\n */\n readonly mandatoryAddonOverrides?: readonly MandatoryAddonOverride[]\n}\n\n// ─── Backward-compat aliases ────────────────────────────────────────────────\n\n/** @deprecated Use {@link ProtocolActionInfo} instead. */\nexport type ProtocolVariantInfo = ProtocolActionInfo\n\n/** @deprecated Use {@link ProtocolActionInfo} instead. */\nexport interface ProtocolDefaultInfo {\n readonly ref: string\n readonly display: string\n readonly code: string\n readonly duration?: Duration\n}\n\n// ─── Detection ───────────────────────────────────────────────────────────────\n\n/**\n * Returns `true` if the PlanDefinition is a protocol-group (wrapping multiple concrete PDs).\n *\n * @param pd - the PlanDefinition to check\n * @returns whether the PlanDefinition is a protocol-group\n */\nexport function isProtocolGroup (pd: PlanDefinition): boolean {\n return (pd.type?.coding ?? []).some(\n (c) => c.system === PD_TYPE_SYSTEM && c.code === PD_TYPE_PROTOCOL_GROUP\n )\n}\n\n// ─── Extraction ──────────────────────────────────────────────────────────────\n\n/**\n * Extracts all protocol actions from a protocol-group PD (preserving order).\n *\n * @param pd - the protocol-group PlanDefinition\n * @returns array of action info objects (the one with `isDefault === true` is the default)\n */\nexport function getProtocolActions (pd: PlanDefinition): ProtocolActionInfo[] {\n return (pd.action ?? [])\n .filter((a): a is PlanDefinitionAction & { definitionCanonical: string } =>\n Boolean(a.definitionCanonical)\n )\n .map((a) => extractActionInfo(a, a.id === 'default'))\n}\n\n/**\n * Extracts the default protocol action from a protocol-group PD.\n *\n * @param pd - the protocol-group PlanDefinition\n * @returns the default protocol info, or undefined if not found\n */\nexport function getDefaultProtocol (pd: PlanDefinition): ProtocolDefaultInfo | undefined {\n const action = (pd.action ?? []).find((a) => a.id === 'default')\n if (!action?.definitionCanonical) { return undefined }\n return {\n ref: action.definitionCanonical,\n display: action.title ?? '',\n code: getActionServiceCode(action),\n duration: action.timingDuration\n }\n}\n\n/**\n * Extracts the non-default variant actions from a protocol-group PD.\n *\n * @param pd - the protocol-group PlanDefinition\n * @returns array of variant info objects\n */\nexport function getProtocolVariants (pd: PlanDefinition): ProtocolActionInfo[] {\n return getProtocolActions(pd).filter((a) => !a.isDefault)\n}\n\n/**\n * Extracts the HealthcareService reference linked to a protocol-group PD.\n *\n * @param pd - the PlanDefinition to inspect\n * @returns the referenced HealthcareService, if present\n */\nexport function getProtocolGroupHealthcareServiceReference (pd: PlanDefinition): string | undefined {\n return pd.extension?.find((e) => e.url === PD_HEALTHCARE_SERVICE_EXTENSION_URL)?.valueReference?.reference\n}\n\n// ─── Construction ────────────────────────────────────────────────────────────\n\n/**\n * Builds a protocol-group PlanDefinition resource.\n *\n * @param title - human-readable title for the group (e.g. \"TAC de hombro — Protocolos\")\n * @param entries - protocol action entries (at least one should have `isDefault: true`)\n * @param existingId - optional ID to reuse when updating an existing group PD\n * @param hsReference - optional HealthcareService reference stored on the group PD\n * @returns the constructed protocol-group PlanDefinition\n */\nexport function buildProtocolGroup (\n title: string,\n entries: readonly ProtocolGroupActionEntry[],\n existingId?: string,\n hsReference?: string\n): PlanDefinition {\n const actions: PlanDefinitionAction[] = entries.map((e) => {\n const subActions = (e.addons ?? []).map((addon) =>\n buildAction(\n addon.id,\n addon.display,\n addon.ref,\n addon.code,\n addon.duration,\n addon.question,\n addon.label,\n addon.mandatory,\n addon.praId\n )\n )\n\n const action = buildAction(\n e.isDefault ? 'default' : e.id,\n e.display,\n e.ref,\n e.code,\n e.duration,\n e.question,\n e.label,\n undefined,\n e.praId\n )\n\n // Top-level actions use exactly-one selection behavior\n action.selectionBehavior = 'exactly-one'\n\n const overrideGroup = buildMandatoryAddonOverrideGroup(e.mandatoryAddonOverrides)\n const childActions = overrideGroup ? [...subActions, overrideGroup] : subActions\n\n if (childActions.length > 0) {\n action.action = childActions\n // When an action has sub-actions (addons), they use `any` grouping\n action.groupingBehavior = 'logical-group'\n }\n\n return action\n })\n\n const pd: PlanDefinition = {\n resourceType: 'PlanDefinition',\n status: 'active',\n title,\n type: {\n coding: [{ system: PD_TYPE_SYSTEM, code: PD_TYPE_PROTOCOL_GROUP }]\n },\n action: actions\n }\n\n if (hsReference) {\n pd.extension = [\n {\n url: PD_HEALTHCARE_SERVICE_EXTENSION_URL,\n valueReference: { reference: hsReference }\n }\n ]\n }\n\n if (existingId) {\n pd.id = existingId\n }\n\n return pd\n}\n\n// ─── Selection / Configuration ──────────────────────────────────────────────\n\n/**\n * A user's selection within a protocol-group PlanDefinition.\n *\n * Represents the patient's choices when configuring a HealthcareService:\n * one main action (from the `exactly-one` selection) plus zero or more\n * addon sub-actions.\n */\nexport interface ProtocolSelection {\n /** The `action.id` of the chosen top-level action. */\n readonly actionId: string\n /** The `action.id`s of toggled-on addon sub-actions within the selected action. */\n readonly addonIds: readonly string[]\n}\n\n/** Resolved booking parameters for a single protocol action. */\nexport interface ResolvedProtocolAction {\n /** The `definitionCanonical` reference to the order-set PlanDefinition. */\n readonly protocolRef: string\n /** The service-type code for slot searching / billing. */\n readonly serviceType: string\n /** Estimated duration for this action. */\n readonly duration?: Duration\n}\n\n/** Fully resolved booking parameters produced by {@link resolveProtocolSelection}. */\nexport interface ResolvedProtocol {\n /** Resolved main action. */\n readonly main: ResolvedProtocolAction\n /** Resolved addon actions (empty when none selected). */\n readonly addons: readonly ResolvedProtocolAction[]\n}\n\n/**\n * Returns a **configured** copy of a protocol-group PlanDefinition by stamping\n * `precheckBehavior` on every action according to the given selection.\n *\n * - The selected top-level action gets `precheckBehavior: \"yes\"`, all others `\"no\"`.\n * - Within the selected action, each addon sub-action is stamped according to\n * whether its id appears in `selection.addonIds`. **Mandatory addons**\n * (`requiredBehavior === 'must'`) are always stamped `\"yes\"` regardless of\n * the caller-provided ids.\n * - Unselected top-level actions have all their sub-actions stamped as `\"no\"`.\n *\n * The returned PD is a shallow copy — the original is never mutated.\n *\n * @param pd - a protocol-group PlanDefinition\n * @param selection - the user's action + addon selection\n * @returns a new PlanDefinition with `precheckBehavior` set on every action\n * @throws if the selected `actionId` is not found in the PD\n */\nexport function configureProtocolGroup (\n pd: PlanDefinition,\n selection: ProtocolSelection\n): PlanDefinition {\n const actions = pd.action ?? []\n const found = actions.some((a) => a.id === selection.actionId)\n if (!found) {\n throw new Error(`Action \"${selection.actionId}\" not found in protocol-group PlanDefinition`)\n }\n\n const addonSet = new Set(selection.addonIds)\n\n return {\n ...pd,\n action: actions.map((a) => {\n const isSelected = a.id === selection.actionId\n const subActions = (a.action ?? []).map((sub) => {\n // The mandatory-addons override group is server-side configuration,\n // not a selectable addon — never stamp it as prechecked, even if a\n // (buggy) caller passes its id among the addonIds.\n const isOverrideGroup = sub.id === MANDATORY_ADDON_OVERRIDE_ACTION_ID\n const isMandatory = sub.requiredBehavior === 'must'\n const isOn = isSelected && !isOverrideGroup && (isMandatory || addonSet.has(sub.id ?? ''))\n return {\n ...sub,\n precheckBehavior: isOn ? 'yes' as const : 'no' as const\n }\n })\n\n return {\n ...a,\n precheckBehavior: isSelected ? 'yes' as const : 'no' as const,\n ...(a.action ? { action: subActions } : {})\n }\n })\n }\n}\n\n/**\n * Resolves a protocol-group PlanDefinition + selection into concrete booking\n * parameters (service-type codes, definitionCanonical references, durations).\n *\n * @param pd - a protocol-group PlanDefinition\n * @param selection - the user's action + addon selection\n * @returns the resolved main + addon protocol references and codes\n * @throws if the selected `actionId` is not found in the PD\n */\nexport function resolveProtocolSelection (\n pd: PlanDefinition,\n selection: ProtocolSelection\n): ResolvedProtocol {\n const actions = pd.action ?? []\n const selected = actions.find((a) => a.id === selection.actionId)\n if (!selected?.definitionCanonical) {\n throw new Error(`Action \"${selection.actionId}\" not found in protocol-group PlanDefinition`)\n }\n\n const addonSet = new Set(selection.addonIds)\n const resolvedAddons: ResolvedProtocolAction[] = (selected.action ?? [])\n .filter((sub): sub is PlanDefinitionAction & { definitionCanonical: string; id: string } => {\n if (!sub.id || !sub.definitionCanonical) { return false }\n const isMandatory = sub.requiredBehavior === 'must'\n return isMandatory || addonSet.has(sub.id)\n })\n .map((sub) => ({\n protocolRef: sub.definitionCanonical,\n serviceType: getActionServiceCode(sub),\n duration: sub.timingDuration\n }))\n\n return {\n main: {\n protocolRef: selected.definitionCanonical,\n serviceType: getActionServiceCode(selected),\n duration: selected.timingDuration\n },\n addons: resolvedAddons\n }\n}\n\n/**\n * Reads the current selection from a **configured** protocol-group PlanDefinition\n * (one whose actions have been stamped with `precheckBehavior` via\n * {@link configureProtocolGroup}).\n *\n * Falls back to `id === \"default\"` with mandatory addons of that default\n * action when no action has `precheckBehavior: \"yes\"`.\n *\n * @param pd - a (possibly configured) protocol-group PlanDefinition\n * @returns the selection encoded in the PD, or the default selection\n */\nexport function readProtocolSelection (pd: PlanDefinition): ProtocolSelection {\n const actions = pd.action ?? []\n\n // Look for an action explicitly marked as prechecked\n const prechecked = actions.find((a) => a.precheckBehavior === 'yes')\n if (prechecked?.id) {\n const addonIds = (prechecked.action ?? [])\n .filter((sub): sub is PlanDefinitionAction & { id: string } => {\n if (!sub.id || sub.id === MANDATORY_ADDON_OVERRIDE_ACTION_ID) { return false }\n if (sub.requiredBehavior === 'must') { return true }\n return sub.precheckBehavior === 'yes'\n })\n .map((sub) => sub.id)\n return { actionId: prechecked.id, addonIds }\n }\n\n // Fallback: default action with its mandatory addons (if any)\n const defaultAction = actions.find((a) => a.id === 'default') ?? actions[0]\n const mandatoryAddonIds = (defaultAction?.action ?? [])\n .filter((sub): sub is PlanDefinitionAction & { id: string } =>\n Boolean(sub.id) && sub.requiredBehavior === 'must'\n )\n .map((sub) => sub.id)\n return { actionId: defaultAction?.id ?? '', addonIds: mandatoryAddonIds }\n}\n\n// ─── Internal helpers ───────────────────────────────────────────────────────\n\nfunction getActionServiceCode (action: PlanDefinitionAction): string {\n const coding = (action.code ?? [])\n .flatMap((cc) => cc.coding ?? [])\n .find((c) => c.system === SERVICE_TYPE_SYSTEM)\n return coding?.code ?? ''\n}\n\nfunction getActionPraId (action: PlanDefinitionAction): string | undefined {\n return (action.code ?? [])\n .flatMap((cc) => cc.coding ?? [])\n .find((c) => c.system === EGES_PRACTICA_SYSTEM)?.code\n}\n\nfunction precheckToBool (value: string | undefined): boolean | undefined {\n if (value === 'yes') { return true }\n if (value === 'no') { return false }\n return undefined\n}\n\nfunction extractActionInfo (a: PlanDefinitionAction & { definitionCanonical: string }, isDefault: boolean): ProtocolActionInfo {\n const subActions = (a.action ?? [])\n .filter((sub): sub is PlanDefinitionAction & { definitionCanonical: string } =>\n Boolean(sub.definitionCanonical) && sub.id !== MANDATORY_ADDON_OVERRIDE_ACTION_ID\n )\n .map((sub) => extractActionInfo(sub, false))\n\n return {\n actionId: a.id ?? '',\n isDefault,\n label: a.textEquivalent ?? a.title ?? '',\n question: a.description ?? '',\n protocolRef: a.definitionCanonical,\n protocolDisplay: a.title ?? '',\n protocolCode: getActionServiceCode(a),\n praId: getActionPraId(a),\n duration: a.timingDuration,\n prechecked: precheckToBool(a.precheckBehavior),\n mandatory: a.requiredBehavior === 'must' ? true : undefined,\n addons: subActions,\n mandatoryAddonOverrides: readMandatoryAddonOverrides(a)\n }\n}\n\n/**\n * Reads the per-variant mandatory-addon overrides out of a variant action's\n * `mandatory-addons` group. Returns `[]` when the variant declares none.\n *\n * @param variantAction - a protocol-group top-level variant action\n * @returns the variant's mandatory-addon overrides (empty when none)\n */\nexport function readMandatoryAddonOverrides (\n variantAction: PlanDefinitionAction\n): MandatoryAddonOverride[] {\n const group = (variantAction.action ?? []).find((sub) => sub.id === MANDATORY_ADDON_OVERRIDE_ACTION_ID)\n const result: MandatoryAddonOverride[] = []\n for (const sub of group?.action ?? []) {\n if (!sub.definitionCanonical) { continue }\n const action = overrideActionFromActionType(sub)\n if (!action) { continue }\n result.push(\n sub.title !== undefined\n ? { ref: sub.definitionCanonical, action, display: sub.title }\n : { ref: sub.definitionCanonical, action }\n )\n }\n return result\n}\n\n/**\n * Resolves the effective mandatory add-on canonicals for a selected variant:\n * the order-set PD defaults, plus the variant's `'add'` overrides, minus its\n * `'remove'` overrides. Order-set defaults and overrides are matched by exact\n * canonical string. Deduplicated; input order of the defaults is preserved,\n * with any added canonicals appended.\n *\n * @param defaultRefs - canonicals of the order-set PD's default mandatory add-ons\n * @param variantAction - the selected protocol-group variant action, or undefined\n * @returns the resolved set of mandatory add-on canonicals\n */\nexport function resolveVariantMandatoryAddons (\n defaultRefs: readonly string[],\n variantAction: PlanDefinitionAction | undefined\n): string[] {\n const resolved = new Set(defaultRefs)\n if (variantAction) {\n for (const override of readMandatoryAddonOverrides(variantAction)) {\n if (override.action === 'add') {\n resolved.add(override.ref)\n } else {\n resolved.delete(override.ref)\n }\n }\n }\n return Array.from(resolved)\n}\n\n/**\n * Maps an override sub-action's `type.coding` (ActionType) back to add/remove.\n *\n * @param sub - an override group sub-action\n * @returns `'add'` for `create`, `'remove'` for `remove`, else undefined\n */\nfunction overrideActionFromActionType (\n sub: PlanDefinitionAction\n): MandatoryAddonOverrideAction | undefined {\n const code = (sub.type?.coding ?? []).find((c) => c.system === ACTION_TYPE_SYSTEM)?.code\n if (code === ACTION_TYPE_ADD) { return 'add' }\n if (code === ACTION_TYPE_REMOVE) { return 'remove' }\n return undefined\n}\n\n/**\n * Builds the `mandatory-addons` override group child for a variant, or returns\n * `undefined` when the variant declares no overrides. Each override becomes a\n * sub-action referencing the add-on's canonical, with `requiredBehavior`\n * `'must'` (add) or `'prohibited'` (remove).\n *\n * @param overrides - the variant's mandatory-addon overrides (may be undefined)\n * @returns the override group action, or undefined when there are no overrides\n */\nfunction buildMandatoryAddonOverrideGroup (\n overrides: readonly MandatoryAddonOverride[] | undefined\n): PlanDefinitionAction | undefined {\n if (!overrides || overrides.length === 0) {\n return undefined\n }\n return {\n id: MANDATORY_ADDON_OVERRIDE_ACTION_ID,\n title: 'Adicionales obligatorios (override por variante)',\n selectionBehavior: 'any',\n action: overrides.map((o) => {\n const sub: PlanDefinitionAction = {\n definitionCanonical: o.ref,\n type: {\n coding: [{ system: ACTION_TYPE_SYSTEM, code: o.action === 'add' ? ACTION_TYPE_ADD : ACTION_TYPE_REMOVE }]\n }\n }\n if (o.display) {\n sub.title = o.display\n }\n return sub\n })\n }\n}\n\nfunction buildAction (\n id: string,\n title: string,\n ref: string,\n code: string,\n duration?: Duration,\n question?: string,\n labelOverride?: string,\n mandatory?: boolean,\n praId?: string\n): PlanDefinitionAction {\n const action: PlanDefinitionAction = {\n id,\n title,\n definitionCanonical: ref\n }\n if (code || praId) {\n action.code = [{\n coding: [\n ...(code ? [{ system: SERVICE_TYPE_SYSTEM, code }] : []),\n ...(praId ? [{ system: EGES_PRACTICA_SYSTEM, code: praId }] : [])\n ]\n }]\n }\n if (duration) {\n action.timingDuration = duration\n }\n if (question) {\n action.description = question\n }\n if (labelOverride) {\n action.textEquivalent = labelOverride\n }\n if (mandatory) {\n action.requiredBehavior = 'must'\n }\n return action\n}\n"]}
@@ -0,0 +1,108 @@
1
+ import type { ConceptMap, Range } from '@medplum/fhirtypes';
2
+ /** FHIR administrative gender codes accepted by mapping conditions. */
3
+ export type PracticaMappingSex = 'male' | 'female' | 'other' | 'unknown';
4
+ /**
5
+ * Conditions under which a mapping rule applies. All present conditions must
6
+ * match (logical AND); a rule with no conditions is an unconditional override.
7
+ */
8
+ export interface PracticaMappingCondition {
9
+ /**
10
+ * Reference to an `InsurancePlan` (plan tier) or a payer `Organization`
11
+ * (obra social tier), e.g. `InsurancePlan/123` / `Organization/45`.
12
+ */
13
+ readonly insuranceRef?: string;
14
+ /**
15
+ * Patient age range; bounds inclusive, either side may be open. Each bound
16
+ * Quantity may carry a UCUM code (`a` years, `mo` months, `d` days) —
17
+ * absent unit means years — and each bound is evaluated in its own unit.
18
+ */
19
+ readonly ageRange?: Range;
20
+ /** FHIR administrative gender. */
21
+ readonly sex?: PracticaMappingSex;
22
+ }
23
+ /** One práctica → práctica substitution rule from the mapping registry. */
24
+ export interface PracticaMappingRule {
25
+ /** EGES pra_id the rule applies to. */
26
+ readonly sourcePraId: number;
27
+ /** EGES pra_id substituted when the rule matches. */
28
+ readonly targetPraId: number;
29
+ readonly condition: PracticaMappingCondition;
30
+ /** Optional human label for the admin editor. */
31
+ readonly display?: string;
32
+ }
33
+ /** Units accepted on `ageRange` bounds (UCUM): years, months, days. */
34
+ export type PracticaAgeUnit = 'a' | 'mo' | 'd';
35
+ /**
36
+ * The patient's exact age at resolution time, floored per calendar unit, so
37
+ * `ageRange` bounds expressed in days, months, or years all compare exactly.
38
+ */
39
+ export interface PatientAge {
40
+ /** Completed calendar years. */
41
+ readonly years: number;
42
+ /** Completed calendar months. */
43
+ readonly months: number;
44
+ /** Completed days. */
45
+ readonly days: number;
46
+ }
47
+ /**
48
+ * The patient-side facts a rule's conditions are matched against. Resolved
49
+ * once per booking (see `resolvePracticaMappingContext`).
50
+ */
51
+ export interface PracticaMappingContext {
52
+ /** `InsurancePlan/{id}` reference of the patient's plan, when known. */
53
+ readonly insurancePlanRef?: string;
54
+ /** `Organization/{id}` reference of the plan's payer, when known. */
55
+ readonly insuranceOrgRef?: string;
56
+ /** Patient age at resolution time, when known. */
57
+ readonly age?: PatientAge;
58
+ readonly sex?: PracticaMappingSex;
59
+ }
60
+ /** Which condition dimensions a matching rule satisfied (for audit/UI). */
61
+ export type PracticaMappingMatchedCondition = 'insurance-plan' | 'insurance-org' | 'age' | 'sex';
62
+ /** A matched rule plus the dimensions it matched on. */
63
+ export interface PracticaMappingMatch {
64
+ readonly rule: PracticaMappingRule;
65
+ readonly matchedConditions: readonly PracticaMappingMatchedCondition[];
66
+ }
67
+ /**
68
+ * Builds the singleton práctica-mapping ConceptMap from a list of rules.
69
+ * Rule order is preserved (it is the final precedence tie-break).
70
+ *
71
+ * @param rules - the mapping rules to serialize
72
+ * @param existingId - optional resource id to reuse when updating
73
+ * @returns the ConceptMap resource ready to be saved
74
+ */
75
+ export declare function buildPracticaMappingConceptMap(rules: readonly PracticaMappingRule[], existingId?: string): ConceptMap;
76
+ /**
77
+ * Reads the mapping rules out of the práctica-mapping ConceptMap, preserving
78
+ * element/target order. Targets with a non-numeric code or an unreadable
79
+ * condition extension are skipped.
80
+ *
81
+ * @param conceptMap - the mapping registry ConceptMap (may be undefined)
82
+ * @returns the parsed rules (empty when the registry is absent or empty)
83
+ */
84
+ export declare function readPracticaMappingRules(conceptMap: ConceptMap | undefined): PracticaMappingRule[];
85
+ /**
86
+ * Finds the winning rule for a source práctica under the given context.
87
+ *
88
+ * Precedence among matching rules:
89
+ * 1. Most matched condition dimensions wins.
90
+ * 2. Insurance tier breaks ties: a plan-tier match beats an obra-social-tier match.
91
+ * 3. Registry order breaks remaining ties (first rule wins).
92
+ *
93
+ * @param rules - all registry rules (in registry order)
94
+ * @param praId - the source pra_id being resolved
95
+ * @param context - the patient-side facts to match against
96
+ * @returns the winning match, or undefined when no rule applies (identity)
97
+ */
98
+ export declare function matchPracticaMapping(rules: readonly PracticaMappingRule[], praId: number, context: PracticaMappingContext): PracticaMappingMatch | undefined;
99
+ /**
100
+ * Computes a patient's exact age (completed years, months, and days) at the
101
+ * given date, so `ageRange` bounds in any unit compare correctly.
102
+ *
103
+ * @param birthDate - ISO date string (`YYYY-MM-DD`)
104
+ * @param at - the reference date (defaults to now)
105
+ * @returns the age, or undefined for an unparsable or future birth date
106
+ */
107
+ export declare function computePatientAge(birthDate: string, at?: Date): PatientAge | undefined;
108
+ //# sourceMappingURL=practica-mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"practica-mapping.d.ts","sourceRoot":"","sources":["../src/practica-mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAmE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAW5H,uEAAuE;AACvE,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;AAExE;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;IACzB,kCAAkC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,kBAAkB,CAAA;CAClC;AAED,2EAA2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,wBAAwB,CAAA;IAC5C,iDAAiD;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,uEAAuE;AACvE,MAAM,MAAM,eAAe,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,CAAA;AAE9C;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,sBAAsB;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,wEAAwE;IACxE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,qEAAqE;IACrE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,kDAAkD;IAClD,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,kBAAkB,CAAA;CAClC;AAED,2EAA2E;AAC3E,MAAM,MAAM,+BAA+B,GAAG,gBAAgB,GAAG,eAAe,GAAG,KAAK,GAAG,KAAK,CAAA;AAEhG,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAA;IAClC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,+BAA+B,EAAE,CAAA;CACvE;AAID;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,SAAS,mBAAmB,EAAE,EACrC,UAAU,CAAC,EAAE,MAAM,GAClB,UAAU,CAkCZ;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAE,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,mBAAmB,EAAE,CA0BnG;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,mBAAmB,EAAE,EACrC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,sBAAsB,GAC9B,oBAAoB,GAAG,SAAS,CAiBlC;AA6DD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAE,SAAS,EAAE,MAAM,EAAE,EAAE,GAAE,IAAiB,GAAG,UAAU,GAAG,SAAS,CAcnG"}