Implement S03 follow-up draft context loop
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# S03: Reply and follow-up drafting from real thread context
|
||||
|
||||
**Goal:** Make follow-up drafting use imported correspondence and saved application material well enough that the job workspace can produce specific, trustworthy follow-up and reply drafts without crossing the manual-send boundary.
|
||||
**Demo:** From a job with imported Gmail correspondence and saved package material, the user opens the Follow-up tab, generates a draft that clearly reflects the thread stage plus saved job context, edits it, and manually sends/logs it while keeping outbound control.
|
||||
|
||||
S03 directly owns active requirements **R004**, **R007**, and **R008**. The main risk is that the existing follow-up draft endpoint still behaves like a generic template generator: it knows basic job facts, but it does not deliberately consume imported thread details or the saved package material that now exists after S02. This slice should strengthen that backend context first, then make the workspace expose the richer draft state clearly without adding autonomous sending behavior or a second competing draft surface.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- Follow-up draft generation in `JobTrackerApi/Controllers/JobApplicationsController.cs` uses imported correspondence, recruiter details, and saved application package material deliberately enough that the draft responds to the real thread stage instead of generic reminders.
|
||||
- The job workspace in `job-tracker-ui/src/components/JobDetailsDialog.tsx` presents follow-up drafting as job-tied working context, including visible thread/package grounding and editable draft state before manual send.
|
||||
- The slice preserves the explicit manual-send boundary: the app may draft and log what was sent, but it must not auto-send or silently dispatch anything.
|
||||
|
||||
## Proof Level
|
||||
|
||||
- This slice proves: integration
|
||||
- Real runtime required: yes
|
||||
- Human/UAT required: yes
|
||||
|
||||
## Verification
|
||||
|
||||
- `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsFollowUpDraftTests`
|
||||
- `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-followup-drafts.test.tsx`
|
||||
- Manual UAT: open a job with imported correspondence and saved package material, generate a follow-up draft, confirm it references the real job/thread/package context, edit the draft, send/log it manually, and verify the job timeline reflects the sent message without any autonomous outbound behavior.
|
||||
|
||||
## Observability / Diagnostics
|
||||
|
||||
- Runtime signals: follow-up draft responses should expose why the draft was generated now, what thread/package context informed it, and sent follow-ups should continue to create correspondence timeline entries.
|
||||
- Inspection surfaces: `GET /api/jobapplications/{id}/followup-draft`, `POST /api/jobapplications/{id}/send-followup`, `GET /api/correspondence/{jobId}`, and the Follow-up tab in `job-tracker-ui/src/components/JobDetailsDialog.tsx`.
|
||||
- Failure visibility: focused backend tests should make missing-context and weak-context behavior obvious, while the workspace should distinguish generation failure, editable draft state, and sent/logged state.
|
||||
- Redaction constraints: imported message bodies and recruiter details stay inside application data flows; no new diagnostic logging should expose raw correspondence or secrets.
|
||||
|
||||
## Integration Closure
|
||||
|
||||
- Upstream surfaces consumed: imported correspondence in `Models/Correspondence.cs` and `JobTrackerApi/Controllers/CorrespondenceController.cs`, saved package material in `JobTrackerApi/Controllers/JobApplicationsController.cs`, and the current follow-up workspace in `job-tracker-ui/src/components/JobDetailsDialog.tsx`.
|
||||
- New wiring introduced in this slice: correspondence-aware follow-up context assembly plus a clearer job-workspace follow-up loop grounded in saved package material and thread state.
|
||||
- What remains before the milestone is truly usable end-to-end: S04 still needs to improve the daily control surfaces, and S05 still needs full live-loop revalidation across import, drafting, follow-up, and tracking.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [x] **T01: Strengthen follow-up draft context assembly and backend reply/follow-up tests** `est:4h`
|
||||
- Why: The slice succeeds or fails on draft quality and trust, so the generator must consume imported thread context plus saved package material before the workspace polish matters.
|
||||
- Files: `JobTrackerApi/Controllers/JobApplicationsController.cs`, `JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs`
|
||||
- Do: Audit `GetFollowUpDraft` and related helpers, add deliberate use of imported correspondence metadata/content, recruiter details, saved tailored CV / cover letter / recruiter message material, and explicit thread-stage cues; keep the manual-send boundary intact; and add focused backend tests proving the returned draft reflects real thread and package context instead of generic follow-up text.
|
||||
- Verify: `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsFollowUpDraftTests`
|
||||
- Done when: follow-up draft generation clearly uses job/thread/package context and focused backend tests prove the response is materially more specific.
|
||||
- [x] **T02: Make the follow-up workspace show thread-grounded draft state without autonomous sending** `est:4h`
|
||||
- Why: Even a stronger backend draft will still feel fragile if the Follow-up tab hides what context informed it or behaves like a blind mail form.
|
||||
- Files: `job-tracker-ui/src/components/JobDetailsDialog.tsx`, `job-tracker-ui/src/types.ts`, `job-tracker-ui/src/job-details-followup-drafts.test.tsx`
|
||||
- Do: Refine the Follow-up tab so the user can see why a draft was generated now, what saved/job/thread context informed it, edit the draft before sending, and observe the manual-send boundary clearly; expand focused frontend coverage for generate/edit/send/log behavior.
|
||||
- Verify: `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-followup-drafts.test.tsx`
|
||||
- Done when: the Follow-up tab presents a grounded editable draft loop tied to the job and the focused frontend test proves generation, editability, and manual send/log behavior.
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
- `JobTrackerApi/Controllers/JobApplicationsController.cs`
|
||||
- `JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs`
|
||||
- `job-tracker-ui/src/components/JobDetailsDialog.tsx`
|
||||
- `job-tracker-ui/src/types.ts`
|
||||
- `job-tracker-ui/src/job-details-followup-drafts.test.tsx`
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
estimated_steps: 4
|
||||
estimated_files: 2
|
||||
skills_used:
|
||||
- test
|
||||
---
|
||||
|
||||
# T01: Strengthen follow-up draft context assembly and backend reply/follow-up tests
|
||||
|
||||
**Slice:** S03 — Reply and follow-up drafting from real thread context
|
||||
**Milestone:** M001
|
||||
|
||||
## Description
|
||||
|
||||
Make the follow-up draft endpoint use imported correspondence, recruiter details, and saved application package material so the draft reflects the real thread stage and saved job context instead of a generic reminder template.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Audit `GetFollowUpDraft` and nearby helpers in `JobApplicationsController` to identify which imported thread/package signals are currently ignored.
|
||||
2. Add or refactor backend context assembly so follow-up drafting consumes recent correspondence, saved package material, recruiter details, and stage-specific cues without crossing the manual-send boundary.
|
||||
3. Add focused backend tests proving the follow-up draft output changes in response to thread/package context and still preserves explicit manual-send behavior.
|
||||
4. Verify the focused backend behavior with an isolated test path if the broader test project remains blocked by unrelated compile drift.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- [ ] Follow-up draft context includes imported correspondence and saved application package material deliberately.
|
||||
- [ ] The generated follow-up draft reflects thread stage/recruiter context instead of generic job-only phrasing.
|
||||
- [ ] Focused backend tests prove the stronger draft grounding.
|
||||
|
||||
## Verification
|
||||
|
||||
- `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsFollowUpDraftTests`
|
||||
- Focused isolated harness if needed: run only `JobApplicationsFollowUpDraftTests` against `JobTrackerApi/Controllers/JobApplicationsController.cs`
|
||||
|
||||
## Observability Impact
|
||||
|
||||
- Signals added/changed: richer follow-up draft reason/context surface and clearer thread-aware draft behavior.
|
||||
- How a future agent inspects this: `GET /api/jobapplications/{id}/followup-draft` plus `JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs`.
|
||||
- Failure state exposed: missing thread/package context should show up as weaker fallback behavior in focused backend tests rather than silent generic output.
|
||||
|
||||
## Inputs
|
||||
|
||||
- `JobTrackerApi/Controllers/JobApplicationsController.cs` — existing follow-up draft and send/log endpoints.
|
||||
- `Models/Correspondence.cs` — imported thread/sender/recipient fields from S01.
|
||||
- `JobTrackerApi.Tests/JobApplicationsApplicationPackageTests.cs` — current focused test seam style for isolated job-application behavior.
|
||||
|
||||
## Expected Output
|
||||
|
||||
- `JobTrackerApi/Controllers/JobApplicationsController.cs` — stronger follow-up draft context assembly.
|
||||
- `JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs` — focused backend proof for thread-aware follow-up drafting.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: T01 summary
|
||||
status: done
|
||||
files:
|
||||
- JobTrackerApi/Controllers/JobApplicationsController.cs
|
||||
- JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs
|
||||
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...'
|
||||
---
|
||||
|
||||
Strengthened follow-up draft generation so it now consumes imported thread context and saved application package material instead of relying mostly on job summary text.
|
||||
|
||||
What changed:
|
||||
- `JobTrackerApi/Controllers/JobApplicationsController.cs`
|
||||
- expanded `FollowUpDraftDto` to expose context summary, context signals, thread subject, and last-correspondence metadata for the workspace
|
||||
- added helpers to parse the saved application-answer draft from notes, derive reply-style subjects from the latest thread, and assemble follow-up context signals from recruiter/package/thread state
|
||||
- enriched `GetFollowUpDraft(...)` so the AI prompt now includes imported correspondence context, recruiter details, saved tailored CV / cover letter / recruiter message / application-answer material, and thread-stage cues
|
||||
- improved the fallback body so it still reflects saved/thread context when AI output is unavailable
|
||||
- `JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs`
|
||||
- added focused backend proof that follow-up draft generation reflects imported thread and saved package state
|
||||
|
||||
Verification:
|
||||
- Backend host build passed with `$HOME/.dotnet/dotnet build JobTrackerApi/JobTrackerApi.csproj`
|
||||
- Focused follow-up draft backend test passed in an isolated Docker harness (`1 passed`)
|
||||
|
||||
Important caveat:
|
||||
- The broader `JobTrackerApi.Tests` project still has unrelated compile drift, so focused follow-up verification was isolated rather than run through the full test project.
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
estimated_steps: 4
|
||||
estimated_files: 3
|
||||
skills_used:
|
||||
- react-best-practices
|
||||
- test
|
||||
---
|
||||
|
||||
# T02: Make the follow-up workspace show thread-grounded draft state without autonomous sending
|
||||
|
||||
**Slice:** S03 — Reply and follow-up drafting from real thread context
|
||||
**Milestone:** M001
|
||||
|
||||
## Description
|
||||
|
||||
Turn the Follow-up tab into a clearer workspace that shows why the draft was generated now, what thread/package context informed it, and what will happen when the user manually sends/logs it.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Align frontend types with any stronger follow-up draft contract exposed by T01.
|
||||
2. Refine the Follow-up tab in `JobDetailsDialog.tsx` so it surfaces thread/package grounding, editable draft state, and the manual-send boundary clearly.
|
||||
3. Add a focused React test that proves generation, editability, and manual send/log behavior for the follow-up loop.
|
||||
4. Verify the focused follow-up workspace test and make sure it covers the saved-context/thread-aware behavior instead of generic form rendering.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- [ ] The Follow-up tab shows why the follow-up is due and what job/thread/package context informed the draft.
|
||||
- [ ] The draft remains editable before sending and the send action stays explicitly manual.
|
||||
- [ ] The focused React test proves generate/edit/send-log behavior for the follow-up loop.
|
||||
|
||||
## Verification
|
||||
|
||||
- `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-followup-drafts.test.tsx`
|
||||
- Confirm the test proves thread-aware draft context plus manual send/log behavior in `job-tracker-ui/src/components/JobDetailsDialog.tsx`.
|
||||
|
||||
## Observability Impact
|
||||
|
||||
- Signals added/changed: clearer Follow-up tab state around draft reason, informing context, and sent/logged outcome.
|
||||
- How a future agent inspects this: open the Follow-up tab in `job-tracker-ui/src/components/JobDetailsDialog.tsx` and read `job-tracker-ui/src/job-details-followup-drafts.test.tsx`.
|
||||
- Failure state exposed: the UI should distinguish draft-generation failure, editable draft state, and sent/logged follow-up state.
|
||||
|
||||
## Inputs
|
||||
|
||||
- `job-tracker-ui/src/components/JobDetailsDialog.tsx` — current follow-up UI.
|
||||
- `job-tracker-ui/src/types.ts` — current frontend contracts.
|
||||
- `JobTrackerApi/Controllers/JobApplicationsController.cs` — stronger follow-up draft contract from T01.
|
||||
|
||||
## Expected Output
|
||||
|
||||
- `job-tracker-ui/src/components/JobDetailsDialog.tsx` — follow-up workspace grounded in saved/job/thread context.
|
||||
- `job-tracker-ui/src/types.ts` — aligned follow-up DTO shape if T01 adds context fields.
|
||||
- `job-tracker-ui/src/job-details-followup-drafts.test.tsx` — focused frontend proof for the follow-up loop.
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: T02 summary
|
||||
status: done
|
||||
files:
|
||||
- job-tracker-ui/src/components/JobDetailsDialog.tsx
|
||||
- job-tracker-ui/src/types.ts
|
||||
- job-tracker-ui/src/job-details-followup-drafts.test.tsx
|
||||
verification:
|
||||
- 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
|
||||
---
|
||||
|
||||
Refined the Follow-up tab so it exposes the thread and saved-package grounding behind the draft instead of behaving like a generic email form.
|
||||
|
||||
What changed:
|
||||
- `job-tracker-ui/src/types.ts`
|
||||
- added a typed `FollowUpDraft` contract aligned to the richer backend response
|
||||
- `job-tracker-ui/src/components/JobDetailsDialog.tsx`
|
||||
- switched the follow-up state to the shared typed DTO
|
||||
- added a follow-up context panel showing thread subject, last sender, context summary, and context signals
|
||||
- clarified the manual-send boundary directly in the recipient/body helper text
|
||||
- kept the draft editable before send while making the send-and-log behavior explicit
|
||||
- `job-tracker-ui/src/job-details-followup-drafts.test.tsx`
|
||||
- added focused frontend proof that the Follow-up tab shows thread grounding, keeps sending manual, and posts the edited draft through the send/log endpoint
|
||||
|
||||
Verification:
|
||||
- Focused follow-up workspace test passed: `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-followup-drafts.test.tsx`
|
||||
- Production frontend build passed: `CI=true npm --prefix job-tracker-ui run build`
|
||||
|
||||
Runtime note:
|
||||
- Browser-based local UAT against this worktree was attempted but blocked by environment issues: port 3000 is served by an external nginx bundle unrelated to this worktree, the CRA dev server crashed under Node 25 in `fork-ts-checker`, and the browser harness did not successfully execute the locally served static bundle. Automated verification for the implemented code paths still passed.
|
||||
Reference in New Issue
Block a user