@f1studio/form-spec 5.0.0-alpha.163 → 5.0.0-alpha.165

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.
Files changed (77) hide show
  1. package/FormSpec.FS/BlueprintValidation.js +1 -1
  2. package/FormSpec.FS/BlueprintValidation.js.map +1 -1
  3. package/FormSpec.FS/Designer.js +1 -1
  4. package/FormSpec.FS/Designer.js.map +1 -1
  5. package/FormSpec.FS/FormSpec.d.ts +14 -1
  6. package/FormSpec.FS/FormSpec.d.ts.map +1 -1
  7. package/FormSpec.FS/FormSpec.js +56 -1
  8. package/FormSpec.FS/FormSpec.js.map +1 -1
  9. package/FormSpec.FS/FormSpecHelpers.js +1 -1
  10. package/FormSpec.FS/FormSpecHelpers.js.map +1 -1
  11. package/FormSpec.FS/FormSpecValues.js +1 -1
  12. package/FormSpec.FS/FormSpecValues.js.map +1 -1
  13. package/FormSpec.FS/Helpers.js +11 -11
  14. package/FormSpec.FS/Helpers.js.map +1 -1
  15. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.d.ts +13 -3
  16. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.d.ts.map +1 -1
  17. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.js +19 -13
  18. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.js.map +1 -1
  19. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.d.ts +20 -0
  20. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.d.ts.map +1 -1
  21. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.js +20 -40
  22. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.js.map +1 -1
  23. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.d.ts +21 -9
  24. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.d.ts.map +1 -1
  25. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.js +46 -25
  26. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.js.map +1 -1
  27. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.d.ts +3 -4
  28. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.d.ts.map +1 -1
  29. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.js +93 -36
  30. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.js.map +1 -1
  31. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.d.ts +33 -8
  32. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.d.ts.map +1 -1
  33. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.js +25 -29
  34. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.js.map +1 -1
  35. package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMREncoder.js.map +1 -1
  36. package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.d.ts +4 -1
  37. package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.d.ts.map +1 -1
  38. package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.js +4 -4
  39. package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.js.map +1 -1
  40. package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRTriggerEnrichment.js +1 -1
  41. package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRTriggerEnrichment.js.map +1 -1
  42. package/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.js +1 -1
  43. package/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.js.map +1 -1
  44. package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.d.ts +40 -8
  45. package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.d.ts.map +1 -1
  46. package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.js +201 -22
  47. package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.js.map +1 -1
  48. package/FormSpec.FS/Interop/FormSpec.Api.Helpers.js +4 -4
  49. package/FormSpec.FS/Interop/FormSpec.Api.Helpers.js.map +1 -1
  50. package/FormSpec.FS/Interop/FormSpec.Api.Option.d.ts +26 -2
  51. package/FormSpec.FS/Interop/FormSpec.Api.Option.d.ts.map +1 -1
  52. package/FormSpec.FS/Interop/FormSpec.Api.Option.js +77 -3
  53. package/FormSpec.FS/Interop/FormSpec.Api.Option.js.map +1 -1
  54. package/FormSpec.FS/Provenance.d.ts +20 -2
  55. package/FormSpec.FS/Provenance.d.ts.map +1 -1
  56. package/FormSpec.FS/Provenance.js +66 -3
  57. package/FormSpec.FS/Provenance.js.map +1 -1
  58. package/README.md +7 -7
  59. package/package.json +1 -1
  60. package/src/FormSpec.FS/BlueprintValidation.ts +1 -1
  61. package/src/FormSpec.FS/Designer.ts +1 -1
  62. package/src/FormSpec.FS/FormSpec.ts +32 -2
  63. package/src/FormSpec.FS/FormSpecHelpers.ts +1 -1
  64. package/src/FormSpec.FS/FormSpecValues.ts +1 -1
  65. package/src/FormSpec.FS/Helpers.ts +11 -11
  66. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.ts +25 -12
  67. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.ts +41 -41
  68. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.ts +62 -30
  69. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.ts +77 -30
  70. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.ts +52 -27
  71. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.ts +7 -5
  72. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRTriggerEnrichment.ts +1 -1
  73. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.ts +1 -1
  74. package/src/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.ts +160 -25
  75. package/src/FormSpec.FS/Interop/FormSpec.Api.Helpers.ts +4 -4
  76. package/src/FormSpec.FS/Interop/FormSpec.Api.Option.ts +63 -8
  77. package/src/FormSpec.FS/Provenance.ts +50 -4
@@ -1,12 +1,12 @@
1
1
  import { Helpers_generateDeterministicGuidRaw, Helpers_canonicalizeFieldKey } from "../../../Helpers.js";
2
2
  import { tryFind, FSharpMap, ofList } from "@fable-org/fable-library-js/Map.js";
3
- import { empty, isEmpty, collect, ofArray, sumBy, FSharpList, map } from "@fable-org/fable-library-js/List.js";
3
+ import { empty, collect, isEmpty, sortBy, FSharpList, map } from "@fable-org/fable-library-js/List.js";
4
4
  import { int32 } from "@fable-org/fable-library-js/Int32.js";
5
5
  import { CoreMRFormData, CoreMRTag, CoreMRItem, CoreMRChoice } from "../../CorEMR/CoreMRTypes.js";
6
6
  import { numberHash, comparePrimitives } from "@fable-org/fable-library-js/Util.js";
7
- import { op_Addition, toInt64, int64, toInt32 } from "@fable-org/fable-library-js/BigInt.js";
8
- import { Spec_FormSpec$1_$reflection, Spec_FieldType_$reflection, Spec_FormSpec$1, Spec_FormClassification_General, Spec_FormLifecycle_Blueprint, ClinicalPathway_ClinicalPathwaySpec, Spec_FormField$1, Shared_FieldKey, Spec_FieldType_$union, Spec_FormStep$1, Spec_Score, Spec_ScoreColor_Danger, Spec_ScoreColor_Warning, Spec_ScoreRange, Spec_ScoreColor_Success } from "../../../FormSpec.js";
9
- import { defaultArg, Option } from "@fable-org/fable-library-js/Option.js";
7
+ import { defaultArg, Option, bind } from "@fable-org/fable-library-js/Option.js";
8
+ import { Spec_FormSpec$1_$reflection, Spec_FieldType_$reflection, Spec_FormSpec$1, Spec_FormClassification_General, Spec_FormLifecycle_Blueprint, ClinicalPathway_ClinicalPathwaySpec, Spec_FormField$1, Shared_FieldKey, Spec_FieldType_$union, Spec_FormStep$1, Spec_VendorScore, Spec_VendorScoreBand } from "../../../FormSpec.js";
9
+ import { FormScoring, ScoringLabel } from "../../CorEMR/TemplateManifestDecoder.js";
10
10
  import { toConsoleError, printf, toText, substring } from "@fable-org/fable-library-js/String.js";
11
11
  import { createSteps } from "./CorEMRStepsBuilder.js";
12
12
  import { List_groupBy } from "@fable-org/fable-library-js/Seq2.js";
@@ -42,19 +42,39 @@ export function createChoiceIdToTextMap(choices: FSharpList<CoreMRChoice>): FSha
42
42
  }
43
43
 
