chore(M001/S01): auto-commit after complete-slice
This commit is contained in:
@@ -7,6 +7,11 @@ files:
|
||||
- JobTrackerApi/Controllers/CorrespondenceController.cs
|
||||
- JobTrackerApi/Program.cs
|
||||
- JobTrackerApi.Tests/GmailControllerTests.cs
|
||||
observability_surfaces:
|
||||
- POST /api/gmail/import
|
||||
- POST /api/gmail/import-thread
|
||||
- persisted Correspondence.ExternalThreadId / ExternalFrom / ExternalTo fields
|
||||
- JobTrackerApi.Tests/GmailControllerTests.cs repeat-import coverage
|
||||
verification:
|
||||
- $HOME/.dotnet/dotnet build JobTrackerApi/JobTrackerApi.csproj
|
||||
- docker run --rm -v "$PWD":/src -w /src mcr.microsoft.com/dotnet/sdk:9.0 bash -lc '...dotnet test /tmp/gmailtests/GmailTests.csproj...'
|
||||
@@ -14,7 +19,8 @@ verification:
|
||||
|
||||
Extended correspondence persistence and Gmail import continuity for S01.
|
||||
|
||||
What changed:
|
||||
## What changed
|
||||
|
||||
- `Models/Correspondence.cs`
|
||||
- added `ExternalThreadId`
|
||||
- added `ExternalFrom`
|
||||
@@ -33,9 +39,25 @@ What changed:
|
||||
- added repeat thread import coverage
|
||||
- retained ranking and owned-job scope coverage from T01
|
||||
|
||||
Verification:
|
||||
## Verification
|
||||
|
||||
- Native API build passed with `$HOME/.dotnet/dotnet build JobTrackerApi/JobTrackerApi.csproj`
|
||||
- Isolated Gmail controller tests passed in Docker (`5 passed`)
|
||||
|
||||
Important caveat:
|
||||
- The repository’s main `JobTrackerApi.Tests` project still has unrelated pre-existing compile failures outside Gmail tests, so the exact planned command `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter GmailControllerTests` remains blocked by broader test drift. Gmail coverage itself passes when isolated.
|
||||
## Verification Evidence
|
||||
|
||||
| # | Command | Exit Code | Verdict | Duration |
|
||||
|---|---------|-----------|---------|----------|
|
||||
| 1 | `$HOME/.dotnet/dotnet build JobTrackerApi/JobTrackerApi.csproj` | 0 | ✅ pass | ~1.2s |
|
||||
| 2 | `docker run --rm -v "$PWD":/src -w /src mcr.microsoft.com/dotnet/sdk:9.0 bash -lc '...dotnet test /tmp/gmailtests/GmailTests.csproj...'` | 0 | ✅ pass | not recorded |
|
||||
|
||||
## Diagnostics
|
||||
|
||||
- Inspect persisted `Correspondence` rows for `ExternalMessageId`, `ExternalThreadId`, `ExternalFrom`, and `ExternalTo` to confirm Gmail imports keep thread identity plus sender/recipient labels.
|
||||
- Hit `POST /api/gmail/import` twice with the same Gmail message id to confirm the duplicate-safe `Imported`/`Skipped` contract.
|
||||
- Hit `POST /api/gmail/import-thread` twice with the same thread payload to confirm repeat imports skip already-linked message ids instead of duplicating correspondence.
|
||||
- Read `JobTrackerApi.Tests/GmailControllerTests.cs` for the durable expected behavior around repeat single-message and repeat thread imports.
|
||||
|
||||
## Important caveat
|
||||
|
||||
The repository’s main `JobTrackerApi.Tests` project still had unrelated pre-existing compile failures outside Gmail tests when this task finished, so the exact planned command `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter GmailControllerTests` remained blocked at that point by broader test drift. Gmail coverage itself passed when isolated.
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
estimated_steps: 4
|
||||
estimated_files: 4
|
||||
skills_used:
|
||||
- react-best-practices
|
||||
- test
|
||||
---
|
||||
|
||||
# T03: Wire ranked Gmail suggestions into the job workspace UI
|
||||
|
||||
**Slice:** S01 — Smarter Gmail import and matching
|
||||
**Milestone:** M001
|
||||
|
||||
## Description
|
||||
|
||||
Deliver the user-facing part of the slice in the actual job workspace. The Correspondence tab should stop acting like a generic Gmail search box and instead open with job-aware ranked suggestions from the backend, explain why each candidate is relevant, let the user override with manual search when needed, and refresh the job-linked correspondence view after import.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Update `job-tracker-ui/src/types.ts` to reflect the new backend candidate contract and enriched correspondence metadata from T01 and T02.
|
||||
2. Pass job context from `job-tracker-ui/src/components/JobDetailsDialog.tsx` into `job-tracker-ui/src/components/Correspondence.tsx` so the Gmail tab can request job-aware suggestions without duplicating the job fetch.
|
||||
3. Refactor `job-tracker-ui/src/components/Correspondence.tsx` to consume the backend-ranked suggestions, show thread/message match reasons and import state, keep manual Gmail query override/search available, and refresh the rendered correspondence list after successful imports.
|
||||
4. Add `job-tracker-ui/src/correspondence-gmail-import.test.tsx` covering ranked suggestion rendering, reason/confidence display, thread vs single-message import actions, and refresh after import.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- [ ] The Gmail tab opens on job-aware ranked suggestions instead of using `scoreMessage(...)` as the primary intelligence.
|
||||
- [ ] The UI still supports manual Gmail searching as a fallback override, but it no longer depends on freeform query heuristics for the core experience.
|
||||
- [ ] The React test proves the user can see ranked suggestions and that importing updates the same job’s correspondence surface.
|
||||
|
||||
## Verification
|
||||
|
||||
- `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx`
|
||||
- Manually inspect the dialog to confirm ranked reasons/import state are visible and the correspondence list refreshes after import.
|
||||
|
||||
## Observability Impact
|
||||
|
||||
- Signals added/changed: visible match reasons/confidence/import state in the Gmail tab and clearer import success/duplicate feedback toasts.
|
||||
- How a future agent inspects this: read `job-tracker-ui/src/correspondence-gmail-import.test.tsx` and open the Correspondence dialog in the running app.
|
||||
- Failure state exposed: the UI should distinguish no matches, already-imported candidates, loading states, and import failures instead of collapsing them into a generic empty list.
|
||||
|
||||
## Inputs
|
||||
|
||||
- `job-tracker-ui/src/components/JobDetailsDialog.tsx` — host dialog that already owns the job record.
|
||||
- `job-tracker-ui/src/components/Correspondence.tsx` — current Gmail import UI with client-side ranking.
|
||||
- `job-tracker-ui/src/types.ts` — frontend API contracts.
|
||||
- `JobTrackerApi/Controllers/GmailController.cs` — T01/T02 backend Gmail candidate and import contract.
|
||||
|
||||
## Expected Output
|
||||
|
||||
- `job-tracker-ui/src/components/JobDetailsDialog.tsx` — passes job context into the correspondence tab.
|
||||
- `job-tracker-ui/src/components/Correspondence.tsx` — renders job-aware Gmail suggestions and refreshed import behavior.
|
||||
- `job-tracker-ui/src/types.ts` — matches the updated backend contract.
|
||||
- `job-tracker-ui/src/correspondence-gmail-import.test.tsx` — proves the UI flow end to end at component level.
|
||||
@@ -6,34 +6,59 @@ files:
|
||||
- job-tracker-ui/src/components/Correspondence.tsx
|
||||
- job-tracker-ui/src/types.ts
|
||||
- job-tracker-ui/src/correspondence-gmail-import.test.tsx
|
||||
observability_surfaces:
|
||||
- job-tracker-ui/src/components/Correspondence.tsx Gmail tab linked-thread state
|
||||
- /gmail/job-candidates requests with queryOverride
|
||||
- /gmail/refresh-linked-threads workspace refresh requests
|
||||
- job-tracker-ui/src/correspondence-gmail-import.test.tsx
|
||||
verification:
|
||||
- npm ci (job-tracker-ui)
|
||||
- CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx
|
||||
---
|
||||
|
||||
Wired the job-aware Gmail matching contract into the actual job workspace UI.
|
||||
Wired the job-aware Gmail matching contract into the actual job workspace UI and completed the live linked-thread refresh loop.
|
||||
|
||||
## What changed
|
||||
|
||||
What changed:
|
||||
- `job-tracker-ui/src/types.ts`
|
||||
- added frontend contracts for job-aware Gmail matches, match reasons, import results, and enriched correspondence metadata
|
||||
- added frontend contracts for job-aware Gmail matches, linked-thread refresh results, import results, and enriched correspondence metadata
|
||||
- `job-tracker-ui/src/components/JobDetailsDialog.tsx`
|
||||
- now passes the loaded `job` into `Correspondence` so the Gmail tab can stay job-aware without another job fetch
|
||||
- passes the loaded `job` into `Correspondence` so the Gmail tab can stay job-aware without another job fetch
|
||||
- `job-tracker-ui/src/components/Correspondence.tsx`
|
||||
- replaced client-side Gmail ranking as the primary workflow
|
||||
- Gmail tab now calls `/gmail/job-candidates`
|
||||
- shows confidence, score, match reasons, and already-linked state
|
||||
- preserves manual query override via the same job-aware endpoint
|
||||
- refreshes correspondence plus Gmail candidate state after single-message and thread imports
|
||||
- automatically calls `/gmail/refresh-linked-threads` when the job already has linked Gmail thread ids
|
||||
- refreshes correspondence plus Gmail candidate state after single-message, thread, and linked-thread refresh actions
|
||||
- renders persisted Gmail metadata (`ExternalThreadId`, `ExternalFrom`, `ExternalTo`) in the correspondence view
|
||||
- shows linked-thread freshness/import summary inside the Gmail area
|
||||
- `job-tracker-ui/src/correspondence-gmail-import.test.tsx`
|
||||
- verifies ranked Gmail suggestions render with visible reasons/confidence
|
||||
- verifies single-message import refreshes the same job’s correspondence view
|
||||
- verifies automatic linked-thread refresh shows a later Gmail reply without manual re-import
|
||||
- verifies manual search override is sent as `queryOverride`
|
||||
|
||||
Verification:
|
||||
## Verification
|
||||
|
||||
- frontend dependencies were installed with `npm ci` in `job-tracker-ui`
|
||||
- focused React test passed:
|
||||
- `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx`
|
||||
|
||||
Notes:
|
||||
- The Gmail tab now treats the backend as the source of truth for ranking while keeping the manual search field as a fallback override.
|
||||
## Verification Evidence
|
||||
|
||||
| # | Command | Exit Code | Verdict | Duration |
|
||||
|---|---------|-----------|---------|----------|
|
||||
| 1 | `npm ci` (job-tracker-ui) | 0 | ✅ pass | not recorded |
|
||||
| 2 | `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx` | 0 | ✅ pass | ~2.8s |
|
||||
|
||||
## Diagnostics
|
||||
|
||||
- Open a job with imported Gmail correspondence and inspect the Gmail tab chips: linked-thread count, last refresh summary, and Gmail connection `lastSyncedAt` show whether the workspace considers the thread live.
|
||||
- Watch network traffic for `GET /gmail/job-candidates` and `POST /gmail/refresh-linked-threads` to confirm the workspace distinguishes ranked suggestions from already-linked thread refresh.
|
||||
- Inspect rendered correspondence chips (`Thread ...`, `From ...`, `To ...`) to verify imported Gmail metadata survived the round trip from persistence to UI.
|
||||
- Read `job-tracker-ui/src/correspondence-gmail-import.test.tsx` for the durable automated proof of manual query override plus no-manual-reimport continuity.
|
||||
|
||||
## Notes
|
||||
|
||||
The Gmail tab now treats the backend as the source of truth for ranking while keeping the manual search field as a fallback override, and it refreshes known linked threads once per loaded job/thread-set automatically to avoid re-import loops.
|
||||
|
||||
Reference in New Issue
Block a user