Move medipostPrivateMessage.service to separate classes, improve logging

This commit is contained in:
2025-11-12 08:51:48 +02:00
parent 0878b5d1bd
commit 8f32fdf08d
12 changed files with 670 additions and 390 deletions

View File

@@ -0,0 +1,142 @@
import type { PostgrestError } from "@supabase/supabase-js";
import { toArray } from '@kit/shared/utils';
import type { AnalysisOrder } from "~/lib/types/order";
import type { AnalysisResponseElement } from '~/lib/types/analysis-response-element';
import { AnalysisOrderStatus } from '@/packages/shared/src/types/medipost-analysis';
import type {
MedipostAnalysisResult,
ResponseUuringuGrupp,
} from '@/packages/shared/src/types/medipost-analysis';
import { getAnalysisResponseElementsForGroup } from "./medipostPrivateMessage.service";
import {
getExistingAnalysisResponseElements,
upsertAnalysisResponse,
upsertAnalysisResponseElement,
} from "../analysis-order.service";
import type { Logger } from './types';
type AnalysisResponseElementMapped = Omit<
AnalysisResponseElement,
'created_at' | 'updated_at' | 'id' | 'analysis_response_id'
>;
export type SyncResult =
| {
isCompleted: boolean;
isPartial?: undefined;
}
| {
isPartial: boolean;
isCompleted?: undefined;
};
export default class MedipostAnalysisResultService {
public async storeAnalysisResult({
messageResponse: {
TellimuseNumber: orderNumber,
TellimuseOlek,
UuringuGrupp,
},
analysisOrder,
log,
}: {
messageResponse: Pick<
NonNullable<MedipostAnalysisResult>,
'TellimuseNumber' | 'TellimuseOlek' | 'UuringuGrupp'
>;
analysisOrder: AnalysisOrder;
log: Logger;
}): Promise<SyncResult> {
const orderStatus = AnalysisOrderStatus[TellimuseOlek];
const { analysisResponseId } = await upsertAnalysisResponse({
analysisOrderId: analysisOrder.id,
orderNumber,
orderStatus,
userId: analysisOrder.user_id,
});
const existingElements = await getExistingAnalysisResponseElements({
analysisResponseId,
});
const analysisGroups = toArray(UuringuGrupp);
log(`Order has results for ${analysisGroups.length} analysis groups`);
const newElements = await this.getNewAnalysisResponseElements({
analysisGroups,
existingElements,
log,
});
for (const element of newElements) {
try {
await upsertAnalysisResponseElement({
element: {
...element,
analysis_response_id: analysisResponseId,
},
});
} catch (e) {
log(
`Failed to create order response element for response id ${analysisResponseId}, element id '${element.analysis_element_original_id}'`,
"error",
e as PostgrestError,
);
}
}
const hasAllResults = await this.hasAllAnalysisResponseElements({
analysisResponseId,
analysisOrder,
});
log(`Order has ${hasAllResults ? 'all' : 'some'} results, status is ${orderStatus}`);
return hasAllResults
? { isCompleted: orderStatus === 'COMPLETED' }
: { isPartial: true };
}
private async getNewAnalysisResponseElements({
analysisGroups,
existingElements,
log,
}: {
analysisGroups: ResponseUuringuGrupp[];
existingElements: AnalysisResponseElement[];
log: Logger;
}): Promise<AnalysisResponseElementMapped[]> {
const newElements: AnalysisResponseElementMapped[] = [];
for (const analysisGroup of analysisGroups) {
log(
`[${analysisGroups.indexOf(analysisGroup) + 1}/${analysisGroups.length}] Syncing analysis group '${analysisGroup.UuringuGruppNimi}'`,
);
const elements = await getAnalysisResponseElementsForGroup({
analysisGroup,
existingElements,
log,
});
newElements.push(...elements);
}
return newElements;
}
private async hasAllAnalysisResponseElements({
analysisResponseId,
analysisOrder,
}: {
analysisResponseId: number;
analysisOrder: Pick<AnalysisOrder, 'analysis_element_ids'>;
}): Promise<boolean> {
const allOrderResponseElements = await getExistingAnalysisResponseElements({
analysisResponseId,
});
const expectedOrderResponseElements = analysisOrder.analysis_element_ids?.length ?? 0;
return allOrderResponseElements.length >= expectedOrderResponseElements;
}
}