44
44
  /**
45
- * Calculate scoring from choice scores
45
+ * ⚰️ `calculateScore` WAS HERE AND IS NOT COMING BACK. It summed every `item_choices.score`
46
+ * in the form — the BITMASK WEIGHT column, which `CoreMRTypes.CoreMRChoice.Score` documents as
47
+ * reaching 2^31 — called the total a clinical maximum, and cut three bands at thirds labelled
48
+ * "Low Risk" / "Medium Risk" / "High Risk". CoreMR states none of that.
49
+ *
50
+ * 🔴 It was not merely noisy. For five of the six forms CoreMR scores, a total the site calls
51
+ * SEVERE fell inside the band this function painted "Low Risk" (GAD-7 severe ≥ 17 against a
52
+ * fabricated Low of 0–37; CIWA severe ≥ 20 against 0–378). ⇒ `AGENTS.md` non-negotiable 3 —
53
+ * *"a score is CoreMR's to state, never ours to compute"* — and non-negotiable 4, a value and
54
+ * its interpretation travel together or neither travels.
55
+ *
56
+ * ⛔ Do not reintroduce a computed maximum "just for a progress bar". `form_scores` is
57
+ * `id · name · form_name · labels · deleted` — there is no max column — and conduit publishes
58
+ * `maxScore: null` for every scored form. A maximum here would be ours, not the site's.
59
+ * Read the stated scale off the catalog row CoreMR published for this form.
60
+ *
61
+ * ⛔ REFUSES rather than degrades. A scale whose bands did not survive (`labels` unparseable,
62
+ * so conduit sent an empty list) yields `None`: a scale's NAME without its bands cannot say
63
+ * what a total means, and carrying half the sentence is how a consumer ends up inventing the
64
+ * cutoff — the exact failure conduit's own `ScoreBand.parse` comment records.
46
65
  */
