feat(MED-131): handle analysis order

This commit is contained in:
2025-08-04 11:53:04 +03:00
parent 08950896e5
commit 91f6dd11be
10 changed files with 310 additions and 140 deletions

View File

@@ -2,7 +2,7 @@ import { cache } from 'react';
import { AdminAccountPage } from '@kit/admin/components/admin-account-page'; import { AdminAccountPage } from '@kit/admin/components/admin-account-page';
import { AdminGuard } from '@kit/admin/components/admin-guard'; import { AdminGuard } from '@kit/admin/components/admin-guard';
import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { getAccount } from '~/lib/services/account.service';
interface Params { interface Params {
params: Promise<{ params: Promise<{
@@ -28,21 +28,4 @@ async function AccountPage(props: Params) {
export default AdminGuard(AccountPage); export default AdminGuard(AccountPage);
const loadAccount = cache(accountLoader); const loadAccount = cache(getAccount);
async function accountLoader(id: string) {
const client = getSupabaseServerClient();
const { data, error } = await client
.schema('medreport')
.from('accounts')
.select('*, memberships: accounts_memberships (*)')
.eq('id', id)
.single();
if (error) {
throw error;
}
return data;
}

View File

@@ -0,0 +1,51 @@
import { retrieveOrder } from "@lib/data";
import { NextRequest, NextResponse } from "next/server";
import { getAccountAdmin } from "~/lib/services/account.service";
import { composeOrderXML, sendPrivateMessage } from "~/lib/services/medipost.service";
import { getOrder, updateOrder } from "~/lib/services/order.service";
interface MedipostCreateRequest {
medusaOrderId: string;
}
export const POST = async (request: NextRequest) => {
const { medusaOrderId } = (await request.json()) as MedipostCreateRequest;
const medusaOrder = await retrieveOrder(medusaOrderId)
const medreportOrder = await getOrder({ medusaOrderId });
const account = await getAccountAdmin({ primaryOwnerUserId: medreportOrder.user_id });
const ANALYSIS_ELEMENT_HANDLE_PREFIX = 'analysis-element-';
const orderedAnalysisElementsIds = (medusaOrder?.items ?? [])
.filter((item) => item.product?.handle?.startsWith(ANALYSIS_ELEMENT_HANDLE_PREFIX))
.map((item) => {
const id = Number(item.product?.handle?.replace(ANALYSIS_ELEMENT_HANDLE_PREFIX, ''));
if (Number.isNaN(id)) {
return null;
}
return id;
})
.filter(Boolean) as number[];
const orderXml = await composeOrderXML({
person: {
idCode: account.personal_code!,
firstName: account.name ?? '',
lastName: account.last_name ?? '',
phone: account.phone ?? '',
},
orderedAnalysisElementsIds,
orderedAnalysesIds: [],
orderId: medusaOrderId,
orderCreatedAt: new Date(medreportOrder.created_at),
comment: '',
});
await sendPrivateMessage(orderXml);
await updateOrder({
orderId: medreportOrder.id,
orderStatus: 'PROCESSING',
});
return NextResponse.json({ orderXml });
};

View File

@@ -0,0 +1,41 @@
import { getSupabaseServerClient } from "@kit/supabase/server-client";
import { getSupabaseServerAdminClient } from "@kit/supabase/server-admin-client";
import type { Tables } from "@/packages/supabase/src/database.types";
type Account = Tables<{ schema: 'medreport' }, 'accounts'>;
type Membership = Tables<{ schema: 'medreport' }, 'accounts_memberships'>;
export type AccountWithMemberships = Account & { memberships: Membership[] }
export async function getAccount(id: string): Promise<AccountWithMemberships> {
const { data } = await getSupabaseServerClient()
.schema('medreport')
.from('accounts')
.select('*, memberships: accounts_memberships (*)')
.eq('id', id)
.single()
.throwOnError();
return data as unknown as AccountWithMemberships;
}
export async function getAccountAdmin({
primaryOwnerUserId,
}: {
primaryOwnerUserId: string;
}): Promise<AccountWithMemberships> {
const query = getSupabaseServerAdminClient()
.schema('medreport')
.from('accounts')
.select('*, memberships: accounts_memberships (*)')
if (primaryOwnerUserId) {
query.eq('primary_owner_user_id', primaryOwnerUserId);
} else {
throw new Error('primaryOwnerUserId is required');
}
const { data } = await query.single().throwOnError();
return data as unknown as AccountWithMemberships;
}

View File

@@ -1,6 +1,13 @@
import type { Tables } from '@/packages/supabase/src/database.types';
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client'; import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
import type { IUuringElement } from "./medipost.types"; import type { IUuringElement } from "./medipost.types";
type AnalysesWithGroupsAndElements = ({
analysis_elements: Tables<{ schema: 'medreport' }, 'analysis_elements'> & {
analysis_groups: Tables<{ schema: 'medreport' }, 'analysis_groups'>;
};
} & Tables<{ schema: 'medreport' }, 'analyses'>)[];
export const createAnalysis = async ( export const createAnalysis = async (
analysis: IUuringElement, analysis: IUuringElement,
insertedAnalysisElementId: number, insertedAnalysisElementId: number,
@@ -97,3 +104,13 @@ export const createMedusaSyncSuccessEntry = async () => {
status: 'SUCCESS', status: 'SUCCESS',
}); });
} }
export async function getAnalyses({ ids }: { ids: number[] }): Promise<AnalysesWithGroupsAndElements> {
const { data } = await getSupabaseServerAdminClient()
.schema('medreport')
.from('analyses')
.select(`*, analysis_elements(*, analysis_groups(*))`)
.in('id', ids);
return data as unknown as AnalysesWithGroupsAndElements;
}

View File

@@ -7,9 +7,13 @@ export type AnalysisElement = Tables<{ schema: 'medreport' }, 'analysis_elements
analysis_groups: Tables<{ schema: 'medreport' }, 'analysis_groups'>; analysis_groups: Tables<{ schema: 'medreport' }, 'analysis_groups'>;
}; };
export async function getAnalysisElements({ originalIds }: { export async function getAnalysisElements({
originalIds?: string[] originalIds,
} = {}) { ids,
}: {
originalIds?: string[];
ids?: number[];
}): Promise<AnalysisElement[]> {
const query = getSupabaseServerClient() const query = getSupabaseServerClient()
.schema('medreport') .schema('medreport')
.from('analysis_elements') .from('analysis_elements')
@@ -20,6 +24,10 @@ export async function getAnalysisElements({ originalIds }: {
query.in('analysis_id_original', [...new Set(originalIds)]); query.in('analysis_id_original', [...new Set(originalIds)]);
} }
if (Array.isArray(ids)) {
query.in('id', ids);
}
const { data: analysisElements } = await query; const { data: analysisElements } = await query;
return analysisElements ?? []; return analysisElements ?? [];

View File

@@ -35,6 +35,10 @@ import { uniqBy } from 'lodash';
import { Tables } from '@kit/supabase/database'; import { Tables } from '@kit/supabase/database';
import { createAnalysisGroup } from './analysis-group.service'; import { createAnalysisGroup } from './analysis-group.service';
import { getSupabaseServerAdminClient } from '@/packages/supabase/src/clients/server-admin-client';
import { getOrder } from './order.service';
import { getAnalysisElements } from './analysis-element.service';
import { getAnalyses } from './analyses.service';
const BASE_URL = process.env.MEDIPOST_URL!; const BASE_URL = process.env.MEDIPOST_URL!;
const USER = process.env.MEDIPOST_USER!; const USER = process.env.MEDIPOST_USER!;
@@ -85,7 +89,7 @@ export async function getLatestPublicMessageListItem() {
throw new Error('Failed to get public message list'); throw new Error('Failed to get public message list');
} }
return getLatestMessage(data?.messages); return getLatestMessage({ messages: data?.messages });
} }
export async function getPublicMessage(messageId: string) { export async function getPublicMessage(messageId: string) {
@@ -104,12 +108,12 @@ export async function getPublicMessage(messageId: string) {
return parseXML(data) as MedipostPublicMessageResponse; return parseXML(data) as MedipostPublicMessageResponse;
} }
export async function sendPrivateMessage(messageXml: string, receiver: string) { export async function sendPrivateMessage(messageXml: string) {
const body = new FormData(); const body = new FormData();
body.append('Action', MedipostAction.SendPrivateMessage); body.append('Action', MedipostAction.SendPrivateMessage);
body.append('User', USER); body.append('User', USER);
body.append('Password', PASSWORD); body.append('Password', PASSWORD);
body.append('Receiver', receiver); body.append('Receiver', RECIPIENT);
body.append('MessageType', 'Tellimus'); body.append('MessageType', 'Tellimus');
body.append( body.append(
'Message', 'Message',
@@ -123,7 +127,11 @@ export async function sendPrivateMessage(messageXml: string, receiver: string) {
await validateMedipostResponse(data); await validateMedipostResponse(data);
} }
export async function getLatestPrivateMessageListItem() { export async function getLatestPrivateMessageListItem({
excludedMessageIds,
}: {
excludedMessageIds: string[];
}) {
const { data } = await axios.get<GetMessageListResponse>(BASE_URL, { const { data } = await axios.get<GetMessageListResponse>(BASE_URL, {
params: { params: {
Action: MedipostAction.GetPrivateMessageList, Action: MedipostAction.GetPrivateMessageList,
@@ -136,7 +144,7 @@ export async function getLatestPrivateMessageListItem() {
throw new Error('Failed to get private message list'); throw new Error('Failed to get private message list');
} }
return getLatestMessage(data?.messages); return getLatestMessage({ messages: data?.messages, excludedMessageIds });
} }
export async function getPrivateMessage(messageId: string) { export async function getPrivateMessage(messageId: string) {
@@ -172,19 +180,30 @@ export async function deletePrivateMessage(messageId: string) {
} }
} }
export async function readPrivateMessageResponse() { export async function readPrivateMessageResponse({
excludedMessageIds,
}: {
excludedMessageIds: string[];
}) {
let messageIdErrored: string | null = null;
try { try {
const privateMessage = await getLatestPrivateMessageListItem(); const privateMessage = await getLatestPrivateMessageListItem({ excludedMessageIds });
if (!privateMessage) { if (!privateMessage) {
return null; throw new Error(`No private message found`);
} }
messageIdErrored = privateMessage.messageId;
const privateMessageContent = await getPrivateMessage( const privateMessageContent = await getPrivateMessage(
privateMessage.messageId, privateMessage.messageId,
); );
const messageResponse = privateMessageContent?.Saadetis?.Vastus;
const status = await syncPrivateMessage(privateMessageContent); if (!messageResponse) {
throw new Error(`Invalid data in private message response`);
}
const status = await syncPrivateMessage({ messageResponse });
if (status === 'COMPLETED') { if (status === 'COMPLETED') {
await deletePrivateMessage(privateMessage.messageId); await deletePrivateMessage(privateMessage.messageId);
@@ -192,6 +211,8 @@ export async function readPrivateMessageResponse() {
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
return { messageIdErrored };
} }
async function saveAnalysisGroup( async function saveAnalysisGroup(
@@ -366,63 +387,28 @@ export async function syncPublicMessage(
} }
} }
export async function composeOrderXML( export async function composeOrderXML({
person,
orderedAnalysisElementsIds,
orderedAnalysesIds,
orderId,
orderCreatedAt,
comment,
}: {
person: { person: {
idCode: string, idCode: string;
firstName: string, firstName: string;
lastName: string, lastName: string;
phone: string, phone: string;
},
comment?: string,
) {
const supabase = createCustomClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
{
auth: {
persistSession: false,
autoRefreshToken: false,
detectSessionInUrl: false,
},
},
);
// TODO remove dummy when actual implemetation is present
const orderedElements = [1, 75];
const orderedAnalyses = [10, 11, 100];
const createdAnalysisOrder = {
id: 4,
user_id: 'currentUser.user?.id',
analysis_element_ids: orderedElements,
analysis_ids: orderedAnalyses,
status: AnalysisOrderStatus[1],
created_at: new Date(),
};
const { data: analysisElements } = (await supabase
.schema('medreport')
.from('analysis_elements')
.select(`*, analysis_groups(*)`)
.in('id', orderedElements)) as {
data: ({
analysis_groups: Tables<{ schema: 'medreport' }, 'analysis_groups'>;
} & Tables<{ schema: 'medreport' }, 'analysis_elements'>)[];
};
const { data: analyses } = (await supabase
.schema('medreport')
.from('analyses')
.select(`*, analysis_elements(*, analysis_groups(*))`)
.in('id', orderedAnalyses)) as {
data: ({
analysis_elements: Tables<
{ schema: 'medreport' },
'analysis_elements'
> & {
analysis_groups: Tables<{ schema: 'medreport' }, 'analysis_groups'>;
};
} & Tables<{ schema: 'medreport' }, 'analyses'>)[];
}; };
orderedAnalysisElementsIds: number[];
orderedAnalysesIds: number[];
orderId: string;
orderCreatedAt: Date;
comment?: string;
}) {
const analysisElements = await getAnalysisElements({ ids: orderedAnalysisElementsIds });
const analyses = await getAnalyses({ ids: orderedAnalysesIds });
const analysisGroups: Tables<{ schema: 'medreport' }, 'analysis_groups'>[] = const analysisGroups: Tables<{ schema: 'medreport' }, 'analysis_groups'>[] =
uniqBy( uniqBy(
@@ -492,12 +478,11 @@ export async function composeOrderXML(
analysisSection.push(groupXml); analysisSection.push(groupXml);
} }
// TODO get actual data when order creation is implemented
return `<?xml version="1.0" encoding="UTF-8"?> return `<?xml version="1.0" encoding="UTF-8"?>
<Saadetis xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TellimusLOINC.xsd"> <Saadetis xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TellimusLOINC.xsd">
${getPais(process.env.MEDIPOST_USER!, process.env.MEDIPOST_RECIPIENT!, createdAnalysisOrder.created_at, createdAnalysisOrder.id)} ${getPais(USER, RECIPIENT, orderCreatedAt, orderId)}
<Tellimus cito="EI"> <Tellimus cito="EI">
<ValisTellimuseId>${createdAnalysisOrder.id}</ValisTellimuseId> <ValisTellimuseId>${orderId}</ValisTellimuseId>
<!--<TellijaAsutus>--> <!--<TellijaAsutus>-->
${getClientInstitution()} ${getClientInstitution()}
<!--<TeostajaAsutus>--> <!--<TeostajaAsutus>-->
@@ -513,48 +498,48 @@ export async function composeOrderXML(
</Saadetis>`; </Saadetis>`;
} }
function getLatestMessage(messages?: Message[]) { function getLatestMessage({
messages,
excludedMessageIds,
}: {
messages?: Message[];
excludedMessageIds?: string[];
}) {
if (!messages?.length) { if (!messages?.length) {
return null; return null;
} }
return messages.reduce((prev, current) => const filtered = messages.filter(({ messageId }) => !excludedMessageIds?.includes(messageId));
if (!filtered.length) {
return null;
}
return filtered.reduce((prev, current) =>
Number(prev.messageId) > Number(current.messageId) ? prev : current, Number(prev.messageId) > Number(current.messageId) ? prev : current,
{ messageId: '' } as Message,
); );
} }
export async function syncPrivateMessage( export async function syncPrivateMessage({
parsedMessage?: MedipostOrderResponse, messageResponse,
) { }: {
const supabase = createCustomClient( messageResponse: MedipostOrderResponse['Saadetis']['Vastus'];
process.env.NEXT_PUBLIC_SUPABASE_URL!, }) {
process.env.SUPABASE_SERVICE_ROLE_KEY!, const supabase = getSupabaseServerAdminClient()
{
auth: {
persistSession: false,
autoRefreshToken: false,
detectSessionInUrl: false,
},
},
);
const response = parsedMessage?.Saadetis?.Vastus; const status = messageResponse.TellimuseOlek;
const order = await getOrder({ medusaOrderId: messageResponse.ValisTellimuseId });
if (!response) {
throw new Error(`Invalid data in private message response`);
}
const status = response.TellimuseOlek;
const { data: analysisOrder, error: analysisOrderError } = await supabase const { data: analysisOrder, error: analysisOrderError } = await supabase
.schema('medreport') .schema('medreport')
.from('analysis_orders') .from('analysis_orders')
.select('user_id') .select('user_id')
.eq('id', response.ValisTellimuseId); .eq('id', order.id);
if (analysisOrderError || !analysisOrder?.[0]?.user_id) { if (analysisOrderError || !analysisOrder?.[0]?.user_id) {
throw new Error( throw new Error(
`Could not find analysis order with id ${response.ValisTellimuseId}`, `Could not find analysis order with id ${messageResponse.ValisTellimuseId}`,
); );
} }
@@ -563,8 +548,8 @@ export async function syncPrivateMessage(
.from('analysis_responses') .from('analysis_responses')
.upsert( .upsert(
{ {
analysis_order_id: response.ValisTellimuseId, analysis_order_id: order.id,
order_number: response.TellimuseNumber, order_number: messageResponse.TellimuseNumber,
order_status: AnalysisOrderStatus[status], order_status: AnalysisOrderStatus[status],
user_id: analysisOrder[0].user_id, user_id: analysisOrder[0].user_id,
}, },
@@ -574,10 +559,10 @@ export async function syncPrivateMessage(
if (error || !analysisResponse?.[0]?.id) { if (error || !analysisResponse?.[0]?.id) {
throw new Error( throw new Error(
`Failed to insert or update analysis order response (external id: ${response?.TellimuseNumber})`, `Failed to insert or update analysis order response (external id: ${messageResponse?.TellimuseNumber})`,
); );
} }
const analysisGroups = toArray(response.UuringuGrupp); const analysisGroups = toArray(messageResponse.UuringuGrupp);
const responses: Omit< const responses: Omit<
Tables<{ schema: 'medreport' }, 'analysis_response_elements'>, Tables<{ schema: 'medreport' }, 'analysis_response_elements'>,

View File

@@ -0,0 +1,88 @@
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
import type { Tables } from '@kit/supabase/database';
import { getSupabaseServerClient } from '@kit/supabase/server-client';
import type { StoreOrder } from '@medusajs/types';
export async function createOrder({
medusaOrder,
}: {
medusaOrder: StoreOrder;
}) {
const supabase = getSupabaseServerClient();
const analysisElementIds = medusaOrder.items
?.filter(({ product }) => product?.handle?.startsWith('analysis-element-'))
.map(({ product }) => Number(product?.handle.replace('analysis-element-', '')))
.filter((id) => !Number.isNaN(id)) as number[];
const { data: { user } } = await supabase.auth.getUser();
if (!user) {
throw new Error('User not found');
}
const orderResult = await supabase.schema('medreport')
.from('analysis_orders')
.insert({
analysis_element_ids: analysisElementIds,
analysis_ids: [],
status: 'QUEUED',
user_id: user.id,
medusa_order_id: medusaOrder.id,
})
.select('id')
.single()
.throwOnError();
if (orderResult.error || !orderResult.data?.id) {
throw new Error(`Failed to create order, message=${orderResult.error}, data=${JSON.stringify(orderResult)}`);
}
}
export async function updateOrder({
orderId,
orderStatus,
}: {
orderId: number;
orderStatus: Tables<{ schema: 'medreport' }, 'analysis_orders'>['status'];
}) {
const { error } = await getSupabaseServerClient()
.schema('medreport')
.from('analysis_orders')
.update({
status: orderStatus,
})
.eq('id', orderId)
.throwOnError();
if (error) {
throw new Error(`Failed to update order, message=${error}, data=${JSON.stringify(error)}`);
}
}
export async function getOrder({
medusaOrderId,
}: {
medusaOrderId: string;
}) {
const query = getSupabaseServerAdminClient()
.schema('medreport')
.from('analysis_orders')
.select('*')
.eq('medusa_order_id', medusaOrderId)
const { data: order } = await query.single().throwOnError();
return order;
}
export async function getOrders({
orderStatus,
}: {
orderStatus?: Tables<{ schema: 'medreport' }, 'analysis_orders'>['status'];
} = {}) {
const query = getSupabaseServerClient()
.schema('medreport')
.from('analysis_orders')
.select('*')
if (orderStatus) {
query.eq('status', orderStatus);
}
const orders = await query.throwOnError();
return orders.data;
}

View File

@@ -102,7 +102,7 @@ export const getPatient = ({
<EesNimi>${firstName}</EesNimi> <EesNimi>${firstName}</EesNimi>
<SynniAeg>${format(isikukood.getBirthday(), DATE_FORMAT)}</SynniAeg> <SynniAeg>${format(isikukood.getBirthday(), DATE_FORMAT)}</SynniAeg>
<SuguOID>1.3.6.1.4.1.28284.6.2.3.16.2</SuguOID> <SuguOID>1.3.6.1.4.1.28284.6.2.3.16.2</SuguOID>
<Sugu>${isikukood.getGender()}</Sugu> <Sugu>${isikukood.getGender() === Gender.MALE ? 'M' : 'N'}</Sugu>
</Patsient>`; </Patsient>`;
}; };

View File

@@ -1,3 +1,12 @@
export interface IMedipostResponseXMLBase {
'?xml': {
'@_version': string;
'@_encoding': string;
'@_standalone': 'yes' | 'no';
};
ANSWER?: { CODE: number };
}
export type Message = { export type Message = {
messageId: string; messageId: string;
messageType: string; messageType: string;
@@ -120,13 +129,7 @@ export type Teostaja = {
Sisendparameeter?: Sisendparameeter | Sisendparameeter[]; //0...n Sisendparameeter?: Sisendparameeter | Sisendparameeter[]; //0...n
}; };
export type MedipostPublicMessageResponse = { export type MedipostPublicMessageResponse = IMedipostResponseXMLBase & {
'?xml': {
'@_version': string;
'@_encoding': string;
'@_standalone'?: 'yes' | 'no';
};
ANSWER?: { CODE: number };
Saadetis?: { Saadetis?: {
Pais: { Pais: {
Pakett: { '#text': 'SL' | 'OL' | 'AL' | 'ME' }; // SL - Teenused, OL - Tellimus (meie poolt saadetav saatekiri), AL - Vastus (saatekirja vastus), ME - Teade Pakett: { '#text': 'SL' | 'OL' | 'AL' | 'ME' }; // SL - Teenused, OL - Tellimus (meie poolt saadetav saatekiri), AL - Vastus (saatekirja vastus), ME - Teade
@@ -186,13 +189,7 @@ export type ResponseUuringuGrupp = {
}; };
// type for UuringuGrupp is correct, but some of this is generated by an LLM and should be checked if data in use // type for UuringuGrupp is correct, but some of this is generated by an LLM and should be checked if data in use
export type MedipostOrderResponse = { export type MedipostOrderResponse = IMedipostResponseXMLBase & {
'?xml': {
'@_version': string;
'@_encoding': string;
'@_standalone': 'yes' | 'no';
};
ANSWER?: { CODE: number };
Saadetis: { Saadetis: {
Pais: { Pais: {
Pakett: { Pakett: {
@@ -206,7 +203,7 @@ export type MedipostOrderResponse = {
Email: string; Email: string;
}; };
Vastus: { Vastus: {
ValisTellimuseId: number; ValisTellimuseId: string;
Asutus: { Asutus: {
'@_tyyp': string; // TEOSTAJA '@_tyyp': string; // TEOSTAJA
'@_jarjenumber': string; '@_jarjenumber': string;
@@ -252,16 +249,16 @@ export type MedipostOrderResponse = {
}; };
}; };
export const AnalysisOrderStatus: Record<number, string> = { export const AnalysisOrderStatus = {
1: 'QUEUED', 1: 'QUEUED',
2: 'ON_HOLD', 2: 'ON_HOLD',
3: 'PROCESSING', 3: 'PROCESSING',
4: 'COMPLETED', 4: 'COMPLETED',
5: 'REJECTED', 5: 'REJECTED',
6: 'CANCELLED', 6: 'CANCELLED',
}; } as const;
export const NormStatus: Record<number, string> = { export const NormStatus: Record<number, string> = {
1: 'NORMAL', 1: 'NORMAL',
2: 'WARNING', 2: 'WARNING',
3: 'REQUIRES_ATTENTION', 3: 'REQUIRES_ATTENTION',
}; } as const;

View File

@@ -87,8 +87,8 @@ export async function getOrSetCart(countryCode: string) {
return cart; return cart;
} }
export async function updateCart(data: HttpTypes.StoreUpdateCart) { export async function updateCart({ id, ...data }: HttpTypes.StoreUpdateCart & { id?: string }) {
const cartId = await getCartId(); const cartId = id || (await getCartId());
if (!cartId) { if (!cartId) {
throw new Error( throw new Error(