From 5cb517612f192c2b33f7c1e562a61b6d7dfc02f9 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Wed, 27 May 2026 12:31:06 +0530 Subject: [PATCH] feat: flush IndexedDB cache on DATA_VERSION bump MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The idempotent upgrade only created missing object stores, so bumping DATA_VERSION no longer reset bad or stale data — it just added stores. This restores a bump as a true global cache flush: the upgrade now clears every existing store before recreating any missing ones, so shipping a version bump forces all clients to refetch fresh on next boot. Gated on oldVersion > 0 so fresh installs skip the flush, and clearing before creating means only pre-existing stores are touched. This is the break-glass lever for the one non-self-healing failure mode (non-empty store holding wrong-shaped data paired with a matching cache key), e.g. after a serializer shape change shipped without a version bump. --- .../dashboard/helper/CacheHelper/DataManager.js | 12 +++++++++++- .../dashboard/helper/CacheHelper/version.js | 12 ++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/javascript/dashboard/helper/CacheHelper/DataManager.js b/app/javascript/dashboard/helper/CacheHelper/DataManager.js index 909301e70..22be6cbde 100644 --- a/app/javascript/dashboard/helper/CacheHelper/DataManager.js +++ b/app/javascript/dashboard/helper/CacheHelper/DataManager.js @@ -13,7 +13,17 @@ export class DataManager { if (this.db) return this.db; const dbName = `cw-store-${this.accountId}`; this.db = await openDB(dbName, DATA_VERSION, { - upgrade(db) { + upgrade(db, oldVersion, _newVersion, tx) { + // Flush data carried over from a previous schema version so a + // DATA_VERSION bump acts as a global cache reset. oldVersion === 0 on + // first install, so fresh devices skip this. Clearing before creating + // means we only ever clear stores that pre-existed this upgrade. + if (oldVersion > 0) { + [...db.objectStoreNames].forEach(name => + tx.objectStore(name).clear() + ); + } + if (!db.objectStoreNames.contains('cache-keys')) { db.createObjectStore('cache-keys'); } diff --git a/app/javascript/dashboard/helper/CacheHelper/version.js b/app/javascript/dashboard/helper/CacheHelper/version.js index 8cd958863..bdf5b04c3 100644 --- a/app/javascript/dashboard/helper/CacheHelper/version.js +++ b/app/javascript/dashboard/helper/CacheHelper/version.js @@ -1,9 +1,9 @@ -// Bump DATA_VERSION whenever a new object store is added to the IDB schema -// (the `upgrade()` callback in DataManager only runs when the stored DB -// version is less than the requested version). The upgrade body itself is -// idempotent — it conditionally creates each store via -// `objectStoreNames.contains(name)` — so a single bump is enough to add any -// number of new stores without losing existing data. +// Bump DATA_VERSION to (a) add new object stores to the IDB schema or (b) +// flush bad/stale cache globally. The `upgrade()` callback in DataManager runs +// only when the stored DB version is less than the requested version; on any +// such bump it clears every existing store (a full cache reset) and then +// idempotently creates any missing stores. So bump this whenever a cached +// model's serializer shape changes, or to force all clients to refetch. // // Wednesday, 21 May 2026 — bumped to add canned_response + account_user stores export const DATA_VERSION = '1747785600';