47
- export function calculateScore(choices: FSharpList<CoreMRChoice>, formName: string): Option<Spec_Score> {
48
- const maxScore: int32 = ~~toInt32(sumBy<CoreMRChoice, int64>((c: CoreMRChoice): int64 => c.Score, choices, {
49
- GetZero: (): int64 => (0n),
50
- Add: (x: int64, y: int64): int64 => toInt64(op_Addition(x, y)),
51
- })) | 0;
52
- if (maxScore > 0) {
53
- return new Spec_Score(maxScore, ofArray([new Spec_ScoreRange(generateStableDeterministicGuid(`score_range_${formName}_low`), 0, ~~(maxScore / 3), "Low Risk", Spec_ScoreColor_Success()), new Spec_ScoreRange(generateStableDeterministicGuid(`score_range_${formName}_medium`), ~~(maxScore / 3) + 1, ~~((maxScore * 2) / 3), "Medium Risk", Spec_ScoreColor_Warning()), new Spec_ScoreRange(generateStableDeterministicGuid(`score_range_${formName}_high`), ~~((maxScore * 2) / 3) + 1, maxScore, "High Risk", Spec_ScoreColor_Danger())]));
54
- }
55
- else {
56
- return undefined;
57
- }
66
+ export function statedScale(scoring: Option<FormScoring>): Option<Spec_VendorScore> {
67
+ return bind<FormScoring, Spec_VendorScore>((s: FormScoring): Option<Spec_VendorScore> => {
68
+ const bands: FSharpList<Spec_VendorScoreBand> = sortBy<Spec_VendorScoreBand, int32>((b: Spec_VendorScoreBand): int32 => b.Min, map<ScoringLabel, Spec_VendorScoreBand>((l: ScoringLabel): Spec_VendorScoreBand => (new Spec_VendorScoreBand(l.Name, l.Min)), s.Labels), {
69
+ Compare: comparePrimitives,
70
+ });
71
+ if (isEmpty(bands)) {
72
+ return undefined;
73
+ }
74
+ else {
75
+ return new Spec_VendorScore(s.ScoreName, bands);
76
+ }
77
+ }, scoring);
58
78
  }
59
79
 
60
80
  /**
@@ -85,9 +105,14 @@ export function extractFormCode(formName: string, formId: int32): string {
85
105
  }
86
106
 
87
107
  /**
88
- * Convert CoreMR form data to FormSpec
108
+ * Convert CoreMR form data to FormSpec.
109
+ *
110
+ * ⭐ `scoring` is the catalog row's OWN sentence about this form's scale, threaded in rather
111
+ * than derived here. ⛔ It is REQUIRED as a parameter — `None` must be a caller's explicit
112
+ * statement that no catalog row was supplied, never this function's default. Nothing in a
113
+ * form's items or choices can tell you what a total means.
89
114
  */
90
- export function convertToFormSpec(formData: CoreMRFormData): Spec_FormSpec$1<Spec_FieldType_$union> {
115
+ export function convertToFormSpec(scoring: Option<FormScoring>, formData: CoreMRFormData): Spec_FormSpec$1<Spec_FieldType_$union> {
91
116
  const formCode: string = extractFormCode(formData.Metadata.FormName, formData.Metadata.FormId);
92
117
  const steps: FSharpList<Spec_FormStep$1<Spec_FieldType_$union>> = createSteps(formCode, formData.Items, ofList<int32, FSharpList<CoreMRChoice>>(List_groupBy<CoreMRChoice, int32>((c: CoreMRChoice): int32 => c.ItemId, formData.Choices, {
93
118
  Equals: (x: int32, y: int32): boolean => (x === y),
@@ -95,7 +120,7 @@ export function convertToFormSpec(formData: CoreMRFormData): Spec_FormSpec$1<Spe
95
120
  }), {
96
121
  Compare: comparePrimitives,
97
122
  }));
98
- const score: Option<Spec_Score> = calculateScore(formData.Choices, formData.Metadata.FormName);
123
+ const vendorScore: Option<Spec_VendorScore> = statedScale(scoring);
99
124
  const fieldKeyBySequence: FSharpMap<int32, Shared_FieldKey> = ofList<int32, Shared_FieldKey>(map<Spec_FormField$1<Spec_FieldType_$union>, [int32, Shared_FieldKey]>((field: Spec_FormField$1<Spec_FieldType_$union>): [int32, Shared_FieldKey] => ([field.FieldOrder, field.FieldKey] as [int32, Shared_FieldKey]), collect<Spec_FormStep$1<Spec_FieldType_$union>, Spec_FormField$1<Spec_FieldType_$union>>((step: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<Spec_FormField$1<Spec_FieldType_$union>> => step.Fields, steps)), {
100
125
  Compare: comparePrimitives,
101
126
  });
@@ -103,7 +128,7 @@ export function convertToFormSpec(formData: CoreMRFormData): Spec_FormSpec$1<Spe
103
128
  Compare: comparePrimitives,
104
129
  });
105
130
  const clinicalPathway: Option<ClinicalPathway_ClinicalPathwaySpec> = isEmpty(formData.Triggers) ? undefined : convertTriggersToSinglePathway(formData.Triggers, (itemId: int32): Shared_FieldKey => defaultArg(tryFind<int32, Shared_FieldKey>(itemId, itemIdToFieldKeyMap), new Shared_FieldKey(generateStableDeterministicGuid(`unknown_item_${itemId}`))), createChoiceIdToTextMap(formData.Choices), formData.Metadata, formData.Items);
106
- return new Spec_FormSpec$1(generateStableDeterministicGuid(`form_${formData.Metadata.FormId}_${formData.Metadata.FormName}`), formCode, formData.Metadata.FormName, defaultArg(formData.Metadata.Description, ""), toText(printf("1.0.0-CoreEMRv%d"))(formData.Metadata.VersionNumber), "5.0.0", steps, map<CoreMRTag, string>((t: CoreMRTag): string => t.TagName, formData.Tags), score, empty<string>(), formData.Metadata.RequiresSignature, false, clinicalPathway, Spec_FormLifecycle_Blueprint(), undefined, undefined, undefined, Spec_FormClassification_General());
131
+ return new Spec_FormSpec$1(generateStableDeterministicGuid(`form_${formData.Metadata.FormId}_${formData.Metadata.FormName}`), formCode, formData.Metadata.FormName, defaultArg(formData.Metadata.Description, ""), toText(printf("1.0.0-CoreEMRv%d"))(formData.Metadata.VersionNumber), "5.0.0", steps, map<CoreMRTag, string>((t: CoreMRTag): string => t.TagName, formData.Tags), undefined, vendorScore, empty<string>(), formData.Metadata.RequiresSignature, false, clinicalPathway, Spec_FormLifecycle_Blueprint(), undefined, undefined, undefined, Spec_FormClassification_General());
107
132
  }
108
133
 
109
134
  /**
@@ -134,17 +159,17 @@ export function serializeFormSpec(formSpec: Spec_FormSpec$1<Spec_FieldType_$unio
134
159
  /**
135
160
  * Main conversion function
136
161
  */
137
- export function convertForm(formData: CoreMRFormData): Spec_FormSpec$1<Spec_FieldType_$union> {
138
- return convertToFormSpec(formData);
162
+ export function convertForm(scoring: Option<FormScoring>, formData: CoreMRFormData): Spec_FormSpec$1<Spec_FieldType_$union> {
163
+ return convertToFormSpec(scoring, formData);
139
164
  }
140
165
 
141
166
  /**
142
167
  * Convert form with validation
143
168
  */
144
- export function convertFormWithValidation(formData: CoreMRFormData): FSharpResult$2_$union<[Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult], string> {
169
+ export function convertFormWithValidation(scoring: Option<FormScoring>, formData: CoreMRFormData): FSharpResult$2_$union<[Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult], string> {
145
170
  try {
146
- const formSpec: Spec_FormSpec$1<Spec_FieldType_$union> = convertToFormSpec(formData);
147
- const matchValue: FSharpResult$2_$union<ValidationResult, string> = FormSpecValidator_validateConversion(formData, formSpec);
171
+ const formSpec: Spec_FormSpec$1<Spec_FieldType_$union> = convertToFormSpec(scoring, formData);
172
+ const matchValue: FSharpResult$2_$union<ValidationResult, string> = FormSpecValidator_validateConversion(scoring, formData, formSpec);
148
173
  return (matchValue.tag === /* Error */ 1) ? FSharpResult$2_Error<[Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult], string>(matchValue.fields[0]) : FSharpResult$2_Ok<[Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult], string>([formSpec, matchValue.fields[0]] as [Spec_FormSpec$1<Spec_FieldType_$union>, ValidationResult]);
149
174
  }
150
175
  catch (ex: any) {
@@ -155,8 +180,8 @@ export function convertFormWithValidation(formData: CoreMRFormData): FSharpResul
155
180
  /**
156
181
  * Convert form with semantic analysis
157
182
  */
158
- export function convertFormWithSemantics(formData: CoreMRFormData): [Spec_FormSpec$1<Spec_FieldType_$union>, string] {
159
- return [convertToFormSpec(formData), buildReport(formData)] as [Spec_FormSpec$1<Spec_FieldType_$union>, string];
183
+ export function convertFormWithSemantics(scoring: Option<FormScoring>, formData: CoreMRFormData): [Spec_FormSpec$1<Spec_FieldType_$union>, string] {
184
+ return [convertToFormSpec(scoring, formData), buildReport(formData)] as [Spec_FormSpec$1<Spec_FieldType_$union>, string];
160
185
  }
161
186
 
162
187
  //# sourceMappingURL=CorEMRTemplateToFormSpec.ts.map
@@ -4,7 +4,7 @@ import { class_type, list_type, option_type, int64_type, int32_type, record_type
4
4
  import { getElementTypeInfo, ElementTypeInfo } from "./CorEMRElementTypeMap.js";
5
5
  import { int32 } from "@fable-org/fable-library-js/Int32.js";
6
6
  import { empty as empty_1, ofList, FSharpMap, tryFind } from "@fable-org/fable-library-js/Map.js";
7
- import { map, defaultArg, Option, value as value_3 } from "@fable-org/fable-library-js/Option.js";
7
+ import { bind, map, defaultArg, Option, value as value_3 } from "@fable-org/fable-library-js/Option.js";
8
8
  import { int64 } from "@fable-org/fable-library-js/BigInt.js";
9
9
  import { Spec_FormClassification_General, Spec_FormStep$1, Spec_FormField$1, Spec_MultiChoiceInfo, Spec_SingleChoiceInfo, Shared_FieldOption, Spec_FormSpec$1_$reflection, Spec_FieldType_$reflection, Spec_FieldType_$union, Spec_FormSpec$1, Spec_FormClassification_$reflection, Spec_FormClassification_$union, Shared_FieldKey_$reflection, Shared_FieldKey, Shared_MatrixItemKey_$reflection, Shared_MatrixItemKey, Shared_FieldOptionKey_$reflection, Shared_FieldOptionKey } from "../../../FormSpec.js";
10
10
  import { tryFind as tryFind_1, choose, item as item_1, length, mapIndexed, sortBy, empty, FSharpList } from "@fable-org/fable-library-js/List.js";
@@ -13,8 +13,8 @@ import { CoreMRFormData, CoreMRItem, CoreMRChoice, CoreMRTag_$reflection, CoreMR
13
13
  import { List_groupBy } from "@fable-org/fable-library-js/Seq2.js";
14
14
  import { detectHeadings, groupItemsByHeadings, Section, HeadingItem } from "./CorEMRSectioning.js";
15
15
  import { convertToFormSpec } from "./CorEMRTemplateToFormSpec.js";
16
+ import { ImportOrigin, ImportOriginModule_provenance } from "../../../Provenance.js";
16
17
  import { Auto_generateBoxedEncoder_437914C6, toString } from "../../../../Thoth.Json/packages/Thoth.Json/Encode.js";
17
- import { IntegrationProvenance } from "../../../Provenance.js";
18
18
 
19
19
  export class ValueEncodingInfo extends Record implements IEquatable<ValueEncodingInfo>, IComparable<ValueEncodingInfo> {
20
20
  readonly ValueEncoding: string;
@@ -381,7 +381,7 @@ export function buildSourceMap(elementTypes: Option<FSharpMap<int32, ElementType
381
381
  * When elementTypes is Some (from bridge templates endpoint), use it for ValueEncoding; else fallback to CorEMRElementTypeMap.
382
382
  */
383
383
  export function convertWithMap(formData: CoreMRFormData, listMetadata: Option<ListMetadata>, elementTypes: Option<FSharpMap<int32, ElementTypeInfo>>, triggersByItemId: FSharpMap<int32, FSharpList<ItemTrigger>>): CoreMRConversionResult {
384
- const formSpec: Spec_FormSpec$1<Spec_FieldType_$union> = convertToFormSpec(formData);
384
+ const formSpec: Spec_FormSpec$1<Spec_FieldType_$union> = convertToFormSpec(bind<ListMetadata, FormScoring>((m: ListMetadata): Option<FormScoring> => m.Scoring, listMetadata), formData);
385
385
  return new CoreMRConversionResult(formSpec, buildSourceMap(elementTypes, triggersByItemId, formData, formSpec, listMetadata));
386
386
  }
387
387
 
@@ -390,13 +390,15 @@ export function convertWithMap(formData: CoreMRFormData, listMetadata: Option<Li
390
390
  * When listMetadata is Some (from the templates catalog during import), Scoring, EncounterTypes,
391
391
  * Usage and Classification are populated. IsIntake always comes from formData.Metadata.
392
392
  * When elementTypes is Some (from bridge templates endpoint), use it for ValueEncoding; else fallback to CorEMRElementTypeMap.
393
+ * ⭐ `origin` is REQUIRED. A blueprint imported without naming its tenant and database produces a
394
+ * provenance that cannot be resolved back — measured 2026-09-23: 228 of 228 imports were unresolvable.
393
395
  */
394
- export function convertWithMapAndProvenance(formData: CoreMRFormData, listMetadata: Option<ListMetadata>, elementTypes: Option<FSharpMap<int32, ElementTypeInfo>>): Spec_FormSpec$1<Spec_FieldType_$union> {
396
+ export function convertWithMapAndProvenance(origin: ImportOrigin, formData: CoreMRFormData, listMetadata: Option<ListMetadata>, elementTypes: Option<FSharpMap<int32, ElementTypeInfo>>): Spec_FormSpec$1<Spec_FieldType_$union> {
395
397
  const result: CoreMRConversionResult = convertWithMap(formData, listMetadata, elementTypes, empty_1<int32, FSharpList<ItemTrigger>>({
396
398
  Compare: comparePrimitives,
397
399
  }));
398
400
  const bind$0040: Spec_FormSpec$1<Spec_FieldType_$union> = result.FormSpec;
399
- return new Spec_FormSpec$1(bind$0040.Id, bind$0040.Code, bind$0040.Title, bind$0040.Abstract, bind$0040.Version, bind$0040.FormSpecVersion, bind$0040.Steps, bind$0040.CategoryTags, bind$0040.Score, bind$0040.AssociatedCodes, bind$0040.RequiresReview, bind$0040.RequiresReviewAndApproval, bind$0040.ClinicalPathway, bind$0040.Lifecycle, bind$0040.FilledMeta, bind$0040.CustomData, new IntegrationProvenance("coremr", toString(0, Auto_generateBoxedEncoder_437914C6(CoreMRSourceMap_$reflection(), undefined, undefined, undefined)(result.SourceMap))), result.SourceMap.Classification);
401
+ return new Spec_FormSpec$1(bind$0040.Id, bind$0040.Code, bind$0040.Title, bind$0040.Abstract, bind$0040.Version, bind$0040.FormSpecVersion, bind$0040.Steps, bind$0040.CategoryTags, bind$0040.Score, bind$0040.VendorScore, bind$0040.AssociatedCodes, bind$0040.RequiresReview, bind$0040.RequiresReviewAndApproval, bind$0040.ClinicalPathway, bind$0040.Lifecycle, bind$0040.FilledMeta, bind$0040.CustomData, ImportOriginModule_provenance(origin, toString(0, Auto_generateBoxedEncoder_437914C6(CoreMRSourceMap_$reflection(), undefined, undefined, undefined)(result.SourceMap))), result.SourceMap.Classification);
400
402
  }
401
403
 
402
404
  //# sourceMappingURL=CoreMRSourceMap.ts.map
@@ -76,7 +76,7 @@ export function convertActionsForCoreMR(actions: FSharpList<ClinicalPathway_Acti
76
76
  const matchValue: Option<IntegrationProvenance> = formSpec.Provenance;
77
77
  let matchResult: int32, p_1: IntegrationProvenance;
78
78
  if (matchValue != null) {
79
- if (value_1(matchValue).IntegrationKey === "coremr") {
79
+ if (value_1(matchValue).Vendor === "coremr") {
80
80
  matchResult = 0;
81
81
  p_1 = value_1(matchValue);
82
82
  }
@@ -302,7 +302,7 @@ const CoreMRPublishMetadataCustomData_sourceMapPayloadDecoder = (path_1: string)
302
302
  function CoreMRPublishMetadataCustomData_tryDeserializeFromProvenance(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): Option<CoreMRPublishMetadata> {
303
303
  return bind<IntegrationProvenance, CoreMRPublishMetadata>((p: IntegrationProvenance): Option<CoreMRPublishMetadata> => {
304
304
  let matchValue_1: Option<string>;
305
- if (p.IntegrationKey !== "coremr") {
305
+ if (p.Vendor !== "coremr") {
306
306
  return undefined;
307
307
  }
308
308
  else {
@@ -1,17 +1,17 @@
1
- import { Record } from "@fable-org/fable-library-js/Types.js";
1
+ import { Union, Record } from "@fable-org/fable-library-js/Types.js";
2
2
  import { int32 } from "@fable-org/fable-library-js/Int32.js";
3
3
  import { toInt32, int64 } from "@fable-org/fable-library-js/BigInt.js";
4
4
  import { map as map_1, defaultArg, Option } from "@fable-org/fable-library-js/Option.js";
5
5
  import { int32ToString, uncurry2, comparePrimitives, IComparable, IEquatable } from "@fable-org/fable-library-js/Util.js";
6
- import { bool_type, class_type, list_type, record_type, option_type, string_type, int64_type, int32_type, TypeInfo } from "@fable-org/fable-library-js/Reflection.js";
6
+ import { union_type, bool_type, class_type, list_type, record_type, option_type, string_type, int64_type, int32_type, TypeInfo } from "@fable-org/fable-library-js/Reflection.js";
7
7
  import { collect, map as map_2, isEmpty, empty, FSharpList } from "@fable-org/fable-library-js/List.js";
8
- import { empty as empty_1, ofList, FSharpMap } from "@fable-org/fable-library-js/Map.js";
8
+ import { tryFind, empty as empty_1, ofList, FSharpMap } from "@fable-org/fable-library-js/Map.js";
9
9
  import { Auto_generateBoxedDecoder_Z6670B51 } from "../../../Thoth.Json/packages/Thoth.Json/Decode.js";
10
10
  import { FSharpResult$2_$union } from "@fable-org/fable-library-js/Result.js";
11
11
  import { ErrorReason_$union } from "../../../Thoth.Json/packages/Thoth.Json/Types.js";
12
12
  import { fromString, bool, list as list_3, IOptionalGetter, IGetters, string, int, IRequiredGetter, object, map, keyValuePairs } from "../../../Thoth.Json/packages/Thoth.Json/Decode.js";
13
+ import { isNullOrEmpty, printf, toFail } from "@fable-org/fable-library-js/String.js";
13
14
  import { CoreMRFormData, CoreMRTag, CoreMRTrigger, CoreMRFormMetadata, CoreMRItem, CoreMRChoice } from "./CoreMRTypes.js";
14
- import { isNullOrEmpty } from "@fable-org/fable-library-js/String.js";
15
15
 
16
16
  export class TemplateChoice extends Record implements IEquatable<TemplateChoice>, IComparable<TemplateChoice> {
17
17
  readonly ChoiceId: int32;
@@ -230,19 +230,53 @@ export function TemplateForm_$reflection(): TypeInfo {
230
230
  }
231
231
 
232
232
  export class ElementTypeEntry extends Record implements IEquatable<ElementTypeEntry>, IComparable<ElementTypeEntry> {
233
- readonly Code: string;
234
- readonly ValueEncoding: string;
235
- readonly TextField: string;
236
- constructor(Code: string, ValueEncoding: string, TextField: string) {
233
+ readonly Label: string;
234
+ readonly Control: string;
235
+ constructor(Label: string, Control: string) {
237
236
  super();
238
- this.Code = Code;
239
- this.ValueEncoding = ValueEncoding;
240
- this.TextField = TextField;
237
+ this.Label = Label;
238
+ this.Control = Control;
241
239
  }
242
240
  }
243
241
 
244
242
  export function ElementTypeEntry_$reflection(): TypeInfo {
245
- return record_type("FormSpec.Integrations.CorEMR.TemplateManifestDecoder.ElementTypeEntry", [], ElementTypeEntry, () => [["Code", string_type], ["ValueEncoding", string_type], ["TextField", string_type]]);
243
+ return record_type("FormSpec.Integrations.CorEMR.TemplateManifestDecoder.ElementTypeEntry", [], ElementTypeEntry, () => [["Label", string_type], ["Control", string_type]]);
244
+ }
245
+
246
+ export type ElementTypesFrom_$union =
247
+ | ElementTypesFrom<0>
248
+ | ElementTypesFrom<1>
249
+ | ElementTypesFrom<2>
250
+
251
+ export type ElementTypesFrom_$cases = {
252
+ 0: ["StatedBy", [string, string, string]],
253
+ 1: ["DeclaredByConduit", [string]],
254
+ 2: ["NotInRelease", [string]]
255
+ }
256
+
257
+ export function ElementTypesFrom_StatedBy(table: string, key: string, label: string) {
258
+ return new ElementTypesFrom<0>(0, [table, key, label]);
259
+ }
260
+
261
+ export function ElementTypesFrom_DeclaredByConduit(because: string) {
262
+ return new ElementTypesFrom<1>(1, [because]);
263
+ }
264
+
265
+ export function ElementTypesFrom_NotInRelease(because: string) {
266
+ return new ElementTypesFrom<2>(2, [because]);
267
+ }
268
+
269
+ export class ElementTypesFrom<Tag extends keyof ElementTypesFrom_$cases> extends Union<Tag, ElementTypesFrom_$cases[Tag][0]> {
270
+ constructor(readonly tag: Tag, readonly fields: ElementTypesFrom_$cases[Tag][1]) {
271
+ super();
272
+ }
273
+ cases() {
274
+ return ["StatedBy", "DeclaredByConduit", "NotInRelease"];
275
+ }
276
+ }
277
+
278
+ export function ElementTypesFrom_$reflection(): TypeInfo {
279
+ return union_type("FormSpec.Integrations.CorEMR.TemplateManifestDecoder.ElementTypesFrom", [], ElementTypesFrom, () => [[["table", string_type], ["key", string_type], ["label", string_type]], [["because", string_type]], [["because", string_type]]]);
246
280
  }
247
281
 
248
282
  export class InstrumentMapEntry extends Record implements IEquatable<InstrumentMapEntry>, IComparable<InstrumentMapEntry> {
@@ -372,11 +406,12 @@ export class TemplateManifest extends Record implements IEquatable<TemplateManif
372
406
  readonly GeneratedFrom: string;
373
407
  readonly CoreEmr: CoreEmrInfo;
374
408
  readonly Stats: TemplateStats;
375
- readonly ElementTypes: FSharpMap<string, ElementTypeEntry>;
409
+ readonly ElementTypes: Option<FSharpMap<string, ElementTypeEntry>>;
410
+ readonly ElementTypesFrom: ElementTypesFrom_$union;
376
411
  readonly Forms: FSharpMap<string, TemplateForm>;
377
412
  readonly InstrumentMap: FSharpMap<string, InstrumentMapEntry>;
378
413
  readonly InstrumentMapStats: InstrumentMapStats;
379
- constructor(Schema: Option<string>, Version: int32, GeneratedAt: string, GeneratedFrom: string, CoreEmr: CoreEmrInfo, Stats: TemplateStats, ElementTypes: FSharpMap<string, ElementTypeEntry>, Forms: FSharpMap<string, TemplateForm>, InstrumentMap: FSharpMap<string, InstrumentMapEntry>, InstrumentMapStats: InstrumentMapStats) {
414
+ constructor(Schema: Option<string>, Version: int32, GeneratedAt: string, GeneratedFrom: string, CoreEmr: CoreEmrInfo, Stats: TemplateStats, ElementTypes: Option<FSharpMap<string, ElementTypeEntry>>, ElementTypesFrom: ElementTypesFrom_$union, Forms: FSharpMap<string, TemplateForm>, InstrumentMap: FSharpMap<string, InstrumentMapEntry>, InstrumentMapStats: InstrumentMapStats) {
380
415
  super();
381
416
  this.Schema = Schema;
382
417
  this.Version = (Version | 0);
@@ -385,6 +420,7 @@ export class TemplateManifest extends Record implements IEquatable<TemplateManif
385
420
  this.CoreEmr = CoreEmr;
386
421
  this.Stats = Stats;
387
422
  this.ElementTypes = ElementTypes;
423
+ this.ElementTypesFrom = ElementTypesFrom;
388
424
  this.Forms = Forms;
389
425
  this.InstrumentMap = InstrumentMap;
390
426
  this.InstrumentMapStats = InstrumentMapStats;
@@ -392,7 +428,7 @@ export class TemplateManifest extends Record implements IEquatable<TemplateManif
392
428
  }
393
429
 
394
430
  export function TemplateManifest_$reflection(): TypeInfo {
395
- return record_type("FormSpec.Integrations.CorEMR.TemplateManifestDecoder.TemplateManifest", [], TemplateManifest, () => [["Schema", option_type(string_type)], ["Version", int32_type], ["GeneratedAt", string_type], ["GeneratedFrom", string_type], ["CoreEmr", CoreEmrInfo_$reflection()], ["Stats", TemplateStats_$reflection()], ["ElementTypes", class_type("Microsoft.FSharp.Collections.FSharpMap`2", [string_type, ElementTypeEntry_$reflection()])], ["Forms", class_type("Microsoft.FSharp.Collections.FSharpMap`2", [string_type, TemplateForm_$reflection()])], ["InstrumentMap", class_type("Microsoft.FSharp.Collections.FSharpMap`2", [string_type, InstrumentMapEntry_$reflection()])], ["InstrumentMapStats", InstrumentMapStats_$reflection()]]);
431
+ return record_type("FormSpec.Integrations.CorEMR.TemplateManifestDecoder.TemplateManifest", [], TemplateManifest, () => [["Schema", option_type(string_type)], ["Version", int32_type], ["GeneratedAt", string_type], ["GeneratedFrom", string_type], ["CoreEmr", CoreEmrInfo_$reflection()], ["Stats", TemplateStats_$reflection()], ["ElementTypes", option_type(class_type("Microsoft.FSharp.Collections.FSharpMap`2", [string_type, ElementTypeEntry_$reflection()]))], ["ElementTypesFrom", ElementTypesFrom_$reflection()], ["Forms", class_type("Microsoft.FSharp.Collections.FSharpMap`2", [string_type, TemplateForm_$reflection()])], ["InstrumentMap", class_type("Microsoft.FSharp.Collections.FSharpMap`2", [string_type, InstrumentMapEntry_$reflection()])], ["InstrumentMapStats", InstrumentMapStats_$reflection()]]);
396
432
  }
397
433
 
398
434
  const liberatedInt64Decoder: ((arg0: string) => ((arg0: any) => FSharpResult$2_$union<int64, [string, ErrorReason_$union]>)) = Auto_generateBoxedDecoder_Z6670B51(int64_type, undefined, undefined);
@@ -456,10 +492,27 @@ const formDecoder = (path_13: string): ((arg0: any) => FSharpResult$2_$union<Tem
456
492
  return new TemplateForm((objectArg = get$.Required, objectArg.Field<int32>("formId", uncurry2(int))), (objectArg_1 = get$.Required, objectArg_1.Field<string>("name", string)), (objectArg_2 = get$.Required, objectArg_2.Field<string>("formCode", string)), (objectArg_3 = get$.Required, objectArg_3.Field<string>("formCodeSource", string)), (objectArg_4 = get$.Required, objectArg_4.Field<string>("description", string)), (objectArg_5 = get$.Required, objectArg_5.Field<int64>("currentVersionId", uncurry2(liberatedInt64Decoder))), (objectArg_6 = get$.Required, objectArg_6.Field<boolean>("isIntake", bool)), (objectArg_7 = get$.Required, objectArg_7.Field<string>("usage", string)), (objectArg_8 = get$.Required, objectArg_8.Field<boolean>("requiresSignature", bool)), (objectArg_9 = get$.Required, objectArg_9.Field<EncounterTypes>("encounterTypes", uncurry2(encounterTypesDecoder))), (objectArg_10 = get$.Required, objectArg_10.Field<boolean>("onceAYear", bool)), (objectArg_11 = get$.Required, objectArg_11.Field<string>("structureHash", string)), (objectArg_12 = get$.Required, objectArg_12.Field<string>("clinicalHash", string)), (objectArg_13 = get$.Required, objectArg_13.Field<string>("cosmeticHash", string)), (objectArg_14 = get$.Required, objectArg_14.Field<string>("hash", string)), (objectArg_15 = get$.Required, objectArg_15.Field<FSharpList<TemplateItem>>("items", (path_12: string, value_12: any): FSharpResult$2_$union<FSharpList<TemplateItem>, [string, ErrorReason_$union]> => list_3<TemplateItem>(uncurry2(itemDecoder), path_12, value_12))), (objectArg_16 = get$.Optional, objectArg_16.Field<FormScoring>("scoring", uncurry2(formScoringDecoder))));
457
493
  }, path_13, v));
458
494
 
459
- const elementTypeDecoder = (path_3: string): ((arg0: any) => FSharpResult$2_$union<ElementTypeEntry, [string, ErrorReason_$union]>) => ((v: any): FSharpResult$2_$union<ElementTypeEntry, [string, ErrorReason_$union]> => object<ElementTypeEntry>((get$: IGetters): ElementTypeEntry => {
460
- let objectArg: IRequiredGetter, objectArg_1: IRequiredGetter, objectArg_2: IRequiredGetter;
461
- return new ElementTypeEntry((objectArg = get$.Required, objectArg.Field<string>("code", string)), (objectArg_1 = get$.Required, objectArg_1.Field<string>("valueEncoding", string)), (objectArg_2 = get$.Required, objectArg_2.Field<string>("textField", string)));
462
- }, path_3, v));
495
+ const elementTypeDecoder = (path_2: string): ((arg0: any) => FSharpResult$2_$union<ElementTypeEntry, [string, ErrorReason_$union]>) => ((v: any): FSharpResult$2_$union<ElementTypeEntry, [string, ErrorReason_$union]> => object<ElementTypeEntry>((get$: IGetters): ElementTypeEntry => {
496
+ let objectArg: IRequiredGetter, objectArg_1: IRequiredGetter;
497
+ return new ElementTypeEntry((objectArg = get$.Required, objectArg.Field<string>("label", string)), (objectArg_1 = get$.Required, objectArg_1.Field<string>("control", string)));
498
+ }, path_2, v));
499
+
500
+ const elementTypesFromDecoder = (path_6: string): ((arg0: any) => FSharpResult$2_$union<ElementTypesFrom_$union, [string, ErrorReason_$union]>) => ((v: any): FSharpResult$2_$union<ElementTypesFrom_$union, [string, ErrorReason_$union]> => object<ElementTypesFrom_$union>((get$: IGetters): ElementTypesFrom_$union => {
501
+ let objectArg_1: IRequiredGetter, objectArg_2: IRequiredGetter, objectArg_3: IRequiredGetter, objectArg_4: IRequiredGetter, objectArg_5: IRequiredGetter;
502
+ let matchValue: string;
503
+ const objectArg: IRequiredGetter = get$.Required;
504
+ matchValue = objectArg.Field<string>("statedBy", string);
505
+ switch (matchValue) {
506
+ case "site":
507
+ return ElementTypesFrom_StatedBy((objectArg_1 = get$.Required, objectArg_1.Field<string>("table", string)), (objectArg_2 = get$.Required, objectArg_2.Field<string>("key", string)), (objectArg_3 = get$.Required, objectArg_3.Field<string>("label", string)));
508
+ case "conduit":
509
+ return ElementTypesFrom_DeclaredByConduit((objectArg_4 = get$.Required, objectArg_4.Field<string>("because", string)));
510
+ case "nobody":
511
+ return ElementTypesFrom_NotInRelease((objectArg_5 = get$.Required, objectArg_5.Field<string>("because", string)));
512
+ default:
513
+ return toFail(printf("elementTypesFrom.statedBy = %s is not a provenance this build understands (site | conduit | nobody)"))(matchValue);
514
+ }
515
+ }, path_6, v));
463
516
 
464
517
  const instrumentMapEntryDecoder = (path_5: string): ((arg0: any) => FSharpResult$2_$union<InstrumentMapEntry, [string, ErrorReason_$union]>) => ((v: any): FSharpResult$2_$union<InstrumentMapEntry, [string, ErrorReason_$union]> => object<InstrumentMapEntry>((get$: IGetters): InstrumentMapEntry => {
465
518
  let objectArg: IRequiredGetter, objectArg_1: IOptionalGetter, objectArg_2: IOptionalGetter, objectArg_3: IRequiredGetter, objectArg_4: IRequiredGetter, objectArg_5: IRequiredGetter;
@@ -494,23 +547,105 @@ const instrumentMapStatsDecoder = (path: string): ((arg0: any) => FSharpResult$2
494
547
  }, path, v));
495
548
 
496
549
  const manifestDecoder = (path_3: string): ((arg0: any) => FSharpResult$2_$union<TemplateManifest, [string, ErrorReason_$union]>) => ((v: any): FSharpResult$2_$union<TemplateManifest, [string, ErrorReason_$union]> => object<TemplateManifest>((get$: IGetters): TemplateManifest => {
497
- let objectArg: IOptionalGetter, objectArg_1: IRequiredGetter, objectArg_2: IRequiredGetter, objectArg_3: IRequiredGetter, objectArg_4: IRequiredGetter, objectArg_5: IRequiredGetter, arg_13: ((arg0: string) => ((arg0: any) => FSharpResult$2_$union<FSharpMap<string, ElementTypeEntry>, [string, ErrorReason_$union]>)), objectArg_6: IRequiredGetter, arg_15: ((arg0: string) => ((arg0: any) => FSharpResult$2_$union<FSharpMap<string, TemplateForm>, [string, ErrorReason_$union]>)), objectArg_7: IRequiredGetter, arg_17: ((arg0: string) => ((arg0: any) => FSharpResult$2_$union<FSharpMap<string, InstrumentMapEntry>, [string, ErrorReason_$union]>)), objectArg_8: IRequiredGetter, objectArg_9: IRequiredGetter;
498
- return new TemplateManifest((objectArg = get$.Optional, objectArg.Field<string>("$schema", string)), (objectArg_1 = get$.Required, objectArg_1.Field<int32>("version", uncurry2(int))), (objectArg_2 = get$.Required, objectArg_2.Field<string>("generatedAt", string)), (objectArg_3 = get$.Required, objectArg_3.Field<string>("generatedFrom", string)), (objectArg_4 = get$.Required, objectArg_4.Field<CoreEmrInfo>("coreEmr", uncurry2(coreEmrDecoder))), (objectArg_5 = get$.Required, objectArg_5.Field<TemplateStats>("stats", uncurry2(statsDecoder))), (arg_13 = dictDecoder<ElementTypeEntry>(uncurry2(elementTypeDecoder)), (objectArg_6 = get$.Required, objectArg_6.Field<FSharpMap<string, ElementTypeEntry>>("elementTypes", uncurry2(arg_13)))), (arg_15 = dictDecoder<TemplateForm>(uncurry2(formDecoder)), (objectArg_7 = get$.Required, objectArg_7.Field<FSharpMap<string, TemplateForm>>("forms", uncurry2(arg_15)))), (arg_17 = dictDecoder<InstrumentMapEntry>(uncurry2(instrumentMapEntryDecoder)), (objectArg_8 = get$.Required, objectArg_8.Field<FSharpMap<string, InstrumentMapEntry>>("instrumentMap", uncurry2(arg_17)))), (objectArg_9 = get$.Required, objectArg_9.Field<InstrumentMapStats>("instrumentMapStats", uncurry2(instrumentMapStatsDecoder))));
550
+ let objectArg: IOptionalGetter, objectArg_1: IRequiredGetter, objectArg_2: IRequiredGetter, objectArg_3: IRequiredGetter, objectArg_4: IRequiredGetter, objectArg_5: IRequiredGetter, arg_13: ((arg0: string) => ((arg0: any) => FSharpResult$2_$union<FSharpMap<string, ElementTypeEntry>, [string, ErrorReason_$union]>)), objectArg_6: IOptionalGetter, objectArg_7: IOptionalGetter, arg_17: ((arg0: string) => ((arg0: any) => FSharpResult$2_$union<FSharpMap<string, TemplateForm>, [string, ErrorReason_$union]>)), objectArg_8: IRequiredGetter, arg_19: ((arg0: string) => ((arg0: any) => FSharpResult$2_$union<FSharpMap<string, InstrumentMapEntry>, [string, ErrorReason_$union]>)), objectArg_9: IRequiredGetter, objectArg_10: IRequiredGetter;
551
+ return new TemplateManifest((objectArg = get$.Optional, objectArg.Field<string>("$schema", string)), (objectArg_1 = get$.Required, objectArg_1.Field<int32>("version", uncurry2(int))), (objectArg_2 = get$.Required, objectArg_2.Field<string>("generatedAt", string)), (objectArg_3 = get$.Required, objectArg_3.Field<string>("generatedFrom", string)), (objectArg_4 = get$.Required, objectArg_4.Field<CoreEmrInfo>("coreEmr", uncurry2(coreEmrDecoder))), (objectArg_5 = get$.Required, objectArg_5.Field<TemplateStats>("stats", uncurry2(statsDecoder))), (arg_13 = dictDecoder<ElementTypeEntry>(uncurry2(elementTypeDecoder)), (objectArg_6 = get$.Optional, objectArg_6.Field<FSharpMap<string, ElementTypeEntry>>("elementTypes", uncurry2(arg_13)))), defaultArg((objectArg_7 = get$.Optional, objectArg_7.Field<ElementTypesFrom_$union>("elementTypesFrom", uncurry2(elementTypesFromDecoder))), ElementTypesFrom_NotInRelease("the manifest carried no `elementTypesFrom`, so no provenance for the item-type vocabulary was stated")), (arg_17 = dictDecoder<TemplateForm>(uncurry2(formDecoder)), (objectArg_8 = get$.Required, objectArg_8.Field<FSharpMap<string, TemplateForm>>("forms", uncurry2(arg_17)))), (arg_19 = dictDecoder<InstrumentMapEntry>(uncurry2(instrumentMapEntryDecoder)), (objectArg_9 = get$.Required, objectArg_9.Field<FSharpMap<string, InstrumentMapEntry>>("instrumentMap", uncurry2(arg_19)))), (objectArg_10 = get$.Required, objectArg_10.Field<InstrumentMapStats>("instrumentMapStats", uncurry2(instrumentMapStatsDecoder))));
499
552
  }, path_3, v));
500
553
 
501
554
  function toCoreMRChoice(itemId: int32, c: TemplateChoice): CoreMRChoice {
502
555
  return new CoreMRChoice(c.ChoiceId, itemId, c.Sequence, c.Text, c.Score, c.BitPosition, c.Code, map_1<int32, string>(int32ToString, c.Highlight));
503
556
  }
504
557
 
505
- function toCoreMRItem(item: TemplateItem): CoreMRItem {
506
- return new CoreMRItem(item.ItemId, item.Sequence, item.NestingLevel, item.SequenceText, item.Type, int32ToString(item.Type), !isEmpty(item.Choices), true, false, item.Text, item.IsRequired, item.GenderRequired, map_1<int32, string>(int32ToString, item.Highlight), item.Code, item.Uuid, undefined, undefined, 0, 0, undefined);
558
+ /**
559
+ * Does this control carry free text, and does it carry a date?
560
+ *
561
+ * ⭐ THE ONE IMPLEMENTATION. It lives here because this file compiles before every adapter that needs
562
+ * it, so nothing downstream has an excuse to write a second one. ⛔ It follows from the CONTROL, which
563
+ * the site states (5.5.0+9704) or conduit declares (5.5.0+10245) — never from the invented `textField`
564
+ * word, which nothing publishes any more.
565
+ * ⚠️ It says what the UI OFFERS, not what a given item's answers contain: type 130 is a vitals widget
566
+ * and 35,427 of its answers carry text anyway.
567
+ */
568
+ export function carriesTextOrDate(control: string): [boolean, boolean] {
569
+ let matchResult: int32, c_3: string;
570
+ switch (control) {
571
+ case "DateField":
572
+ case "DateFieldWithTime": {
573
+ matchResult = 0;
574
+ break;
575
+ }
576
+ case "SignatureAndDate":
577
+ case "SignatureAndDateWithTime": {
578
+ matchResult = 1;
579
+ break;
580
+ }
581
+ case "ShortAnswer":
582
+ case "NoteEssay": {
583
+ matchResult = 2;
584
+ break;
585
+ }
586
+ case "PatientVitals": {
587
+ if (control.endsWith("PlusNotes")) {
588
+ matchResult = 3;
589
+ c_3 = control;
590
+ }
591
+ else {
592
+ matchResult = 4;
593
+ }
594
+ break;
595
+ }
596
+ case "AllergyFinder": {
597
+ if (control.endsWith("PlusNotes")) {
598
+ matchResult = 3;
599
+ c_3 = control;
600
+ }
601
+ else {
602
+ matchResult = 4;
603
+ }
604
+ break;
605
+ }
606
+ default:
607
+ if (control.endsWith("PlusNotes")) {
608
+ matchResult = 3;
609
+ c_3 = control;
610
+ }
611
+ else {
612
+ matchResult = 5;
613
+ }
614
+ }
615
+ switch (matchResult) {
616
+ case 0:
617
+ return [true, true] as [boolean, boolean];
618
+ case 1:
619
+ return [true, true] as [boolean, boolean];
620
+ case 2:
621
+ return [true, false] as [boolean, boolean];
622
+ case 3:
623
+ return [true, false] as [boolean, boolean];
624
+ case 4:
625
+ return [true, false] as [boolean, boolean];
626
+ default:
627
+ return [false, false] as [boolean, boolean];
628
+ }
629
+ }
630
+
631
+ function toCoreMRItem(kinds: FSharpMap<string, ElementTypeEntry>, item: TemplateItem): CoreMRItem {
632
+ let control: string;
633
+ const value = `unresolved_${item.Type}`;
634
+ control = defaultArg(map_1<ElementTypeEntry, string>((k: ElementTypeEntry): string => k.Control, tryFind<string, ElementTypeEntry>(int32ToString(item.Type), kinds)), value);
635
+ const patternInput: [boolean, boolean] = carriesTextOrDate(control);
636
+ return new CoreMRItem(item.ItemId, item.Sequence, item.NestingLevel, item.SequenceText, item.Type, control, !isEmpty(item.Choices), patternInput[0], patternInput[1], item.Text, item.IsRequired, item.GenderRequired, map_1<int32, string>(int32ToString, item.Highlight), item.Code, item.Uuid, undefined, undefined, 0, 0, undefined);
507
637
  }
508
638
 
509
639
  /**
510
640
  * Convert a TemplateForm to CoreMRFormData — the universal pipeline input.
641
+ * ⭐ `kinds` IS REQUIRED — the manifest's item vocabulary, stated by the site or declared by conduit.
642
+ * ⛔ It is not optional and it does not default: the whole point of FLIP-9 is that a form's fields are
643
+ * typed by what the SITE says an item kind is, and a caller that has no kinds is a caller whose items
644
+ * cannot be resolved. Passing `Map.empty` is a legitimate statement ("nothing states them"), and every
645
+ * field then arrives NAMED as unresolved rather than silently guessed.
511
646
  */
512
- export function toCoreMRFormData(form: TemplateForm): CoreMRFormData {
513
- return new CoreMRFormData(new CoreMRFormMetadata(form.FormId, form.Name, isNullOrEmpty(form.Description) ? undefined : form.Description, ~~toInt32(form.CurrentVersionId), 1, undefined, form.RequiresSignature, form.IsIntake, "", ""), map_2<TemplateItem, CoreMRItem>(toCoreMRItem, form.Items), collect<TemplateItem, CoreMRChoice>((item_1: TemplateItem): FSharpList<CoreMRChoice> => map_2<TemplateChoice, CoreMRChoice>((c: TemplateChoice): CoreMRChoice => toCoreMRChoice(item_1.ItemId, c), item_1.Choices), form.Items), empty<CoreMRTrigger>(), empty<CoreMRTag>());
647
+ export function toCoreMRFormData(kinds: FSharpMap<string, ElementTypeEntry>, form: TemplateForm): CoreMRFormData {
648
+ return new CoreMRFormData(new CoreMRFormMetadata(form.FormId, form.Name, isNullOrEmpty(form.Description) ? undefined : form.Description, ~~toInt32(form.CurrentVersionId), 1, undefined, form.RequiresSignature, form.IsIntake, "", ""), map_2<TemplateItem, CoreMRItem>((item: TemplateItem): CoreMRItem => toCoreMRItem(kinds, item), form.Items), collect<TemplateItem, CoreMRChoice>((item_1: TemplateItem): FSharpList<CoreMRChoice> => map_2<TemplateChoice, CoreMRChoice>((c: TemplateChoice): CoreMRChoice => toCoreMRChoice(item_1.ItemId, c), item_1.Choices), form.Items), empty<CoreMRTrigger>(), empty<CoreMRTag>());
514
649
  }
515
650
 
516
651
  /**
@@ -700,7 +700,7 @@ export function createFormStep(stepOrder: int32, stepLabel: string, fields: Spec
700
700
  * TypeScript: createFormSpec(id: string, title: string, steps: FormStep[])
701
701
  */
702
702
  export function createFormSpec(idString: string, title: string, steps: Spec_FormStep$1<Spec_FieldType_$union>[]): Spec_FormSpec$1<Spec_FieldType_$union> {
703
- return new Spec_FormSpec$1(parse(idString), "DYN", title, "Dynamically created FormSpec", "1.0.0", "2.0.5", ofSeq_1<Spec_FormStep$1<Spec_FieldType_$union>>(steps), empty<string>(), undefined, empty<string>(), false, false, undefined, Spec_FormLifecycle_Blueprint(), undefined, undefined, undefined, Spec_FormClassification_General());
703
+ return new Spec_FormSpec$1(parse(idString), "DYN", title, "Dynamically created FormSpec", "1.0.0", "2.0.5", ofSeq_1<Spec_FormStep$1<Spec_FieldType_$union>>(steps), empty<string>(), undefined, undefined, empty<string>(), false, false, undefined, Spec_FormLifecycle_Blueprint(), undefined, undefined, undefined, Spec_FormClassification_General());
704
704
  }
705
705
 
706
706
  /**
@@ -766,7 +766,7 @@ export function createClinicalPathway(name: string, states: ClinicalPathway_Stat
766
766
  * TypeScript: addPathwayToFormSpec(formSpec: FormSpec, pathway: ClinicalPathwaySpec)
767
767
  */
768
768
  export function addPathwayToFormSpec(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>, pathway: ClinicalPathway_ClinicalPathwaySpec): Spec_FormSpec$1<Spec_FieldType_$union> {
769
- return new Spec_FormSpec$1(formSpec.Id, formSpec.Code, formSpec.Title, formSpec.Abstract, formSpec.Version, formSpec.FormSpecVersion, formSpec.Steps, formSpec.CategoryTags, formSpec.Score, formSpec.AssociatedCodes, formSpec.RequiresReview, formSpec.RequiresReviewAndApproval, pathway, formSpec.Lifecycle, formSpec.FilledMeta, formSpec.CustomData, formSpec.Provenance, formSpec.Classification);
769
+ return new Spec_FormSpec$1(formSpec.Id, formSpec.Code, formSpec.Title, formSpec.Abstract, formSpec.Version, formSpec.FormSpecVersion, formSpec.Steps, formSpec.CategoryTags, formSpec.Score, formSpec.VendorScore, formSpec.AssociatedCodes, formSpec.RequiresReview, formSpec.RequiresReviewAndApproval, pathway, formSpec.Lifecycle, formSpec.FilledMeta, formSpec.CustomData, formSpec.Provenance, formSpec.Classification);
770
770
  }
771
771
 
772
772
  /**
@@ -835,7 +835,7 @@ export function createTestFormSpec(): Spec_FormSpec$1<Spec_FieldType_$union> {
835
835
  const option1: Shared_FieldOption = new Shared_FieldOption("Option 1", "opt1", new Shared_FieldOptionKey(newGuid()), undefined);
836
836
  const option2: Shared_FieldOption = new Shared_FieldOption("Option 2", "opt2", new Shared_FieldOptionKey(newGuid()), undefined);
837
837
  const testStep: Spec_FormStep$1<Spec_FieldType_$union> = new Spec_FormStep$1(1, "Test Step", ofArray_2([new Spec_FormField$1(1, new Shared_FieldKey("11111111-1111-1111-1111-111111111111"), "Test Text Field", undefined, undefined, false, false, false, Spec_FieldType_Text(new Spec_TextInfo(undefined)), undefined), new Spec_FormField$1(2, new Shared_FieldKey("22222222-2222-2222-2222-222222222222"), "Test Checkbox List", undefined, undefined, false, false, false, Spec_FieldType_CheckboxList(new Spec_MultiChoiceInfo(ofArray_2([option1, option2]))), undefined), new Spec_FormField$1(3, new Shared_FieldKey("33333333-3333-3333-3333-333333333333"), "Test Matrix", undefined, undefined, false, false, false, Spec_FieldType_Matrix(new Spec_MatrixInfo(ofArray_2([option1, option2]), ofArray_2([new Shared_FieldOption("Scale 1", "1", new Shared_FieldOptionKey(newGuid()), 1), new Shared_FieldOption("Scale 2", "2", new Shared_FieldOptionKey(newGuid()), 2)]))), undefined), new Spec_FormField$1(4, new Shared_FieldKey("44444444-4444-4444-4444-444444444444"), "Test Plugin Field", undefined, undefined, false, false, false, Spec_FieldType_PluginField(new Spec_PluginFieldConfig("test.plugin", undefined, undefined)), undefined)]));
838
- return new Spec_FormSpec$1(newGuid(), "TEST-001", "Test Form", "Test form for buildDynamicFormResultData", "1.0.0", "5.0.0", singleton_1(testStep), empty<string>(), undefined, empty<string>(), false, false, undefined, Spec_FormLifecycle_Blueprint(), undefined, undefined, undefined, Spec_FormClassification_General());
838
+ return new Spec_FormSpec$1(newGuid(), "TEST-001", "Test Form", "Test form for buildDynamicFormResultData", "1.0.0", "5.0.0", singleton_1(testStep), empty<string>(), undefined, undefined, empty<string>(), false, false, undefined, Spec_FormLifecycle_Blueprint(), undefined, undefined, undefined, Spec_FormClassification_General());
839
839
  }
840
840
 
841
841
  /**
@@ -1613,7 +1613,7 @@ export function getFieldCoreMRAnchor(formSpec: Spec_FormSpec$1<Spec_FieldType_$u
1613
1613
  const matchValue: Option<IntegrationProvenance> = formSpec.Provenance;
1614
1614
  let matchResult: int32, provenance_1: IntegrationProvenance;
1615
1615
  if (matchValue != null) {
1616
- if (value_19(matchValue).IntegrationKey === "coremr") {
1616
+ if (value_19(matchValue).Vendor === "coremr") {
1617
1617
  matchResult = 0;
1618
1618
  provenance_1 = value_19(matchValue);
1619
1619
  }