@f1studio/form-spec 5.0.0-alpha.164 → 5.0.0-alpha.166

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 (83) 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 +13 -14
  28. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.d.ts.map +1 -1
  29. package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.js +18 -61
  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 +34 -10
  45. package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.d.ts.map +1 -1
  46. package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.js +191 -30
  47. package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.js.map +1 -1
  48. package/FormSpec.FS/Interop/Facade/FormItemLookup.d.ts +95 -0
  49. package/FormSpec.FS/Interop/Facade/FormItemLookup.d.ts.map +1 -0
  50. package/FormSpec.FS/Interop/Facade/FormItemLookup.js +155 -0
  51. package/FormSpec.FS/Interop/Facade/FormItemLookup.js.map +1 -0
  52. package/FormSpec.FS/Interop/FormSpec.Api.Helpers.js +4 -4
  53. package/FormSpec.FS/Interop/FormSpec.Api.Helpers.js.map +1 -1
  54. package/FormSpec.FS/Interop/FormSpec.Api.Option.d.ts +26 -2
  55. package/FormSpec.FS/Interop/FormSpec.Api.Option.d.ts.map +1 -1
  56. package/FormSpec.FS/Interop/FormSpec.Api.Option.js +77 -3
  57. package/FormSpec.FS/Interop/FormSpec.Api.Option.js.map +1 -1
  58. package/FormSpec.FS/Provenance.d.ts +20 -2
  59. package/FormSpec.FS/Provenance.d.ts.map +1 -1
  60. package/FormSpec.FS/Provenance.js +66 -3
  61. package/FormSpec.FS/Provenance.js.map +1 -1
  62. package/README.md +7 -7
  63. package/Thoth.Json/packages/Thoth.Json/Encode.js.map +1 -1
  64. package/package.json +5 -1
  65. package/src/FormSpec.FS/BlueprintValidation.ts +1 -1
  66. package/src/FormSpec.FS/Designer.ts +1 -1
  67. package/src/FormSpec.FS/FormSpec.ts +32 -2
  68. package/src/FormSpec.FS/FormSpecHelpers.ts +1 -1
  69. package/src/FormSpec.FS/FormSpecValues.ts +1 -1
  70. package/src/FormSpec.FS/Helpers.ts +11 -11
  71. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.ts +25 -12
  72. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.ts +41 -41
  73. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.ts +62 -30
  74. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.ts +28 -46
  75. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.ts +52 -27
  76. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.ts +7 -5
  77. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRTriggerEnrichment.ts +1 -1
  78. package/src/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.ts +1 -1
  79. package/src/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.ts +154 -42
  80. package/src/FormSpec.FS/Interop/Facade/FormItemLookup.ts +179 -0
  81. package/src/FormSpec.FS/Interop/FormSpec.Api.Helpers.ts +4 -4
  82. package/src/FormSpec.FS/Interop/FormSpec.Api.Option.ts +63 -8
  83. package/src/FormSpec.FS/Provenance.ts +50 -4
@@ -2,16 +2,17 @@ import { toString, Record, Union } from "@fable-org/fable-library-js/Types.js";
2
2
  import { int32 } from "@fable-org/fable-library-js/Int32.js";
3
3
  import { defaultArg, value as value_3, map as map_1, Option } from "@fable-org/fable-library-js/Option.js";
4
4
  import { record_type, list_type, union_type, option_type, bool_type, string_type, int32_type, TypeInfo } from "@fable-org/fable-library-js/Reflection.js";
5
- import { isEmpty, filter, empty as empty_1, singleton as singleton_1, ofSeq, choose, collect, map, sumBy, length, FSharpList } from "@fable-org/fable-library-js/List.js";
5
+ import { isEmpty, filter, singleton as singleton_1, empty as empty_1, ofSeq, choose, collect, sortBy, map, sumBy, length, FSharpList } from "@fable-org/fable-library-js/List.js";
6
6
  import { IDisposable, disposeSafe, IEnumerator, getEnumerator, compare, int32ToString, comparePrimitives, numberHash, IComparable, IEquatable } from "@fable-org/fable-library-js/Util.js";
