108 lines
9.0 KiB
Markdown
108 lines
9.0 KiB
Markdown
---
|
|
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: Reply and follow-up drafting from real thread context
|
|
|
|
**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.**
|
|
|
|
## 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.
|