Files
jobtrackingapp/.gsd/milestones/M001/slices/S02/S02-SUMMARY.md
T

8.2 KiB
Raw Blame History

id, parent, milestone, provides, requires, affects, key_files, key_decisions, patterns_established, observability_surfaces, duration, verification_result, completed_at
id parent milestone provides requires affects key_files key_decisions patterns_established observability_surfaces duration verification_result completed_at
S02 M001 M001
stronger application-package generation that uses imported correspondence, recruiter/job context, profile CV structure, and attachment signals
a persisted package workspace inside the job dialog for tailored CV, cover letter, recruiter message, and application-answer draft material
slice provides
S01 imported and auto-refreshed job-linked correspondence plus trusted thread metadata for package context assembly
S03
JobTrackerApi/Controllers/JobApplicationsController.cs
JobTrackerApi.Tests/JobApplicationsApplicationPackageTests.cs
job-tracker-ui/src/components/JobDetailsDialog.tsx
job-tracker-ui/src/job-details-generated-drafts.test.tsx
D006
persist the application-answer draft as a replaceable marker-delimited notes block until a dedicated field exists
assemble AI package context from persisted job, recruiter, correspondence, saved-draft, profile-CV, and attachment signals before prompting
treat generated artifacts as editable workspace state with explicit saved/generated/unsaved status rather than disposable preview output
POST /api/jobapplications/{id}/generate-application-package
PUT /api/jobapplications/{id}/tailored-cv
PUT /api/jobapplications/{id}/application-drafts
job-tracker-ui/src/job-details-generated-drafts.test.tsx
JobTrackerApi.Tests/JobApplicationsApplicationPackageTests.cs
2 tasks passed 2026-03-24

S02: Stronger AI application package drafting

Imported Gmail/job context now feeds a persisted application-package workspace that generates, edits, saves, and reloads job-specific draft material instead of one-shot generic previews.

What Happened

S02 closed the main draft-quality gap by wiring S01s imported correspondence into application-package generation and then making the Tailored CV tab behave like a real working surface.

On the backend, JobTrackerApi/Controllers/JobApplicationsController.cs now builds package context from more than the job description. Generation explicitly pulls in recruiter identity, job URL, imported correspondence, saved package material already tied to the job, profile CV structure, and selected attachment signals. That context is reused across tailored CV, cover letter, application answer, recruiter message, and package key points so the returned artifacts can react to real recruiter/thread context instead of defaulting to generic role-summary language.

On the frontend, job-tracker-ui/src/components/JobDetailsDialog.tsx now treats tailored CV, cover letter, recruiter message, and application-answer text as one package workspace. Reopening the job loads the saved copy back into the editors, generation replaces the current working copy for all package artifacts, save persists the package back to the job, and reset restores the last saved state. Status chips make the persistence state legible by distinguishing Saved to job, Generated only, and Unsaved edits.

S02 also established a temporary but stable persistence contract for the application-answer draft: until a dedicated field exists, it lives in a marker-delimited block inside JobApplication.Notes, and save replaces that block rather than appending indefinitely. That keeps the workspace trustworthy and gives S03 a reliable place to read package context back from.

The net effect is that S01 correspondence is no longer just imported and displayed; it now materially influences package drafting, and the resulting artifacts persist as reusable job workspace material.

Verification

  • $HOME/.dotnet/dotnet build JobTrackerApi/JobTrackerApi.csproj — passed
  • $HOME/.dotnet/dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsApplicationPackageTests — passed (2 tests)
  • CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/job-details-generated-drafts.test.tsx — passed (2 tests)
  • Observability surfaces confirmed by implementation/tests:
    • POST /api/jobapplications/{id}/generate-application-package now emits package artifacts grounded in correspondence/recruiter/job context
    • PUT /api/jobapplications/{id}/tailored-cv and PUT /api/jobapplications/{id}/application-drafts form the durable save loop the workspace depends on
    • focused backend/frontend tests cover package generation specificity, notes replacement, saved-state load, edit, save, and redisplay behavior

New Requirements Surfaced

  • none

Deviations

  • The plan did not call out storage for the application-answer draft, but execution required a concrete persistence strategy before the workspace could be trustworthy. S02 therefore adopted the marker-delimited notes-block approach captured in D006 instead of introducing a new schema field mid-slice.

Known Limitations

  • The application-answer draft is still stored inside JobApplication.Notes rather than a first-class field, so downstream work must keep honoring the marker-block contract.
  • Automated verification proves context wiring and persistence loops, but it does not replace human judgment on whether the generated writing feels genuinely strong enough for a real application; that still needs live UAT with real imported correspondence and AI output.
  • Draft quality still depends on the quality of the imported correspondence, recruiter metadata, profile CV structure, and selected attachments available on the job.

Follow-ups

  • S03 should consume the saved package workspace artifacts, including the marker-delimited application-answer block, instead of reconstructing package context from scratch.
  • A later milestone can promote the application-answer draft to a dedicated persisted field if the notes-block workaround starts constraining editing, analytics, or downstream composition.
  • Milestone-level live UAT should include at least one job with strong imported Gmail context to judge whether the upgraded generator actually feels specific enough to start from.

Files Created/Modified

  • JobTrackerApi/Controllers/JobApplicationsController.cs — strengthened package-context assembly, notes replacement behavior, and generation/save contracts
  • JobTrackerApi.Tests/JobApplicationsApplicationPackageTests.cs — focused backend proof for correspondence-aware package output and notes replacement
  • job-tracker-ui/src/components/JobDetailsDialog.tsx — converted the Tailored CV tab into a coherent generate/edit/save/reset package workspace
  • job-tracker-ui/src/job-details-generated-drafts.test.tsx — verified saved-state load, generation, editing, coherent save payload, and redisplay behavior
  • .gsd/REQUIREMENTS.md — refreshed R003 validation to reflect the direct filtered backend test plus frontend workspace proof
  • .gsd/KNOWLEDGE.md — recorded the marker-delimited application-answer persistence contract and the authoritative direct S02 test command

Forward Intelligence

What the next slice should know

  • S03 can now assume package context lives in durable job fields: tailoredCvText, coverLetterText, recruiterMessageDraft, and the marker-delimited application-answer block inside notes; use those saved values as the baseline context for reply/follow-up generation.

What's fragile

  • Application-answer persistence via the <<<APPLICATION_ANSWER_DRAFT>>> ... <<<END_APPLICATION_ANSWER_DRAFT>>> notes block — downstream code must replace/parse that block consistently or the workspace will drift back into duplicate or stale-answer behavior.

Authoritative diagnostics

  • JobTrackerApi.Tests/JobApplicationsApplicationPackageTests.cs and job-tracker-ui/src/job-details-generated-drafts.test.tsx — these are the tightest trustworthy checks for whether package generation is context-aware and whether the workspace save/reload loop still works end to end.

What assumptions changed

  • Earlier task execution assumed the filtered backend verification might still need an isolated harness because of broader test-project drift — in this worktree, dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter JobApplicationsApplicationPackageTests now passes directly and should be treated as the primary S02 regression check.