diff --git a/docs/email-migration-checklist.md b/docs/email-migration-checklist.md deleted file mode 100644 index e2a0fac2..00000000 --- a/docs/email-migration-checklist.md +++ /dev/null @@ -1,108 +0,0 @@ -# Email sidecar migration — test checklist - -For `7c173b4`, which moved the mail store and all 14 routes out of the platform and into -`officer-email`. Each line is a single yes/no. Report as "M3 ok, R2 needs fix". - -**Pre-req:** `pm2 restart officer-email && pm2 restart officer`, then hard-refresh. Both are needed — -the sidecar gained an HTTP listener and the platform became a proxy; restarting only one leaves them -speaking different protocols. - -**Why this needs testing at all:** the routes moved *verbatim*, so the logic should be identical. What -changed underneath is the transport (browser → platform proxy → sidecar HTTP) and where the user -identity comes from (`X-Officer-User` header instead of the platform's `userMiddleware`). Failures will -cluster in those two places, not in mail logic. - ---- - -## M — Messages and folders - -- [ ] **M1** `/email` loads and lists messages. -- [ ] **M2** Folder switching works, and per-folder counts look right (inbox / sent / all). -- [ ] **M3** Paging past the first page works. -- [ ] **M4** `/email/stats` renders — the totals panel is populated, not zeroed. -- [ ] **M5** Labels/folders list is populated. - -## R — Reading a message - -- [ ] **R1** Open a message → body, sender, date, recipients all render. -- [ ] **R2** Open a thread → the whole conversation, in order. -- [ ] **R3** Mark as read → state sticks after a refresh. -- [ ] **R4** Mark a whole thread read. -- [ ] **R5** Delete a message → it disappears and stays gone after a refresh. -- [ ] **R6** Deep-link `/email/:emailId` in a fresh tab opens that message. - -## S — Search and contacts - -- [ ] **S1** Search returns sensible results. -- [ ] **S2** Search with an apostrophe or quote in the term behaves (`it's`, `"x"`), i.e. no 500. -- [ ] **S3** Contacts list populates (used by the compose autocomplete). - -## A — Attachments - -- [ ] **A1** A message with attachments shows them. -- [ ] **A2** Extracting/downloading an attachment works and the file is intact. - *Attachments write under `DATA_PATH`; the sidecar does this now, so a permissions problem would - surface here first.* - -## L — Live updates (the SSE path) - -- [ ] **L1** Leave `/email` open, send yourself mail → it appears without a manual refresh. -- [ ] **L2** No repeated reconnect errors in the browser console while the page sits idle. - *This is the biggest structural change: `email:new` used to travel sidecar → platform → SSE. The - stream is inside the sidecar now and the IDLE watcher pushes to it in-process.* - -## C — Accounts - -- [ ] **C1** The accounts screen lists the account with its status. -- [ ] **C2** Sync status / last-synced is shown and looks current. -- [ ] **C3** Trigger a manual sync → it starts. -- [ ] **C4** Adding an account still validates the IMAP connection (test with a deliberately wrong - password and expect a clear failure, not a hang). - -## X — Sync regression (still platform-side, deliberately) - -The two sync handlers did **not** move; they still run in the platform queue and now import the store -from its new location. So this block is checking nothing *broke*, not that anything improved. - -- [ ] **X1** New mail still arrives — the periodic sync is running. -- [ ] **X2** Email sync jobs still appear in the Jobs list (they will stop doing so in stage 2, by - design — option A). - -## P — Proxy behaviour - -Run from the host. Mint a token the same way the app does, or reuse a browser one. - -- [ ] **P1** A long request survives: trigger a from-scratch resync and confirm it isn't cut off around - 60s. The proxy sets `timeoutSeconds: 1800` for the whole `/api/email` prefix. -- [ ] **P2** `/api/email/messages` returns 503 (not a hang or a 500) while `officer-email` is stopped: - ```bash - pm2 stop officer-email - curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $TOK" \ - -H 'Host: officer.pastilhas.dev' http://127.0.0.1:9010/api/email/messages # expect 503 - pm2 start officer-email - ``` -- [ ] **P3** Nothing in `pm2 logs officer` mentions email internals any more — the platform should be - logging proxy failures at most, never mail. - ---- - -## Attributing a failure - -The split makes this quick: - -| symptom | look at | -|---|---| -| `503 email sidecar not available` | the sidecar isn't running, or hasn't announced its port — `pm2 logs officer-email` | -| `502 email sidecar unreachable` | it announced a port but died; check for a crash on boot | -| `401 missing X-Officer-User` | the proxy didn't inject the header — a platform-side problem | -| anything about messages, folders, IMAP | the sidecar — `pm2 logs officer-email` | - -`pm2 logs officer-email` should now carry everything mail-related. If mail errors are still appearing -in `pm2 logs officer`, something didn't move. - -## Known-broken already, not caused by this - -`gmail-sync` is hardcoded in all three channel handlers (telegram, discord, whatsapp), but the only -account is `provider=gmail, auth_type=password`, which routes to IMAP. So "sync emails" from a chat -channel was already failing before this change. It gets fixed in stage 2, when the channels stop -opening the mail store directly and ask the sidecar over HTTP. diff --git a/docs/nav-test-checklist.md b/docs/nav-test-checklist.md deleted file mode 100644 index e100406e..00000000 --- a/docs/nav-test-checklist.md +++ /dev/null @@ -1,106 +0,0 @@ -# Navigation refactor + sidecars — runtime test checklist - -**Complete.** 41 checks run, 15 voided when Projects was removed. Three defects found and fixed: -C4 (`d8cf79b`), D7/D8 (`18e732f`), plus an unrelated layout bug found along the way (`1a5c6c8`). -One known issue left unfixed on purpose: D12-edit on mobile. - -Provenance: written by the session that did the navigation refactor (`eff24773`, last message -2026-07-30T06:21Z) and never saved before that session was lost. Recovered from its transcript. - -**Pre-req:** `master` at `3c3b67c` or later covers **everything**, including the **X** block — the -original note said X needed the `navigation-refactor` branch, but the sidecar work is merged now, so -nav and sidecars are on master together. Restart before testing (`pm2 restart officer`) and -hard-refresh the browser; a stale bundle looks exactly like a failure. Watch the console as you go. - -Status key: `[x]` verified working · `[!]` found broken, fixed, re-verified · `[ ]` not yet tested. - ---- - -## C — Chat: session list & routing (`/chat`) — 6/6 ✅ - -- [x] **C1** Click a chat row → URL changes to `/chat/`. -- [x] **C2** Right-click a row → "Copy link" gives `/chat/` (a real link, not a button). -- [x] **C3** Clicking a row loads that conversation in the right panel. -- [!] **C4** The cwd/folder picker shows the correct folder for the opened chat. **Was broken — fixed.** -- [x] **C5** Refresh while on `/chat/` → lands back in the same chat. -- [x] **C6** Paste a `/chat/` URL into a fresh tab → opens that chat with the right cwd. - -### C4: what was wrong - -Opening any session from a non-default folder moved the picker to a **subdirectory** of that folder — -three of the four sessions under `~/dockers/officer.dev` jumped to `platform`, the fourth to `Lyrics`. -The list stayed correct; only the picker moved, and everything after it was scoped to the wrong dir. - -Two functions in `claude-sessions.ts` derived cwd in opposite directions: - -| | line | rule | -|---|---|---| -| `parseSummary` (builds the list) | `:103` | `if (entry.cwd && !cwd)` → **first** cwd wins | -| `parseClaudeTranscript` (opens one) | `:182` | `if (entry.cwd)` → **last** cwd wins, overwritten every entry | - -A transcript records a `cwd` on every entry, so the last one is wherever a tool happened to `cd` — not -the session's home. Fixed by taking the first cwd in both, which is also where Claude Code files the -transcript on disk. - -Pre-existing, but **surfaced** by the nav work: once rows became real ``s (`f35c145`), clicking -one is a route change, so the deep-link resolver in `ChatHistory/index.tsx:69` — previously reached only -on refresh or a pasted URL — now runs on every ordinary click, and it calls `setActiveCwd(detail.cwd)`. - -## L — Chat: long-transcript lazy-load — 8/8 ✅ - -- [x] **L1** Open a very long chat → instantly at the newest message (no long scroll or visible jump). -- [x] **L2** Open is fast (only the tail loads, not thousands of messages). -- [x] **L3** Scroll near the top → older messages load (brief spinner at top). -- [x] **L4** After older messages load, the view stays put (doesn't snap to top or bottom). -- [x] **L5** Keep scrolling up → eventually reaches the true first message; loading stops. -- [x] **L6** Send a new message in a resumed chat → appends at the bottom, view follows. -- [x] **L7** A short chat (<20 msgs) behaves normally — all visible, no spinner. -- [x] **L8** "Jump to bottom" appears when scrolled up, and works. - -## J — Jobs (`/jobs`) — H1 — 8/8 ✅ - -- [x] **J1** Click a job row → URL changes to `/jobs/`. -- [x] **J2** The clicked job's detail renders on the right. -- [x] **J3** The active row is highlighted. -- [x] **J4** Right-click a row → "Copy link" gives `/jobs/`. -- [x] **J5** The row's stop/delete button works and does **not** navigate. -- [x] **J6** Refresh on `/jobs/` → same job detail loads. -- [x] **J7** Both panels (Running/Queued **and** History) navigate correctly. -- [x] **J8** Different detail types still render (script terminal / pipeline steps / download). - -## D — Dashboards (`/dashboards`) — H2 — 12/13 ✅ (D12-edit on mobile: not fixed, mobile web being retired) - -- [x] **D1** Click a row → URL becomes `/dashboards?selected=`. -- [x] **D2** The preview panel shows that dashboard. -- [x] **D3** The clicked row is highlighted. -- [x] **D4** Preview's "open" arrow overlay → `/dashboards/` (full page). -- [x] **D5** "New Dashboard" → create form appears; `?selected=` cleared from the URL. -- [x] **D6** Create a dashboard → navigates to the full `/dashboards/`. -- [!] **D7** Edit (pencil) → edit form appears; does **not** navigate. -- [x] **D8** Save an edit → preview shows the edited dashboard (`?selected=`). -- [x] **D9** Delete → removed; if it was selected, the preview clears. -- [x] **D10** Edit/delete buttons do **not** trigger navigation (siblings of the link, not nested). -- [x] **D11** A dashboard row **outside** `/dashboards` opens `/dashboards/` directly. -- [~] **D12** Mobile: selecting shows the detail panel; back clears it. -- [x] **D13** Deep-link `/dashboards?selected=` in a fresh tab → preview shows it. - -## P — Projects — DROPPED - -The Projects feature was removed rather than fixed (see the deletion commit). All 15 P checks are void. - -It had the same two defects Dashboards had — edit clearing `?selected=`, and an abandoned edit following -you to the next item — plus the same structure that caused them: the form reachable only through the -empty state. None of it was worth repairing for a feature being retired. - -## X — Chat lazy-load × sidecars — 3/3 ✅ - -- [x] **X1** Open a long chat → **no** spurious "⚠️ some output could not be recovered" banner. -- [x] **X2** Send a new turn → appends correctly below the loaded tail. -- [x] **X3** Scroll up to load history, then send a turn / reconnect → prepended older messages are - **not** wiped. - -## R — Quick regressions — 3/3 ✅ - -- [x] **R1** Search/filter boxes in Jobs / Dashboards / Projects still filter the list. -- [x] **R2** No new console errors on `/jobs`, `/dashboards`, `/projects`, `/chat`. -- [x] **R3** Browser back/forward moves between selections sensibly (selection is in the URL now).