feat(MED-85): update dispatch order to medipost retry

This commit is contained in:
2025-08-27 08:04:37 +03:00
parent da8b5aa59f
commit 2b2a0b8bc4
7 changed files with 141 additions and 6 deletions

View File

@@ -0,0 +1,40 @@
import { NextRequest, NextResponse } from "next/server";
import loadEnv from "../handler/load-env";
import validateApiKey from "../handler/validate-api-key";
import { getOrderedAnalysisElementsIds, sendOrderToMedipost } from "~/lib/services/medipost.service";
import { retrieveOrder } from "@lib/data/orders";
import { getMedipostDispatchTries } from "~/lib/services/audit.service";
export const POST = async (request: NextRequest) => {
loadEnv();
const { medusaOrderId } = await request.json();
try {
validateApiKey(request);
} catch (e) {
return NextResponse.json({}, { status: 401, statusText: 'Unauthorized' });
}
const tries = await getMedipostDispatchTries(medusaOrderId);
if (tries >= 3) {
return NextResponse.json({
message: 'Order has been retried too many times',
}, { status: 400 });
}
try {
const medusaOrder = await retrieveOrder(medusaOrderId);
const orderedAnalysisElements = await getOrderedAnalysisElementsIds({ medusaOrder });
await sendOrderToMedipost({ medusaOrderId, orderedAnalysisElements });
console.info("Successfully sent order to medipost");
return NextResponse.json({
message: 'Successfully sent order to medipost',
}, { status: 200 });
} catch (e) {
console.error("Error sending order to medipost", e);
return NextResponse.json({
message: 'Failed to send order to medipost',
}, { status: 500 });
}
};

View File

@@ -4,6 +4,7 @@ import { RequestStatus } from '@/lib/types/audit';
import { ConnectedOnlineMethodName } from '@/lib/types/connected-online';
import { ExternalApi } from '@/lib/types/external';
import { MedipostAction } from '@/lib/types/medipost';
import { getSupabaseServerAdminClient } from '@/packages/supabase/src/clients/server-admin-client';
import { getSupabaseServerClient } from '@/packages/supabase/src/clients/server-client';
export default async function logRequestResult(
@@ -45,7 +46,7 @@ export async function logMedipostDispatch({
isMedipostError: boolean;
errorMessage?: string;
}) {
const { error } = await getSupabaseServerClient()
const { error } = await getSupabaseServerAdminClient()
.schema('audit')
.from('medipost_dispatch')
.insert({
@@ -59,3 +60,12 @@ export async function logMedipostDispatch({
throw new Error('Failed to insert log entry, error: ' + error.message);
}
}
export async function getMedipostDispatchTries(medusaOrderId: string) {
const { data } = await getSupabaseServerAdminClient()
.schema('medreport')
.rpc('get_medipost_dispatch_tries', { p_medusa_order_id: medusaOrderId })
.throwOnError();
return data;
}

View File

@@ -709,11 +709,12 @@ export async function sendOrderToMedipost({
try {
await sendPrivateMessage(orderXml);
} catch (e) {
const isMedipostError = e instanceof MedipostValidationError;
await logMedipostDispatch({
medusaOrderId,
isSuccess: false,
isMedipostError: e instanceof MedipostValidationError,
errorMessage: e instanceof MedipostValidationError ? e.response : undefined,
isMedipostError,
errorMessage: isMedipostError ? e.response : undefined,
});
throw e;
}

View File

@@ -99,7 +99,10 @@ export async function getOrder({
throw new Error('Either medusaOrderId or orderId must be provided');
}
const { data: order } = await query.single().throwOnError();
const { data: order, error } = await query.single();
if (error) {
throw new Error(`Failed to get order by medusaOrderId=${medusaOrderId} or orderId=${orderId}, message=${error.message}, data=${JSON.stringify(order)}`);
}
return order;
}

View File

@@ -2003,6 +2003,21 @@ export type Database = {
}
Returns: Json
}
medipost_retry_dispatch: {
Args: {
order_id: string
}
Returns: {
success: boolean
error: string | null
}
}
get_medipost_dispatch_tries: {
Args: {
p_medusa_order_id: string
}
Returns: number
}
}
Enums: {
analysis_feedback_status: "STARTED" | "DRAFT" | "COMPLETED"

View File

@@ -5,8 +5,32 @@ CREATE TABLE "audit"."medipost_dispatch" (
"is_success" boolean not null,
"error_message" text,
"created_at" timestamp with time zone not null default now(),
"changed_by" uuid not null
"changed_by" uuid default auth.uid()
);
grant usage on schema audit to service_role;
grant usage on schema audit to authenticated;
grant select, insert, update, delete on table audit.medipost_dispatch to authenticated;
grant usage on schema medreport to service_role;
alter table "audit"."medipost_dispatch" enable row level security;
create policy "service_role_select" on "audit"."medipost_dispatch" for select to service_role using (true);
create policy "service_role_insert" on "audit"."medipost_dispatch" for insert to service_role with check (true);
create policy "service_role_update" on "audit"."medipost_dispatch" for update to service_role using (true);
create policy "service_role_delete" on "audit"."medipost_dispatch" for delete to service_role using (true);
CREATE OR REPLACE FUNCTION medreport.get_medipost_dispatch_tries(p_medusa_order_id text)
returns integer
language plpgsql
security definer
as $function$
declare
tries integer;
begin
select count(*) from audit.medipost_dispatch m where m.medusa_order_id = p_medusa_order_id and m.created_at > now() - interval '1 day' and m.is_success = false into tries;
return tries;
end;
$function$;
grant execute on function medreport.get_medipost_dispatch_tries(text) to service_role;
grant select, insert, update, delete on table audit.medipost_dispatch to service_role;

View File

@@ -0,0 +1,42 @@
create extension if not exists pg_net;
create or replace function medreport.medipost_retry_dispatch(
order_id text
)
returns jsonb
language plpgsql
as $function$
declare
response_result record;
begin
select into response_result
net.http_post(
url := 'https://test.medreport.ee/api/job/medipost-retry-dispatch',
headers := jsonb_build_object(
'Content-Type', 'application/json',
'x-jobs-api-key', 'fd26ec26-70ed-11f0-9e95-431ac3b15a84'
),
body := jsonb_build_object(
'medusaOrderId', order_id
)::text
) as request_id;
return jsonb_build_object(
'success', true
);
exception
when others then
return jsonb_build_object(
'success', false
);
end;
$function$;
grant execute on function medreport.medipost_retry_dispatch(text) to service_role;
comment on function medreport.medipost_retry_dispatch(text) is
'Manually trigger a medipost retry dispatch for a specific order ID.
Parameters:
- order_id: The medusa order ID to retry dispatch for
Returns: JSONB with success status and request details';