From 23862d3ae0c662cbcde34b268ecb129a2aab350f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Fri, 24 Jul 2026 08:39:05 +0000 Subject: [PATCH] todo: record shipped email work and deferred follow-ups Co-Authored-By: Claude Opus 4.8 --- TODO.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/TODO.md b/TODO.md index ec6264f0..a3f22dd1 100644 --- a/TODO.md +++ b/TODO.md @@ -39,6 +39,25 @@ Deferred work. Context: Officer is collapsing from multi-tenant / open-source-re DB (`from:github OR from:deepgram` = 90+7 = 97 exactly). - [ ] **Remaining:** parenthesised grouping (nesting `(a OR b) c`), `in:sent/inbox/spam/trash` (folder scope), and relative dates (`newer_than:7d`). Grouping needs a recursive parser. + - [ ] **Group search results into threads too.** Folder views group by conversation (`ee11c94`), but + `/email/search` still returns one row per message. Apply the same `thread_id` collapse to the + FTS result set so search matches Gmail's grouped results. + +- [x] **Conversation threading** (done 2026-07-24, `ee11c94`). `thread_id` column on `emails`: + header-based for new mail (`id` = `sha1(Message-Id)`, so `References[0]` hashes to the root's + id — `computeThreadId` in `email-db.ts`), subject+counterpart backfill for already-synced mail. + `/messages` collapses to one row per thread (window fn) with count/unread; `/thread/:id` + + `/thread/:id/read`; reader renders a collapsible stack. Verified on synthetic + 18k real DB. + - [ ] **Upgrade old mail to exact threading.** One-time full re-fetch to capture `References` for + already-synced mail — replaces the subject+counterpart fallback (which can over-merge recurring + same-subject mail from one sender). Heavy/network-bound; opt-in. + - [ ] **Store the RFC `Message-Id` header** on ingest so replies can set a real `In-Reply-To` + (currently reply threading leans on subject/participants; `id` is a local hash, not the header). + +- [x] **Compose/reply/send** (done 2026-07-24). Gmail SMTP send with contacts autocomplete, rich + contenteditable body (inline images at the caret via paste/drag-drop, Bcc), single close button. +- [x] **`busy_timeout` on the email db** (done 2026-07-24, `9527e0b`). API + email sidecar share + `emails.db`; wait out a concurrent writer instead of 500-ing with "database is locked". ## Known bugs