From ddde284f178868b82db4126672386a8d1553b655 Mon Sep 17 00:00:00 2001 From: Till JS Date: Thu, 9 Apr 2026 12:22:01 +0200 Subject: [PATCH] fix(memoro): decrypt DetailView fields + stamp createdAt on memo create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two pre-existing bugs in the memoro module that became visible after the Phase 5 LLM auto-title work landed. Both are independent of the Phase 5 framework — neither was introduced by it — but the auto-title was the first feature to systematically write to memo.title, which is when the broken read path stopped hiding behind always-null titles. Bug 1: DetailView shows ciphertext instead of plaintext apps/mana/apps/web/src/lib/modules/memoro/views/DetailView.svelte passed `useDetailEntity({ table: 'memos', ... })` WITHOUT setting `decrypt: true`. The crypto registry has memos.{title, intro, transcript} marked as encrypted, so the inputs were binding to raw `enc:1:Ghj1eJV0zz4PgfRL...` ciphertext strings instead of plaintext. Nobody noticed before because: - title was always null (no UI path to set it until Phase 5) - intro is rarely used - transcript was the only visible encrypted field, and the garbled `enc:1:...` string in the transcript area was apparently attributed to "broken transcription" rather than "broken read" Add `decrypt: true` to the useDetailEntity options. Same flag the other Mana modules already use for their encrypted DetailViews. Bug 2: createdAt and updatedAt never set on memo records apps/mana/apps/web/src/lib/modules/memoro/stores/memos.svelte.ts create() built a LocalMemo object without populating createdAt or updatedAt. The LocalMemo type declares both as required strings, but TypeScript didn't catch the omission because the store relied on a TS Type assertion / partial-shape pattern. The Dexie creating hook in apps/mana/apps/web/src/lib/data/database.ts only auto-stamps userId + __fieldTimestamps — it does NOT auto-stamp createdAt. Module stores are expected to set their own timestamps (consistent with the todo, calendar, contacts, notes stores etc.). So every memoro memo had `createdAt === undefined`, and the DetailView's `new Date(memo.createdAt ?? '').toLocaleDateString('de')` rendered as "Erstellt: Invalid Date" for every single memo. Fix: set both timestamps explicitly in create() before the Dexie add. Existing memos in the wild are still broken — they'd need a one-shot migration to backfill createdAt from the __fieldTimestamps map, but that's a bigger commit. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../web/src/lib/modules/memoro/stores/memos.svelte.ts | 11 ++++++++++- .../src/lib/modules/memoro/views/DetailView.svelte | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/mana/apps/web/src/lib/modules/memoro/stores/memos.svelte.ts b/apps/mana/apps/web/src/lib/modules/memoro/stores/memos.svelte.ts index 011f30edf..d9010bb64 100644 --- a/apps/mana/apps/web/src/lib/modules/memoro/stores/memos.svelte.ts +++ b/apps/mana/apps/web/src/lib/modules/memoro/stores/memos.svelte.ts @@ -29,6 +29,7 @@ export const memosStore = { audioDurationMs?: number; processingStatus?: LocalMemo['processingStatus']; }) { + const now = new Date().toISOString(); const newLocal: LocalMemo = { id: crypto.randomUUID(), title: data.title ?? null, @@ -41,7 +42,15 @@ export const memosStore = { isPublic: false, blueprintId: data.blueprintId ?? null, language: data.language ?? null, - }; + // createdAt + updatedAt are required by LocalMemo's type but the + // previous create() never set them — DetailView showed + // "Erstellt: Invalid Date" for every memo. The Dexie creating + // hook only auto-stamps userId + __fieldTimestamps; module + // stores have to set their own createdAt/updatedAt explicitly + // (consistent with the rest of the Mana modules). + createdAt: now, + updatedAt: now, + } as LocalMemo; const plaintextSnapshot = toMemo(newLocal); await encryptRecord('memos', newLocal); await memoTable.add(newLocal); diff --git a/apps/mana/apps/web/src/lib/modules/memoro/views/DetailView.svelte b/apps/mana/apps/web/src/lib/modules/memoro/views/DetailView.svelte index 4e9c1bae8..bc87516db 100644 --- a/apps/mana/apps/web/src/lib/modules/memoro/views/DetailView.svelte +++ b/apps/mana/apps/web/src/lib/modules/memoro/views/DetailView.svelte @@ -20,6 +20,13 @@ const detail = useDetailEntity({ id: () => memoId, table: 'memos', + // title, intro, transcript live in the encryption registry — without + // `decrypt: true` the inputs would bind to raw `enc:1:...` ciphertext + // strings instead of plaintext. Pre-existing bug surfaced when the + // LLM auto-title started populating the title field for the first + // time on 2026-04-09; previously the field was always null and the + // transcript was the only encrypted field shown, but no one noticed. + decrypt: true, onLoad: (val) => { editTitle = val.title ?? ''; editIntro = val.intro ?? '';