feat(MED-168): move analysis result element mapping to shared

This commit is contained in:
2025-09-19 12:48:57 +03:00
parent 81f7a03388
commit e7b484e1d4
4 changed files with 68 additions and 40 deletions

View File

@@ -16,6 +16,7 @@ import type {
import { toArray } from '@kit/shared/utils'; import { toArray } from '@kit/shared/utils';
import type { AnalysisOrder } from '~/lib/types/analysis-order'; import type { AnalysisOrder } from '~/lib/types/analysis-order';
import type { AnalysisResponseElement } from '~/lib/types/analysis-response-element'; import type { AnalysisResponseElement } from '~/lib/types/analysis-response-element';
import { createUserAnalysesApi } from '@/packages/features/user-analyses/src/server/api';
import { Tables } from '@kit/supabase/database'; import { Tables } from '@kit/supabase/database';
import { getSupabaseServerAdminClient } from '@/packages/supabase/src/clients/server-admin-client'; import { getSupabaseServerAdminClient } from '@/packages/supabase/src/clients/server-admin-client';
@@ -138,28 +139,25 @@ export async function getAnalysisResponseElementsForGroup({
continue; continue;
} }
const responseValueIsNumeric = responseValue !== null; const mappedResponse = createUserAnalysesApi(getSupabaseServerAdminClient())
const responseValueIsNegative = vastuseVaartus === 'Negatiivne'; .mapUuringVastus({ uuringVastus: response });
const responseValueIsWithinNorm = vastuseVaartus === 'Normi piires';
results.push({ results.push({
analysis_element_original_id: analysisElementOriginalId, analysis_element_original_id: analysisElementOriginalId,
norm_lower: response.NormAlum?.['#text'] ?? null, norm_lower: mappedResponse.normLower,
norm_lower_included: norm_lower_included: mappedResponse.normLowerIncluded,
response.NormAlum?.['@_kaasaarvatud'].toLowerCase() === 'jah', norm_status: mappedResponse.normStatus,
norm_status: response.NormiStaatus, norm_upper: mappedResponse.normUpper,
norm_upper: response.NormYlem?.['#text'] ?? null, norm_upper_included: mappedResponse.normUpperIncluded,
norm_upper_included: response_time: mappedResponse.responseTime,
response.NormYlem?.['@_kaasaarvatud'].toLowerCase() === 'jah', response_value: mappedResponse.responseValue,
response_time: response.VastuseAeg ?? null,
response_value: responseValue,
unit: groupUuringElement.Mootyhik ?? null, unit: groupUuringElement.Mootyhik ?? null,
original_response_element: groupUuringElement, original_response_element: groupUuringElement,
analysis_name: groupUuringElement.UuringNimi || groupUuringElement.KNimetus, analysis_name: groupUuringElement.UuringNimi || groupUuringElement.KNimetus,
comment: groupUuringElement.UuringuKommentaar ?? null, comment: groupUuringElement.UuringuKommentaar ?? null,
status: status.toString(), status: status.toString(),
response_value_is_within_norm: responseValueIsNumeric ? null : responseValueIsWithinNorm, response_value_is_within_norm: mappedResponse.responseValueIsWithinNorm,
response_value_is_negative: responseValueIsNumeric ? null : responseValueIsNegative, response_value_is_negative: mappedResponse.responseValueIsNegative,
}); });
} }
} }

View File

