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 { ConnectedOnlineMethodName } from '@/lib/types/connected-online';
|
||||||
import { ExternalApi } from '@/lib/types/external';
|
import { ExternalApi } from '@/lib/types/external';
|
||||||
import { MedipostAction } from '@/lib/types/medipost';
|
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';
|
import { getSupabaseServerClient } from '@/packages/supabase/src/clients/server-client';
|
||||||
|
|
||||||
export default async function logRequestResult(
|
export default async function logRequestResult(
|
||||||
@@ -45,7 +46,7 @@ export async function logMedipostDispatch({
|
|||||||
isMedipostError: boolean;
|
isMedipostError: boolean;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
}) {
|
}) {
|
||||||
const { error } = await getSupabaseServerClient()
|
const { error } = await getSupabaseServerAdminClient()
|
||||||
.schema('audit')
|
.schema('audit')
|
||||||
.from('medipost_dispatch')
|
.from('medipost_dispatch')
|
||||||
.insert({
|
.insert({
|
||||||
@@ -59,3 +60,12 @@ export async function logMedipostDispatch({
|
|||||||
throw new Error('Failed to insert log entry, error: ' + error.message);
|
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 {
|
try {
|
||||||
await sendPrivateMessage(orderXml);
|
await sendPrivateMessage(orderXml);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
const isMedipostError = e instanceof MedipostValidationError;
|
||||||
await logMedipostDispatch({
|
await logMedipostDispatch({
|
||||||
medusaOrderId,
|
medusaOrderId,
|
||||||
isSuccess: false,
|
isSuccess: false,
|
||||||
isMedipostError: e instanceof MedipostValidationError,
|
isMedipostError,
|
||||||
errorMessage: e instanceof MedipostValidationError ? e.response : undefined,
|
errorMessage: isMedipostError ? e.response : undefined,
|
||||||
});
|
});
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,10 @@ export async function getOrder({
|
|||||||
throw new Error('Either medusaOrderId or orderId must be provided');
|
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;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2003,6 +2003,21 @@ export type Database = {
|
|||||||
}
|
}
|
||||||
Returns: Json
|
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: {
|
Enums: {
|
||||||
analysis_feedback_status: "STARTED" | "DRAFT" | "COMPLETED"
|
analysis_feedback_status: "STARTED" | "DRAFT" | "COMPLETED"
|
||||||
|
|||||||
@@ -5,8 +5,32 @@ CREATE TABLE "audit"."medipost_dispatch" (
|
|||||||
"is_success" boolean not null,
|
"is_success" boolean not null,
|
||||||
"error_message" text,
|
"error_message" text,
|
||||||
"created_at" timestamp with time zone not null default now(),
|
"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;
|
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