@openhealth/oht-custom-parser-lib 0.4.2 → 0.5.2
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/dist/index.d.ts +3 -1
- package/dist/index.js +20 -2
- package/dist/index.js.map +1 -1
- package/dist/service/auxiliaryFunctions.service.d.ts +2 -0
- package/dist/service/auxiliaryFunctions.service.js +4 -3
- package/dist/service/auxiliaryFunctions.service.js.map +1 -1
- package/dist/service/fileUploadErrorHandler.service.d.ts +26 -0
- package/dist/service/fileUploadErrorHandler.service.js +257 -0
- package/dist/service/fileUploadErrorHandler.service.js.map +1 -0
- package/dist/service/ohtMeasurementsExtractor.service.js +22 -23
- package/dist/service/ohtMeasurementsExtractor.service.js.map +1 -1
- package/dist/service/ohtReportMeasurementsExtractor.service.d.ts +1 -0
- package/dist/service/ohtReportMeasurementsExtractor.service.js +33 -37
- package/dist/service/ohtReportMeasurementsExtractor.service.js.map +1 -1
- package/dist/service/processingLogger.service.d.ts +140 -0
- package/dist/service/processingLogger.service.js +515 -0
- package/dist/service/processingLogger.service.js.map +1 -0
- package/dist/service/reportCreator.service.d.ts +1 -1
- package/dist/service/reportCreator.service.js +53 -64
- package/dist/service/reportCreator.service.js.map +1 -1
- package/dist/service/slackMessages.service.js +4 -5
- package/dist/service/slackMessages.service.js.map +1 -1
- package/dist/service/transformationRules.service.js +3 -10
- package/dist/service/transformationRules.service.js.map +1 -1
- package/dist/types/error.types.d.ts +82 -0
- package/dist/types/error.types.js +195 -0
- package/dist/types/error.types.js.map +1 -1
- package/dist/types/oht.types.d.ts +5 -1
- package/dist/types/oht.types.js +4 -0
- package/dist/types/oht.types.js.map +1 -1
- package/dist/util-ts/apiUtils.js +2 -3
- package/dist/util-ts/apiUtils.js.map +1 -1
- package/dist/util-ts/dataUtils.js +24 -16
- package/dist/util-ts/dataUtils.js.map +1 -1
- package/dist/util-ts/extractionUtils.js +4 -8
- package/dist/util-ts/extractionUtils.js.map +1 -1
- package/dist/util-ts/pinoLogger.js +28 -1
- package/dist/util-ts/pinoLogger.js.map +1 -1
- package/package.json +36 -34
- package/readme.md +115 -99
package/dist/index.d.ts
CHANGED
|
@@ -7,8 +7,10 @@ export { aggregateMessages, aggregateBiMessages, publishToTopic, generateBIMessa
|
|
|
7
7
|
export { applyRules as applyTransformationRules, validateJsonataExpression as validateTransformationRuleExpression, } from './service/transformationRules.service';
|
|
8
8
|
export { LabToOhtContract, LabToOhtMapper, UnknownMeasurementExtraction, ReferenceAsAnnotation, UnitExtraction, RangeExtraction, RangeExtractionResponse, ValueExtraction, unitSynonyms, ValueExtractionResponse, SynonymUnit, UnknownUnits, } from './types/custom-parser.types';
|
|
9
9
|
export { AcfBiomarkerRangeAnnotationCheck, AcfBiomarkerGenericDisclaimerLogic, ManualCheck, BiomarkerCompatibility, ReferenceRangeType, AcfReferenceRange, VisualRange, NameAlias, AlternativeUnit, BiomarkerAcf, Biomarker, PipelineStep, DigitizationStatus, MeasurementValueComparator, BiomarkerValueType, DataImportFileUploadStatus, Sex, Digitization, PatientInfo, UnknownMeasurement, UnmappedLabKey, Measurement, DataImportFileUpload, MessagePayload, SignedUpload, ReportStyleConfig, LanguageCode, BiomarkerCustomisation, PartnerCustomPanel, ReportDisplaySettings, ReportCustomisation, OHTPartner, UploadType, RejectReason, AnnotationLabKey, ExtractionPath, AnnotationConfig, } from './types/oht.types';
|
|
10
|
-
export { ErrorMessage } from './types/error.types';
|
|
10
|
+
export { ErrorMessage, ErrorCode, ERROR_CATALOG, ERROR_MESSAGES, getErrorMessage, getRejectReason, } from './types/error.types';
|
|
11
|
+
export { handleError, ValidationError, shouldSendSlackNotification, extractFormattedRejectReason, mapErrorToRejectReason, } from './service/fileUploadErrorHandler.service';
|
|
11
12
|
export type { TransformationRule, TransformationContext, ApplyRulesResult as TransformationApplyRulesResult, ApplyRulesOptions as TransformationApplyRulesOptions, ValidationResult as TransformationValidationResult, } from './types/transformationRules.types';
|
|
13
|
+
export { processingLogger, ProcessingContext, StageDuration, getRequestIdFromContext, runWithContext, runWithContextAsync, } from './service/processingLogger.service';
|
|
12
14
|
export { makeApiCallWithRetry, parseErrorObj } from './util-ts/apiUtils';
|
|
13
15
|
export { extractValue, isBiomarkerValueNumerical, isBiomarkerExternalNoVisualRange, processAppendedMappings, fetchSynonymUnits, resolveUnitFromSynonyms, extractFromPath, applyFormat } from './util-ts/dataUtils';
|
|
14
16
|
export { readFileFromBucket, uploadFileBufferToGCS } from './util-ts/googleStorageUtils';
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
exports.parseRange = exports.getMappedBiomarkersLatest = exports.getMappedBiomarkers = exports.getLowerThanPatterns = exports.getGreaterThanPatterns = exports.pinoLogger = exports.uploadFileBufferToGCS = void 0;
|
|
6
|
+
exports.processingLogger = exports.mapErrorToRejectReason = exports.extractFormattedRejectReason = exports.shouldSendSlackNotification = exports.ValidationError = exports.handleError = exports.getRejectReason = exports.getErrorMessage = exports.ERROR_MESSAGES = exports.ERROR_CATALOG = exports.ErrorCode = exports.RejectReason = exports.UploadType = exports.Sex = exports.DataImportFileUploadStatus = exports.BiomarkerValueType = exports.MeasurementValueComparator = exports.DigitizationStatus = exports.PipelineStep = exports.ReferenceRangeType = exports.BiomarkerCompatibility = exports.ManualCheck = exports.AcfBiomarkerGenericDisclaimerLogic = exports.AcfBiomarkerRangeAnnotationCheck = exports.unitSynonyms = exports.validateTransformationRuleExpression = exports.applyTransformationRules = exports.generateBIMessages = exports.publishToTopic = exports.aggregateBiMessages = exports.aggregateMessages = exports.sendMessageToSlack = exports.getSlackFileIssueNotificationMessage = exports.extractValueFromGreaterLowerThan = exports.extractUnit = exports.getRangeFromPositionAndRegex = exports.parseExamValue = exports.extractReferenceAnnotation = exports.extractReferenceRanges = exports.checkValueForPlausibleValues = exports.ohtMeasurementsExtractor = exports.ohtReportMeasurementsExtractor = exports.postFileUploadSetStatus = exports.queryFileUploadsWithFilters = exports.handleRejection = exports.isPatientAgeValid = exports.parseGender = exports.parseExternalPatientId = exports.postReportPreviewToCore = exports.postDataImportFileUploadToCore = void 0;
|
|
7
|
+
exports.parseRange = exports.getMappedBiomarkersLatest = exports.getMappedBiomarkers = exports.getLowerThanPatterns = exports.getGreaterThanPatterns = exports.pinoLogger = exports.uploadFileBufferToGCS = exports.readFileFromBucket = exports.applyFormat = exports.extractFromPath = exports.resolveUnitFromSynonyms = exports.fetchSynonymUnits = exports.processAppendedMappings = exports.isBiomarkerExternalNoVisualRange = exports.isBiomarkerValueNumerical = exports.extractValue = exports.parseErrorObj = exports.makeApiCallWithRetry = exports.runWithContextAsync = exports.runWithContext = exports.getRequestIdFromContext = void 0;
|
|
8
8
|
// ### SERVICES ###
|
|
9
9
|
var reportCreator_service_1 = require("./service/reportCreator.service");
|
|
10
10
|
Object.defineProperty(exports, "postDataImportFileUploadToCore", { enumerable: true, get: function () { return reportCreator_service_1.postDataImportFileUploadToCore; } });
|
|
@@ -55,6 +55,24 @@ Object.defineProperty(exports, "DataImportFileUploadStatus", { enumerable: true,
|
|
|
55
55
|
Object.defineProperty(exports, "Sex", { enumerable: true, get: function () { return oht_types_1.Sex; } });
|
|
56
56
|
Object.defineProperty(exports, "UploadType", { enumerable: true, get: function () { return oht_types_1.UploadType; } });
|
|
57
57
|
Object.defineProperty(exports, "RejectReason", { enumerable: true, get: function () { return oht_types_1.RejectReason; } });
|
|
58
|
+
var error_types_1 = require("./types/error.types");
|
|
59
|
+
Object.defineProperty(exports, "ErrorCode", { enumerable: true, get: function () { return error_types_1.ErrorCode; } });
|
|
60
|
+
Object.defineProperty(exports, "ERROR_CATALOG", { enumerable: true, get: function () { return error_types_1.ERROR_CATALOG; } });
|
|
61
|
+
Object.defineProperty(exports, "ERROR_MESSAGES", { enumerable: true, get: function () { return error_types_1.ERROR_MESSAGES; } });
|
|
62
|
+
Object.defineProperty(exports, "getErrorMessage", { enumerable: true, get: function () { return error_types_1.getErrorMessage; } });
|
|
63
|
+
Object.defineProperty(exports, "getRejectReason", { enumerable: true, get: function () { return error_types_1.getRejectReason; } });
|
|
64
|
+
var fileUploadErrorHandler_service_1 = require("./service/fileUploadErrorHandler.service");
|
|
65
|
+
Object.defineProperty(exports, "handleError", { enumerable: true, get: function () { return fileUploadErrorHandler_service_1.handleError; } });
|
|
66
|
+
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return fileUploadErrorHandler_service_1.ValidationError; } });
|
|
67
|
+
Object.defineProperty(exports, "shouldSendSlackNotification", { enumerable: true, get: function () { return fileUploadErrorHandler_service_1.shouldSendSlackNotification; } });
|
|
68
|
+
Object.defineProperty(exports, "extractFormattedRejectReason", { enumerable: true, get: function () { return fileUploadErrorHandler_service_1.extractFormattedRejectReason; } });
|
|
69
|
+
Object.defineProperty(exports, "mapErrorToRejectReason", { enumerable: true, get: function () { return fileUploadErrorHandler_service_1.mapErrorToRejectReason; } });
|
|
70
|
+
// ### PROCESSING LOGGER ###
|
|
71
|
+
var processingLogger_service_1 = require("./service/processingLogger.service");
|
|
72
|
+
Object.defineProperty(exports, "processingLogger", { enumerable: true, get: function () { return processingLogger_service_1.processingLogger; } });
|
|
73
|
+
Object.defineProperty(exports, "getRequestIdFromContext", { enumerable: true, get: function () { return processingLogger_service_1.getRequestIdFromContext; } });
|
|
74
|
+
Object.defineProperty(exports, "runWithContext", { enumerable: true, get: function () { return processingLogger_service_1.runWithContext; } });
|
|
75
|
+
Object.defineProperty(exports, "runWithContextAsync", { enumerable: true, get: function () { return processingLogger_service_1.runWithContextAsync; } });
|
|
58
76
|
// ### UTIL-TS ###
|
|
59
77
|
var apiUtils_1 = require("./util-ts/apiUtils");
|
|
60
78
|
Object.defineProperty(exports, "makeApiCallWithRetry", { enumerable: true, get: function () { return apiUtils_1.makeApiCallWithRetry; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;AAAA,mBAAmB;AACnB,yEAGyC;AAFvC,uIAAA,8BAA8B,OAAA;AAC9B,gIAAA,uBAAuB,OAAA;AAEzB,mFAQ8C;AAP5C,oIAAA,sBAAsB,OAAA;AACtB,yHAAA,WAAW,OAAA;AACX,+HAAA,iBAAiB,OAAA;AACjB,6HAAA,eAAe,OAAA;AACf,yIAAA,2BAA2B,OAAA;AAC3B,qIAAA,uBAAuB,OAAA;AAIzB,2GAE0D;AADxD,wJAAA,8BAA8B,OAAA;AAGhC,+FASoD;AARlD,4IAAA,wBAAwB,OAAA;AACxB,gJAAA,4BAA4B,OAAA;AAC5B,0IAAA,sBAAsB,OAAA;AACtB,8IAAA,0BAA0B,OAAA;AAC1B,kIAAA,cAAc,OAAA;AACd,gJAAA,4BAA4B,OAAA;AAC5B,+HAAA,WAAW,OAAA;AACX,oJAAA,gCAAgC,OAAA;AAGlC,yEAEyC;AADvC,6IAAA,oCAAoC,OAAA;AAAE,2HAAA,kBAAkB,OAAA;AAE1D,yEAKyC;AAJvC,0HAAA,iBAAiB,OAAA;AACjB,4HAAA,mBAAmB,OAAA;AACnB,uHAAA,cAAc,OAAA;AACd,2HAAA,kBAAkB,OAAA;AAEpB,qFAG+C;AAF7C,uIAAA,UAAU,OAA4B;AACtC,mJAAA,yBAAyB,OAAwC;AAGnE,gBAAgB;AAChB,mEAaqC;AAJnC,mHAAA,YAAY,OAAA;AAKd,+CAsC2B;AArCzB,6HAAA,gCAAgC,OAAA;AAChC,+HAAA,kCAAkC,OAAA;AAClC,wGAAA,WAAW,OAAA;AACX,mHAAA,sBAAsB,OAAA;AACtB,+GAAA,kBAAkB,OAAA;AAOlB,yGAAA,YAAY,OAAA;AACZ,+GAAA,kBAAkB,OAAA;AAClB,uHAAA,0BAA0B,OAAA;AAC1B,+GAAA,kBAAkB,OAAA;AAClB,uHAAA,0BAA0B,OAAA;AAC1B,gGAAA,GAAG,OAAA;AAgBH,uGAAA,UAAU,OAAA;AACV,yGAAA,YAAY,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;AAAA,mBAAmB;AACnB,yEAGyC;AAFvC,uIAAA,8BAA8B,OAAA;AAC9B,gIAAA,uBAAuB,OAAA;AAEzB,mFAQ8C;AAP5C,oIAAA,sBAAsB,OAAA;AACtB,yHAAA,WAAW,OAAA;AACX,+HAAA,iBAAiB,OAAA;AACjB,6HAAA,eAAe,OAAA;AACf,yIAAA,2BAA2B,OAAA;AAC3B,qIAAA,uBAAuB,OAAA;AAIzB,2GAE0D;AADxD,wJAAA,8BAA8B,OAAA;AAGhC,+FASoD;AARlD,4IAAA,wBAAwB,OAAA;AACxB,gJAAA,4BAA4B,OAAA;AAC5B,0IAAA,sBAAsB,OAAA;AACtB,8IAAA,0BAA0B,OAAA;AAC1B,kIAAA,cAAc,OAAA;AACd,gJAAA,4BAA4B,OAAA;AAC5B,+HAAA,WAAW,OAAA;AACX,oJAAA,gCAAgC,OAAA;AAGlC,yEAEyC;AADvC,6IAAA,oCAAoC,OAAA;AAAE,2HAAA,kBAAkB,OAAA;AAE1D,yEAKyC;AAJvC,0HAAA,iBAAiB,OAAA;AACjB,4HAAA,mBAAmB,OAAA;AACnB,uHAAA,cAAc,OAAA;AACd,2HAAA,kBAAkB,OAAA;AAEpB,qFAG+C;AAF7C,uIAAA,UAAU,OAA4B;AACtC,mJAAA,yBAAyB,OAAwC;AAGnE,gBAAgB;AAChB,mEAaqC;AAJnC,mHAAA,YAAY,OAAA;AAKd,+CAsC2B;AArCzB,6HAAA,gCAAgC,OAAA;AAChC,+HAAA,kCAAkC,OAAA;AAClC,wGAAA,WAAW,OAAA;AACX,mHAAA,sBAAsB,OAAA;AACtB,+GAAA,kBAAkB,OAAA;AAOlB,yGAAA,YAAY,OAAA;AACZ,+GAAA,kBAAkB,OAAA;AAClB,uHAAA,0BAA0B,OAAA;AAC1B,+GAAA,kBAAkB,OAAA;AAClB,uHAAA,0BAA0B,OAAA;AAC1B,gGAAA,GAAG,OAAA;AAgBH,uGAAA,UAAU,OAAA;AACV,yGAAA,YAAY,OAAA;AAKd,mDAO6B;AAL3B,wGAAA,SAAS,OAAA;AACT,4GAAA,aAAa,OAAA;AACb,6GAAA,cAAc,OAAA;AACd,8GAAA,eAAe,OAAA;AACf,8GAAA,eAAe,OAAA;AAEjB,2FAMkD;AALhD,6HAAA,WAAW,OAAA;AACX,iIAAA,eAAe,OAAA;AACf,6IAAA,2BAA2B,OAAA;AAC3B,8IAAA,4BAA4B,OAAA;AAC5B,wIAAA,sBAAsB,OAAA;AAUxB,4BAA4B;AAC5B,+EAO4C;AAN1C,4HAAA,gBAAgB,OAAA;AAGhB,mIAAA,uBAAuB,OAAA;AACvB,0HAAA,cAAc,OAAA;AACd,+HAAA,mBAAmB,OAAA;AAGrB,kBAAkB;AAClB,+CAAuE;AAA/D,gHAAA,oBAAoB,OAAA;AAAE,yGAAA,aAAa,OAAA;AAC3C,iDAAiN;AAAzM,yGAAA,YAAY,OAAA;AAAE,sHAAA,yBAAyB,OAAA;AAAE,6HAAA,gCAAgC,OAAA;AAAE,oHAAA,uBAAuB,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,oHAAA,uBAAuB,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,wGAAA,WAAW,OAAA;AACpL,mEAAuF;AAA/E,wHAAA,kBAAkB,OAAA;AAAE,2HAAA,qBAAqB,OAAA;AACjD,mDAA2D;AAAnD,yHAAA,OAAO,OAAc;AAC7B,mDAAkF;AAA1E,oHAAA,sBAAsB,OAAA;AAAE,kHAAA,oBAAoB,OAAA;AACpD,iDAAmF;AAA3E,gHAAA,mBAAmB,OAAA;AAAE,sHAAA,yBAAyB,OAAA;AACtD,6DAAqD;AAA7C,6GAAA,UAAU,OAAA"}
|
|
@@ -15,6 +15,8 @@ declare function parseGender(patientGender?: string): {
|
|
|
15
15
|
*
|
|
16
16
|
* @param parseType - The type of parsing that failed (e.g., "age", "exam date", "units")
|
|
17
17
|
* @param errorMessages - Array to append error messages to
|
|
18
|
+
* @param notifySlack - notifySlack
|
|
19
|
+
* @param notifyNotes - notifyNotes
|
|
18
20
|
* @returns Object containing rejectedStatus and rejectReason
|
|
19
21
|
*/
|
|
20
22
|
declare function handleRejection(parseType: string, errorMessages: ErrorMessage[], notifySlack?: boolean, notifyNotes?: boolean, notifyBi?: boolean): {
|
|
@@ -13,14 +13,13 @@ exports.postFileUploadSetStatus = postFileUploadSetStatus;
|
|
|
13
13
|
exports.getPartnerTransformationRules = getPartnerTransformationRules;
|
|
14
14
|
const moment_1 = __importDefault(require("moment/moment"));
|
|
15
15
|
const apiUtils_1 = require("../util-ts/apiUtils");
|
|
16
|
-
const
|
|
16
|
+
const processingLogger_service_1 = require("./processingLogger.service");
|
|
17
17
|
const oht_types_1 = require("../types/oht.types");
|
|
18
18
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
19
19
|
const customParseFormat_1 = __importDefault(require("dayjs/plugin/customParseFormat"));
|
|
20
20
|
const utc_1 = __importDefault(require("dayjs/plugin/utc"));
|
|
21
21
|
dayjs_1.default.extend(customParseFormat_1.default);
|
|
22
22
|
dayjs_1.default.extend(utc_1.default);
|
|
23
|
-
const logger = (0, pinoLogger_1.default)();
|
|
24
23
|
const OHT_CORE_URL = process.env.OHT_CORE_URL;
|
|
25
24
|
function getPatientAge(documentDate, patientBirthdate) {
|
|
26
25
|
if (!patientBirthdate || !documentDate)
|
|
@@ -61,6 +60,8 @@ function parseGender(patientGender) {
|
|
|
61
60
|
*
|
|
62
61
|
* @param parseType - The type of parsing that failed (e.g., "age", "exam date", "units")
|
|
63
62
|
* @param errorMessages - Array to append error messages to
|
|
63
|
+
* @param notifySlack - notifySlack
|
|
64
|
+
* @param notifyNotes - notifyNotes
|
|
64
65
|
* @returns Object containing rejectedStatus and rejectReason
|
|
65
66
|
*/
|
|
66
67
|
function handleRejection(parseType, errorMessages, notifySlack = true, notifyNotes = false, notifyBi = false) {
|
|
@@ -188,7 +189,7 @@ async function postFileUploadSetStatus(payload, fileUploadId, filename, ohtCoreA
|
|
|
188
189
|
formattedPayload.digitalization = digitalization;
|
|
189
190
|
}
|
|
190
191
|
const processingResponse = await (0, apiUtils_1.makeApiCallWithRetry)('post', ohtCoreFileUploadSetStatusUrl, formattedPayload, ohtCoreApiKey);
|
|
191
|
-
|
|
192
|
+
processingLogger_service_1.processingLogger.logInfo(`Resp: POST status: ${payload.status} /file-uploads/${fileUploadId}, filename: ${filename}`, { resp: processingResponse?.data });
|
|
192
193
|
return processingResponse?.data;
|
|
193
194
|
}
|
|
194
195
|
// getPartnerTransformationRules fetches all the available partner transformation rules
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auxiliaryFunctions.service.js","sourceRoot":"","sources":["../../service/auxiliaryFunctions.service.ts"],"names":[],"mappings":";;;;;AAiTE,wDAAsB;AACtB,kCAAW;AACX,8CAAiB;AACjB,sCAAa;AACb,0CAAe;AACf,kEAA2B;AAC3B,0DAAuB;AACvB,sEAA6B;AAxT/B,2DAAmC;AAEnC,kDAAyD;AACzD,
|
|
1
|
+
{"version":3,"file":"auxiliaryFunctions.service.js","sourceRoot":"","sources":["../../service/auxiliaryFunctions.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { RejectReason } from '../types/oht.types';
|
|
2
|
+
/**
|
|
3
|
+
* Validation error for parser/report validation (rejectReason + optional field).
|
|
4
|
+
* Used by mapErrorToRejectReason and handleError.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ValidationError extends Error {
|
|
7
|
+
rejectReason: RejectReason;
|
|
8
|
+
fieldName?: string;
|
|
9
|
+
constructor(message: string, rejectReason: RejectReason, fieldName?: string);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Whether to send Slack notification for this reject reason (not in silent list).
|
|
13
|
+
*/
|
|
14
|
+
export declare function shouldSendSlackNotification(rejectReason: RejectReason | undefined, silentRejectReasons: RejectReason[]): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Formats reject reason with field name and context for better client messages.
|
|
17
|
+
*/
|
|
18
|
+
export declare function extractFormattedRejectReason(rejectReason: RejectReason, fieldName?: string, errorMessage?: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Maps error to an appropriate RejectReason.
|
|
21
|
+
*/
|
|
22
|
+
export declare function mapErrorToRejectReason(error: Error, errorMessage: string, statusCode?: number, responseData?: any): RejectReason;
|
|
23
|
+
/**
|
|
24
|
+
* Handles file-upload processing errors: updates status, notifies Slack, logs with error_code.
|
|
25
|
+
*/
|
|
26
|
+
export declare function handleError(error: Error, fileName: string, signedUploadId: string | undefined, apiKey: string, ohapiUrl: string, cloudEventId?: string, partnerName?: string, silentRejectReasons?: RejectReason[]): Promise<void>;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ValidationError = void 0;
|
|
7
|
+
exports.shouldSendSlackNotification = shouldSendSlackNotification;
|
|
8
|
+
exports.extractFormattedRejectReason = extractFormattedRejectReason;
|
|
9
|
+
exports.mapErrorToRejectReason = mapErrorToRejectReason;
|
|
10
|
+
exports.handleError = handleError;
|
|
11
|
+
const oht_types_1 = require("../types/oht.types");
|
|
12
|
+
const slackMessages_service_1 = require("./slackMessages.service");
|
|
13
|
+
const auxiliaryFunctions_service_1 = require("./auxiliaryFunctions.service");
|
|
14
|
+
const apiUtils_1 = require("../util-ts/apiUtils");
|
|
15
|
+
const processingLogger_service_1 = require("./processingLogger.service");
|
|
16
|
+
const error_types_1 = require("../types/error.types");
|
|
17
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
18
|
+
const utc_1 = __importDefault(require("dayjs/plugin/utc"));
|
|
19
|
+
dayjs_1.default.extend(utc_1.default);
|
|
20
|
+
/**
|
|
21
|
+
* Validation error for parser/report validation (rejectReason + optional field).
|
|
22
|
+
* Used by mapErrorToRejectReason and handleError.
|
|
23
|
+
*/
|
|
24
|
+
class ValidationError extends Error {
|
|
25
|
+
constructor(message, rejectReason, fieldName) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = 'ValidationError';
|
|
28
|
+
this.rejectReason = rejectReason;
|
|
29
|
+
this.fieldName = fieldName;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.ValidationError = ValidationError;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to send Slack notification for this reject reason (not in silent list).
|
|
35
|
+
*/
|
|
36
|
+
function shouldSendSlackNotification(rejectReason, silentRejectReasons) {
|
|
37
|
+
if (!rejectReason || silentRejectReasons.length === 0) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return !silentRejectReasons.includes(rejectReason);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Formats reject reason with field name and context for better client messages.
|
|
44
|
+
*/
|
|
45
|
+
function extractFormattedRejectReason(rejectReason, fieldName, errorMessage) {
|
|
46
|
+
const baseRejectReason = String(rejectReason);
|
|
47
|
+
if (rejectReason === oht_types_1.RejectReason.INVALID_DATA_FORMAT && errorMessage) {
|
|
48
|
+
const formattedMatch = errorMessage.match(/Invalid Data Format \[expected: ([^\]]+), received: ([^\]]+)\]/);
|
|
49
|
+
if (formattedMatch) {
|
|
50
|
+
const expectedFormat = formattedMatch[1];
|
|
51
|
+
const receivedFormat = formattedMatch[2];
|
|
52
|
+
const fieldPart = fieldName ? ` for '${fieldName}'` : '';
|
|
53
|
+
return `Invalid Data Format${fieldPart} [expected: ${expectedFormat}, received: ${receivedFormat}]`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (fieldName) {
|
|
57
|
+
switch (rejectReason) {
|
|
58
|
+
case oht_types_1.RejectReason.INCOMPLETE_DATA:
|
|
59
|
+
if (fieldName === 'patient.id') {
|
|
60
|
+
return `Patient external ID conflict: '${fieldName}' does not match user's external reference`;
|
|
61
|
+
}
|
|
62
|
+
return `${baseRejectReason} - Missing or invalid '${fieldName}'`;
|
|
63
|
+
case oht_types_1.RejectReason.MISSING_EXAM_DATE:
|
|
64
|
+
return `${baseRejectReason} - Missing '${fieldName}'`;
|
|
65
|
+
case oht_types_1.RejectReason.MISSING_LAB_ORDER_ID:
|
|
66
|
+
return `${baseRejectReason} - Missing '${fieldName}'`;
|
|
67
|
+
case oht_types_1.RejectReason.MISSING_EXTERNAL_PATIENT_ID:
|
|
68
|
+
return `${baseRejectReason} - Missing '${fieldName}'`;
|
|
69
|
+
case oht_types_1.RejectReason.MISSING_PATIENT_SEX:
|
|
70
|
+
return `${baseRejectReason} - Missing '${fieldName}'`;
|
|
71
|
+
case oht_types_1.RejectReason.INVALID_DATA_NO_BIOMARKER_DATA:
|
|
72
|
+
return `${baseRejectReason} - Invalid '${fieldName}'`;
|
|
73
|
+
default:
|
|
74
|
+
return `${baseRejectReason} - Issue with '${fieldName}'`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return baseRejectReason;
|
|
78
|
+
}
|
|
79
|
+
function isPatientExternalIdConflict(statusCode, errorMessage, responseData) {
|
|
80
|
+
const lowerMessage = errorMessage.toLowerCase();
|
|
81
|
+
const is409Error = statusCode === 409 ||
|
|
82
|
+
lowerMessage.includes('status code 409') ||
|
|
83
|
+
lowerMessage.includes('409');
|
|
84
|
+
if (!is409Error)
|
|
85
|
+
return false;
|
|
86
|
+
const isExplicitlyNotPatientConflict = lowerMessage.includes('duplicate') &&
|
|
87
|
+
!lowerMessage.includes('patient') &&
|
|
88
|
+
!lowerMessage.includes('external');
|
|
89
|
+
return !isExplicitlyNotPatientConflict;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Maps error to an appropriate RejectReason.
|
|
93
|
+
*/
|
|
94
|
+
function mapErrorToRejectReason(error, errorMessage, statusCode, responseData) {
|
|
95
|
+
if (isPatientExternalIdConflict(statusCode, errorMessage, responseData)) {
|
|
96
|
+
return oht_types_1.RejectReason.INCOMPLETE_DATA;
|
|
97
|
+
}
|
|
98
|
+
const hasRejectReason = error instanceof ValidationError || 'rejectReason' in error;
|
|
99
|
+
if (hasRejectReason) {
|
|
100
|
+
const rejectReason = error.rejectReason;
|
|
101
|
+
if (rejectReason !== undefined && rejectReason !== null && rejectReason !== '') {
|
|
102
|
+
return rejectReason;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const lowerMessage = errorMessage.toLowerCase();
|
|
106
|
+
if (lowerMessage.includes('invalid data format') || lowerMessage.includes('invalid format') || lowerMessage.includes('iso 8601 format')) {
|
|
107
|
+
return oht_types_1.RejectReason.INVALID_DATA_FORMAT;
|
|
108
|
+
}
|
|
109
|
+
if (lowerMessage.includes('no biomarker') || lowerMessage.includes('invalid input') || lowerMessage.includes('no measurements')) {
|
|
110
|
+
return oht_types_1.RejectReason.INVALID_DATA_NO_BIOMARKER_DATA;
|
|
111
|
+
}
|
|
112
|
+
if (lowerMessage.includes('image quality') || lowerMessage.includes('low quality')) {
|
|
113
|
+
return oht_types_1.RejectReason.LOW_IMAGE_QUALITY;
|
|
114
|
+
}
|
|
115
|
+
if (lowerMessage.includes('underage') || (lowerMessage.includes('age') && lowerMessage.includes('invalid'))) {
|
|
116
|
+
return oht_types_1.RejectReason.UNDERAGE_PERSON;
|
|
117
|
+
}
|
|
118
|
+
if (lowerMessage.includes('language') || lowerMessage.includes('unsupported language')) {
|
|
119
|
+
return oht_types_1.RejectReason.LANGUAGE_NOT_SUPPORTED;
|
|
120
|
+
}
|
|
121
|
+
if (lowerMessage.includes('implausible') || lowerMessage.includes('invalid value')) {
|
|
122
|
+
return oht_types_1.RejectReason.IMPLAUSIBLE_DATA;
|
|
123
|
+
}
|
|
124
|
+
if (lowerMessage.includes('missing exam date') || lowerMessage.includes('no date') || lowerMessage.includes('date')) {
|
|
125
|
+
return oht_types_1.RejectReason.MISSING_EXAM_DATE;
|
|
126
|
+
}
|
|
127
|
+
if (lowerMessage.includes('missing unit') || lowerMessage.includes('incomplete') || lowerMessage.includes('missing data')) {
|
|
128
|
+
return oht_types_1.RejectReason.INCOMPLETE_DATA;
|
|
129
|
+
}
|
|
130
|
+
if (lowerMessage.includes('not an official') || lowerMessage.includes('not official')) {
|
|
131
|
+
return oht_types_1.RejectReason.NOT_AN_OFFICIAL_REPORT;
|
|
132
|
+
}
|
|
133
|
+
if (lowerMessage.includes('missing external patient') || lowerMessage.includes('missing patient id')) {
|
|
134
|
+
return oht_types_1.RejectReason.MISSING_EXTERNAL_PATIENT_ID;
|
|
135
|
+
}
|
|
136
|
+
if (lowerMessage.includes('unsupported') || lowerMessage.includes('not supported')) {
|
|
137
|
+
return oht_types_1.RejectReason.UNSUPPORTED_UPLOAD;
|
|
138
|
+
}
|
|
139
|
+
return oht_types_1.RejectReason.UNSUPPORTED_UPLOAD;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Handles file-upload processing errors: updates status, notifies Slack, logs with error_code.
|
|
143
|
+
*/
|
|
144
|
+
async function handleError(error, fileName, signedUploadId, apiKey, ohapiUrl, cloudEventId, partnerName, silentRejectReasons = []) {
|
|
145
|
+
const errorDetails = (0, apiUtils_1.parseErrorObj)(error);
|
|
146
|
+
const responseData = errorDetails.responseData;
|
|
147
|
+
const statusCode = errorDetails.status;
|
|
148
|
+
const axiosStatusCode = error.response?.status;
|
|
149
|
+
const finalStatusCode = statusCode || axiosStatusCode;
|
|
150
|
+
const errorMessage = responseData
|
|
151
|
+
? `${error.message} - Response: ${JSON.stringify(responseData)}`
|
|
152
|
+
: error.message || 'Unknown error occurred';
|
|
153
|
+
const isIngestionError = finalStatusCode === 409 ||
|
|
154
|
+
errorMessage.toLowerCase().includes('ingestion') ||
|
|
155
|
+
errorDetails.config?.url?.includes('/ingestion');
|
|
156
|
+
const pipelineStep = isIngestionError
|
|
157
|
+
? oht_types_1.PipelineStep.SENDING_RESULTS
|
|
158
|
+
: oht_types_1.PipelineStep.EXTRACTING_METADATA;
|
|
159
|
+
const errorType = error.constructor.name;
|
|
160
|
+
const rejectReason = mapErrorToRejectReason(error, errorMessage, finalStatusCode, responseData);
|
|
161
|
+
let fieldName;
|
|
162
|
+
if (error instanceof ValidationError) {
|
|
163
|
+
fieldName = error.fieldName;
|
|
164
|
+
}
|
|
165
|
+
else if (finalStatusCode === 409 && rejectReason === oht_types_1.RejectReason.INCOMPLETE_DATA) {
|
|
166
|
+
fieldName = 'patient.id';
|
|
167
|
+
}
|
|
168
|
+
const formattedRejectReason = extractFormattedRejectReason(rejectReason, fieldName, errorMessage);
|
|
169
|
+
if (!signedUploadId) {
|
|
170
|
+
const noUploadError = new Error((0, error_types_1.getErrorMessage)(error_types_1.ErrorCode.UPLOAD_MISSING_SIGNED_UPLOAD_ID));
|
|
171
|
+
processingLogger_service_1.processingLogger.addError(noUploadError, 'error_handling');
|
|
172
|
+
processingLogger_service_1.processingLogger.logError('Processing failed: Missing signed upload ID', noUploadError, {
|
|
173
|
+
error_code: error_types_1.ErrorCode.UPLOAD_MISSING_SIGNED_UPLOAD_ID,
|
|
174
|
+
cloud_event_id: cloudEventId,
|
|
175
|
+
partner_name: partnerName,
|
|
176
|
+
});
|
|
177
|
+
processingLogger_service_1.processingLogger.logEnd(false);
|
|
178
|
+
throw noUploadError;
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
processingLogger_service_1.processingLogger.addError(error, 'error_handling');
|
|
182
|
+
const fileUploads = await (0, auxiliaryFunctions_service_1.queryFileUploadsWithFilters)([{ field: 'signedUploadId', search: signedUploadId }], apiKey);
|
|
183
|
+
const fileUploadId = fileUploads[0]?.id;
|
|
184
|
+
if (!fileUploadId) {
|
|
185
|
+
const notFoundError = new Error((0, error_types_1.getErrorMessage)(error_types_1.ErrorCode.UPLOAD_FILE_NOT_FOUND));
|
|
186
|
+
processingLogger_service_1.processingLogger.addError(notFoundError, 'error_handling');
|
|
187
|
+
processingLogger_service_1.processingLogger.logError('Processing failed: File upload not found', notFoundError, {
|
|
188
|
+
error_code: error_types_1.ErrorCode.UPLOAD_FILE_NOT_FOUND,
|
|
189
|
+
signed_upload_id: signedUploadId,
|
|
190
|
+
partner_name: partnerName,
|
|
191
|
+
});
|
|
192
|
+
processingLogger_service_1.processingLogger.logEnd(false);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const fileUrl = `${ohapiUrl}/data-import/file-uploads/${fileUploadId}`;
|
|
196
|
+
const sendSlack = shouldSendSlackNotification(rejectReason, silentRejectReasons);
|
|
197
|
+
const fieldInfo = fieldName ? `\n*Field:* \`${fieldName}\`` : '';
|
|
198
|
+
const slackMessage = (0, slackMessages_service_1.getSlackFileIssueNotificationMessage)(`🚨 *AgnosticParser Processing Error*\n\n` +
|
|
199
|
+
`*Error:* ${errorType}: ${errorMessage}\n` +
|
|
200
|
+
`*Reject Reason:* ${formattedRejectReason}${fieldInfo}\n` +
|
|
201
|
+
`*File:* \`${fileName}\`\n` +
|
|
202
|
+
`*Partner:* ${partnerName || 'Unknown'}\n` +
|
|
203
|
+
`*File Upload ID:* \`${fileUploadId}\`\n` +
|
|
204
|
+
(cloudEventId ? `*Event ID:* \`${cloudEventId}\`\n` : ''), `AgnosticParser - ${partnerName || 'Unknown Partner'}`, fileUrl);
|
|
205
|
+
const [slackResult, statusResult] = await Promise.allSettled([
|
|
206
|
+
sendSlack ? (0, slackMessages_service_1.sendMessageToSlack)(slackMessage) : Promise.resolve(),
|
|
207
|
+
(0, auxiliaryFunctions_service_1.postFileUploadSetStatus)({
|
|
208
|
+
status: oht_types_1.DataImportFileUploadStatus.REJECTED,
|
|
209
|
+
digitalization: {
|
|
210
|
+
status: oht_types_1.DigitizationStatus.ERROR,
|
|
211
|
+
pipelineStep: pipelineStep,
|
|
212
|
+
pipelineStepData: formattedRejectReason,
|
|
213
|
+
timestamp: dayjs_1.default.utc().toISOString(),
|
|
214
|
+
},
|
|
215
|
+
...(formattedRejectReason && { rejectReason: formattedRejectReason }),
|
|
216
|
+
}, fileUploadId, fileName, apiKey),
|
|
217
|
+
]);
|
|
218
|
+
if (slackResult.status === 'rejected') {
|
|
219
|
+
processingLogger_service_1.processingLogger.logWarn('Slack notification failed', {
|
|
220
|
+
error_code: error_types_1.ErrorCode.UPLOAD_SLACK_FAILED,
|
|
221
|
+
file_upload_id: fileUploadId,
|
|
222
|
+
slack_error: (0, apiUtils_1.parseErrorObj)(slackResult.reason),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (statusResult.status === 'rejected') {
|
|
226
|
+
const statusErrorDetails = (0, apiUtils_1.parseErrorObj)(statusResult.reason);
|
|
227
|
+
const statusResponseData = statusErrorDetails.responseData;
|
|
228
|
+
processingLogger_service_1.processingLogger.logError(`Failed to update file upload status: ${statusErrorDetails.message}${statusResponseData ? ` - ${JSON.stringify(statusResponseData)}` : ''}`, undefined, {
|
|
229
|
+
error_code: error_types_1.ErrorCode.UPLOAD_STATUS_UPDATE_FAILED,
|
|
230
|
+
file_upload_id: fileUploadId,
|
|
231
|
+
status_error: statusErrorDetails,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
// Single "Processing failed" log from logEnd(false), with full error detail in processing_summary.errors (message, step, stack, error_type)
|
|
235
|
+
processingLogger_service_1.processingLogger.logEnd(false);
|
|
236
|
+
}
|
|
237
|
+
catch (handleErrorException) {
|
|
238
|
+
const exceptionMessage = handleErrorException instanceof Error
|
|
239
|
+
? handleErrorException.message
|
|
240
|
+
: String(handleErrorException);
|
|
241
|
+
const handlingError = handleErrorException instanceof Error
|
|
242
|
+
? handleErrorException
|
|
243
|
+
: new Error(String(handleErrorException));
|
|
244
|
+
processingLogger_service_1.processingLogger.addError(handlingError, 'error_handling_failure');
|
|
245
|
+
processingLogger_service_1.processingLogger.logError(`Error handling failed: ${exceptionMessage}`, handlingError, {
|
|
246
|
+
error_code: error_types_1.ErrorCode.UPLOAD_HANDLING_FAILED,
|
|
247
|
+
signed_upload_id: signedUploadId,
|
|
248
|
+
partner_name: partnerName,
|
|
249
|
+
original_error: errorMessage,
|
|
250
|
+
original_error_type: errorType,
|
|
251
|
+
handling_error: exceptionMessage,
|
|
252
|
+
});
|
|
253
|
+
processingLogger_service_1.processingLogger.logEnd(false);
|
|
254
|
+
throw error;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=fileUploadErrorHandler.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileUploadErrorHandler.service.js","sourceRoot":"","sources":["../../service/fileUploadErrorHandler.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,12 +14,11 @@ exports.extractValueFromGreaterLowerThan = extractValueFromGreaterLowerThan;
|
|
|
14
14
|
const crypto_1 = __importDefault(require("crypto"));
|
|
15
15
|
const dataUtils_1 = require("../util-ts/dataUtils");
|
|
16
16
|
const regexUtils_1 = require("../util-ts/regexUtils");
|
|
17
|
-
const
|
|
17
|
+
const processingLogger_service_1 = require("./processingLogger.service");
|
|
18
18
|
const apiUtils_1 = require("../util-ts/apiUtils");
|
|
19
19
|
const oht_types_1 = require("../types/oht.types");
|
|
20
20
|
const transformationRules_service_1 = require("./transformationRules.service");
|
|
21
21
|
const auxiliaryFunctions_service_1 = require("./auxiliaryFunctions.service");
|
|
22
|
-
const logger = (0, pinoLogger_1.default)();
|
|
23
22
|
const OHT_CORE_URL = process.env.OHT_CORE_URL;
|
|
24
23
|
let filename = '';
|
|
25
24
|
function extractUnit(unitExtraction, rawData, ohtBiomarker, synonymUnits = null, partnerId = null) {
|
|
@@ -297,7 +296,7 @@ function checkValueForPlausibleValues(labToOhtMapper, ohtBiomarker, unit, value,
|
|
|
297
296
|
const isPlausibleValue = value >= plausibleLowerValue && value <= plausibleUpperValue;
|
|
298
297
|
// Log if the value is not plausible
|
|
299
298
|
if (!isPlausibleValue) {
|
|
300
|
-
|
|
299
|
+
processingLogger_service_1.processingLogger.logWarn(`Value "${value} ${standardUnit}" not plausible "${plausibleLowerValue} to ${plausibleUpperValue}" for "${labToOhtMapper.ohtBmId}" | "${labToOhtMapper.labKey}", filename: ${filename}`, { labToOhtMapper, value, standardUnit, plausibleLowerValue, plausibleUpperValue, filename });
|
|
301
300
|
}
|
|
302
301
|
return isPlausibleValue;
|
|
303
302
|
}
|
|
@@ -307,9 +306,9 @@ function checkValueForPlausibleValues(labToOhtMapper, ohtBiomarker, unit, value,
|
|
|
307
306
|
*
|
|
308
307
|
* @param exams - Array of original exam objects with synthetic IDs
|
|
309
308
|
* @param transformationRules - Mapping of labKey to transformation rule chains
|
|
310
|
-
* @param patientInfo -
|
|
311
|
-
* @param documentDate -
|
|
312
|
-
* @returns Promise<ApplyTransformationRulesResult> - Array of transformed exams
|
|
309
|
+
* @param patientInfo - PatientInfo
|
|
310
|
+
* @param documentDate - Source DocumentDate
|
|
311
|
+
* @returns Promise<ApplyTransformationRulesResult[]> - Array of transformed exams
|
|
313
312
|
*/
|
|
314
313
|
async function applyTransformationRulesToExams(exams, transformationRules, patientInfo, documentDate) {
|
|
315
314
|
if (transformationRules.size === 0) {
|
|
@@ -331,7 +330,7 @@ async function applyTransformationRulesToExams(exams, transformationRules, patie
|
|
|
331
330
|
const ohtReport = {
|
|
332
331
|
exams: exams.map(e => e.ohtExam),
|
|
333
332
|
};
|
|
334
|
-
|
|
333
|
+
processingLogger_service_1.processingLogger.logInfo('Applying transformation rules to exams...', { exams_count: exams.length, chains_count: transformationRules.size, filename });
|
|
335
334
|
let labKeysWithRulesCount = 0;
|
|
336
335
|
let transformedLabKeysCount = 0;
|
|
337
336
|
const applicationErrorMessages = [];
|
|
@@ -349,7 +348,7 @@ async function applyTransformationRulesToExams(exams, transformationRules, patie
|
|
|
349
348
|
contextJson: reportContext,
|
|
350
349
|
});
|
|
351
350
|
if (result.errors.length > 0) {
|
|
352
|
-
|
|
351
|
+
processingLogger_service_1.processingLogger.logWarn('Errors applying transformation rule(s) for labKey.', { labKey, errors: result.errors, filename });
|
|
353
352
|
applicationErrorMessages.push(`${labKey}: ${result.errors.map(e => `(rule ID ${e.ruleId}) ${e.error}`).join('; ')}`);
|
|
354
353
|
// Keep original exam when transformation fails
|
|
355
354
|
transformedExams.push(exam);
|
|
@@ -358,7 +357,7 @@ async function applyTransformationRulesToExams(exams, transformationRules, patie
|
|
|
358
357
|
if (result.appliedRules.length > 0) {
|
|
359
358
|
transformedLabKeysCount++;
|
|
360
359
|
}
|
|
361
|
-
|
|
360
|
+
processingLogger_service_1.processingLogger.logInfo('Done applying transformation rule(s) for labKey.', { labKey, applied_rules: result.appliedRules.length, filename });
|
|
362
361
|
// Preserve the synthetic ID through transformation
|
|
363
362
|
transformedExams.push({
|
|
364
363
|
_syntheticId: exam._syntheticId,
|
|
@@ -368,19 +367,19 @@ async function applyTransformationRulesToExams(exams, transformationRules, patie
|
|
|
368
367
|
}
|
|
369
368
|
}
|
|
370
369
|
catch (error) {
|
|
371
|
-
|
|
370
|
+
processingLogger_service_1.processingLogger.logError('Failed to apply transformation rules for labKey.', error instanceof Error ? error : undefined, { labKey, filename });
|
|
372
371
|
applicationErrorMessages.push(`${labKey}: Unhandled error occurred.`);
|
|
373
372
|
// Keep original exam when transformation throws
|
|
374
373
|
transformedExams.push(exam);
|
|
375
374
|
}
|
|
376
375
|
}
|
|
377
|
-
|
|
376
|
+
processingLogger_service_1.processingLogger.logInfo('Done applying the transformation rules to exams.', {
|
|
378
377
|
filename,
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
transformedLabKeysCount,
|
|
382
|
-
labKeysWithRulesCount,
|
|
383
|
-
}
|
|
378
|
+
exams_count: exams.length,
|
|
379
|
+
chains_count: transformationRules.size,
|
|
380
|
+
transformed_lab_keys_count: transformedLabKeysCount,
|
|
381
|
+
lab_keys_with_rules_count: labKeysWithRulesCount,
|
|
382
|
+
});
|
|
384
383
|
return {
|
|
385
384
|
transformedExams,
|
|
386
385
|
applicationErrorMessages
|
|
@@ -414,7 +413,7 @@ async function ohtMeasurementsExtractor(labToOhtContract, exams, transformationR
|
|
|
414
413
|
transformedExamsResult = await applyTransformationRulesToExams(examsWithIds, transformationRules, labToOhtContract.patientInfo, labToOhtContract.documentDate);
|
|
415
414
|
}
|
|
416
415
|
catch (error) {
|
|
417
|
-
|
|
416
|
+
processingLogger_service_1.processingLogger.logError('Unhandled error while applying transformation rules to exams.', error instanceof Error ? error : undefined, { filename });
|
|
418
417
|
labToOhtContract.errorMessages.push({
|
|
419
418
|
destination: { slack: true, notes: true, bi: false },
|
|
420
419
|
message: `Failed applying the transformation rules for filename ${filename}. ${error instanceof Error ? error.message : error}`,
|
|
@@ -476,7 +475,7 @@ async function ohtMeasurementsExtractor(labToOhtContract, exams, transformationR
|
|
|
476
475
|
if (labToOhtMapper?.ohtBmId && labToOhtMapper?.ohtBmId !== -1) {
|
|
477
476
|
// if BM is already in measurements, continue to the next one
|
|
478
477
|
if (measurements.some(measurement => measurement.biomarkerId === labToOhtMapper.ohtBmId)) {
|
|
479
|
-
|
|
478
|
+
processingLogger_service_1.processingLogger.logWarn(`Biomarker already in measurements array, should investigate, filename: ${filename}`, { labToOhtMapper });
|
|
480
479
|
labToOhtContract.errorMessages.push({
|
|
481
480
|
destination: { slack: false, notes: false, bi: true },
|
|
482
481
|
message: `Biomarkers Duplicated keys:[PLACEHOLDER]`,
|
|
@@ -503,7 +502,7 @@ async function ohtMeasurementsExtractor(labToOhtContract, exams, transformationR
|
|
|
503
502
|
});
|
|
504
503
|
}
|
|
505
504
|
if (!isUnitParsedCorrectly) {
|
|
506
|
-
|
|
505
|
+
processingLogger_service_1.processingLogger.logWarn(`Unit not extracted correctly for "${labToOhtMapper.ohtBmId}|${labToOhtMapper.labKey}", filename: ${filename}`, { labToOhtMapper });
|
|
507
506
|
labToOhtContract.errorMessages.push({
|
|
508
507
|
destination: { slack: true, notes: true, bi: true },
|
|
509
508
|
message: `Unit not extracted correctly for:[PLACEHOLDER]`,
|
|
@@ -513,7 +512,7 @@ async function ohtMeasurementsExtractor(labToOhtContract, exams, transformationR
|
|
|
513
512
|
}
|
|
514
513
|
let { valueType, alphanumericalValue, numberValue, valueComparator, isValueParsedCorrectly } = parseExamValue(examObj, labToOhtMapper.valueExtraction, ohtBiomarker);
|
|
515
514
|
if (!isValueParsedCorrectly) {
|
|
516
|
-
|
|
515
|
+
processingLogger_service_1.processingLogger.logWarn(`Value not extracted correctly for "${labToOhtMapper.ohtBmId}|${labToOhtMapper.labKey}", filename: ${filename}`, { labToOhtMapper });
|
|
517
516
|
labToOhtContract.errorMessages.push({
|
|
518
517
|
destination: { slack: true, notes: true, bi: true },
|
|
519
518
|
message: `Value not extracted correctly for:[PLACEHOLDER]`,
|
|
@@ -549,7 +548,7 @@ async function ohtMeasurementsExtractor(labToOhtContract, exams, transformationR
|
|
|
549
548
|
if (isValueParsedCorrectly && valueType === 'NUMERICAL') {
|
|
550
549
|
const isPlausibleValue = numberValue !== null && checkValueForPlausibleValues(labToOhtMapper, ohtBiomarker, unit, numberValue, isUnitParsedCorrectly);
|
|
551
550
|
if (!isPlausibleValue) {
|
|
552
|
-
|
|
551
|
+
processingLogger_service_1.processingLogger.logWarn(`Value [${numberValue} ${unit}] is not plausible for "${labToOhtMapper.ohtBmId}|${labToOhtMapper.labKey}", filename: ${filename}`, { labToOhtMapper });
|
|
553
552
|
labToOhtContract.errorMessages.push({
|
|
554
553
|
destination: { slack: true, notes: true, bi: true },
|
|
555
554
|
message: `Value is not plausible for:[PLACEHOLDER]`,
|
|
@@ -567,7 +566,7 @@ async function ohtMeasurementsExtractor(labToOhtContract, exams, transformationR
|
|
|
567
566
|
to = extractedRange.to ?? null;
|
|
568
567
|
isRangeParsedCorrectly = extractedRange.isRangeParsedCorrectly;
|
|
569
568
|
if (!isRangeParsedCorrectly) {
|
|
570
|
-
|
|
569
|
+
processingLogger_service_1.processingLogger.logWarn(`Range not extracted correctly for "${labToOhtMapper.ohtBmId}|${labToOhtMapper.labKey}", filename: ${filename}`, { labToOhtMapper });
|
|
571
570
|
labToOhtContract.errorMessages.push({
|
|
572
571
|
destination: { slack: true, notes: true, bi: true },
|
|
573
572
|
message: `Range not extracted correctly for:[PLACEHOLDER]`,
|
|
@@ -624,7 +623,7 @@ async function ohtMeasurementsExtractor(labToOhtContract, exams, transformationR
|
|
|
624
623
|
measurements.push(measurement);
|
|
625
624
|
}
|
|
626
625
|
else {
|
|
627
|
-
|
|
626
|
+
processingLogger_service_1.processingLogger.logWarn(`Created an ungroupedBiomarker for id: ${labToOhtMapper.labKey}, filename: ${filename}`);
|
|
628
627
|
labToOhtContract.errorMessages.push({
|
|
629
628
|
destination: { slack: false, notes: false, bi: true },
|
|
630
629
|
message: `Created ungroupedBiomarkers for:[PLACEHOLDER]`,
|