@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.
- package/FormSpec.FS/BlueprintValidation.js +1 -1
- package/FormSpec.FS/BlueprintValidation.js.map +1 -1
- package/FormSpec.FS/Designer.js +1 -1
- package/FormSpec.FS/Designer.js.map +1 -1
- package/FormSpec.FS/FormSpec.d.ts +14 -1
- package/FormSpec.FS/FormSpec.d.ts.map +1 -1
- package/FormSpec.FS/FormSpec.js +56 -1
- package/FormSpec.FS/FormSpec.js.map +1 -1
- package/FormSpec.FS/FormSpecHelpers.js +1 -1
- package/FormSpec.FS/FormSpecHelpers.js.map +1 -1
- package/FormSpec.FS/FormSpecValues.js +1 -1
- package/FormSpec.FS/FormSpecValues.js.map +1 -1
- package/FormSpec.FS/Helpers.js +11 -11
- package/FormSpec.FS/Helpers.js.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.d.ts +13 -3
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.d.ts.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.js +19 -13
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.js.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.d.ts +20 -0
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.d.ts.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.js +20 -40
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.js.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.d.ts +21 -9
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.d.ts.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.js +46 -25
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.js.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.d.ts +13 -14
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.d.ts.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.js +18 -61
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.js.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.d.ts +33 -8
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.d.ts.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.js +25 -29
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.js.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMREncoder.js.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.d.ts +4 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.d.ts.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.js +4 -4
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.js.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRTriggerEnrichment.js +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRTriggerEnrichment.js.map +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.js +1 -1
- package/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.js.map +1 -1
- package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.d.ts +34 -10
- package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.d.ts.map +1 -1
- package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.js +191 -30
- package/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.js.map +1 -1
- package/FormSpec.FS/Interop/Facade/FormItemLookup.d.ts +95 -0
- package/FormSpec.FS/Interop/Facade/FormItemLookup.d.ts.map +1 -0
- package/FormSpec.FS/Interop/Facade/FormItemLookup.js +155 -0
- package/FormSpec.FS/Interop/Facade/FormItemLookup.js.map +1 -0
- package/FormSpec.FS/Interop/FormSpec.Api.Helpers.js +4 -4
- package/FormSpec.FS/Interop/FormSpec.Api.Helpers.js.map +1 -1
- package/FormSpec.FS/Interop/FormSpec.Api.Option.d.ts +26 -2
- package/FormSpec.FS/Interop/FormSpec.Api.Option.d.ts.map +1 -1
- package/FormSpec.FS/Interop/FormSpec.Api.Option.js +77 -3
- package/FormSpec.FS/Interop/FormSpec.Api.Option.js.map +1 -1
- package/FormSpec.FS/Provenance.d.ts +20 -2
- package/FormSpec.FS/Provenance.d.ts.map +1 -1
- package/FormSpec.FS/Provenance.js +66 -3
- package/FormSpec.FS/Provenance.js.map +1 -1
- package/README.md +7 -7
- package/Thoth.Json/packages/Thoth.Json/Encode.js.map +1 -1
- package/package.json +5 -1
- package/src/FormSpec.FS/BlueprintValidation.ts +1 -1
- package/src/FormSpec.FS/Designer.ts +1 -1
- package/src/FormSpec.FS/FormSpec.ts +32 -2
- package/src/FormSpec.FS/FormSpecHelpers.ts +1 -1
- package/src/FormSpec.FS/FormSpecValues.ts +1 -1
- package/src/FormSpec.FS/Helpers.ts +11 -11
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRAdapter.ts +25 -12
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFieldTypeMapper.ts +41 -41
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRFormSpecValidator.ts +62 -30
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateMapper.ts +28 -46
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CorEMRTemplateToFormSpec.ts +52 -27
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRSourceMap.ts +7 -5
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/CoreMRTriggerEnrichment.ts +1 -1
- package/src/FormSpec.FS/Integrations/Adapters/CorEMR/FormSpecToCoreMRInsert.ts +1 -1
- package/src/FormSpec.FS/Integrations/CorEMR/TemplateManifestDecoder.ts +154 -42
- package/src/FormSpec.FS/Interop/Facade/FormItemLookup.ts +179 -0
- package/src/FormSpec.FS/Interop/FormSpec.Api.Helpers.ts +4 -4
- package/src/FormSpec.FS/Interop/FormSpec.Api.Option.ts +63 -8
- 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,
|
|
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,
|
|
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 {
|
|
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", [
|
|
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:
|
|
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",
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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
|
-
*
|
|
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(
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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 {
|
|
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 {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
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<
|
|
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
|
|
76
|
+
let info: ElementTypeEntry;
|
|
103
77
|
const itemTypeId: int32 = item.Type | 0;
|
|
104
|
-
const value:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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> =
|
|
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,
|
|
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 {
|
|
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,
|
|
9
|
-
import {
|
|
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
|
-
*
|
|
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
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
|
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),
|
|
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,
|
|
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).
|
|
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.
|
|
305
|
+
if (p.Vendor !== "coremr") {
|
|
306
306
|
return undefined;
|
|
307
307
|
}
|
|
308
308
|
else {
|