@@ -1,6 +1,7 @@
import { SupabaseClient } from '@supabase/supabase-js'; import { SupabaseClient } from '@supabase/supabase-js';
import { Database } from '@kit/supabase/database'; import { Database } from '@kit/supabase/database';
import { toArray } from '@kit/shared/utils';
import type { UuringElement, UuringuVastus } from '@kit/shared/types/medipost-analysis'; import type { UuringElement, UuringuVastus } from '@kit/shared/types/medipost-analysis';
import type { AnalysisResultDetails, AnalysisResultDetailsMapped, UserAnalysis } from '../types/analysis-results'; import type { AnalysisResultDetails, AnalysisResultDetailsMapped, UserAnalysis } from '../types/analysis-results';
@@ -143,6 +144,7 @@ class UserAnalysesApi {
analysisResponseElements, analysisResponseElements,
}); });
}).sort((a, b) => a.analysisName.localeCompare(b.analysisName)); }).sort((a, b) => a.analysisName.localeCompare(b.analysisName));
const nestedAnalysisElementIds = mappedOrderedAnalysisElements const nestedAnalysisElementIds = mappedOrderedAnalysisElements
.map(({ results }) => results?.nestedElements.map(({ analysisElementOriginalId }) => analysisElementOriginalId)) .map(({ results }) => results?.nestedElements.map(({ analysisElementOriginalId }) => analysisElementOriginalId))
.flat().filter(Boolean); .flat().filter(Boolean);
@@ -151,7 +153,7 @@ class UserAnalysesApi {
.schema('medreport') .schema('medreport')
.from('analysis_elements') .from('analysis_elements')
.select('*') .select('*')
.in('id', nestedAnalysisElementIds); .in('analysis_id_original', nestedAnalysisElementIds);
if (!nestedAnalysisElementsError && nestedAnalysisElements) { if (!nestedAnalysisElementsError && nestedAnalysisElements) {
for (const mappedOrderedAnalysisElement of mappedOrderedAnalysisElements) { for (const mappedOrderedAnalysisElement of mappedOrderedAnalysisElements) {
const { results } = mappedOrderedAnalysisElement; const { results } = mappedOrderedAnalysisElement;
@@ -160,7 +162,7 @@ class UserAnalysesApi {
} }
for (const nestedElement of results.nestedElements) { for (const nestedElement of results.nestedElements) {
const { analysisElementOriginalId } = nestedElement; const { analysisElementOriginalId } = nestedElement;
const nestedAnalysisElement = nestedAnalysisElements.find(({ id }) => id === analysisElementOriginalId); const nestedAnalysisElement = nestedAnalysisElements.find(({ analysis_id_original }) => analysis_id_original === analysisElementOriginalId);
if (!nestedAnalysisElement) { if (!nestedAnalysisElement) {
continue; continue;
} }
@@ -220,25 +222,24 @@ class UserAnalysesApi {
if (!nestedElements) { if (!nestedElements) {
return []; return [];
} }
return nestedElements.map((element) => { return toArray(nestedElements).map((element) => {
const elementVastus = element.UuringuVastus as UuringuVastus | undefined; const mappedResponse = this.mapUuringVastus({
const responseValue = elementVastus?.VastuseVaartus; uuringVastus: element.UuringuVastus as UuringuVastus | undefined,
const responseValueIsNumeric = !isNaN(Number(responseValue)); });
const responseValueIsNegative = responseValue === 'Negatiivne';
const responseValueIsWithinNorm = responseValue === 'Normi piires';
return { return {
status: element.UuringOlek, status: element.UuringOlek,
unit: element.Mootyhik, unit: element.Mootyhik ?? null,
normLower: elementVastus?.NormAlum?.['#text'], normLower: mappedResponse.normLower,
normUpper: elementVastus?.NormYlem?.['#text'], normUpper: mappedResponse.normUpper,
normStatus: elementVastus?.NormiStaatus, normStatus: mappedResponse.normStatus,
responseTime: elementVastus?.VastuseAeg, responseTime: mappedResponse.responseTime,
response_value: responseValueIsNegative || !responseValueIsNumeric ? null : (responseValue ?? null), responseValue: mappedResponse.responseValue,
response_value_is_negative: responseValueIsNumeric ? null : responseValueIsNegative, responseValueIsNegative: mappedResponse.responseValueIsNegative,
response_value_is_within_norm: responseValueIsNumeric ? null : responseValueIsWithinNorm, responseValueIsWithinNorm: mappedResponse.responseValueIsWithinNorm,
normLowerIncluded: elementVastus?.NormAlum?.['@_kaasaarvatud'] === 'JAH', normLowerIncluded: mappedResponse.normLowerIncluded,
normUpperIncluded: elementVastus?.NormYlem?.['@_kaasaarvatud'] === 'JAH', normUpperIncluded: mappedResponse.normUpperIncluded,
analysisElementOriginalId: element.UuringId, analysisElementOriginalId: element.UuringId,
analysisName: undefined,
}; };
}); });
})(), })(),
@@ -260,6 +261,34 @@ class UserAnalysesApi {
}; };
} }
mapUuringVastus({ uuringVastus }: { uuringVastus?: UuringuVastus }) {
const vastuseVaartus = uuringVastus?.VastuseVaartus;
const responseValue = (() => {
const valueAsNumber = Number(vastuseVaartus);
if (isNaN(valueAsNumber)) {
return null;
}
return valueAsNumber;
})();
const responseValueNumber = Number(responseValue);
const responseValueIsNumeric = !isNaN(responseValueNumber);
const responseValueIsNegative = vastuseVaartus === 'Negatiivne';
const responseValueIsWithinNorm = vastuseVaartus === 'Normi piires';
return {
normLower: uuringVastus?.NormAlum?.['#text'] ?? null,
normUpper: uuringVastus?.NormYlem?.['#text'] ?? null,
normStatus: uuringVastus?.NormiStaatus ?? null,
responseTime: uuringVastus?.VastuseAeg ?? null,
responseValue: responseValueIsNegative || !responseValueIsNumeric ? null : (responseValueNumber ?? null),
responseValueIsNegative: responseValueIsNumeric ? null : responseValueIsNegative,
responseValueIsWithinNorm: responseValueIsNumeric ? null : responseValueIsWithinNorm,
normLowerIncluded:
uuringVastus?.NormAlum?.['@_kaasaarvatud'].toLowerCase() === 'jah',
normUpperIncluded:
uuringVastus?.NormYlem?.['@_kaasaarvatud'].toLowerCase() === 'jah',
};
}
// @TODO unused currently // @TODO unused currently
async getUserAnalyses(): Promise<UserAnalysis | null> { async getUserAnalyses(): Promise<UserAnalysis | null> {
const authUser = await this.client.auth.getUser(); const authUser = await this.client.auth.getUser();

View File

@@ -88,13 +88,14 @@ export type AnalysisResultDetailsElementResults = {
analysisElementOriginalId: string; analysisElementOriginalId: string;
normLower?: number | null; normLower?: number | null;
normLowerIncluded: boolean; normLowerIncluded: boolean;
normStatus: number; normStatus: number | null;
normUpper?: number | null; normUpper?: number | null;
normUpperIncluded: boolean; normUpperIncluded: boolean;
responseTime: string; responseTime: string | null;
responseValue: number; responseValue: number | null;
status: number; status: number;
unit: string; unit: string | null;
analysisName?: string | null;
}[]; }[];
labComment?: string | null; labComment?: string | null;
}; };
@@ -103,7 +104,7 @@ export type AnalysisResultDetailsElement = {
analysisIdOriginal: string; analysisIdOriginal: string;
isWaitingForResults: boolean; isWaitingForResults: boolean;
analysisName: string; analysisName: string;
results: AnalysisResultDetailsElementResults; results?: AnalysisResultDetailsElementResults;
}; };
export type AnalysisResultDetailsMapped = { export type AnalysisResultDetailsMapped = {

View File

@@ -685,7 +685,7 @@ export type Database = {
norm_upper: number | null norm_upper: number | null
norm_upper_included: boolean | null norm_upper_included: boolean | null
original_response_element: Json original_response_element: Json
response_time: string response_time: string | null
response_value: number | null response_value: number | null
response_value_is_negative?: boolean | null response_value_is_negative?: boolean | null
response_value_is_within_norm?: boolean | null response_value_is_within_norm?: boolean | null
@@ -706,7 +706,7 @@ export type Database = {
norm_upper?: number | null norm_upper?: number | null
norm_upper_included?: boolean | null norm_upper_included?: boolean | null
original_response_element: Json original_response_element: Json
response_time: string response_time: string | null
response_value: number | null response_value: number | null
response_value_is_negative?: boolean | null response_value_is_negative?: boolean | null
response_value_is_within_norm?: boolean | null response_value_is_within_norm?: boolean | null
@@ -727,7 +727,7 @@ export type Database = {
norm_upper?: number | null norm_upper?: number | null
norm_upper_included?: boolean | null norm_upper_included?: boolean | null
original_response_element?: Json original_response_element?: Json
response_time?: string response_time?: string | null
response_value?: number | null response_value?: number | null
response_value_is_negative?: boolean | null response_value_is_negative?: boolean | null
response_value_is_within_norm?: boolean | null response_value_is_within_norm?: boolean | null