fix(stock): 7-day heartbeat write bypasses dedup for stale observations

upsertStockObservation dedup guard was preventing writes for unchanged
stock data (e.g. ATGBICS all-OOS for 55d), causing v_scraper_health to
mark sources as dead even when scrapers run normally. Skip dedup when
last observation is >7 days old so health view stays current.
This commit is contained in:
root 2026-07-07 11:39:38 +00:00
parent 86d1531d52
commit 73ad10f1a6

View File

@ -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 =