7
7
  import { HeadingItem, detectHeadings } from "./CorEMRSectioning.js";
8
8
  import { CoreMRTrigger, CoreMRFormData, CoreMRFormMetadata, CoreMRChoice, CoreMRItem } from "../../CorEMR/CoreMRTypes.js";
9
- import { ClinicalPathway_ClinicalPathwaySpec, Spec_Score, Spec_SingleChoiceInfo, Spec_MultiChoiceInfo, Spec_FormField$1, Shared_FieldKey, Spec_FormSpec$1, Spec_FieldType_$union, Spec_FormStep$1 } from "../../../FormSpec.js";
9
+ import { ClinicalPathway_ClinicalPathwaySpec, Spec_VendorScore, Spec_VendorScoreBand, Spec_SingleChoiceInfo, Spec_MultiChoiceInfo, Spec_FormField$1, Shared_FieldKey, Spec_FormSpec$1, Spec_FieldType_$union, Spec_FormStep$1 } from "../../../FormSpec.js";
10
10
  import { tryFind, FSharpMap, ofList } from "@fable-org/fable-library-js/Map.js";
11
11
  import { List_groupBy } from "@fable-org/fable-library-js/Seq2.js";
12
- import { toInt32 } from "@fable-org/fable-library-js/BigInt.js";
12
+ import { join } from "@fable-org/fable-library-js/String.js";
13
13
  import { empty, singleton, append, delay, toList } from "@fable-org/fable-library-js/Seq.js";
14
14
  import { getElementTypeInfo } from "./CorEMRElementTypeMap.js";
15
+ import { FormScoring, ScoringLabel } from "../../CorEMR/TemplateManifestDecoder.js";
15
16
  import { FSharpResult$2_$union, FSharpResult$2_Ok, FSharpResult$2_Error } from "@fable-org/fable-library-js/Result.js";
16
17
 
17
18
  export type ValidationError_$union =
