diff --git a/packages/scraper/src/utils/db.ts b/packages/scraper/src/utils/db.ts index d29b56f..903ca68 100644 --- a/packages/scraper/src/utils/db.ts +++ b/packages/scraper/src/utils/db.ts @@ -417,9 +417,11 @@ export async function upsertStockObservation(params: { return false; } - // Compare against the last observation to avoid duplicate writes + // Compare against the last observation to avoid duplicate writes. + // Bypass dedup if last observation is older than 7 days (heartbeat to keep health view alive). + const STOCK_REFRESH_DAYS = 7; const lastObs = await pool.query( - `SELECT warehouse_de_qty, warehouse_global_qty, backorder_qty, units_sold, quantity_available + `SELECT warehouse_de_qty, warehouse_global_qty, backorder_qty, units_sold, quantity_available, time FROM stock_observations WHERE transceiver_id = $1 AND source_vendor_id = $2 ORDER BY time DESC LIMIT 1`, @@ -428,13 +430,17 @@ export async function upsertStockObservation(params: { if (lastObs.rows.length > 0) { const r = lastObs.rows[0]; - const unchanged = - (r.warehouse_de_qty ?? null) === (params.warehouseDeQty ?? null) && - (r.warehouse_global_qty ?? null) === (params.warehouseGlobalQty ?? null) && - (r.backorder_qty ?? null) === (params.backorderQty ?? null) && - (r.units_sold ?? null) === (params.unitsSold ?? null) && - (r.quantity_available ?? null) === (params.quantityAvailable ?? null); - if (unchanged) return false; + const ageMs = Date.now() - new Date(r.time).getTime(); + const ageDays = ageMs / (1000 * 60 * 60 * 24); + if (ageDays < STOCK_REFRESH_DAYS) { + const unchanged = + (r.warehouse_de_qty ?? null) === (params.warehouseDeQty ?? null) && + (r.warehouse_global_qty ?? null) === (params.warehouseGlobalQty ?? null) && + (r.backorder_qty ?? null) === (params.backorderQty ?? null) && + (r.units_sold ?? null) === (params.unitsSold ?? null) && + (r.quantity_available ?? null) === (params.quantityAvailable ?? null); + if (unchanged) return false; + } } const inStock =