feat: update Keepa and Stalker functionalities with enhanced price extraction logic and test cases

This commit is contained in:
Victor Noguera
2026-05-19 19:59:20 -04:00
parent 0552d183b3
commit 7bda3710ed
4 changed files with 30 additions and 24 deletions

View File

@@ -48,7 +48,7 @@ test("lookupKeepaUpcs returns found, not_found, and multiple_asins outcomes", as
current: [null, null, null, 1234], current: [null, null, null, 1234],
avg: [2500, null, null, 1400], avg: [2500, null, null, 1400],
}, },
csv: [[1, 2999]], csv: [[5000000, 2999, 5000100]],
}, },
{ {
asin: "B000MULTI01", asin: "B000MULTI01",
@@ -85,6 +85,7 @@ test("lookupKeepaUpcs returns found, not_found, and multiple_asins outcomes", as
expect(details.get("012345678901")?.status).toBe("found"); expect(details.get("012345678901")?.status).toBe("found");
expect(details.get("012345678901")?.asin).toBe("B000FOUND01"); expect(details.get("012345678901")?.asin).toBe("B000FOUND01");
expect(details.get("012345678901")?.keepaData?.currentPrice).toBe(29.99); expect(details.get("012345678901")?.keepaData?.currentPrice).toBe(29.99);
expect(details.get("012345678901")?.keepaData?.currentPrice).toBe(29.99);
expect(details.get("098765432109")?.status).toBe("multiple_asins"); expect(details.get("098765432109")?.status).toBe("multiple_asins");
expect(details.get("098765432109")?.candidateAsins).toEqual([ expect(details.get("098765432109")?.candidateAsins).toEqual([

View File

@@ -531,11 +531,14 @@ function computeAmazonBuyBoxSharePctFromHistory(
function extractLatestPositivePrice(series: unknown): number | null { function extractLatestPositivePrice(series: unknown): number | null {
if (!Array.isArray(series) || series.length < 2) return null; if (!Array.isArray(series) || series.length < 2) return null;
const last = series[series.length - 1]; for (let i = series.length - 1; i >= 1; i--) {
if (typeof last !== "number" || !Number.isFinite(last) || last <= 0) { if (i % 2 === 0) continue;
return null; const value = series[i];
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
return value / 100;
}
} }
return last / 100; return null;
} }
function pickKeepaNumber(...values: unknown[]): number | null { function pickKeepaNumber(...values: unknown[]): number | null {
@@ -552,12 +555,10 @@ function extractCurrentPrice(csv: number[][] | undefined): number | null {
if (!csv) return null; if (!csv) return null;
// csv[0] = Amazon price history, csv[1] = Marketplace new price history // csv[0] = Amazon price history, csv[1] = Marketplace new price history
// Each is [time, price, time, price, ...] — last value is most recent // Each is [time, price, time, price, ...]. Only odd indexes are prices.
for (const series of [csv[0], csv[1]]) { for (const series of [csv[0], csv[1]]) {
if (series && series.length >= 2) { const latestPrice = extractLatestPositivePrice(series);
const lastPrice = series[series.length - 1]!; if (latestPrice != null) return latestPrice;
if (lastPrice > 0) return lastPrice / 100;
}
} }
return null; return null;
} }

View File

@@ -89,7 +89,7 @@ test("sellability checks matched seller inventory, not the source ASIN", async (
current: [null, null, null, 12345, null, null, null, null, null, null, null, 7], current: [null, null, null, 12345, null, null, null, null, null, null, null, 7],
avg: [2500], avg: [2500],
}, },
csv: [[0, 1999]], csv: [[5000000, 1999, 5000100]],
}, },
], ],
tokensLeft: 10, tokensLeft: 10,

View File

@@ -1355,7 +1355,11 @@ function extractCurrentPrice(csv: unknown): number | null {
function extractLatestPositiveKeepaPrice(history: unknown): number | null { function extractLatestPositiveKeepaPrice(history: unknown): number | null {
if (!Array.isArray(history)) return null; if (!Array.isArray(history)) return null;
for (let i = history.length - 1; i >= 0; i--) {
// Keepa CSV histories are [time, value, time, value, ...]. Only odd indexes
// are prices; even indexes are Keepa timestamps and can look like huge prices.
for (let i = history.length - 1; i >= 1; i--) {
if (i % 2 === 0) continue;
const value = extractNumber(history[i]); const value = extractNumber(history[i]);
if (value != null && value > 0) return value / 100; if (value != null && value > 0) return value / 100;
} }