import refreshTokenHelper from "../../../utils/refreshTokenHelper" import forceLogoutHelper from "../../../utils/forceLogoutHelper" import errorHandlingHelper from "../../../utils/errorHandlingHelper" import { resolveOrderSourceAmazonConnection, getItemOffers, getFeesEstimate, throttledBatch } from "../../../utils/amazonSpApi" // SIS — Buy Box + fees refresh for ONE page of rows at a time (never the // whole catalog eagerly: Product Pricing / Fees have no bulk equivalent and // are tightly rate-limited, ~1 req/sec). Body: { orderSourceId, items: [{ // sku, asin, price, fulfillmentChannel }] }. Fail-soft per row — one item's // SP-API error never aborts the batch or the request. const handleFunc = async (event: any, authToken: any = null) => { const token = authToken ?? await getTokenHelper(event) const body = await readBody(event) const orderSourceId = Number(body?.orderSourceId) const items: any[] = Array.isArray(body?.items) ? body.items : [] if (!orderSourceId) return { status: 400, message: 'orderSourceId is required' } if (items.length === 0) return { status: 200, results: [] } if (items.length > 100) return { status: 400, message: 'Too many items in one refresh batch (max 100) — refresh in smaller pages.' } const { marketplaceId, accessToken } = await resolveOrderSourceAmazonConnection(event, token, orderSourceId) const results = await throttledBatch(items, async (it: any) => { const sku = String(it.sku || '') const asin = String(it.asin || '') const price = Number(it.price) const isAmazonFulfilled = String(it.fulfillmentChannel || '').toUpperCase() === 'AFN' const [buyBox, fees] = await Promise.all([ asin ? getItemOffers(accessToken, asin, marketplaceId).catch((e: any) => ({ __error: e?.message || String(e) })) : Promise.resolve(null), (sku && Number.isFinite(price) && price > 0) ? getFeesEstimate(accessToken, sku, marketplaceId, price, isAmazonFulfilled).catch((e: any) => ({ __error: e?.message || String(e) })) : Promise.resolve(null) ]) return { sku, asin, buyBox: (buyBox && !(buyBox as any).__error) ? buyBox : null, buyBoxError: (buyBox as any)?.__error || null, fees: (fees && !(fees as any).__error) ? fees : null, feesError: (fees as any)?.__error || null } }) return { status: 200, results: results.map(r => r.error ? { sku: (r.item as any).sku, asin: (r.item as any).asin, buyBox: null, fees: null, error: r.error } : r.result) } } export default defineEventHandler(async (event) => { let data: any = {} try { data = await handleFunc(event) } catch (err: any) { try { let authToken: any = await refreshTokenHelper(event) data = await handleFunc(event, authToken) } catch (error: any) { data = errorHandlingHelper(err?.data ?? err, error?.data ?? error) forceLogoutHelper(event, data) } } return data })