--- estimated_steps: 4 estimated_files: 4 skills_used: - react-best-practices - test --- # T02: Surface live Gmail thread continuity in the job workspace **Slice:** S01 — Smarter Gmail import and matching **Milestone:** M001 ## Description Complete S01 in the UI by turning the existing ranked Gmail import tab into a live linked-thread workspace. The executor should preserve the current ranked suggestion/import flow, then layer in automatic refresh for already-linked Gmail threads so the user sees new replies appear on the same job without using the import action again. ## Steps 1. Inspect the current Gmail UI in `job-tracker-ui/src/components/Correspondence.tsx`, the host wiring in `job-tracker-ui/src/components/JobDetailsDialog.tsx`, and the existing component test in `job-tracker-ui/src/correspondence-gmail-import.test.tsx`. 2. Update `job-tracker-ui/src/types.ts` and `job-tracker-ui/src/components/Correspondence.tsx` to consume the new backend linked-thread refresh contract and track refresh/loading/freshness state separately from the ranked import-suggestion state. 3. Wire `job-tracker-ui/src/components/Correspondence.tsx` so already-linked threads refresh automatically at the right moment in the job workspace flow, refresh the rendered correspondence list after sync, and make the linked/live state legible in the UI. 4. Extend `job-tracker-ui/src/correspondence-gmail-import.test.tsx` to prove the continuity path: after a thread is already linked, a refresh brings in a later Gmail reply and renders it on the same job without another import action. ## Must-Haves - [ ] The UI keeps ranked job-aware Gmail suggestions for first import while clearly distinguishing already-linked live threads from new import candidates. - [ ] Linked-thread refresh happens through the new backend contract and updates the visible correspondence list without requiring the user to click an import button again. - [ ] The React test proves the continuity path, not just the original ranked-import path. ## Verification - `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx` - Manually inspect the Correspondence dialog to confirm linked-thread state, refresh/loading state, and the newly synced message all appear in the workspace. ## Observability Impact - Signals added/changed: visible linked/live thread state, refresh progress/freshness state, and clearer no-new-messages vs failure feedback. - How a future agent inspects this: run `job-tracker-ui/src/correspondence-gmail-import.test.tsx` and inspect the Gmail area in `job-tracker-ui/src/components/Correspondence.tsx`. - Failure state exposed: the UI should distinguish refresh failure, disconnected Gmail, no linked threads, and successful refresh with zero new messages. ## Inputs - `job-tracker-ui/src/components/Correspondence.tsx` — current ranked Gmail import UI. - `job-tracker-ui/src/components/JobDetailsDialog.tsx` — host dialog that owns the job workspace. - `job-tracker-ui/src/types.ts` — frontend Gmail and correspondence contracts. - `job-tracker-ui/src/correspondence-gmail-import.test.tsx` — existing Gmail import component test. - `JobTrackerApi/Controllers/GmailController.cs` — T01 backend refresh contract consumed by the UI. ## Expected Output - `job-tracker-ui/src/components/Correspondence.tsx` — renders linked-thread refresh state and continuity behavior. - `job-tracker-ui/src/types.ts` — matches the backend refresh contract. - `job-tracker-ui/src/correspondence-gmail-import.test.tsx` — proves the no-manual-reimport continuity path. - `job-tracker-ui/src/components/JobDetailsDialog.tsx` — includes any required wiring for the refreshed workspace flow.