feat(MED-85): update dispatch order to medipost retry
This commit is contained in:
40
app/api/job/medipost-retry-dispatch/route.ts
Normal file
40
app/api/job/medipost-retry-dispatch/route.ts
Normal 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 });
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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';
|
||||
Reference in New Issue
Block a user