MED-56: show specific error when job taken, other small improvements (#58)

* show specific error when job taken, other small improvements

* enum name case

* enum value case, actually
This commit is contained in:
Helena
2025-08-26 11:43:31 +03:00
committed by GitHub
parent f5abf2d21e
commit 5d92c34259
8 changed files with 94 additions and 51 deletions

View File

@@ -86,27 +86,23 @@ export default function AnalysisView({
data: DoctorAnalysisFeedbackForm, data: DoctorAnalysisFeedbackForm,
status: 'DRAFT' | 'COMPLETED', status: 'DRAFT' | 'COMPLETED',
) => { ) => {
try { const result = await giveFeedbackAction({
const feedbackPromise = giveFeedbackAction({ ...data,
...data, analysisOrderId: order.analysisOrderId,
analysisOrderId: order.analysisOrderId, status,
status, });
});
toast.promise(() => feedbackPromise, { if (!result.success) {
success: <Trans i18nKey={'doctor:updateFeedbackSuccess'} />, return toast.error(<Trans i18nKey="common:genericServerError" />);
error: <Trans i18nKey={'doctor:updateFeedbackError'} />,
loading: <Trans i18nKey={'doctor:updateFeedbackLoading'} />,
});
queryClient.invalidateQueries({
predicate: (query) => query.queryKey.includes('doctor-jobs'),
});
return setIsConfirmOpen(false);
} catch (error) {
toast.error(<Trans i18nKey="common:genericServerError" />);
} }
queryClient.invalidateQueries({
predicate: (query) => query.queryKey.includes('doctor-jobs'),
});
toast.success(<Trans i18nKey={'doctor:updateFeedbackSuccess'} />);
return setIsConfirmOpen(false);
}; };
const handleDraftSubmit = async (e: React.FormEvent) => { const handleDraftSubmit = async (e: React.FormEvent) => {

View File

@@ -10,6 +10,7 @@ import {
selectJobAction, selectJobAction,
unselectJobAction, unselectJobAction,
} from '@kit/doctor/actions/doctor-server-actions'; } from '@kit/doctor/actions/doctor-server-actions';
import { ErrorReason } from '@kit/doctor/schema/error.type';
import { Button, ButtonProps } from '@kit/ui/button'; import { Button, ButtonProps } from '@kit/ui/button';
import { toast } from '@kit/ui/sonner'; import { toast } from '@kit/ui/sonner';
import { Trans } from '@kit/ui/trans'; import { Trans } from '@kit/ui/trans';
@@ -50,7 +51,14 @@ export default function DoctorJobSelect({
onJobUpdate(); onJobUpdate();
linkTo && router.push(linkTo); linkTo && router.push(linkTo);
} else { } else {
toast.error('common.genericServerError'); toast.error(
<Trans
i18nKey={`doctor:error.${result.reason ?? ErrorReason.UNKNOWN}`}
/>,
);
if (result.reason === ErrorReason.JOB_ASSIGNED) {
onJobUpdate();
}
} }
}); });
}; };
@@ -64,7 +72,11 @@ export default function DoctorJobSelect({
if (result?.success) { if (result?.success) {
onJobUpdate(); onJobUpdate();
} else { } else {
toast.error('common.genericServerError'); toast.error(
<Trans
i18nKey={`doctor:error.${result.reason ?? ErrorReason.UNKNOWN}`}
/>,
);
} }
}); });
}; };

View File

