MED-88: add doctor email notifications (#65)

* MED-88: add doctor email notifications

* add logging, send open jobs notification on partial analysis response

* update permissions

* fix import, permissions

* casing, let email be null

* unused import
This commit is contained in:
Helena
2025-09-02 12:14:01 +03:00
committed by GitHub
parent 56a832b96b
commit 3498406a0c
41 changed files with 751 additions and 69 deletions

View File

@@ -1,7 +1,20 @@
import { SupabaseClient } from '@supabase/supabase-js';
import {
renderAllResultsReceivedEmail,
renderFirstResultsReceivedEmail,
} from '@kit/email-templates';
import { Database } from '@kit/supabase/database';
import {
getAssignedDoctorAccount,
getDoctorAccounts,
} from '../../../../../lib/services/account.service';
import {
NotificationAction,
createNotificationLog,
} from '../../../../../lib/services/audit/notificationEntries.service';
import { sendEmailFromTemplate } from '../../../../../lib/services/mailer.service';
import { RecordChange, Tables } from '../record-change.type';
export function createDatabaseWebhookRouterService(
@@ -42,6 +55,12 @@ class DatabaseWebhookRouterService {
return this.handleAccountsWebhook(payload);
}
case 'analysis_orders': {
const payload = body as RecordChange<typeof body.table>;
return this.handleAnalysisOrdersWebhook(payload);
}
default: {
return;
}
@@ -83,4 +102,69 @@ class DatabaseWebhookRouterService {
return service.handleAccountDeletedWebhook(body.old_record);
}
}
private async handleAnalysisOrdersWebhook(
body: RecordChange<'analysis_orders'>,
) {
if (body.type === 'UPDATE' && body.record && body.old_record) {
const { record, old_record } = body;
if (record.status === old_record.status) {
return;
}
let action;
try {
const data = {
analysisOrderId: record.id,
language: 'et',
};
if (record.status === 'PARTIAL_ANALYSIS_RESPONSE') {
action = NotificationAction.NEW_JOBS_ALERT;
const doctorAccounts = await getDoctorAccounts();
const doctorEmails: string[] = doctorAccounts
.map(({ email }) => email)
.filter((email): email is string => !!email);
await sendEmailFromTemplate(
renderFirstResultsReceivedEmail,
data,
doctorEmails,
);
} else if (record.status === 'FULL_ANALYSIS_RESPONSE') {
action = NotificationAction.PATIENT_RESULTS_RECEIVED_ALERT;
const doctorAccount = await getAssignedDoctorAccount(record.id);
const assignedDoctorEmail = doctorAccount?.email;
if (!assignedDoctorEmail) {
return;
}
await sendEmailFromTemplate(
renderAllResultsReceivedEmail,
data,
assignedDoctorEmail,
);
}
if (action) {
await createNotificationLog({
action,
status: 'SUCCESS',
relatedRecordId: record.id,
});
}
} catch (e: any) {
if (action)
await createNotificationLog({
action,
status: 'FAIL',
comment: e?.message,
relatedRecordId: record.id,
});
}
}
}
}