From 6124ae9cd6ec4eb46ec6e63725dc6b8ff086693a Mon Sep 17 00:00:00 2001 From: Till JS Date: Thu, 9 Apr 2026 16:14:39 +0200 Subject: [PATCH] fix(mana/web): bump Dexie schema to v3 for the who tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The who module landed with whoGames + whoMessages declared inside db.version(1). That's wrong: existing browsers (every tester including the developer's own) already had Dexie persisted at v1 with the OLD schema (no who tables). When the new bundle declared v1 with a different schema, Dexie refused the schema diff and the optimistic insert in whoGamesStore.sendMessage silently failed — neither the user's message nor the server reply appeared in the PlayView, even though the deck picker and game start worked (those write whoGames which has the same schema-mismatch issue but the failure is only visible once a chat starts). The pre-launch cleanup doc says "edit version(1) directly until launch", but in practice that bricks every developer's local state on every additive change. The right rule is: bump the version for additive table additions even pre-launch — Dexie handles the additive case cleanly with no upgrade function. This commit: - Removes whoGames + whoMessages from db.version(1) - Adds them to a new db.version(3) block (v2 was already taken by the bodyExercises / bodyRoutines / etc. body module) - Existing IndexedDB databases at v1 or v2 will run the additive upgrade automatically on next page load. No data loss, no upgrade function needed (no rows to migrate yet). Also: add a console.error to PlayView's send() catch so future sendMessage failures actually show up in DevTools instead of only being visible as a tiny error banner near the input. Fixes the "ich tippe eine frage und nichts passiert" symptom the developer hit on the first end-to-end live test of the who module on production. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/mana/apps/web/src/lib/data/database.ts | 42 +++++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/apps/mana/apps/web/src/lib/data/database.ts b/apps/mana/apps/web/src/lib/data/database.ts index 7afeacf39..97d70b1b0 100644 --- a/apps/mana/apps/web/src/lib/data/database.ts +++ b/apps/mana/apps/web/src/lib/data/database.ts @@ -99,14 +99,6 @@ db.version(1).stores({ cards: 'id, deckId, difficulty, nextReview, order, [deckId+order]', deckTags: 'id, deckId, tagId, [deckId+tagId]', - // ─── Who (appId: 'who') ─── - // LLM character-guessing game. whoGames holds one row per session - // (status, deck, character id, message count); whoMessages holds the - // chat scrollback. Standard plaintext index pattern: id, FK, status, - // timestamps for sort/filter; content + revealedName encrypted. - whoGames: 'id, status, deckId, startedAt, finishedAt, [status+startedAt]', - whoMessages: 'id, gameId, sender, createdAt, [gameId+createdAt]', - // ─── Zitare (appId: 'zitare') ─── zitareFavorites: 'id, quoteId', zitareLists: 'id', @@ -303,6 +295,40 @@ db.version(1).stores({ manaLinks: 'id, sourceAppId, sourceRecordId, targetAppId, targetRecordId', }); +// Schema version 2 — adds the unified Body module (combined fitness training +// + body composition tracking). Additive only; no v1 tables touched. +// +// Index strategy: +// - bodySets indexes [workoutId+order] so the per-workout view can do a +// range scan instead of loading every set and filtering in JS. +// - bodyMeasurements indexes [type+date] for the per-metric trend chart +// (e.g. "weight over time"). +// - bodyChecks indexes `date` so the daily upsert can `.where('date')`. +// - bodyPhases indexes `endDate` to find the active (open) phase quickly. +db.version(2).stores({ + bodyExercises: 'id, muscleGroup, equipment, isArchived, isPreset', + bodyRoutines: 'id, order, isArchived', + bodyWorkouts: 'id, startedAt, endedAt, routineId, [endedAt+startedAt]', + bodySets: 'id, workoutId, exerciseId, order, [workoutId+order], [exerciseId+createdAt]', + bodyMeasurements: 'id, date, type, [type+date]', + bodyChecks: 'id, date', + bodyPhases: 'id, kind, startDate, endDate', +}); + +// Schema version 3 — adds the Who module (LLM character-guessing game). +// Additive only; no v1/v2 tables touched. +// +// Index strategy: +// - whoGames indexes status + startedAt + the [status+startedAt] composite +// so the past-games ListView can sort active vs finished cleanly without +// loading the full set every render. +// - whoMessages indexes [gameId+createdAt] for the chat scrollback query +// (range scan inside one game's messages, ordered by time). +db.version(3).stores({ + whoGames: 'id, status, deckId, startedAt, finishedAt, [status+startedAt]', + whoMessages: 'id, gameId, sender, createdAt, [gameId+createdAt]', +}); + // ─── Sync Routing ────────────────────────────────────────── // SYNC_APP_MAP, TABLE_TO_SYNC_NAME, TABLE_TO_APP, SYNC_NAME_TO_TABLE, // toSyncName() and fromSyncName() are now derived from per-module