chore(M001/S03): auto-commit after complete-slice

This commit is contained in:
2026-03-24 12:40:09 +01:00
parent 406a1c15c7
commit ac1832ea04
11 changed files with 258 additions and 48 deletions
+102 -29
View File
@@ -1,34 +1,107 @@
---
title: S03 summary
status: done
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/followuptests/FollowUpTests.csproj...'
- CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-followup-drafts.test.tsx
- CI=true npm --prefix job-tracker-ui run build
- Browser UAT on built branch UI via localhost:3001 against localhost:5202
id: S03
parent: M001
milestone: M001
provides:
- Context-grounded follow-up drafting that combines imported correspondence, saved application package material, and explicit manual send/log behavior inside the job workspace.
requires:
- slice: S01
provides: Imported correspondence records, linked Gmail thread metadata, and ongoing thread refresh continuity tied to a job.
- slice: S02
provides: Saved tailored CV, cover letter, recruiter message, and marker-delimited application-answer draft state reused by follow-up drafting.
affects:
- S04
key_files:
- JobTrackerApi/Controllers/JobApplicationsController.cs
- JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs
- JobTrackerApi.Tests/JobTrackerApi.Tests.csproj
- job-tracker-ui/src/components/JobDetailsDialog.tsx
- job-tracker-ui/src/types.ts
- job-tracker-ui/src/job-details-followup-drafts.test.tsx
key_decisions:
- Expose follow-up grounding (`contextSummary`, `contextSignals`, thread subject, and last-correspondence metadata) directly from the backend DTO so the workspace explains why the draft exists instead of inferring context client-side.
- Preserve the manual-send boundary by keeping follow-up generation separate from explicit send/log submission.
patterns_established:
- Assemble thread/package grounding once in the backend and return it as part of the draft contract, then render the same grounding verbatim in the workspace.
- Reuse the S02 notes marker block for saved application-answer context instead of inventing a second persistence path for follow-up drafting.
observability_surfaces:
- GET /api/jobapplications/{id}/followup-draft
- POST /api/jobapplications/{id}/send-followup
- GET /api/correspondence/{jobId}
- JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs
- job-tracker-ui/src/job-details-followup-drafts.test.tsx
drill_down_paths:
- .gsd/milestones/M001/slices/S03/tasks/T01-SUMMARY.md
- .gsd/milestones/M001/slices/S03/tasks/T02-SUMMARY.md
duration: 2-task slice; planned 8h implementation plus closeout verification
verification_result: passed
completed_at: 2026-03-24
---
S03 turned follow-up drafting into a real thread-aware workspace flow.
# S03: Reply and follow-up drafting from real thread context
Delivered:
- stronger backend follow-up draft context in `JobTrackerApi/Controllers/JobApplicationsController.cs`
- imported correspondence, recruiter details, saved package material, and saved application-answer content now inform the follow-up draft
- follow-up responses expose context summary, context signals, thread subject, and last-correspondence metadata for the workspace
- reply-style subjects now reuse the active thread where available
- focused backend proof in `JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs`
- verifies the follow-up draft reacts to imported thread and saved package state
- stronger Follow-up tab in `job-tracker-ui/src/components/JobDetailsDialog.tsx`
- surfaces why the draft exists now
- shows thread/package grounding explicitly
- keeps manual-send behavior clear and editable
- focused frontend proof in `job-tracker-ui/src/job-details-followup-drafts.test.tsx`
- verifies thread grounding, editable draft state, and manual send/log behavior
- runtime browser proof
- built branch UI served locally on `localhost:3001`
- logged into the local app, opened the seeded job, verified the Follow-up tab showed thread/package grounding, sent a manual follow-up, and confirmed it logged back into Correspondence
**Follow-up drafting now reuses imported thread history plus saved package material, shows that grounding in the job workspace, and keeps outbound email behind an explicit manual send/log action.**
Net effect:
- imported correspondence and saved package material now feed useful follow-up drafting instead of sitting in separate surfaces
- the manual-send boundary remains intact
- the job workspace can now carry the user from imported thread context to reviewed draft to logged outbound follow-up
## What Happened
S03 closed the gap between the correspondence workspace built in S01 and the saved application package workspace built in S02. Before this slice, follow-up generation mostly behaved like a generic prompt over job summary text. After this slice, `JobApplicationsController` assembles follow-up context from the latest imported correspondence, recruiter details, saved tailored CV / cover letter / recruiter message material, and the marker-delimited application-answer draft saved in notes. The API now returns not only a draft subject/body, but also the grounding metadata the UI needs to explain why the draft was generated and what informed it.
On the frontend, `JobDetailsDialog.tsx` now treats follow-up drafting as part of the same per-job working loop rather than a blind compose form. The Follow-up tab shows thread subject, latest sender, context summary, and context signals; keeps the body editable before send; and makes the manual-send boundary explicit in the helper text and button flow. The UI posts the edited draft through the existing send/log endpoint instead of silently dispatching anything.
During closeout, the slice-level backend verification command in the plan was restored as a first-class path by repairing missing framework/package references in `JobTrackerApi.Tests/JobTrackerApi.Tests.csproj`. That means future agents can use the filtered `dotnet test ... --filter JobApplicationsFollowUpDraftTests` command directly in this worktree instead of relying on the older isolated harness workaround recorded during task execution.
Net effect: imported correspondence, saved package drafts, and the follow-up compose/send-log loop now form one coherent job-level workspace path. S04 can build overview and urgency surfaces on top of a follow-up flow that is already grounded and manually controlled.
## Verification
- Passed: `$HOME/.dotnet/dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsFollowUpDraftTests`
- Passed: `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-followup-drafts.test.tsx`
- Passed: `$HOME/.dotnet/dotnet build JobTrackerApi/JobTrackerApi.csproj`
- Passed: `CI=true npm --prefix job-tracker-ui run build`
- Observability surfaces confirmed through code/test contracts:
- `GET /api/jobapplications/{id}/followup-draft` now exposes grounding metadata (`contextSummary`, `contextSignals`, thread subject, last-correspondence details)
- `POST /api/jobapplications/{id}/send-followup` remains the explicit manual send/log boundary
- `GET /api/correspondence/{jobId}` remains the authoritative timeline surface for confirming logged outbound follow-up entries
## New Requirements Surfaced
- none
## Deviations
The written plan expected the filtered backend command to be the slice-level proof path, but task execution had fallen back to an isolated harness because `JobTrackerApi.Tests.csproj` was missing required ASP.NET Core / Identity / xUnit references. Closeout repaired the test project so the plan-level verification command now passes directly in this worktree.
## Known Limitations
- The slice materially strengthened follow-up drafting, but it still does not introduce a separate rich reply-specific workflow beyond thread-aware subject/context reuse; deeper reply-mode specialization can still be expanded later if usage demands it.
- This closeout did not re-run a full live Gmail + browser UAT loop end to end; the trusted evidence for S03 in this worktree is the focused backend/frontend verification plus the production frontend build.
- Follow-up quality still depends on upstream data quality from S01 and S02: weak imported thread metadata or missing saved package material will reduce how specific the draft can be.
## Follow-ups
- S04 should consume the new follow-up grounding/status signals to show which jobs are ready for follow-up, missing context, or need attention from overview surfaces.
- S05 should re-run the full live loop with real Gmail continuity plus follow-up drafting to reconfirm milestone trust end to end.
## Files Created/Modified
- `JobTrackerApi/Controllers/JobApplicationsController.cs` — assembled correspondence-aware follow-up context, exposed draft grounding metadata, and improved fallback/reply-style subject behavior.
- `JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs` — added focused backend proof that imported thread state plus saved package material change the follow-up draft.
- `JobTrackerApi.Tests/JobTrackerApi.Tests.csproj` — restored missing framework/package references so filtered backend verification commands run directly again.
- `job-tracker-ui/src/components/JobDetailsDialog.tsx` — exposed follow-up grounding in the workspace, kept drafts editable, and clarified the manual-send boundary.
- `job-tracker-ui/src/types.ts` — added the richer `FollowUpDraft` contract used by the workspace.
- `job-tracker-ui/src/job-details-followup-drafts.test.tsx` — proved the Follow-up tab renders context grounding and only sends/logs after explicit user action.
## Forward Intelligence
### What the next slice should know
- S03 made the follow-up flow depend on three upstream context sources at once: imported correspondence, saved package fields, and the marker-delimited application-answer draft in `JobApplication.Notes`. If S04 wants actionable table/dashboard indicators, it should reuse the backend grounding signals instead of trying to infer readiness from scattered raw fields in the browser.
### What's fragile
- `JobApplication.Notes` marker parsing for `<<<APPLICATION_ANSWER_DRAFT>>> ... <<<END_APPLICATION_ANSWER_DRAFT>>>` — if another slice starts appending free-form notes around that block incorrectly, follow-up context quality will silently degrade because saved application-answer reuse depends on parsing that exact marker format.
### Authoritative diagnostics
- `GET /api/jobapplications/{id}/followup-draft` and `JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs` — the endpoint payload is the single source of truth for what grounding the backend believes it has, and the focused backend test is the fastest trustworthy check when prompt assembly or DTO shape changes.
- `job-tracker-ui/src/job-details-followup-drafts.test.tsx` — this is the most reliable UI-level diagnostic for the manual-send boundary and edited-draft payload because it asserts the exact send/log request body after user edits.
### What assumptions changed
- “The slice may need an isolated backend harness because the filtered test command is not trustworthy.” — no longer true in this worktree; closeout repaired `JobTrackerApi.Tests.csproj`, so the plan-level filtered backend command now passes directly and should replace the older workaround.