chore: auto-commit after execute-task
GSD-Unit: M001/S06/T01
This commit is contained in:
@@ -1,60 +1,12 @@
|
||||
# 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
|
||||
|
||||
- [x] 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.
|
||||
- [x] 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.
|
||||
- [x] 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.
|
||||
**Demo:** After this: Inside a job, the user can generate follow-up and reply drafts grounded in imported and automatically refreshed correspondence plus saved application context, then edit them before sending manually.
|
||||
|
||||
## 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.
|
||||
- [x] **T01: Strengthen follow-up draft context assembly and backend reply/follow-up tests** —
|
||||
- Files: JobTrackerApi/Controllers/JobApplicationsController.cs, JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs
|
||||
- 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.
|
||||
- [x] **T02: Make the follow-up workspace show thread-grounded draft state without autonomous sending** —
|
||||
- Files: job-tracker-ui/src/components/JobDetailsDialog.tsx, job-tracker-ui/src/types.ts, job-tracker-ui/src/job-details-followup-drafts.test.tsx
|
||||
- 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`
|
||||
|
||||
@@ -1,45 +1,22 @@
|
||||
---
|
||||
title: T01 summary
|
||||
status: done
|
||||
files:
|
||||
- JobTrackerApi/Controllers/JobApplicationsController.cs
|
||||
- JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs
|
||||
verification:
|
||||
- $HOME/.dotnet/dotnet build JobTrackerApi/JobTrackerApi.csproj
|
||||
- $HOME/.dotnet/dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsFollowUpDraftTests
|
||||
observability_surfaces:
|
||||
- GET /api/jobapplications/{id}/followup-draft
|
||||
- POST /api/jobapplications/{id}/send-followup
|
||||
- GET /api/correspondence/{jobId}
|
||||
- JobTrackerApi.Tests/JobApplicationsFollowUpDraftTests.cs
|
||||
id: T01
|
||||
parent: S03
|
||||
milestone: M001
|
||||
provides: []
|
||||
requires: []
|
||||
affects: []
|
||||
key_files: []
|
||||
key_decisions: []
|
||||
patterns_established: []
|
||||
drill_down_paths: []
|
||||
observability_surfaces: []
|
||||
duration: ""
|
||||
verification_result: ""
|
||||
completed_at: 2026-03-27T07:30:18.613Z
|
||||
blocker_discovered: false
|
||||
---
|
||||
|
||||
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.
|
||||
# T01: Strengthen follow-up draft context assembly and backend reply/follow-up tests
|
||||
|
||||
## What changed
|
||||
|
||||
- `JobTrackerApi/Controllers/JobApplicationsController.cs`
|
||||
- expanded `FollowUpDraftDto` to expose `contextSummary`, `contextSignals`, `threadSubject`, 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
|
||||
|
||||
## Diagnostics
|
||||
|
||||
- Call `GET /api/jobapplications/{id}/followup-draft` and inspect `contextSummary`, `contextSignals`, `threadSubject`, `lastCorrespondenceFrom`, and `lastCorrespondenceAt` to confirm the draft is grounded in saved package material plus imported correspondence.
|
||||
- Call `POST /api/jobapplications/{id}/send-followup` only after editing the returned draft; this is the authoritative manual-send/log boundary surface for the slice.
|
||||
- Use `GET /api/correspondence/{jobId}` after a manual send/log to confirm the outbound follow-up appears back in the job timeline rather than remaining transient UI-only state.
|
||||
- Re-run `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsFollowUpDraftTests` when follow-up prompt assembly, DTO shape, or fallback behavior changes.
|
||||
|
||||
## Verification Evidence
|
||||
|
||||
| Check | Command | Exit code | Verdict | Duration |
|
||||
|---|---|---:|---|---|
|
||||
| Backend build | `$HOME/.dotnet/dotnet build JobTrackerApi/JobTrackerApi.csproj` | 0 | PASS | 00:00:03 |
|
||||
| Focused backend follow-up test | `$HOME/.dotnet/dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsFollowUpDraftTests` | 0 | PASS | 00:00:01 |
|
||||
|
||||
## Important caveat
|
||||
|
||||
- The original task had to fall back to an isolated harness because `JobTrackerApi.Tests.csproj` was missing required framework/package references. During slice closeout, the test project was repaired so the plan-level filtered command now runs directly in this worktree again.
|
||||
## What Happened
|
||||
No summary recorded.
|
||||
|
||||
@@ -1,48 +1,22 @@
|
||||
---
|
||||
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
|
||||
observability_surfaces:
|
||||
- job-tracker-ui/src/components/JobDetailsDialog.tsx (Follow-up tab)
|
||||
- job-tracker-ui/src/job-details-followup-drafts.test.tsx
|
||||
- GET /api/jobapplications/{id}/followup-draft
|
||||
- POST /api/jobapplications/{id}/send-followup
|
||||
id: T02
|
||||
parent: S03
|
||||
milestone: M001
|
||||
provides: []
|
||||
requires: []
|
||||
affects: []
|
||||
key_files: []
|
||||
key_decisions: []
|
||||
patterns_established: []
|
||||
drill_down_paths: []
|
||||
observability_surfaces: []
|
||||
duration: ""
|
||||
verification_result: ""
|
||||
completed_at: 2026-03-27T07:30:18.614Z
|
||||
blocker_discovered: false
|
||||
---
|
||||
|
||||
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.
|
||||
# T02: Make the follow-up workspace show thread-grounded draft state without autonomous sending
|
||||
|
||||
## 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
|
||||
|
||||
## Diagnostics
|
||||
|
||||
- Open the Follow-up tab in `job-tracker-ui/src/components/JobDetailsDialog.tsx` and confirm the context panel renders `threadSubject`, `contextSummary`, and `contextSignals` from the backend instead of showing only a blank compose form.
|
||||
- Edit the generated body before pressing **Send and log email**; the UI should preserve the edited body and only call `POST /api/jobapplications/{id}/send-followup` after the explicit button click.
|
||||
- Re-run `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-followup-drafts.test.tsx` after changes to follow-up state wiring, helper text, or send/log payloads.
|
||||
- Re-run `CI=true npm --prefix job-tracker-ui run build` after UI changes to catch contract drift or production-only compilation regressions.
|
||||
|
||||
## Verification Evidence
|
||||
|
||||
| Check | Command | Exit code | Verdict | Duration |
|
||||
|---|---|---:|---|---|
|
||||
| Focused follow-up workspace test | `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-followup-drafts.test.tsx` | 0 | PASS | 00:00:02 |
|
||||
| Production frontend build | `CI=true npm --prefix job-tracker-ui run build` | 0 | PASS | 00:00:24 |
|
||||
|
||||
## Runtime note
|
||||
|
||||
- Earlier local browser UAT was blocked by an unrelated port-3000 nginx bundle and a CRA dev-server crash under Node 25. The production build and focused follow-up UI test both passed during closeout, so the durable verification path for this task is the filtered React test plus the build output rather than the old dev-server attempt.
|
||||
## What Happened
|
||||
No summary recorded.
|
||||
|
||||
Reference in New Issue
Block a user