From bcb1a7a6d1516b34dd79008fc8b7e6c8dfcdeb2b Mon Sep 17 00:00:00 2001 From: Christian Vidal Wolf Date: Sat, 17 Jan 2026 11:41:41 +0100 Subject: [PATCH] fix: add cache versioning to invalidate stale data on schema changes --- services/storage.ts | 54 ++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/services/storage.ts b/services/storage.ts index 98c8993..419d6f9 100644 --- a/services/storage.ts +++ b/services/storage.ts @@ -4,18 +4,21 @@ import { SalesRecord } from '../types'; const DB_NAME = 'CrazeAnalytixDB'; const STORE_NAME = 'salesData'; const DB_VERSION = 1; +// Increment this when data processing logic changes (e.g., field mapping changes) +// This forces cache invalidation and re-processing of CSV data +const DATA_SCHEMA_VERSION = 2; // Updated for LICENSE column mapping const initDB = (): Promise => { return new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, DB_VERSION); - + request.onupgradeneeded = (event) => { const db = (event.target as IDBOpenDBRequest).result; if (!db.objectStoreNames.contains(STORE_NAME)) { db.createObjectStore(STORE_NAME); } }; - + request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); @@ -27,12 +30,14 @@ export const saveSalesData = async (data: SalesRecord[]): Promise => { return new Promise((resolve, reject) => { const transaction = db.transaction(STORE_NAME, 'readwrite'); const store = transaction.objectStore(STORE_NAME); - + // Store the data array store.put(data, 'currentData'); // Store the timestamp store.put(new Date().toISOString(), 'lastUpdated'); - + // Store schema version + store.put(DATA_SCHEMA_VERSION, 'schemaVersion'); + transaction.oncomplete = () => resolve(); transaction.onerror = () => reject(transaction.error); }); @@ -48,17 +53,30 @@ export const loadSalesData = async (): Promise<{ data: SalesRecord[]; lastUpdate return new Promise((resolve, reject) => { const transaction = db.transaction(STORE_NAME, 'readonly'); const store = transaction.objectStore(STORE_NAME); - + const dataReq = store.get('currentData'); const dateReq = store.get('lastUpdated'); + const versionReq = store.get('schemaVersion'); transaction.oncomplete = () => { + const cachedVersion = versionReq.result; + + // If schema version doesn't match, invalidate cache + if (cachedVersion !== DATA_SCHEMA_VERSION) { + console.log('[Storage] Schema version mismatch. Cached:', cachedVersion, 'Current:', DATA_SCHEMA_VERSION); + resolve({ + data: [], + lastUpdated: null + }); + return; + } + resolve({ data: dataReq.result || [], lastUpdated: dateReq.result || null }); }; - + transaction.onerror = () => reject(transaction.error); }); } catch (error) { @@ -68,16 +86,16 @@ export const loadSalesData = async (): Promise<{ data: SalesRecord[]; lastUpdate }; export const clearSalesData = async (): Promise => { - try { - const db = await initDB(); - return new Promise((resolve, reject) => { - const transaction = db.transaction(STORE_NAME, 'readwrite'); - const store = transaction.objectStore(STORE_NAME); - store.clear(); - transaction.oncomplete = () => resolve(); - transaction.onerror = () => reject(transaction.error); - }); - } catch (e) { - console.error(e); - } + try { + const db = await initDB(); + return new Promise((resolve, reject) => { + const transaction = db.transaction(STORE_NAME, 'readwrite'); + const store = transaction.objectStore(STORE_NAME); + store.clear(); + transaction.oncomplete = () => resolve(); + transaction.onerror = () => reject(transaction.error); + }); + } catch (e) { + console.error(e); + } }