@@ -44,7 +45,7 @@ export type ValidationError_$cases = {
44
45
  7: ["MissingStep", [string]],
45
46
  8: ["ChoiceCountMismatch", [int32, string, int32, int32]],
46
47
  9: ["RequiredFieldMismatch", [int32, string, boolean, boolean]],
47
- 10: ["ScoreMismatch", [int32, Option<int32>]],
48
+ 10: ["ScoreMismatch", [string, Option<string>]],
48
49
  11: ["TagCountMismatch", [int32, int32]],
49
50
  12: ["PathwayMissing", [int32]],
50
51
  13: ["PathwayStateCountInvalid", [string, int32, int32]],
@@ -93,7 +94,7 @@ export function ValidationError_RequiredFieldMismatch(itemId: int32, itemLabel:
93
94
  return new ValidationError<9>(9, [itemId, itemLabel, expected, actual]);
94
95
  }
95
96
 
96
- export function ValidationError_ScoreMismatch(expected: int32, actual: Option<int32>) {
97
+ export function ValidationError_ScoreMismatch(expected: string, actual: Option<string>) {
97
98
  return new ValidationError<10>(10, [expected, actual]);
98
99
  }
99
100
 
@@ -131,7 +132,7 @@ export class ValidationError<Tag extends keyof ValidationError_$cases> extends U
131
132
  }
132
133
 
133
134
  export function ValidationError_$reflection(): TypeInfo {
134
- return union_type("FormSpec.Integrations.CorEMR.CorEMRFormSpecValidator.ValidationError", [], ValidationError, () => [[["expected", int32_type], ["actual", int32_type]], [["expected", int32_type], ["actual", int32_type]], [["step", string_type], ["expected", int32_type], ["actual", int32_type]], [["field", string_type], ["expected", string_type], ["actual", string_type]], [["itemId", int32_type], ["itemLabel", string_type]], [["itemId", int32_type], ["itemType", string_type], ["reason", string_type]], [["itemId", int32_type], ["heading", string_type]], [["heading", string_type]], [["itemId", int32_type], ["itemLabel", string_type], ["expected", int32_type], ["actual", int32_type]], [["itemId", int32_type], ["itemLabel", string_type], ["expected", bool_type], ["actual", bool_type]], [["expected", int32_type], ["actual", option_type(int32_type)]], [["expected", int32_type], ["actual", int32_type]], [["triggerCount", int32_type]], [["pathwayId", string_type], ["expected", int32_type], ["actual", int32_type]], [["pathwayId", string_type], ["expected", int32_type], ["actual", int32_type]], [["triggerId", int32_type], ["expected", int32_type], ["actual", int32_type]], [["triggerId", int32_type], ["expected", int32_type], ["actual", int32_type]]]);
135
+ return union_type("FormSpec.Integrations.CorEMR.CorEMRFormSpecValidator.ValidationError", [], ValidationError, () => [[["expected", int32_type], ["actual", int32_type]], [["expected", int32_type], ["actual", int32_type]], [["step", string_type], ["expected", int32_type], ["actual", int32_type]], [["field", string_type], ["expected", string_type], ["actual", string_type]], [["itemId", int32_type], ["itemLabel", string_type]], [["itemId", int32_type], ["itemType", string_type], ["reason", string_type]], [["itemId", int32_type], ["heading", string_type]], [["heading", string_type]], [["itemId", int32_type], ["itemLabel", string_type], ["expected", int32_type], ["actual", int32_type]], [["itemId", int32_type], ["itemLabel", string_type], ["expected", bool_type], ["actual", bool_type]], [["expected", string_type], ["actual", option_type(string_type)]], [["expected", int32_type], ["actual", int32_type]], [["triggerCount", int32_type]], [["pathwayId", string_type], ["expected", int32_type], ["actual", int32_type]], [["pathwayId", string_type], ["expected", int32_type], ["actual", int32_type]], [["triggerId", int32_type], ["expected", int32_type], ["actual", int32_type]], [["triggerId", int32_type], ["expected", int32_type], ["actual", int32_type]]]);
135
136
  }
136
137
 
137
138
  export class ValidationResult extends Record implements IEquatable<ValidationResult>, IComparable<ValidationResult> {
@@ -213,14 +214,10 @@ export function FormSpecValidator_getChoicesPerItem(choices: FSharpList<CoreMRCh
213
214
  });
214
215
  }
215
216
 