@@ -1,6 +1,6 @@
'use server'; 'use server';
import { revalidatePath, revalidateTag } from 'next/cache'; import { revalidatePath } from 'next/cache';
import { enhanceAction } from '@kit/next/actions'; import { enhanceAction } from '@kit/next/actions';
import { getLogger } from '@kit/shared/logger'; import { getLogger } from '@kit/shared/logger';
@@ -13,6 +13,7 @@ import {
doctorJobSelectSchema, doctorJobSelectSchema,
doctorJobUnselectSchema, doctorJobUnselectSchema,
} from '../schema/doctor-analysis.schema'; } from '../schema/doctor-analysis.schema';
import { ErrorReason } from '../schema/error.type';
import { import {
selectJob, selectJob,
submitFeedback, submitFeedback,
@@ -29,14 +30,27 @@ export const selectJobAction = doctorAction(
async ({ analysisOrderId, userId }: DoctorJobSelect) => { async ({ analysisOrderId, userId }: DoctorJobSelect) => {
const logger = await getLogger(); const logger = await getLogger();
logger.info({ analysisOrderId }, `Selecting new job`); try {
logger.info({ analysisOrderId }, `Selecting new job`);
await selectJob(analysisOrderId, userId); await selectJob(analysisOrderId, userId);
logger.info({ analysisOrderId }, `Successfully selected`);
logger.info({ analysisOrderId }, `Successfully selected`); revalidateDoctorAnalysis();
return { success: true };
revalidateDoctorAnalysis(); } catch (e) {
return { success: true }; logger.error('Failed to select job', e);
if (e instanceof Error) {
return {
success: false,
reason:
e['message'] === ErrorReason.JOB_ASSIGNED
? ErrorReason.JOB_ASSIGNED
: ErrorReason.UNKNOWN,
};
}
return { success: false, reason: ErrorReason.UNKNOWN };
}
}, },
{ {
schema: doctorJobSelectSchema, schema: doctorJobSelectSchema,
@@ -52,17 +66,21 @@ export const unselectJobAction = doctorAction(
enhanceAction( enhanceAction(
async ({ analysisOrderId }: DoctorJobUnselect) => { async ({ analysisOrderId }: DoctorJobUnselect) => {
const logger = await getLogger(); const logger = await getLogger();
try {
logger.info({ analysisOrderId }, `Removing doctor from job`);
logger.info({ analysisOrderId }, `Removing doctor from job`); await unselectJob(analysisOrderId);
await unselectJob(analysisOrderId); logger.info(
{ analysisOrderId },
logger.info( `Successfully removed current doctor from job`,
{ analysisOrderId }, );
`Successfully removed current doctor from job`, revalidateDoctorAnalysis();
); return { success: true };
revalidateDoctorAnalysis(); } catch (e) {
return { success: true }; logger.error('Failed to unselect job', e);
return { success: false, reason: ErrorReason.UNKNOWN };
}
}, },
{ {
schema: doctorJobUnselectSchema, schema: doctorJobUnselectSchema,
@@ -89,21 +107,21 @@ export const giveFeedbackAction = doctorAction(
}) => { }) => {
const logger = await getLogger(); const logger = await getLogger();
logger.info( try {
{ analysisOrderId }, logger.info(
`Submitting feedback for analysis order...`, { analysisOrderId },
); `Submitting feedback for analysis order...`,
);
const result = await submitFeedback( await submitFeedback(analysisOrderId, userId, feedbackValue, status);
analysisOrderId, logger.info({ analysisOrderId }, `Successfully submitted feedback`);
userId,
feedbackValue,
status,
);
logger.info({ analysisOrderId }, `Successfully submitted feedback`);
revalidateDoctorAnalysis(); revalidateDoctorAnalysis();
return result; return { success: true };
} catch (e) {
logger.error('Failed to give feedback', e);
return { success: false, reason: ErrorReason.UNKNOWN };
}
}, },
{ {
schema: doctorAnalysisFeedbackSchema, schema: doctorAnalysisFeedbackSchema,

View File

@@ -0,0 +1,4 @@
export enum ErrorReason {
JOB_ASSIGNED = 'JOB_ASSIGNED',
UNKNOWN = 'UNKNOWN',
}

View File

@@ -12,6 +12,7 @@ import {
PaginationParams, PaginationParams,
ResponseTable, ResponseTable,
} from '../schema/doctor-analysis.schema'; } from '../schema/doctor-analysis.schema';
import { ErrorReason } from '../schema/error.type';
async function enrichAnalysisData(analysisResponses?: AnalysisResponseBase[]) { async function enrichAnalysisData(analysisResponses?: AnalysisResponseBase[]) {
const supabase = getSupabaseServerClient(); const supabase = getSupabaseServerClient();
@@ -534,7 +535,7 @@ export async function selectJob(analysisOrderId: number, userId: string) {
const jobAssignedToUserId = existingFeedback?.[0]?.doctor_user_id; const jobAssignedToUserId = existingFeedback?.[0]?.doctor_user_id;
if (!!jobAssignedToUserId && jobAssignedToUserId !== user.id) { if (!!jobAssignedToUserId && jobAssignedToUserId !== user.id) {
throw new Error('Job already assigned to another doctor.'); throw new Error(ErrorReason.JOB_ASSIGNED);
} }
const { data, error } = await supabase const { data, error } = await supabase

View File

@@ -39,6 +39,10 @@
"title": "Confirm publishing summary", "title": "Confirm publishing summary",
"description": "When confirmed, the summary will be published to the patient." "description": "When confirmed, the summary will be published to the patient."
}, },
"error": {
"UNKNOWN": "Something went wrong",
"JOB_ASSIGNED": "Job already selected"
},
"updateFeedbackSuccess": "Summary updated", "updateFeedbackSuccess": "Summary updated",
"updateFeedbackLoading": "Updating summary...", "updateFeedbackLoading": "Updating summary...",
"updateFeedbackError": "Failed to update summary", "updateFeedbackError": "Failed to update summary",

View File

@@ -39,6 +39,10 @@
"title": "Kinnita kokkuvõtte avaldamine", "title": "Kinnita kokkuvõtte avaldamine",
"description": "Kinnitamisel avaldatakse kokkuvõte patsiendile." "description": "Kinnitamisel avaldatakse kokkuvõte patsiendile."
}, },
"error": {
"UNKNOWN": "Midagi läks valesti",
"JOB_ASSIGNED": "Töö on juba võetud"
},
"updateFeedbackSuccess": "Kokkuvõte uuendatud", "updateFeedbackSuccess": "Kokkuvõte uuendatud",
"updateFeedbackLoading": "Kokkuvõtet uuendatakse...", "updateFeedbackLoading": "Kokkuvõtet uuendatakse...",
"updateFeedbackError": "Kokkuvõtte uuendamine ebaõnnestus", "updateFeedbackError": "Kokkuvõtte uuendamine ebaõnnestus",

View File

@@ -39,6 +39,10 @@
"title": "Confirm publishing summary", "title": "Confirm publishing summary",
"description": "When confirmed, the summary will be published to the patient." "description": "When confirmed, the summary will be published to the patient."
}, },
"error": {
"UNKNOWN": "Something went wrong",
"JOB_ASSIGNED": "Job already selected"
},
"updateFeedbackSuccess": "Summary updated", "updateFeedbackSuccess": "Summary updated",
"updateFeedbackLoading": "Updating summary...", "updateFeedbackLoading": "Updating summary...",
"updateFeedbackError": "Failed to update summary", "updateFeedbackError": "Failed to update summary",