diff --git a/assets/js/app.js b/assets/js/app.js index 862ad47..c40191b 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -4449,12 +4449,43 @@ function _urgencyToSpec(urgency, brand) { return brand || ''; } +// ===== BRING! PURCHASED BLOCKLIST ===== +// When an item disappears from Bring (user bought it), we block auto-re-add for 4h. +const _BRING_PURCHASED_TTL = 4 * 60 * 60 * 1000; // 4 hours + +function _getBringPurchasedBlocklist() { + try { + const raw = localStorage.getItem('_bringPurchasedBlocklist'); + const map = raw ? JSON.parse(raw) : {}; + const now = Date.now(); + // Prune expired entries + let changed = false; + for (const key of Object.keys(map)) { + if (now - map[key] > _BRING_PURCHASED_TTL) { delete map[key]; changed = true; } + } + if (changed) localStorage.setItem('_bringPurchasedBlocklist', JSON.stringify(map)); + return map; + } catch(e) { return {}; } +} + +function _markBringPurchased(names) { + const map = _getBringPurchasedBlocklist(); + const now = Date.now(); + for (const n of names) map[n.toLowerCase()] = now; + localStorage.setItem('_bringPurchasedBlocklist', JSON.stringify(map)); +} + +function _isBringPurchased(name) { + const map = _getBringPurchasedBlocklist(); + return Object.keys(map).some(k => _nameTokens(name)[0] === _nameTokens(k)[0] || k === name.toLowerCase()); +} + async function autoAddCriticalItems() { // Time-based guard: run at most once every 10 minutes (not session-based, so new critical items get added promptly) const lastRun = parseInt(localStorage.getItem('_autoAddedCriticalTs') || '0'); if (Date.now() - lastRun < 10 * 60 * 1000) return; localStorage.setItem('_autoAddedCriticalTs', String(Date.now())); - const critical = smartShoppingItems.filter(i => i.urgency === 'critical' && !i.on_bring); + const critical = smartShoppingItems.filter(i => i.urgency === 'critical' && !i.on_bring && !_isBringPurchased(i.name)); if (critical.length === 0) return; const itemsToAdd = critical.map(i => ({ name: i.name, specification: _urgencyToSpec(i.urgency, i.brand) })); try { @@ -4994,7 +5025,15 @@ async function loadShoppingList() { } shoppingListUUID = data.listUUID; - shoppingItems = data.purchase || []; + // Detect items removed from Bring since last load (= just purchased by user) + const prevNames = new Set((shoppingItems || []).map(i => i.name.toLowerCase())); + const newItems = data.purchase || []; + const newNames = new Set(newItems.map(i => i.name.toLowerCase())); + if (prevNames.size > 0) { + const removedNames = [...prevNames].filter(n => !newNames.has(n)); + if (removedNames.length) _markBringPurchased(removedNames); + } + shoppingItems = newItems; // Clean up shoppingPrices for items no longer on the list const currentKeys = new Set(shoppingItems.map(i => i.name.toLowerCase())); @@ -7937,8 +7976,8 @@ async function _backgroundBringSync() { }); if (!bringMatch) { - // Not on Bring — add if critical - if (si.urgency === 'critical') { + // Not on Bring — add if critical AND not recently purchased + if (si.urgency === 'critical' && !_isBringPurchased(si.name)) { toAdd.push({ name: si.name, specification: expectedSpec }); } } else { diff --git a/data/cron.log b/data/cron.log index 37c9d2a..89cd6e4 100644 --- a/data/cron.log +++ b/data/cron.log @@ -979,3 +979,498 @@ [2026-04-04 15:25:02] OK — 11 items cached [2026-04-04 15:30:02] OK — 11 items cached [2026-04-04 15:35:01] OK — 11 items cached +[2026-04-04 15:40:02] OK — 11 items cached +[2026-04-04 15:45:02] OK — 11 items cached +[2026-04-04 15:50:01] OK — 11 items cached +[2026-04-04 15:55:02] OK — 11 items cached +[2026-04-04 16:00:02] OK — 11 items cached +[2026-04-04 16:05:01] OK — 11 items cached +[2026-04-04 16:10:02] OK — 11 items cached +[2026-04-04 16:15:02] OK — 11 items cached +[2026-04-04 16:20:02] OK — 11 items cached +[2026-04-04 16:25:02] OK — 11 items cached +[2026-04-04 16:30:01] OK — 11 items cached +[2026-04-04 16:35:02] OK — 11 items cached +[2026-04-04 16:40:02] OK — 11 items cached +[2026-04-04 16:45:01] OK — 11 items cached +[2026-04-04 16:50:02] OK — 11 items cached +[2026-04-04 16:55:02] OK — 11 items cached +[2026-04-04 17:00:01] OK — 11 items cached +[2026-04-04 17:05:02] OK — 11 items cached +[2026-04-04 17:10:02] OK — 11 items cached +[2026-04-04 17:15:02] OK — 11 items cached +[2026-04-04 17:20:02] OK — 11 items cached +[2026-04-04 17:25:02] OK — 11 items cached +[2026-04-04 17:30:01] OK — 11 items cached +[2026-04-04 17:35:02] OK — 11 items cached +[2026-04-04 17:40:02] OK — 11 items cached +[2026-04-04 17:45:02] OK — 11 items cached +[2026-04-04 17:50:01] OK — 11 items cached +[2026-04-04 17:55:02] OK — 11 items cached +[2026-04-04 18:00:02] OK — 11 items cached +[2026-04-04 18:05:01] OK — 11 items cached +[2026-04-04 18:10:02] OK — 11 items cached +[2026-04-04 18:15:02] OK — 11 items cached +[2026-04-04 18:20:02] OK — 11 items cached +[2026-04-04 18:25:01] OK — 11 items cached +[2026-04-04 18:30:02] OK — 11 items cached +[2026-04-04 18:35:02] OK — 11 items cached +[2026-04-04 18:40:01] OK — 12 items cached +[2026-04-04 18:45:02] OK — 12 items cached +[2026-04-04 18:50:02] OK — 12 items cached +[2026-04-04 18:55:01] OK — 12 items cached +[2026-04-04 19:00:02] OK — 12 items cached +[2026-04-04 19:05:02] OK — 12 items cached +[2026-04-04 19:10:01] OK — 12 items cached +[2026-04-04 19:15:03] OK — 12 items cached +[2026-04-04 19:20:01] OK — 12 items cached +[2026-04-04 19:25:02] OK — 12 items cached +[2026-04-04 19:30:02] OK — 12 items cached +[2026-04-04 19:35:01] OK — 12 items cached +[2026-04-04 19:40:02] OK — 12 items cached +[2026-04-04 19:45:02] OK — 12 items cached +[2026-04-04 19:50:01] OK — 12 items cached +[2026-04-04 19:55:02] OK — 12 items cached +[2026-04-04 20:00:02] OK — 12 items cached +[2026-04-04 20:05:01] OK — 12 items cached +[2026-04-04 20:10:02] OK — 12 items cached +[2026-04-04 20:15:02] OK — 12 items cached +[2026-04-04 20:20:02] OK — 12 items cached +[2026-04-04 20:25:01] OK — 12 items cached +[2026-04-04 20:30:02] OK — 12 items cached +[2026-04-04 20:35:02] OK — 12 items cached +[2026-04-04 20:40:01] OK — 12 items cached +[2026-04-04 20:45:02] OK — 12 items cached +[2026-04-04 20:50:02] OK — 12 items cached +[2026-04-04 20:55:01] OK — 12 items cached +[2026-04-04 21:00:02] OK — 12 items cached +[2026-04-04 21:05:02] OK — 12 items cached +[2026-04-04 21:10:01] OK — 12 items cached +[2026-04-04 21:15:02] OK — 12 items cached +[2026-04-04 21:20:02] OK — 12 items cached +[2026-04-04 21:25:02] OK — 12 items cached +[2026-04-04 21:30:01] OK — 12 items cached +[2026-04-04 21:35:02] OK — 12 items cached +[2026-04-04 21:40:01] OK — 12 items cached +[2026-04-04 21:45:02] OK — 12 items cached +[2026-04-04 21:50:02] OK — 12 items cached +[2026-04-04 21:55:01] OK — 12 items cached +[2026-04-04 22:00:02] OK — 12 items cached +[2026-04-04 22:05:02] OK — 12 items cached +[2026-04-04 22:10:01] OK — 12 items cached +[2026-04-04 22:15:02] OK — 12 items cached +[2026-04-04 22:20:02] OK — 12 items cached +[2026-04-04 22:25:02] OK — 12 items cached +[2026-04-04 22:30:01] OK — 12 items cached +[2026-04-04 22:35:02] OK — 12 items cached +[2026-04-04 22:40:01] OK — 12 items cached +[2026-04-04 22:45:02] OK — 12 items cached +[2026-04-04 22:50:02] OK — 12 items cached +[2026-04-04 22:55:01] OK — 12 items cached +[2026-04-04 23:00:02] OK — 12 items cached +[2026-04-04 23:05:02] OK — 12 items cached +[2026-04-04 23:10:01] OK — 12 items cached +[2026-04-04 23:15:02] OK — 12 items cached +[2026-04-04 23:20:02] OK — 12 items cached +[2026-04-04 23:25:02] OK — 12 items cached +[2026-04-04 23:30:01] OK — 12 items cached +[2026-04-04 23:35:02] OK — 12 items cached +[2026-04-04 23:40:01] OK — 12 items cached +[2026-04-04 23:45:02] OK — 12 items cached +[2026-04-04 23:50:02] OK — 12 items cached +[2026-04-04 23:55:01] OK — 12 items cached +[2026-04-05 00:00:02] OK — 12 items cached +[2026-04-05 00:05:02] OK — 12 items cached +[2026-04-05 00:10:01] OK — 12 items cached +[2026-04-05 00:15:02] OK — 12 items cached +[2026-04-05 00:20:02] OK — 12 items cached +[2026-04-05 00:25:02] OK — 12 items cached +[2026-04-05 00:30:01] OK — 12 items cached +[2026-04-05 00:35:02] OK — 12 items cached +[2026-04-05 00:40:01] OK — 12 items cached +[2026-04-05 00:45:02] OK — 12 items cached +[2026-04-05 00:50:02] OK — 12 items cached +[2026-04-05 00:55:01] OK — 12 items cached +[2026-04-05 01:00:02] OK — 12 items cached +[2026-04-05 01:05:02] OK — 12 items cached +[2026-04-05 01:10:01] OK — 12 items cached +[2026-04-05 01:15:02] OK — 12 items cached +[2026-04-05 01:20:02] OK — 12 items cached +[2026-04-05 01:25:02] OK — 12 items cached +[2026-04-05 01:30:01] OK — 12 items cached +[2026-04-05 01:35:02] OK — 12 items cached +[2026-04-05 01:40:01] OK — 12 items cached +[2026-04-05 01:45:02] OK — 12 items cached +[2026-04-05 01:50:02] OK — 12 items cached +[2026-04-05 01:55:01] OK — 12 items cached +[2026-04-05 02:00:02] OK — 12 items cached +[2026-04-05 02:05:02] OK — 12 items cached +[2026-04-05 02:10:01] OK — 12 items cached +[2026-04-05 02:15:02] OK — 12 items cached +[2026-04-05 02:20:02] OK — 12 items cached +[2026-04-05 02:25:02] OK — 12 items cached +[2026-04-05 02:30:01] OK — 12 items cached +[2026-04-05 02:35:02] OK — 12 items cached +[2026-04-05 02:40:02] OK — 12 items cached +[2026-04-05 02:45:01] OK — 12 items cached +[2026-04-05 02:50:02] OK — 12 items cached +[2026-04-05 02:55:01] OK — 12 items cached +[2026-04-05 03:00:02] OK — 12 items cached +[2026-04-05 03:05:02] OK — 12 items cached +[2026-04-05 03:10:02] OK — 12 items cached +[2026-04-05 03:15:02] OK — 12 items cached +[2026-04-05 03:20:01] OK — 12 items cached +[2026-04-05 03:25:02] OK — 12 items cached +[2026-04-05 03:30:02] OK — 12 items cached +[2026-04-05 03:35:01] OK — 12 items cached +[2026-04-05 03:40:02] OK — 12 items cached +[2026-04-05 03:45:02] OK — 12 items cached +[2026-04-05 03:50:01] OK — 12 items cached +[2026-04-05 03:55:02] OK — 12 items cached +[2026-04-05 04:00:01] OK — 12 items cached +[2026-04-05 04:05:02] OK — 12 items cached +[2026-04-05 04:10:02] OK — 12 items cached +[2026-04-05 04:15:02] OK — 12 items cached +[2026-04-05 04:20:01] OK — 12 items cached +[2026-04-05 04:25:02] OK — 12 items cached +[2026-04-05 04:30:02] OK — 12 items cached +[2026-04-05 04:35:01] OK — 12 items cached +[2026-04-05 04:40:02] OK — 12 items cached +[2026-04-05 04:45:02] OK — 12 items cached +[2026-04-05 04:50:01] OK — 12 items cached +[2026-04-05 04:55:02] OK — 12 items cached +[2026-04-05 05:00:01] OK — 12 items cached +[2026-04-05 05:05:02] OK — 12 items cached +[2026-04-05 05:10:02] OK — 12 items cached +[2026-04-05 05:15:02] OK — 12 items cached +[2026-04-05 05:20:02] OK — 12 items cached +[2026-04-05 05:25:01] OK — 12 items cached +[2026-04-05 05:30:02] OK — 12 items cached +[2026-04-05 05:35:01] OK — 12 items cached +[2026-04-05 05:40:02] OK — 12 items cached +[2026-04-05 05:45:02] OK — 12 items cached +[2026-04-05 05:50:01] OK — 12 items cached +[2026-04-05 05:55:02] OK — 12 items cached +[2026-04-05 06:00:02] OK — 12 items cached +[2026-04-05 06:05:01] OK — 12 items cached +[2026-04-05 06:10:02] OK — 12 items cached +[2026-04-05 06:15:02] OK — 12 items cached +[2026-04-05 06:20:02] OK — 12 items cached +[2026-04-05 06:25:01] OK — 12 items cached +[2026-04-05 06:30:02] OK — 12 items cached +[2026-04-05 06:35:02] OK — 12 items cached +[2026-04-05 06:40:01] OK — 12 items cached +[2026-04-05 06:45:01] OK — 12 items cached +[2026-04-05 06:50:02] OK — 12 items cached +[2026-04-05 06:55:01] OK — 12 items cached +[2026-04-05 07:00:02] OK — 12 items cached +[2026-04-05 07:05:02] OK — 12 items cached +[2026-04-05 07:10:02] OK — 12 items cached +[2026-04-05 07:15:02] OK — 12 items cached +[2026-04-05 07:20:02] OK — 12 items cached +[2026-04-05 07:25:01] OK — 12 items cached +[2026-04-05 07:30:02] OK — 12 items cached +[2026-04-05 07:35:01] OK — 12 items cached +[2026-04-05 07:40:02] OK — 12 items cached +[2026-04-05 07:45:02] OK — 12 items cached +[2026-04-05 07:50:01] OK — 12 items cached +[2026-04-05 07:55:02] OK — 12 items cached +[2026-04-05 08:00:02] OK — 12 items cached +[2026-04-05 08:05:02] OK — 12 items cached +[2026-04-05 08:10:01] OK — 12 items cached +[2026-04-05 08:15:02] OK — 12 items cached +[2026-04-05 08:20:02] OK — 12 items cached +[2026-04-05 08:25:02] OK — 12 items cached +[2026-04-05 08:30:01] OK — 12 items cached +[2026-04-05 08:35:02] OK — 12 items cached +[2026-04-05 08:40:01] OK — 12 items cached +[2026-04-05 08:45:02] OK — 12 items cached +[2026-04-05 08:50:02] OK — 12 items cached +[2026-04-05 08:55:01] OK — 12 items cached +[2026-04-05 09:00:02] OK — 12 items cached +[2026-04-05 09:05:02] OK — 12 items cached +[2026-04-05 09:10:01] OK — 12 items cached +[2026-04-05 09:15:03] OK — 12 items cached +[2026-04-05 09:20:01] OK — 12 items cached +[2026-04-05 09:25:02] OK — 12 items cached +[2026-04-05 09:30:02] OK — 12 items cached +[2026-04-05 09:35:01] OK — 12 items cached +[2026-04-05 09:40:02] OK — 12 items cached +[2026-04-05 09:45:01] OK — 12 items cached +[2026-04-05 09:50:02] OK — 12 items cached +[2026-04-05 09:55:02] OK — 12 items cached +[2026-04-05 10:00:02] OK — 12 items cached +[2026-04-05 10:05:01] OK — 12 items cached +[2026-04-05 10:10:02] OK — 12 items cached +[2026-04-05 10:15:02] OK — 12 items cached +[2026-04-05 10:20:02] OK — 12 items cached +[2026-04-05 10:25:01] OK — 12 items cached +[2026-04-05 10:30:02] OK — 12 items cached +[2026-04-05 10:35:02] OK — 12 items cached +[2026-04-05 10:40:01] OK — 12 items cached +[2026-04-05 10:45:02] OK — 12 items cached +[2026-04-05 10:50:02] OK — 12 items cached +[2026-04-05 10:55:01] OK — 12 items cached +[2026-04-05 11:00:02] OK — 12 items cached +[2026-04-05 11:05:02] OK — 12 items cached +[2026-04-05 11:10:01] OK — 12 items cached +[2026-04-05 11:15:02] OK — 12 items cached +[2026-04-05 11:20:02] OK — 12 items cached +[2026-04-05 11:25:02] OK — 12 items cached +[2026-04-05 11:30:01] OK — 12 items cached +[2026-04-05 11:35:02] OK — 12 items cached +[2026-04-05 11:40:01] OK — 12 items cached +[2026-04-05 11:45:02] OK — 12 items cached +[2026-04-05 11:50:02] OK — 12 items cached +[2026-04-05 11:55:01] OK — 12 items cached +[2026-04-05 12:00:02] OK — 12 items cached +[2026-04-05 12:05:02] OK — 12 items cached +[2026-04-05 12:10:01] OK — 12 items cached +[2026-04-05 12:15:02] OK — 12 items cached +[2026-04-05 12:20:02] OK — 12 items cached +[2026-04-05 12:25:02] OK — 12 items cached +[2026-04-05 12:30:01] OK — 12 items cached +[2026-04-05 12:35:02] OK — 12 items cached +[2026-04-05 12:40:01] OK — 12 items cached +[2026-04-05 12:45:01] OK — 12 items cached +[2026-04-05 12:50:02] OK — 12 items cached +[2026-04-05 12:55:01] OK — 12 items cached +[2026-04-05 13:00:02] OK — 12 items cached +[2026-04-05 13:05:02] OK — 12 items cached +[2026-04-05 13:10:01] OK — 12 items cached +[2026-04-05 13:15:02] OK — 12 items cached +[2026-04-05 13:20:01] OK — 12 items cached +[2026-04-05 13:25:02] OK — 12 items cached +[2026-04-05 13:30:01] OK — 12 items cached +[2026-04-05 13:35:02] OK — 12 items cached +[2026-04-05 13:40:02] OK — 12 items cached +[2026-04-05 13:45:01] OK — 12 items cached +[2026-04-05 13:50:02] OK — 12 items cached +[2026-04-05 13:55:02] OK — 12 items cached +[2026-04-05 14:00:01] OK — 12 items cached +[2026-04-05 14:05:02] OK — 12 items cached +[2026-04-05 14:10:01] OK — 12 items cached +[2026-04-05 14:15:03] OK — 12 items cached +[2026-04-05 14:20:01] OK — 12 items cached +[2026-04-05 14:25:02] OK — 12 items cached +[2026-04-05 14:30:02] OK — 12 items cached +[2026-04-05 14:35:01] OK — 12 items cached +[2026-04-05 14:40:02] OK — 12 items cached +[2026-04-05 14:45:01] OK — 12 items cached +[2026-04-05 14:50:02] OK — 12 items cached +[2026-04-05 14:55:08] OK — 12 items cached +[2026-04-05 15:00:02] OK — 12 items cached +[2026-04-05 15:05:02] OK — 12 items cached +[2026-04-05 15:10:01] OK — 12 items cached +[2026-04-05 15:15:03] OK — 12 items cached +[2026-04-05 15:20:01] OK — 12 items cached +[2026-04-05 15:25:02] OK — 12 items cached +[2026-04-05 15:30:01] OK — 12 items cached +[2026-04-05 15:35:02] OK — 12 items cached +[2026-04-05 15:40:02] OK — 12 items cached +[2026-04-05 15:45:01] OK — 12 items cached +[2026-04-05 15:50:02] OK — 12 items cached +[2026-04-05 15:55:02] OK — 12 items cached +[2026-04-05 16:00:02] OK — 12 items cached +[2026-04-05 16:05:01] OK — 12 items cached +[2026-04-05 16:10:02] OK — 12 items cached +[2026-04-05 16:15:02] OK — 12 items cached +[2026-04-05 16:20:02] OK — 12 items cached +[2026-04-05 16:25:01] OK — 12 items cached +[2026-04-05 16:30:02] OK — 12 items cached +[2026-04-05 16:35:02] OK — 12 items cached +[2026-04-05 16:40:02] OK — 12 items cached +[2026-04-05 16:45:01] OK — 12 items cached +[2026-04-05 16:50:02] OK — 12 items cached +[2026-04-05 16:55:01] OK — 12 items cached +[2026-04-05 17:00:02] OK — 12 items cached +[2026-04-05 17:05:02] OK — 12 items cached +[2026-04-05 17:10:01] OK — 12 items cached +[2026-04-05 17:15:03] OK — 12 items cached +[2026-04-05 17:20:01] OK — 12 items cached +[2026-04-05 17:25:02] OK — 12 items cached +[2026-04-05 17:30:01] OK — 12 items cached +[2026-04-05 17:35:02] OK — 12 items cached +[2026-04-05 17:40:02] OK — 12 items cached +[2026-04-05 17:45:01] OK — 12 items cached +[2026-04-05 17:50:02] OK — 12 items cached +[2026-04-05 17:55:02] OK — 12 items cached +[2026-04-05 18:00:01] OK — 12 items cached +[2026-04-05 18:05:02] OK — 12 items cached +[2026-04-05 18:10:02] OK — 12 items cached +[2026-04-05 18:15:02] OK — 12 items cached +[2026-04-05 18:20:01] OK — 12 items cached +[2026-04-05 18:25:02] OK — 12 items cached +[2026-04-05 18:30:02] OK — 12 items cached +[2026-04-05 18:35:01] OK — 12 items cached +[2026-04-05 18:40:02] OK — 12 items cached +[2026-04-05 18:45:02] OK — 12 items cached +[2026-04-05 18:50:01] OK — 12 items cached +[2026-04-05 18:55:02] OK — 12 items cached +[2026-04-05 19:00:01] OK — 12 items cached +[2026-04-05 19:05:02] OK — 12 items cached +[2026-04-05 19:10:02] OK — 12 items cached +[2026-04-05 19:15:02] OK — 12 items cached +[2026-04-05 19:20:01] OK — 12 items cached +[2026-04-05 19:25:02] OK — 12 items cached +[2026-04-05 19:30:02] OK — 12 items cached +[2026-04-05 19:35:01] OK — 12 items cached +[2026-04-05 19:40:02] OK — 12 items cached +[2026-04-05 19:45:02] OK — 12 items cached +[2026-04-05 19:50:01] OK — 12 items cached +[2026-04-05 19:55:02] OK — 12 items cached +[2026-04-05 20:00:02] OK — 12 items cached +[2026-04-05 20:05:01] OK — 12 items cached +[2026-04-05 20:10:02] OK — 12 items cached +[2026-04-05 20:15:02] OK — 12 items cached +[2026-04-05 20:20:02] OK — 12 items cached +[2026-04-05 20:25:02] OK — 12 items cached +[2026-04-05 20:30:01] OK — 12 items cached +[2026-04-05 20:35:02] OK — 12 items cached +[2026-04-05 20:40:02] OK — 12 items cached +[2026-04-05 20:45:01] OK — 12 items cached +[2026-04-05 20:50:02] OK — 12 items cached +[2026-04-05 20:55:01] OK — 12 items cached +[2026-04-05 21:00:02] OK — 12 items cached +[2026-04-05 21:05:02] OK — 12 items cached +[2026-04-05 21:10:01] OK — 12 items cached +[2026-04-05 21:15:03] OK — 12 items cached +[2026-04-05 21:20:01] OK — 12 items cached +[2026-04-05 21:25:02] OK — 12 items cached +[2026-04-05 21:30:01] OK — 12 items cached +[2026-04-05 21:35:02] OK — 12 items cached +[2026-04-05 21:40:02] OK — 12 items cached +[2026-04-05 21:45:01] OK — 12 items cached +[2026-04-05 21:50:02] OK — 12 items cached +[2026-04-05 21:55:02] OK — 12 items cached +[2026-04-05 22:00:01] OK — 12 items cached +[2026-04-05 22:05:02] OK — 12 items cached +[2026-04-05 22:10:01] OK — 12 items cached +[2026-04-05 22:15:02] OK — 12 items cached +[2026-04-05 22:20:01] OK — 12 items cached +[2026-04-05 22:25:02] OK — 12 items cached +[2026-04-05 22:30:02] OK — 12 items cached +[2026-04-05 22:35:01] OK — 12 items cached +[2026-04-05 22:40:02] OK — 12 items cached +[2026-04-05 22:45:01] OK — 12 items cached +[2026-04-05 22:50:02] OK — 12 items cached +[2026-04-05 22:55:02] OK — 12 items cached +[2026-04-05 23:00:01] OK — 12 items cached +[2026-04-05 23:05:02] OK — 12 items cached +[2026-04-05 23:10:02] OK — 12 items cached +[2026-04-05 23:15:02] OK — 12 items cached +[2026-04-05 23:20:01] OK — 12 items cached +[2026-04-05 23:25:02] OK — 12 items cached +[2026-04-05 23:30:02] OK — 12 items cached +[2026-04-05 23:35:01] OK — 12 items cached +[2026-04-05 23:40:02] OK — 12 items cached +[2026-04-05 23:45:01] OK — 12 items cached +[2026-04-05 23:50:02] OK — 12 items cached +[2026-04-05 23:55:02] OK — 12 items cached +[2026-04-06 00:00:01] OK — 13 items cached +[2026-04-06 00:05:02] OK — 13 items cached +[2026-04-06 00:10:02] OK — 13 items cached +[2026-04-06 00:15:02] OK — 13 items cached +[2026-04-06 00:20:02] OK — 13 items cached +[2026-04-06 00:25:01] OK — 13 items cached +[2026-04-06 00:30:02] OK — 13 items cached +[2026-04-06 00:35:02] OK — 13 items cached +[2026-04-06 00:40:01] OK — 13 items cached +[2026-04-06 00:45:02] OK — 13 items cached +[2026-04-06 00:50:02] OK — 13 items cached +[2026-04-06 00:55:01] OK — 13 items cached +[2026-04-06 01:00:02] OK — 13 items cached +[2026-04-06 01:05:01] OK — 13 items cached +[2026-04-06 01:10:02] OK — 13 items cached +[2026-04-06 01:15:02] OK — 13 items cached +[2026-04-06 01:20:02] OK — 13 items cached +[2026-04-06 01:25:01] OK — 13 items cached +[2026-04-06 01:30:01] OK — 13 items cached +[2026-04-06 01:35:02] OK — 13 items cached +[2026-04-06 01:40:01] OK — 13 items cached +[2026-04-06 01:45:02] OK — 13 items cached +[2026-04-06 01:50:02] OK — 13 items cached +[2026-04-06 01:55:01] OK — 13 items cached +[2026-04-06 02:00:02] OK — 13 items cached +[2026-04-06 02:05:02] OK — 13 items cached +[2026-04-06 02:10:01] OK — 13 items cached +[2026-04-06 02:15:02] OK — 13 items cached +[2026-04-06 02:20:02] OK — 13 items cached +[2026-04-06 02:25:02] OK — 13 items cached +[2026-04-06 02:30:01] OK — 13 items cached +[2026-04-06 02:35:02] OK — 13 items cached +[2026-04-06 02:40:01] OK — 13 items cached +[2026-04-06 02:45:02] OK — 13 items cached +[2026-04-06 02:50:02] OK — 13 items cached +[2026-04-06 02:55:01] OK — 13 items cached +[2026-04-06 03:00:02] OK — 13 items cached +[2026-04-06 03:05:02] OK — 13 items cached +[2026-04-06 03:10:02] OK — 13 items cached +[2026-04-06 03:15:02] OK — 13 items cached +[2026-04-06 03:20:01] OK — 13 items cached +[2026-04-06 03:25:02] OK — 13 items cached +[2026-04-06 03:30:02] OK — 13 items cached +[2026-04-06 03:35:01] OK — 13 items cached +[2026-04-06 03:40:02] OK — 13 items cached +[2026-04-06 03:45:02] OK — 13 items cached +[2026-04-06 03:50:01] OK — 13 items cached +[2026-04-06 03:55:02] OK — 13 items cached +[2026-04-06 04:00:02] OK — 13 items cached +[2026-04-06 04:05:01] OK — 13 items cached +[2026-04-06 04:10:02] OK — 13 items cached +[2026-04-06 04:15:02] OK — 13 items cached +[2026-04-06 04:20:02] OK — 13 items cached +[2026-04-06 04:25:01] OK — 13 items cached +[2026-04-06 04:30:02] OK — 13 items cached +[2026-04-06 04:35:02] OK — 13 items cached +[2026-04-06 04:40:01] OK — 13 items cached +[2026-04-06 04:45:02] OK — 13 items cached +[2026-04-06 04:50:01] OK — 13 items cached +[2026-04-06 04:55:02] OK — 13 items cached +[2026-04-06 05:00:02] OK — 13 items cached +[2026-04-06 05:05:01] OK — 13 items cached +[2026-04-06 05:10:02] OK — 13 items cached +[2026-04-06 05:15:02] OK — 13 items cached +[2026-04-06 05:20:02] OK — 13 items cached +[2026-04-06 05:25:02] OK — 13 items cached +[2026-04-06 05:30:01] OK — 13 items cached +[2026-04-06 05:35:02] OK — 13 items cached +[2026-04-06 05:40:01] OK — 13 items cached +[2026-04-06 05:45:02] OK — 13 items cached +[2026-04-06 05:50:02] OK — 13 items cached +[2026-04-06 05:55:01] OK — 13 items cached +[2026-04-06 06:00:02] OK — 13 items cached +[2026-04-06 06:05:02] OK — 13 items cached +[2026-04-06 06:10:01] OK — 13 items cached +[2026-04-06 06:15:03] OK — 13 items cached +[2026-04-06 06:20:01] OK — 13 items cached +[2026-04-06 06:25:02] OK — 13 items cached +[2026-04-06 06:30:01] OK — 13 items cached +[2026-04-06 06:35:02] OK — 13 items cached +[2026-04-06 06:40:02] OK — 13 items cached +[2026-04-06 06:45:01] OK — 13 items cached +[2026-04-06 06:50:02] OK — 13 items cached +[2026-04-06 06:55:02] OK — 13 items cached +[2026-04-06 07:00:01] OK — 13 items cached +[2026-04-06 07:05:02] OK — 13 items cached +[2026-04-06 07:10:02] OK — 13 items cached +[2026-04-06 07:15:02] OK — 13 items cached +[2026-04-06 07:20:01] OK — 13 items cached +[2026-04-06 07:25:02] OK — 13 items cached +[2026-04-06 07:30:02] OK — 13 items cached +[2026-04-06 07:35:01] OK — 13 items cached +[2026-04-06 07:40:02] OK — 13 items cached +[2026-04-06 07:45:02] OK — 13 items cached +[2026-04-06 07:50:01] OK — 13 items cached +[2026-04-06 07:55:02] OK — 13 items cached +[2026-04-06 08:00:02] OK — 13 items cached +[2026-04-06 08:05:01] OK — 13 items cached +[2026-04-06 08:10:02] OK — 13 items cached +[2026-04-06 08:15:01] OK — 13 items cached +[2026-04-06 08:20:02] OK — 13 items cached +[2026-04-06 08:25:02] OK — 13 items cached +[2026-04-06 08:30:02] OK — 13 items cached +[2026-04-06 08:35:01] OK — 13 items cached +[2026-04-06 08:40:02] OK — 13 items cached +[2026-04-06 08:45:02] OK — 13 items cached +[2026-04-06 08:50:01] OK — 13 items cached diff --git a/data/dispensa.db b/data/dispensa.db index 178dac1..a5a1167 100644 Binary files a/data/dispensa.db and b/data/dispensa.db differ diff --git a/data/smart_shopping_cache.json b/data/smart_shopping_cache.json index fd2b072..ec86792 100644 --- a/data/smart_shopping_cache.json +++ b/data/smart_shopping_cache.json @@ -1 +1 @@ -{"success":true,"items":[{"product_id":151,"name":"Arance Tarocco","brand":"","category":"frutta","unit":"pz","current_qty":0,"default_qty":0,"package_unit":"","pct_left":0,"use_count":9,"buy_count":2,"daily_rate":0.55,"uses_per_month":13.6,"days_since_last_use":2,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito","Uso frequente (9x)"],"score":135,"on_bring":true,"locations":""},{"product_id":70,"name":"Latte Parzialmente Scremato Uht","brand":"Latteria","category":"bevande","unit":"conf","current_qty":0,"default_qty":500,"package_unit":"ml","pct_left":0,"use_count":13,"buy_count":3,"daily_rate":6.73,"uses_per_month":15.5,"days_since_last_use":9,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito","Uso frequente (13x)"],"score":135,"on_bring":true,"locations":""},{"product_id":129,"name":"Latte di Montagna","brand":"Mila","category":"en:dairies","unit":"conf","current_qty":0,"default_qty":1000,"package_unit":"ml","pct_left":0,"use_count":9,"buy_count":3,"daily_rate":0.2,"uses_per_month":13.6,"days_since_last_use":1,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito","Uso frequente (9x)"],"score":135,"on_bring":true,"locations":""},{"product_id":47,"name":"Lenticchie","brand":"Primia","category":"en:plant-based-foods-and-beverages","unit":"g","current_qty":0,"default_qty":400,"package_unit":"","pct_left":0,"use_count":5,"buy_count":3,"daily_rate":35.82,"uses_per_month":6,"days_since_last_use":0,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito","Uso frequente (5x)"],"score":130,"on_bring":true,"locations":""},{"product_id":115,"name":"Aglio rosso","brand":"Duoccio","category":"condimenti","unit":"pz","current_qty":0,"default_qty":0,"package_unit":"","pct_left":0,"use_count":2,"buy_count":2,"daily_rate":0.14,"uses_per_month":2.7,"days_since_last_use":15,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito"],"score":100,"on_bring":true,"locations":""},{"product_id":152,"name":"Muesli Frutta Secca","brand":"Crownfield","category":"altro","unit":"g","current_qty":0,"default_qty":750,"package_unit":"","pct_left":0,"use_count":4,"buy_count":2,"daily_rate":33.93,"uses_per_month":6.9,"days_since_last_use":9,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito"],"score":100,"on_bring":false,"locations":""},{"product_id":3,"name":"Cracker integrali","brand":"Barilla,Mulino Bianco","category":"en:snacks","unit":"conf","current_qty":2,"default_qty":25,"package_unit":"g","pct_left":12,"use_count":6,"buy_count":1,"daily_rate":0.56,"uses_per_month":7.1,"days_since_last_use":6,"days_left":4,"expiry_date":"2026-04-28","days_to_expiry":23,"is_opened":true,"urgency":"high","reasons":["Quasi finito (12%)"],"score":90,"on_bring":true,"locations":"dispensa"},{"product_id":132,"name":"Noci sgusciate","brand":"Fruttbella","category":"conserve","unit":"g","current_qty":60,"default_qty":200,"package_unit":"","pct_left":30,"use_count":4,"buy_count":1,"daily_rate":7.03,"uses_per_month":6,"days_since_last_use":0,"days_left":9,"expiry_date":"2026-04-29","days_to_expiry":24,"is_opened":true,"urgency":"medium","reasons":["Finisce tra ~9gg"],"score":50,"on_bring":true,"locations":"dispensa"},{"product_id":69,"name":"Cipolla Dorata","brand":"","category":"verdura","unit":"pz","current_qty":4,"default_qty":0,"package_unit":"","pct_left":44,"use_count":12,"buy_count":1,"daily_rate":0.32,"uses_per_month":14.3,"days_since_last_use":0,"days_left":12,"expiry_date":"2026-04-13","days_to_expiry":8,"is_opened":false,"urgency":"low","reasons":["Previsto esaurimento tra ~12gg"],"score":40,"on_bring":true,"locations":"frigo"},{"product_id":154,"name":"Mela Rossa","brand":"","category":"frutta","unit":"pz","current_qty":7,"default_qty":1,"package_unit":"","pct_left":32,"use_count":5,"buy_count":1,"daily_rate":0.87,"uses_per_month":8.7,"days_since_last_use":0,"days_left":8,"expiry_date":"2026-04-15","days_to_expiry":10,"is_opened":false,"urgency":"low","reasons":["Previsto esaurimento tra ~8gg"],"score":35,"on_bring":false,"locations":"frigo"},{"product_id":136,"name":"Biscotti Pastefrolle","brand":"Balocco","category":"snack","unit":"g","current_qty":350,"default_qty":700,"package_unit":"","pct_left":67,"use_count":4,"buy_count":2,"daily_rate":35.15,"uses_per_month":6,"days_since_last_use":0,"days_left":10,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"low","reasons":["Previsto esaurimento tra ~10gg"],"score":25,"on_bring":false,"locations":"dispensa"}],"cached_at":"2026-04-04T15:35:01+00:00","cached_ts":1775316901} \ No newline at end of file +{"success":true,"items":[{"product_id":151,"name":"Arance Tarocco","brand":"","category":"frutta","unit":"pz","current_qty":0,"default_qty":0,"package_unit":"","pct_left":0,"use_count":9,"buy_count":2,"daily_rate":0.51,"uses_per_month":12.5,"days_since_last_use":4,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito","Uso frequente (9x)"],"score":135,"on_bring":true,"locations":""},{"product_id":70,"name":"Latte Parzialmente Scremato Uht","brand":"Latteria","category":"bevande","unit":"conf","current_qty":0,"default_qty":500,"package_unit":"ml","pct_left":0,"use_count":13,"buy_count":3,"daily_rate":6.3,"uses_per_month":14.5,"days_since_last_use":11,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito","Uso frequente (13x)"],"score":135,"on_bring":true,"locations":""},{"product_id":47,"name":"Lenticchie","brand":"Primia","category":"en:plant-based-foods-and-beverages","unit":"g","current_qty":0,"default_qty":400,"package_unit":"","pct_left":0,"use_count":5,"buy_count":3,"daily_rate":33.53,"uses_per_month":5.6,"days_since_last_use":2,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito","Uso frequente (5x)"],"score":130,"on_bring":true,"locations":""},{"product_id":115,"name":"Aglio rosso","brand":"Duoccio","category":"condimenti","unit":"pz","current_qty":0,"default_qty":0,"package_unit":"","pct_left":0,"use_count":2,"buy_count":2,"daily_rate":0.13,"uses_per_month":2.5,"days_since_last_use":17,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito"],"score":100,"on_bring":true,"locations":""},{"product_id":152,"name":"Muesli Frutta Secca","brand":"Crownfield","category":"altro","unit":"g","current_qty":0,"default_qty":750,"package_unit":"","pct_left":0,"use_count":4,"buy_count":2,"daily_rate":30.88,"uses_per_month":6.3,"days_since_last_use":11,"days_left":0,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"critical","reasons":["Esaurito"],"score":100,"on_bring":false,"locations":""},{"product_id":3,"name":"Cracker integrali","brand":"Barilla,Mulino Bianco","category":"en:snacks","unit":"conf","current_qty":2,"default_qty":25,"package_unit":"g","pct_left":12,"use_count":6,"buy_count":1,"daily_rate":0.52,"uses_per_month":6.7,"days_since_last_use":8,"days_left":4,"expiry_date":"2026-04-28","days_to_expiry":22,"is_opened":true,"urgency":"high","reasons":["Quasi finito (12%)"],"score":90,"on_bring":true,"locations":"dispensa"},{"product_id":154,"name":"Mela Rossa","brand":"","category":"frutta","unit":"pz","current_qty":6,"default_qty":1,"package_unit":"","pct_left":27,"use_count":6,"buy_count":1,"daily_rate":0.85,"uses_per_month":9.5,"days_since_last_use":2,"days_left":7,"expiry_date":"2026-04-15","days_to_expiry":9,"is_opened":false,"urgency":"medium","reasons":["Finisce tra ~7gg"],"score":60,"on_bring":false,"locations":"frigo"},{"product_id":129,"name":"Latte di Montagna","brand":"Mila","category":"en:dairies","unit":"conf","current_qty":1,"default_qty":1000,"package_unit":"ml","pct_left":67,"use_count":11,"buy_count":4,"daily_rate":0.23,"uses_per_month":15.3,"days_since_last_use":0,"days_left":4,"expiry_date":"2026-04-09","days_to_expiry":3,"is_opened":true,"urgency":"medium","reasons":["Scade tra 3gg"],"score":55,"on_bring":true,"locations":"frigo"},{"product_id":132,"name":"Noci sgusciate","brand":"Fruttbella","category":"conserve","unit":"g","current_qty":60,"default_qty":200,"package_unit":"","pct_left":30,"use_count":4,"buy_count":1,"daily_rate":6.47,"uses_per_month":5.5,"days_since_last_use":2,"days_left":9,"expiry_date":"2026-04-29","days_to_expiry":23,"is_opened":true,"urgency":"medium","reasons":["Finisce tra ~9gg"],"score":50,"on_bring":true,"locations":"dispensa"},{"product_id":10,"name":"Passata di pomodoro","brand":"Primia","category":"en:condiments","unit":"g","current_qty":292,"default_qty":700,"package_unit":"","pct_left":44,"use_count":7,"buy_count":3,"daily_rate":38.23,"uses_per_month":7.8,"days_since_last_use":2,"days_left":8,"expiry_date":"2026-04-09","days_to_expiry":3,"is_opened":true,"urgency":"medium","reasons":["Scade tra 3gg"],"score":50,"on_bring":false,"locations":"frigo"},{"product_id":69,"name":"Cipolla Dorata","brand":"","category":"verdura","unit":"pz","current_qty":3,"default_qty":0,"package_unit":"","pct_left":33,"use_count":13,"buy_count":1,"daily_rate":0.34,"uses_per_month":14.5,"days_since_last_use":2,"days_left":9,"expiry_date":"2026-04-13","days_to_expiry":7,"is_opened":false,"urgency":"low","reasons":["Previsto esaurimento tra ~9gg"],"score":40,"on_bring":false,"locations":"frigo"},{"product_id":34,"name":"Tortiglioni","brand":"Barilla, Barilla Pasta","category":"en:plant-based-foods-and-beverages","unit":"g","current_qty":270,"default_qty":500,"package_unit":"","pct_left":73,"use_count":1,"buy_count":1,"daily_rate":3.72,"uses_per_month":1.1,"days_since_last_use":4,"days_left":73,"expiry_date":"2026-04-09","days_to_expiry":3,"is_opened":true,"urgency":"medium","reasons":["Scade tra 3gg"],"score":40,"on_bring":false,"locations":"dispensa"},{"product_id":136,"name":"Biscotti Pastefrolle","brand":"Balocco","category":"snack","unit":"g","current_qty":350,"default_qty":700,"package_unit":"","pct_left":67,"use_count":4,"buy_count":2,"daily_rate":32.36,"uses_per_month":5.5,"days_since_last_use":2,"days_left":11,"expiry_date":null,"days_to_expiry":999,"is_opened":false,"urgency":"low","reasons":["Previsto esaurimento tra ~11gg"],"score":25,"on_bring":false,"locations":"dispensa"}],"cached_at":"2026-04-06T08:50:01+00:00","cached_ts":1775465401} \ No newline at end of file