216
- /**
217
- * Calculate expected max score from CoreMR
218
- */
219
- export function FormSpecValidator_calculateExpectedMaxScore(choices: FSharpList<CoreMRChoice>): int32 {
220
- return sumBy<CoreMRChoice, int32>((c: CoreMRChoice): int32 => ~~toInt32(c.Score), choices, {
221
- GetZero: (): int32 => 0,
222
- Add: (x: int32, y: int32): int32 => (x + y),
223
- });
217
+ function FormSpecValidator_describeScale(name: string, bands: FSharpList<[string, int32]>): string {
218
+ return `${name} [${join(", ", map<[string, int32], string>((tupledArg: [string, int32]): string => (`${tupledArg[0]}>=${tupledArg[1]}`), sortBy<[string, int32], int32>((tuple: [string, int32]): int32 => tuple[1], bands, {
219
+ Compare: comparePrimitives,
220
+ })))}]`;
224
221
  }
225
222
 
226
223
  /**
@@ -398,27 +395,62 @@ export function FormSpecValidator_validateRequiredFields(coreMR: CoreMRFormData,
398
395
  }
399
396
 
400
397
  /**
401
- * Validate scoring calculation
398
+ * Does the blueprint carry exactly the scale CoreMR stated for this form?
399
+ *
400
+ * ⭐ THE ORACLE IS THE SITE, NOT US. `scoring` is the form's own `form_scores` row as conduit
401
+ * published it — the scale's name and its bands. This function only asks whether the
402
+ * blueprint says the same thing.
403
+ *
404
+ * It catches, by construction, the defect that shipped for months and that no validator saw:
405
+ * a blueprint carrying bands nobody stated. ⛔ It must never grow a branch that computes a
406
+ * scale of its own to compare against — that is precisely how it went blind the first time.
407
+ *
408
+ * | the site | the blueprint | verdict |
409
+ * |---|---|---|
410
+ * | states a scale | carries the same one | ✅ |
411
+ * | states a scale | carries a different one, or none | 🚨 `ScoreMismatch` |
412
+ * | states none | carries none | ✅ |
413
+ * | states none | carries one | 🚨 `ScoreMismatch` — invented out of nothing |
402
414
  */
403
- export function FormSpecValidator_validateScoring(coreMR: CoreMRFormData, formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): FSharpList<ValidationError_$union> {
404
- const expectedScore: int32 = FormSpecValidator_calculateExpectedMaxScore(coreMR.Choices) | 0;
405
- if (expectedScore > 0) {
406
- const matchValue: Option<Spec_Score> = formSpec.Score;
407
- if (matchValue == null) {
408
- return singleton_1(ValidationError_ScoreMismatch(expectedScore, undefined));
409
- }
410
- else {
411
- const score: Spec_Score = value_3(matchValue);
412
- if (score.MaxScore !== expectedScore) {
413
- return singleton_1(ValidationError_ScoreMismatch(expectedScore, score.MaxScore));
415
+ export function FormSpecValidator_validateScoring(scoring: Option<FormScoring>, formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): FSharpList<ValidationError_$union> {
416
+ const statedText: Option<string> = map_1<FormScoring, string>((s: FormScoring): string => FormSpecValidator_describeScale(s.ScoreName, map<ScoringLabel, [string, int32]>((l: ScoringLabel): [string, int32] => ([l.Name, l.Min] as [string, int32]), s.Labels)), scoring);
417
+ const carriedText: Option<string> = map_1<Spec_VendorScore, string>((sc: Spec_VendorScore): string => FormSpecValidator_describeScale(sc.ScaleName, map<Spec_VendorScoreBand, [string, int32]>((b: Spec_VendorScoreBand): [string, int32] => ([b.Label, b.Min] as [string, int32]), sc.Bands)), formSpec.VendorScore);
418
+ let matchResult: int32, carried_1: string, stated_1: string, carried_2: Option<string>, stated_2: string, carried_3: string;
419
+ if (statedText != null) {
420
+ if (carriedText != null) {
421
+ if (value_3(statedText) === value_3(carriedText)) {
422
+ matchResult = 1;
423
+ carried_1 = value_3(carriedText);
424
+ stated_1 = value_3(statedText);
414
425
  }
415
426
  else {
416
- return empty_1<ValidationError_$union>();
427
+ matchResult = 2;
428
+ carried_2 = carriedText;
429
+ stated_2 = value_3(statedText);
417
430
  }
418
431
  }
432
+ else {
433
+ matchResult = 2;
434
+ carried_2 = carriedText;
435
+ stated_2 = value_3(statedText);
436
+ }
437
+ }
438
+ else if (carriedText != null) {
439
+ matchResult = 3;
440
+ carried_3 = value_3(carriedText);
419
441
  }
420
442
  else {
421
- return empty_1<ValidationError_$union>();
443
+ matchResult = 0;
444
+ }
445
+ switch (matchResult) {
446
+ case 0:
447
+ return empty_1<ValidationError_$union>();
448
+ case 1:
449
+ return empty_1<ValidationError_$union>();
450
+ case 2:
451
+ return singleton_1(ValidationError_ScoreMismatch(stated_2!, carried_2!));
452
+ default:
453
+ return singleton_1(ValidationError_ScoreMismatch("(CoreMR states no scale for this form)", carried_3!));
422
454
  }
423
455
  }
424
456
 
@@ -478,9 +510,9 @@ export function FormSpecValidator_validatePathways(triggers: FSharpList<CoreMRTr
478
510
  /**
479
511
  * Main validation function
480
512
  */
481
- export function FormSpecValidator_validateConversion(coreMR: CoreMRFormData, formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): FSharpResult$2_$union<ValidationResult, string> {
513
+ export function FormSpecValidator_validateConversion(scoring: Option<FormScoring>, coreMR: CoreMRFormData, formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): FSharpResult$2_$union<ValidationResult, string> {
482
514
  try {
483
- const allErrors: FSharpList<ValidationError_$union> = toList<ValidationError_$union>(delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateMetadata(coreMR.Metadata, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateCounts(coreMR, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateChoices(coreMR, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateRequiredFields(coreMR, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateScoring(coreMR, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateTags(coreMR, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => FormSpecValidator_validatePathways(coreMR.Triggers, formSpec.ClinicalPathway)))))))))))))));
515
+ const allErrors: FSharpList<ValidationError_$union> = toList<ValidationError_$union>(delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateMetadata(coreMR.Metadata, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateCounts(coreMR, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateChoices(coreMR, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateRequiredFields(coreMR, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateScoring(scoring, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => append<ValidationError_$union>(FormSpecValidator_validateTags(coreMR, formSpec), delay<ValidationError_$union>((): Iterable<ValidationError_$union> => FormSpecValidator_validatePathways(coreMR.Triggers, formSpec.ClinicalPathway)))))))))))))));
484
516
  return FSharpResult$2_Ok<ValidationResult, string>(new ValidationResult(isEmpty(allErrors), allErrors, empty_1<ValidationError_$union>(), FormSpecValidator_createSummary(coreMR, formSpec)));
