feat(redesign): [P2] data model + migration + Jest setup #1
Reference in New Issue
Block a user
Delete Branch "wt/redesign-data-model"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 2 — Trello-style data model + Jest setup
Establishes the v2 normalized shape and the one-shot v1->v2 migration. Stands up Jest + React Testing Library so every subsequent phase (P3-P8) has a real test harness.
v2 shape (localStorage key
ultra-todo-v2-state)@dnd-kit/sortablewill need stable ids for reorder.boardId+listIdso cleanup is easy if a list is dropped.createdAtis a number (Date.now()) for stable ordering.Migration
schemaVersion === 2.ultra-todo-items(v1), builds a single Inbox board with one Todo list, maps each item to a card (text->title, dropcompleted, preservedueDate).Store
useBoardStore()returns{ state, actions }. Pure reducer (useState + functional updates), persists on every state change. No async.Tests (25 pass)
src/lib/migrate.test.js(7): existing v2 untouched, fresh empty state, v1->v2 mapping, v1 key intact, idempotent, corrupt v1, persistence.src/store/boardStore.test.js(17): initial state, persistence, every action's happy path.src/store/boardStore.migration.test.js(1): end-to-end — write v1, mount hook, verify v2 shape and v1 key intact.Jest + RTL setup
babel.config.jsis only for Jest's transform — Vite's esbuild ignores it for dev/build.jest.config.js: jsdom env,setupFilesAfterEnvfor jest-dom, transform^.+\.(js|jsx)$with babel-jest, testEnvironmentOptions for crypto.randomUUID compat, transformIgnorePatterns pre-wired for @dnd-kit (P5).npm test,npm run test:watch.No UI yet
App.jsxand the v1 components (TodoForm/TodoList/TodoItem) are untouched. Old UI still renders and the production build still produces the same bundle (verified:npm run buildsucceeds, 197 kB JS / 2.3 kB CSS).Acceptance
npm testruns and 25/25 boardStore tests passnpm run buildsucceeds (old UI still renders)wt/redesign-data-modelpushed to originOut of scope (later phases)
@dnd-kitdrag-and-drop- src/lib/migrate.js: one-shot v1->v2 migration under 'ultra-todo-v2-state'. Maps legacy ultra-todo-items to a single Inbox/Todo board, preserves text/title and dueDate, drops completed. Leaves v1 key intact for rollback. Guarded by schemaVersion === 2. - src/store/boardStore.js: useBoardStore() hook returning { state, actions }. Pure reducer (useState + functional updates), persists on every change. Actions: addBoard/renameBoard/deleteBoard/setActiveBoard, addList/renameList/deleteList/moveList, addCard/updateCard/deleteCard/moveCard. Migration runs synchronously in the useState initializer so no empty-board flash on first paint. - src/hooks/useLocalStorage.js: JSDoc updated to document v1/v2 key contract. - Jest + RTL setup: babel-jest + jsdom, @testing-library/jest-dom, scripts test / test:watch. 25 tests pass; npm run build still produces old UI.Pull request closed