Complete Gmail correspondence workflow

This commit is contained in:
2026-04-02 12:29:24 +02:00
parent 1f34eb42d2
commit 5cd34f17bb
10 changed files with 1390 additions and 145 deletions
+67 -53
View File
@@ -1,62 +1,76 @@
# Smart Gmail Job Correspondence Integration Progress
## Branch
- feat/gmail-job-correspondence
- main
## Status
- Workstream initialized.
- Milestones planned: M006-M010.
- Current focus: M006 / S01 foundation work.
- Core Phase 1 Gmail correspondence feature is now implemented in code.
- Remaining gap is deployment/runtime rollout on the live host, not missing product logic in this repo.
## Completed so far
- Created separate Gmail feature branch and merged the completed checkpoint into `main`.
- Captured foundation context in `.gsd/milestones/M006/M006-CONTEXT.md`.
- Planned milestones M006-M010 for the Gmail workstream.
- Planned slice M006/S01.
- Confirmed existing architecture seams:
- Gmail OAuth/token flow already exists.
- Per-job Gmail candidate search/import/thread refresh already exists.
- Correspondence persistence already stores Gmail thread/message metadata.
- Current implementation is job-local, not global-inbox/review oriented.
- Implemented M006/S01 foundation changes:
- durable Gmail sync-state fields on `GmailConnection`
- SQLite/MySQL bootstrap support for new Gmail sync-state columns
- richer `GET /api/gmail/status` response
- per-job correspondence UI now shows sync diagnostics
- focused backend/frontend Gmail tests added and passing
- Phase 2 extension seam scaffolded with a no-op enrichment service
- Phase 1/2 design doc added at `docs/gmail-correspondence-phase1.md`
- Started M007 ingestion/storage work:
- imported correspondence now stores direction, Gmail labels JSON, and attachment metadata JSON
- Gmail message detail extraction now reads labels and attachment metadata from Gmail payloads
- focused Gmail backend/frontend tests pass against the richer import contract
- Added the first cross-job UX surface:
- new `/correspondence` inbox API
- new global correspondence inbox page and nav route
- focused frontend test for inbox filtering/refresh behavior
- Current next focus:
- deterministic Gmail matching logic now extracted into `JobTrackerApi/Services/GmailJobMatchingService.cs`
- next step is to build cross-job routing/review behavior on top of that reusable matching seam
- branch context has been merged into `main`; continue delivery directly on `main`
- Added a first review surface:
- backend `GET /api/gmail/review-candidates`
- frontend `/correspondence/review` page
- focused review-page frontend test
- Review queue is now actionable:
- backend `POST /api/gmail/review-decision`
- frontend actions for link/reject/keep-in-review
- focused action test and successful frontend build
- Backend release build for `JobTrackerApi` is clean again after fixing a duplicated `app.Run()` tail in `Program.cs`.
- Cleaned the new Gmail page tests to use the same React Router future flags as the app, removing warning noise from the inbox/review suites.
## Completed
## Next tasks
1. Implement M006/S01/T01: refactor Gmail connection foundation and sync-state model.
2. Implement M006/S01/T02: expose sync-state surfaces in UI without breaking current correspondence workflow.
3. Implement M006/S01/T03: prepare Phase 2 extension seam/docs.
4. Verify backend + frontend Gmail focused tests.
5. Commit and push incremental progress.
### Foundation
- Gmail OAuth connect/disconnect/status flow preserved.
- Durable Gmail sync-state fields added and surfaced from `GET /api/gmail/status`.
- Per-job correspondence UI shows Gmail sync diagnostics.
### Ingestion and storage
- Imported Gmail correspondence stores:
- direction
- Gmail labels JSON
- attachment metadata JSON
- Gmail payload parsing extracts labels and attachment metadata.
- Message-level deduplication remains in place.
- Linked-thread refresh continues to import only new thread messages.
### Matching and routing
- Deterministic scoring extracted to `JobTrackerApi/Services/GmailJobMatchingService.cs`.
- Review queue backend exists at `GET /api/gmail/review-candidates`.
- Review decisions persist through `POST /api/gmail/review-decision`.
- Manual sync now exists at `POST /api/gmail/manual-sync`.
- Manual sync applies a bounded historical window and excludes spam/trash by default.
- High-confidence matches now auto-link during manual sync.
- Medium-confidence matches remain in review.
- Low-confidence job-like threads can be marked as suggested jobs.
- Suggested-job surfaces now exist via:
- `GET /api/gmail/suggested-jobs`
- `POST /api/gmail/create-suggested-job`
### Correspondence UX
- Global inbox exists at `/correspondence`.
- Gmail review page exists at `/correspondence/review`.
- Review page now supports:
- manual sync
- routing filters
- review notes
- link/review/reject/suggested actions
- create-job flow from suggested Gmail threads
- Per-job correspondence workspace now supports:
- linked-thread refresh
- unlink thread from current job
- move/relink thread to another existing job
- Backend relink/unlink endpoints now exist:
- `POST /api/gmail/relink-thread`
- `POST /api/gmail/unlink-thread`
### Phase 2 prep
- Future seam remains in place at `JobTrackerApi/Services/GmailCorrespondenceEnrichment.cs`.
- Design doc remains in place at `docs/gmail-correspondence-phase1.md`.
### Deployment hardening
- Added deploy smoke-check logic to `deploy/deploy.sh`.
- Deploy now fails if `${APP_PUBLIC_BASE_URL}/api/auth/config` returns HTML or non-JSON instead of backend auth config JSON.
## Verification completed
- `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter GmailControllerTests /p:DisableSourceControlManagerQueries=true`
- `cd job-tracker-ui && CI=true ./node_modules/.bin/react-scripts test --runInBand --watch=false src/correspondence-gmail-import.test.tsx src/gmail-review-page.test.tsx src/correspondence-inbox-page.test.tsx`
- `dotnet build './Job tracker.sln' -c Release`
## Runtime note
- Live host check shows `https://jobs.cesnimda.uk/api/auth/config` currently returns the frontend HTML shell (`x-powered-by: Express`) instead of backend JSON.
- That is a deployment/proxy mismatch outside the app code in this checkout.
- The new deploy smoke-check was added so future deploys fail fast on that condition.
## Resume notes
- Previous CV/parsing branch work is separate and already pushed.
- Local dev SQLite runtime still has missing-table drift in some unrelated surfaces (`RuleSettings`, `Companies`, etc.); avoid conflating that with the Gmail feature work.
- Existing per-job Gmail tests live in `JobTrackerApi.Tests/GmailControllerTests.cs` and `job-tracker-ui/src/correspondence-gmail-import.test.tsx`.
- If the live site still shows 404s for `/api/...`, the running service is not the repos Dockerized frontend+backend path.
- The CRA/Express-style live response and websocket attempts to `:3000/ws` suggest an old dev-style frontend process or wrong reverse-proxy target is still serving the domain.