Skip to content

Commit 763cb83

Browse files
committed
refactor(storage): add legacy task normalization for migration to IndexedDB
1 parent e0ba475 commit 763cb83

2 files changed

Lines changed: 51 additions & 3 deletions

File tree

packages/web/src/common/utils/storage/task-migration.util.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,29 @@ describe("task-migration.util", () => {
195195
expect(allTasks).toHaveLength(1);
196196
expect(allTasks[0].title).toBe("Valid Task");
197197
});
198+
199+
it("should migrate legacy tasks with id mapped to _id", async () => {
200+
const task = createMockTask({
201+
_id: "legacy-task-id",
202+
title: "Legacy Task",
203+
});
204+
const { _id, ...rest } = task;
205+
const legacyTask = { ...rest, id: _id };
206+
207+
localStorage.setItem(
208+
`${TASK_STORAGE_KEY_PREFIX}2024-01-15`,
209+
JSON.stringify([legacyTask]),
210+
);
211+
212+
const migratedCount = await migrateTasksFromLocalStorageToIndexedDB();
213+
214+
expect(migratedCount).toBe(1);
215+
216+
const allTasks = await loadAllTasksFromIndexedDB();
217+
expect(allTasks).toHaveLength(1);
218+
expect(allTasks[0]._id).toBe("legacy-task-id");
219+
expect(allTasks[0].title).toBe("Legacy Task");
220+
});
198221
});
199222

200223
describe("resetTaskMigrationFlag", () => {

packages/web/src/common/utils/storage/task-migration.util.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,29 @@ import { saveTaskToIndexedDB } from "./task.storage.util";
55
const MIGRATION_FLAG_KEY = "compass.tasks.migrated-to-indexeddb";
66
const TASK_STORAGE_KEY_PREFIX = "compass.today.tasks.";
77

8+
function normalizeLegacyTask(item: unknown): Task | null {
9+
if (isTask(item)) {
10+
return item;
11+
}
12+
13+
if (!item || typeof item !== "object") {
14+
return null;
15+
}
16+
17+
const legacyTask = item as Record<string, unknown> & { id?: unknown };
18+
if (typeof legacyTask.id !== "string") {
19+
return null;
20+
}
21+
22+
const { id, ...rest } = legacyTask;
23+
const mappedTask = {
24+
...rest,
25+
_id: id,
26+
};
27+
28+
return isTask(mappedTask) ? mappedTask : null;
29+
}
30+
831
/**
932
* Checks if task migration from localStorage to IndexedDB has been completed.
1033
*/
@@ -69,13 +92,15 @@ export async function migrateTasksFromLocalStorageToIndexedDB(): Promise<number>
6992
// in localStorage so successful migrations are not duplicated on retry.
7093
const remainingTasks: Task[] = [];
7194
for (const item of parsed) {
72-
if (isTask(item)) {
95+
const normalizedTask = normalizeLegacyTask(item);
96+
97+
if (normalizedTask) {
7398
try {
74-
await saveTaskToIndexedDB(item, dateKey);
99+
await saveTaskToIndexedDB(normalizedTask, dateKey);
75100
migratedCount++;
76101
} catch (saveError) {
77102
hasSaveFailures = true;
78-
remainingTasks.push(item);
103+
remainingTasks.push(normalizedTask);
79104
console.error(
80105
`Failed to save task to IndexedDB for dateKey: ${dateKey}`,
81106
saveError,

0 commit comments

Comments
 (0)