/** Hours after which a stored price is considered stale for live refresh. */ export const PRICE_STALE_HOURS = 24; /** * Resolve the unit price for a owned card row (foil-aware). * MTG: current_price = nonfoil USD, market_price = foil USD (Scryfall mapping). * * @param {{ currentPrice?: number | null, marketPrice?: number | null, isFoil?: boolean }} params * @returns {number | null} */ export function resolveUnitPrice({ currentPrice, marketPrice, isFoil = false }) { const current = currentPrice != null ? Number(currentPrice) : null; const market = marketPrice != null ? Number(marketPrice) : null; if (isFoil) { return market ?? current ?? null; } return current ?? market ?? null; } /** * @param {Date | string | null | undefined} pricesUpdatedAt * @returns {boolean} */ export function isPriceStale(pricesUpdatedAt) { if (!pricesUpdatedAt) return true; const updated = pricesUpdatedAt instanceof Date ? pricesUpdatedAt : new Date(pricesUpdatedAt); if (Number.isNaN(updated.getTime())) return true; const ageMs = Date.now() - updated.getTime(); return ageMs > PRICE_STALE_HOURS * 60 * 60 * 1000; }