485
517
  }
486
518
  catch (ex: any) {
@@ -1,42 +1,16 @@
1
- import { FSharpRef, Record } from "@fable-org/fable-library-js/Types.js";
2
- import { int32ToString, comparePrimitives, IComparable, IEquatable } from "@fable-org/fable-library-js/Util.js";
3
- import { record_type, string_type, TypeInfo } from "@fable-org/fable-library-js/Reflection.js";
4
- import { FSharpSet__Contains, contains, FSharpSet, ofSeq } from "@fable-org/fable-library-js/Set.js";
5
- import { tryParse, int32 } from "@fable-org/fable-library-js/Int32.js";
6
1
  import { Spec_FormClassification_$union, Spec_FormClassification_General, Spec_FormClassification_Screening, Spec_FormClassification_Intake, Spec_FormClassification_ClinicalInstrument, Spec_ClinicalInstrumentInfo } from "../../../FormSpec.js";
7
- import { bind, orElse, map as map_1, orElseWith, defaultArg, Option, value as value_5 } from "@fable-org/fable-library-js/Option.js";
2
+ import { tryParse, int32 } from "@fable-org/fable-library-js/Int32.js";
3
+ import { bind, orElse, map as map_1, defaultArg, Option, value as value_5 } from "@fable-org/fable-library-js/Option.js";
8
4
  import { isNullOrEmpty } from "@fable-org/fable-library-js/String.js";
9
5
  import { int64, toInt32 } from "@fable-org/fable-library-js/BigInt.js";
10
- import { CoreMRFormDetail, CoreMRTag, CoreMRTrigger, CoreMRTriggerEvent, CoreMRTriggerCondition, CoreMRChoice, CoreMRItem, CoreMRFormMetadata } from "../../CorEMR/CoreMRTypes.js";
6
+ import { CoreMRFormData, CoreMRFormDetail, CoreMRTag, CoreMRTrigger, CoreMRTriggerEvent, CoreMRTriggerCondition, CoreMRChoice, CoreMRItem, CoreMRFormMetadata } from "../../CorEMR/CoreMRTypes.js";
11
7
  import { empty, choose, item as item_3, length, mapIndexed, sortBy, collect, FSharpList, isEmpty, map } from "@fable-org/fable-library-js/List.js";
12
- import { FSharpMap, filter, keys, isEmpty as isEmpty_1, tryFind } from "@fable-org/fable-library-js/Map.js";
13
- import { ElementTypeInfo, getElementTypeInfo } from "./CorEMRElementTypeMap.js";
14
- import { TemplateForm, ItemTrigger, TriggerAction, TriggerCondition, TemplateChoice, TemplateItem } from "../../CorEMR/TemplateManifestDecoder.js";
8
+ import { TemplateForm, ItemTrigger, TriggerAction, TriggerCondition, TemplateChoice, TemplateItem, carriesTextOrDate, ElementTypeEntry } from "../../CorEMR/TemplateManifestDecoder.js";
9
+ import { FSharpMap, tryFind } from "@fable-org/fable-library-js/Map.js";
10
+ import { comparePrimitives, int32ToString } from "@fable-org/fable-library-js/Util.js";
11
+ import { FSharpSet__Contains, FSharpSet, ofSeq } from "@fable-org/fable-library-js/Set.js";
15
12
  import { normalizeChoiceScores } from "../../../BitmaskHelpers.js";
16
-
17
- export class BridgeElementTypeInfo extends Record implements IEquatable<BridgeElementTypeInfo>, IComparable<BridgeElementTypeInfo> {
18
- readonly Code: string;
19
- readonly ValueEncoding: string;
20
- readonly TextFieldRole: string;
21
- constructor(Code: string, ValueEncoding: string, TextFieldRole: string) {
22
- super();
23
- this.Code = Code;
24
- this.ValueEncoding = ValueEncoding;
25
- this.TextFieldRole = TextFieldRole;
26
- }
27
- }
28
-
29
- export function BridgeElementTypeInfo_$reflection(): TypeInfo {
30
- return record_type("FormSpec.Integrations.CorEMR.CorEMRTemplateMapper.BridgeElementTypeInfo", [], BridgeElementTypeInfo, () => [["Code", string_type], ["ValueEncoding", string_type], ["TextFieldRole", string_type]]);
31
- }
32
-
33
- const multiSelectCodes: FSharpSet<string> = ofSeq(["chips_notes", "checkbox", "checkbox_notes", "chips_ros"], {
34
- Compare: comparePrimitives,
35
- });
36
-
37
- function hasTextHasDateFromBridge(textField: string): [boolean, boolean] {
38
- return [(textField === "content") ? true : (textField === "optional_notes"), textField === "iso_date"] as [boolean, boolean];
39
- }
13
+ import { FSharpRef } from "@fable-org/fable-library-js/Types.js";
40
14
 
41
15
  /**
42
16
  * Map catalog classification fields to the FormClassification DU.
@@ -96,22 +70,17 @@ export function mapFormClassification(formCategory: Option<string>, instrumentTy
96
70
  * When elementTypes is non-empty, use it for ItemTypeName, HasText, HasDate, and bitmask detection.
97
71
  * When elementTypes is empty, fallback to CorEMRElementTypeMap.
98
72
  */
99
- export function mapNewTemplateToCoreMRDetail(elementTypes: FSharpMap<int32, BridgeElementTypeInfo>, template: TemplateForm): CoreMRFormDetail {
73
+ export function mapNewTemplateToCoreMRDetail(elementTypes: FSharpMap<string, ElementTypeEntry>, template: TemplateForm): CoreMRFormDetail {
100
74
  const metadata: CoreMRFormMetadata = new CoreMRFormMetadata(template.FormId, template.Name, isNullOrEmpty(template.Description) ? undefined : template.Description, ~~toInt32(template.CurrentVersionId), 1, undefined, template.RequiresSignature, template.IsIntake, template.FormCode, "");
101
75
  const items: FSharpList<CoreMRItem> = map<TemplateItem, CoreMRItem>((item: TemplateItem): CoreMRItem => {
102
- let info_1: BridgeElementTypeInfo;
76
+ let info: ElementTypeEntry;
103
77
  const itemTypeId: int32 = item.Type | 0;
104
- const value: BridgeElementTypeInfo = new BridgeElementTypeInfo(`unknown_${itemTypeId}`, "unknown", "unknown");
105
- info_1 = defaultArg(orElseWith<BridgeElementTypeInfo>(tryFind<int32, BridgeElementTypeInfo>(itemTypeId, elementTypes), (): Option<BridgeElementTypeInfo> => {
106
- const info: ElementTypeInfo = getElementTypeInfo(itemTypeId);
107
- return new BridgeElementTypeInfo(info.Code, info.ValueEncoding, info.TextFieldRole);
108
- }), value);
109
- const patternInput: [boolean, boolean] = hasTextHasDateFromBridge(info_1.TextFieldRole);
110
- return new CoreMRItem(item.ItemId, item.Sequence, item.NestingLevel, item.SequenceText, item.Type, info_1.Code, !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);
78
+ const value: ElementTypeEntry = new ElementTypeEntry(`unresolved item kind ${itemTypeId}`, `unresolved_${itemTypeId}`);
79
+ info = defaultArg(tryFind<string, ElementTypeEntry>(int32ToString(itemTypeId), elementTypes), value);
80
+ const patternInput: [boolean, boolean] = carriesTextOrDate(info.Control);
81
+ return new CoreMRItem(item.ItemId, item.Sequence, item.NestingLevel, item.SequenceText, item.Type, info.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);
111
82
  }, template.Items);
112
- const multiSelectTypes: FSharpSet<int32> = isEmpty_1<int32, BridgeElementTypeInfo>(elementTypes) ? ofSeq([26, 40, 41, 143], {
113
- Compare: comparePrimitives,
114
- }) : ofSeq<int32>(keys<int32, BridgeElementTypeInfo>(filter<int32, BridgeElementTypeInfo>((_arg: int32, info_2: BridgeElementTypeInfo): boolean => contains<string>(info_2.Code, multiSelectCodes), elementTypes)), {
83
+ const multiSelectTypes: FSharpSet<int32> = ofSeq([26, 40, 41, 143], {
115
84
  Compare: comparePrimitives,
116
85
  });
117
86
  return new CoreMRFormDetail(metadata, items, collect<TemplateItem, CoreMRChoice>((item_1: TemplateItem): FSharpList<CoreMRChoice> => {
@@ -147,4 +116,17 @@ export function mapNewTemplateToCoreMRDetail(elementTypes: FSharpMap<int32, Brid
147
116
  }, item_2.Triggers), template.Items), empty<CoreMRTag>(), undefined);
148
117
  }
149
118
 
119
+ /**
120
+ * ⭐ THE ONE `TemplateForm -> CoreMRFormData` PATH. A projection of the single builder above, so
121
+ * Studio and f1-api cannot drift: the same CoreMR form becomes the same record in both.
122
+ *
123
+ * ⚰️ It replaces `TemplateManifestDecoder.toCoreMRFormData`, a SECOND builder that stringified the
124
+ * item type code, hardcoded `HasText`/`HasDate`, dropped every trigger and tag, and never computed a
125
+ * choice's `BitPosition`. Studio used that one and f1-api used this one.
126
+ */
127
+ export function toCoreMRFormData(elementTypes: FSharpMap<string, ElementTypeEntry>, template: TemplateForm): CoreMRFormData {
128
+ const detail: CoreMRFormDetail = mapNewTemplateToCoreMRDetail(elementTypes, template);
129
+ return new CoreMRFormData(detail.Metadata, detail.Items, detail.Choices, detail.Triggers, detail.Tags);
130
+ }
131
+
150
132
  //# sourceMappingURL=CorEMRTemplateMapper.ts.map
@@ -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 {