chore(M001/S01): auto-commit after rewrite-docs
This commit is contained in:
@@ -12,3 +12,4 @@
|
||||
| D004 | M001 | pattern | Daily navigation hierarchy | Job table first, then follow-up/dashboard, then individual job workspace | The user explicitly described this as the intended control flow for daily use. | Yes — if real usage disproves the hierarchy | collaborative |
|
||||
| D005 | M001 | roadmap | First milestone focus | Prioritize Gmail import quality and AI draft quality before broader expansion | The user identified Gmail import and AI drafts as the weakest current areas and the first bar for daily use. | Yes — if execution proves another blocker is more fundamental | collaborative |
|
||||
| D006 | M001/S02 | workspace-persistence | How the saved application answer draft should persist inside the job workspace before a dedicated field exists | Store the application answer draft in a replaceable notes block and make SaveApplicationDrafts overwrite notes when notes are explicitly provided | The existing append-only notes behavior made the Tailored CV workspace untrustworthy because repeated saves duplicated the application answer indefinitely. A replaceable notes block preserves current schema compatibility while giving the workspace a stable saved/read-back loop for later slices. | Yes | agent |
|
||||
| D007 | M001/S01 | gmail-continuity | What “good Gmail import” now means for M001 | Treat Gmail import as full-thread continuity: the user must be able to import the whole relevant thread, and already-linked Gmail threads must refresh automatically so later inbound messages and user-sent replies appear on the job without manual re-import. This supersedes the narrower one-time-import interpretation inside D005’s Gmail-import focus. | The user explicitly asked whether the app can bring the whole email thread and automatically show their reply later without re-pulling/importing again. That changes the trust bar from “find and import the right message” to “keep the linked thread current over time,” while still preserving the no-auto-send boundary from D002. | Yes — if Gmail API or product constraints later require a different sync model | human |
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ User-issued overrides that supersede plan document content.
|
||||
## Override: 2026-03-24T10:57:41.499Z
|
||||
|
||||
**Change:** can the gmail import bring the while tread of emails though? and also update automatically so if i reply to an email itll ahow my responce automaticslly without havjng to repull/kmport the emaila
|
||||
**Scope:** active
|
||||
**Scope:** resolved
|
||||
**Applied-at:** M001/S01/T01
|
||||
|
||||
---
|
||||
|
||||
+4
-4
@@ -6,15 +6,15 @@ Job Tracker is a personal job-application workspace for an individual user. The
|
||||
|
||||
## Core Value
|
||||
|
||||
The product must let one person run a real job search without losing the thread: import a role, prepare stronger application material, track what happened, and know exactly what needs follow-up next.
|
||||
The product must let one person run a real job search without losing the thread: import a role, prepare stronger application material, track what happened, keep Gmail correspondence tied to the right job, and know exactly what needs follow-up next.
|
||||
|
||||
## Current State
|
||||
|
||||
A substantial brownfield app already exists. The repo has a React frontend, an ASP.NET Core API, and a local FastAPI AI service. Current capabilities already include job tracking, companies, attachments, correspondence, reminders, job import preview, Gmail connection/import, profile CV upload/parsing/rewrite flows, AI-assisted tailored CV and cover-letter generation, candidate-fit/focus-plan/interview-prep/readiness endpoints, and dashboard/system surfaces. S01 moved Gmail import from a generic search surface to a job-aware workspace flow: the backend ranks likely Gmail threads/messages for a specific job, imports report duplicate state explicitly, correspondence persists Gmail thread and sender/recipient metadata, and the job workspace renders those ranked suggestions directly. S02 then tightened the package loop around that context: backend package generation now consumes imported correspondence plus recruiter/job state, and the Tailored CV tab treats tailored CV, cover letter, recruiter message, and saved application-answer material as one editable workspace tied back to the job instead of a throwaway preview pane. S03 turned follow-up drafting into a real thread-aware workspace flow, and S04 connected the dashboard, reminders, and table into one routed daily control loop that opens the same per-job workspace state. The next phase is not greenfield feature invention; it is full milestone revalidation and final workflow polish.
|
||||
A substantial brownfield app already exists. The repo has a React frontend, an ASP.NET Core API, and a local FastAPI AI service. Current capabilities already include job tracking, companies, attachments, correspondence, reminders, job import preview, Gmail connection/import, profile CV upload/parsing/rewrite flows, AI-assisted tailored CV and cover-letter generation, candidate-fit/focus-plan/interview-prep/readiness endpoints, and dashboard/system surfaces. S01 moved Gmail import from a generic search surface to a job-aware workspace flow: the backend ranks likely Gmail threads/messages for a specific job, imports report duplicate state explicitly, correspondence persists Gmail thread and sender/recipient metadata, and the job workspace renders those ranked suggestions directly. The new milestone direction raises that bar further: Gmail import must now support trustworthy whole-thread continuity, so already-linked Gmail threads need to refresh automatically and show later inbound messages or user-sent replies on the job without requiring manual re-import. S02 then tightened the package loop around that context: backend package generation now consumes imported correspondence plus recruiter/job state, and the Tailored CV tab treats tailored CV, cover letter, recruiter message, and saved application-answer material as one editable workspace tied back to the job instead of a throwaway preview pane. S03 turned follow-up drafting into a real thread-aware workspace flow, and S04 connected the dashboard, reminders, and table into one routed daily control loop that opens the same per-job workspace state. The next phase is not greenfield feature invention; it is milestone revalidation plus Gmail thread-continuity polish so the correspondence loop stays live after first import.
|
||||
|
||||
## Architecture / Key Patterns
|
||||
|
||||
The frontend lives in `job-tracker-ui/` and is a React + TypeScript app using MUI. The backend lives in `JobTrackerApi/` and is an ASP.NET Core API with EF Core, Identity, background hosted services, and controller-based endpoints. The local AI service lives in `tools/summarizer/` and provides summarization plus OCR/text extraction. Existing patterns already center around per-job workspaces, Gmail-backed correspondence import, profile-CV-as-source-of-truth, attachment-level AI inclusion controls, and server-side generation endpoints that return drafts for user review rather than autonomous sending.
|
||||
The frontend lives in `job-tracker-ui/` and is a React + TypeScript app using MUI. The backend lives in `JobTrackerApi/` and is an ASP.NET Core API with EF Core, Identity, background hosted services, and controller-based endpoints. The local AI service lives in `tools/summarizer/` and provides summarization plus OCR/text extraction. Existing patterns already center around per-job workspaces, Gmail-backed correspondence import, profile-CV-as-source-of-truth, attachment-level AI inclusion controls, and server-side generation endpoints that return drafts for user review rather than autonomous sending. With the override, Gmail-backed correspondence is no longer just a one-time import pattern; it is a linked-thread continuity pattern that must keep the job timeline aligned with the user’s real Gmail thread history.
|
||||
|
||||
## Capability Contract
|
||||
|
||||
@@ -22,7 +22,7 @@ See `.gsd/REQUIREMENTS.md` for the explicit capability contract, requirement sta
|
||||
|
||||
## Milestone Sequence
|
||||
|
||||
- [ ] M001: Gmail and draft quality loop — Make Gmail import and AI drafting strong enough to trust as a daily workflow.
|
||||
- [ ] M001: Gmail and draft quality loop — Make Gmail import and AI drafting strong enough to trust as a daily workflow, including whole-thread Gmail continuity after import.
|
||||
- [ ] M002: Tracking control center — Strengthen the job table, follow-up surfaces, and tracking rhythm into a clearer control center.
|
||||
- [ ] M003: Deeper inbox-aware assistance — Extend correspondence awareness and context-driven assistance beyond the first Gmail improvements.
|
||||
- [ ] M004: Trust, launchability, and hardening — Polish validation, clarity, performance, and operational trust surfaces for sustained daily use.
|
||||
|
||||
+24
-24
@@ -4,6 +4,17 @@ This file is the explicit capability and coverage contract for the project.
|
||||
|
||||
## Active
|
||||
|
||||
### R002 — Gmail connection, message retrieval, thread import, and linked-thread refresh must help the user pull real correspondence into the right job and keep it current with materially less manual cleanup.
|
||||
- Class: integration
|
||||
- Status: active
|
||||
- Description: Gmail connection, message retrieval, single-message/thread import, and linked-thread refresh must help the user pull real correspondence into the right job, preserve full thread continuity, and automatically surface later inbound or user-sent replies without requiring manual re-import of the thread.
|
||||
- Why it matters: Gmail import is one of the two clearest current weaknesses and a major trust surface for daily use; one-time import alone is not enough if the thread immediately goes stale.
|
||||
- Source: user
|
||||
- Primary owning slice: M001/S01
|
||||
- Supporting slices: M001/S03, M001/S05
|
||||
- Validation: remapped after override; previous S01 validation covered ranked import and persisted thread metadata, but the requirement now also includes full-thread continuity and automatic refresh of linked Gmail threads.
|
||||
- Notes: This requirement was previously treated as validated for one-time import quality. The 2026-03-24 override re-opened it by raising the bar to include ongoing thread sync.
|
||||
|
||||
### R008 — The app may draft application, reply, and follow-up content, but it must not auto-send emails or auto-apply to jobs.
|
||||
- Class: constraint
|
||||
- Status: active
|
||||
@@ -26,16 +37,16 @@ This file is the explicit capability and coverage contract for the project.
|
||||
- Validation: mapped
|
||||
- Notes: Shared/team workflows are not the current product target.
|
||||
|
||||
### R010 — The app must preserve a coherent history across manual status changes, imported Gmail correspondence, reminders, and follow-up work.
|
||||
### R010 — The app must preserve a coherent history across manual status changes, imported Gmail correspondence, linked-thread updates, reminders, and follow-up work.
|
||||
- Class: continuity
|
||||
- Status: active
|
||||
- Description: The app must preserve a coherent history across manual status changes, imported Gmail correspondence, reminders, and follow-up work.
|
||||
- Why it matters: The product promise is to keep the thread of the job search intact over time.
|
||||
- Description: The app must preserve a coherent history across manual status changes, imported Gmail correspondence, linked-thread updates, reminders, and follow-up work.
|
||||
- Why it matters: The product promise is to keep the thread of the job search intact over time, including new Gmail replies that happen after the first import.
|
||||
- Source: user
|
||||
- Primary owning slice: M001/S04
|
||||
- Supporting slices: M001/S01, M001/S03, M001/S05
|
||||
- Validation: mapped
|
||||
- Notes: This is part of what makes the app a tracker and follow-up system, not just a draft generator.
|
||||
- Notes: This now explicitly includes automatic continuity for already-linked Gmail threads so the correspondence timeline does not become a stale snapshot.
|
||||
|
||||
## Validated
|
||||
|
||||
@@ -50,17 +61,6 @@ This file is the explicit capability and coverage contract for the project.
|
||||
- Validation: S01 completed with a job-scoped Gmail import loop wired into the job workspace: backend `GET /api/gmail/job-candidates` uses the owned job as context, imports target that job directly, and focused UI verification passed in `job-tracker-ui/src/correspondence-gmail-import.test.tsx`.
|
||||
- Notes: Validation is contract/UI-level plus workspace integration. Live user UAT of the broader milestone loop still remains for later slices.
|
||||
|
||||
### R002 — Gmail connection, message retrieval, and message/thread import must help the user pull real correspondence into the right job with materially less manual cleanup.
|
||||
- Class: integration
|
||||
- Status: validated
|
||||
- Description: Gmail connection, message retrieval, and message/thread import must help the user pull real correspondence into the right job with materially less manual cleanup.
|
||||
- Why it matters: Gmail import is one of the two clearest current weaknesses and a major trust surface for daily use.
|
||||
- Source: user
|
||||
- Primary owning slice: M001/S01
|
||||
- Supporting slices: M001/S03, M001/S05
|
||||
- Validation: S01 completed with backend-ranked job-aware Gmail candidates, explicit imported/skipped import payloads, persisted thread/sender/recipient metadata, and focused verification across isolated `GmailControllerTests` plus `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx`.
|
||||
- Notes: The broader JobTrackerApi.Tests project still has unrelated compile drift, so Gmail backend coverage was isolated instead of run through the full test project. Live Gmail UAT is still needed to judge trust on a real inbox.
|
||||
|
||||
### R003 — Tailored CV and cover-letter drafts must feel specific, credible, and good enough that the user wants to start from them.
|
||||
- Class: differentiator
|
||||
- Status: validated
|
||||
@@ -114,7 +114,7 @@ This file is the explicit capability and coverage contract for the project.
|
||||
- Primary owning slice: M001/S03
|
||||
- Supporting slices: M001/S02, M001/S04
|
||||
- Validation: Validated by M001/S03 and M001/S04: the per-job workspace now supports imported correspondence review, package drafting, follow-up drafting, and routed entry from overview surfaces, with focused tests and browser verification covering package and follow-up loops.
|
||||
- Notes: S01-S04 now make the individual job workspace the real execution surface for import, drafting, and follow-up work.
|
||||
- Notes: S01-S04 now make the individual job workspace the real execution surface for import, drafting, and follow-up work. The reopened Gmail continuity work extends what that correspondence review surface must keep current over time.
|
||||
|
||||
## Deferred
|
||||
|
||||
@@ -129,16 +129,16 @@ This file is the explicit capability and coverage contract for the project.
|
||||
- Validation: unmapped
|
||||
- Notes: Deferred because Gmail import and draft quality are higher-value first fixes.
|
||||
|
||||
### R012 — The product may later add richer message understanding, smarter thread handling, and broader inbox-aware assistance after the first Gmail milestone.
|
||||
### R012 — The app may later add richer message understanding, smarter thread handling, and broader inbox-aware assistance after the first Gmail milestone.
|
||||
- Class: integration
|
||||
- Status: deferred
|
||||
- Description: The product may later add richer message understanding, smarter thread handling, and broader inbox-aware assistance after the first Gmail milestone.
|
||||
- Description: The app may later add richer message understanding, smarter thread handling, and broader inbox-aware assistance after the first Gmail milestone.
|
||||
- Why it matters: This extends the correspondence workflow, but it depends on getting the initial import/matching loop right first.
|
||||
- Source: inferred
|
||||
- Primary owning slice: M003/S01
|
||||
- Supporting slices: none
|
||||
- Validation: unmapped
|
||||
- Notes: This is the natural next step after M001 proves the core Gmail path.
|
||||
- Notes: This is the natural next step after M001 proves the core Gmail path, including linked-thread continuity.
|
||||
|
||||
### R013 — The app may later add broader strategic coaching and more advanced guidance beyond application package and follow-up/reply drafting.
|
||||
- Class: differentiator
|
||||
@@ -173,7 +173,7 @@ This file is the explicit capability and coverage contract for the project.
|
||||
- Primary owning slice: none
|
||||
- Supporting slices: none
|
||||
- Validation: n/a
|
||||
- Notes: Drafting is allowed; autonomous sending is not.
|
||||
- Notes: Drafting is allowed; autonomous sending is not. Automatic thread refresh/import of already-sent Gmail replies is allowed because it reflects history after the user sends manually.
|
||||
|
||||
### R016 — The product will not optimize for shared pipelines, recruiter operations, or multi-user coaching workflows right now.
|
||||
- Class: out-of-scope
|
||||
@@ -202,7 +202,7 @@ This file is the explicit capability and coverage contract for the project.
|
||||
| ID | Class | Status | Primary owner | Supporting | Proof |
|
||||
|---|---|---|---|---|---|
|
||||
| R001 | primary-user-loop | validated | M001/S01 | M001/S05 | S01 completed with a job-scoped Gmail import loop wired into the job workspace: backend `GET /api/gmail/job-candidates` uses the owned job as context, imports target that job directly, and focused UI verification passed in `job-tracker-ui/src/correspondence-gmail-import.test.tsx`. |
|
||||
| R002 | integration | validated | M001/S01 | M001/S03, M001/S05 | S01 completed with backend-ranked job-aware Gmail candidates, explicit imported/skipped import payloads, persisted thread/sender/recipient metadata, and focused verification across isolated `GmailControllerTests` plus `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx`. |
|
||||
| R002 | integration | active | M001/S01 | M001/S03, M001/S05 | Remapped after the 2026-03-24 override: ranked import and metadata persistence exist, but the requirement now also includes full-thread continuity and automatic refresh of linked Gmail threads so later inbound/user-sent replies appear without manual re-import. |
|
||||
| R003 | differentiator | validated | M001/S02 | M001/S05 | Validated by M001/S02: backend application-package generation now uses recruiter/job/profile/attachment/imported-correspondence context, focused backend tests pass in an isolated harness, and the Tailored CV workspace test proves generation, editing, save, and saved-state redisplay behavior. |
|
||||
| R004 | primary-user-loop | validated | M001/S03 | M001/S01, M001/S02, M001/S05 | Validated by M001/S03: follow-up draft generation now consumes imported correspondence plus saved application package material, focused backend follow-up tests pass in an isolated harness, the focused React follow-up test passes, and browser verification on the built branch UI proved the grounded follow-up draft plus manual send/log flow back into correspondence. |
|
||||
| R005 | continuity | validated | M001/S04 | M001/S05 | Validated by M001/S04: the job table now exposes actionable urgency chips that route directly into the relevant job workspace tab, focused daily-loop UI tests pass, and browser verification confirmed the table/dashboard/reminders flow routes into the same workspace model. |
|
||||
@@ -221,7 +221,7 @@ This file is the explicit capability and coverage contract for the project.
|
||||
|
||||
## Coverage Summary
|
||||
|
||||
- Active requirements: 3
|
||||
- Mapped to slices: 3
|
||||
- Validated: 7 (R001, R002, R003, R004, R005, R006, R007)
|
||||
- Active requirements: 4
|
||||
- Mapped to slices: 4
|
||||
- Validated: 6 (R001, R003, R004, R005, R006, R007)
|
||||
- Unmapped active requirements: 0
|
||||
|
||||
@@ -18,3 +18,8 @@
|
||||
{"ts":"2026-03-24T10:54:52.466Z","flowId":"662968ba-327c-45d5-9750-a7fe584653c2","seq":2,"eventType":"dispatch-match","rule":"executing → execute-task","data":{"unitType":"execute-task","unitId":"M001/S01/T01"}}
|
||||
{"ts":"2026-03-24T10:54:52.472Z","flowId":"662968ba-327c-45d5-9750-a7fe584653c2","seq":3,"eventType":"unit-start","data":{"unitType":"execute-task","unitId":"M001/S01/T01"}}
|
||||
{"ts":"2026-03-24T11:07:25.305Z","flowId":"662968ba-327c-45d5-9750-a7fe584653c2","seq":4,"eventType":"unit-end","data":{"unitType":"execute-task","unitId":"M001/S01/T01","status":"completed","artifactVerified":true},"causedBy":{"flowId":"662968ba-327c-45d5-9750-a7fe584653c2","seq":3}}
|
||||
{"ts":"2026-03-24T11:07:25.770Z","flowId":"662968ba-327c-45d5-9750-a7fe584653c2","seq":5,"eventType":"iteration-end","data":{"iteration":1}}
|
||||
{"ts":"2026-03-24T11:07:25.771Z","flowId":"e9654b40-266b-4b80-8bc0-81ad865b7163","seq":1,"eventType":"iteration-start","data":{"iteration":2}}
|
||||
{"ts":"2026-03-24T11:07:25.846Z","flowId":"e9654b40-266b-4b80-8bc0-81ad865b7163","seq":2,"eventType":"dispatch-match","rule":"rewrite-docs (override gate)","data":{"unitType":"rewrite-docs","unitId":"M001/S01"}}
|
||||
{"ts":"2026-03-24T11:07:25.852Z","flowId":"e9654b40-266b-4b80-8bc0-81ad865b7163","seq":3,"eventType":"unit-start","data":{"unitType":"rewrite-docs","unitId":"M001/S01"}}
|
||||
{"ts":"2026-03-24T11:11:32.454Z","flowId":"e9654b40-266b-4b80-8bc0-81ad865b7163","seq":4,"eventType":"unit-end","data":{"unitType":"rewrite-docs","unitId":"M001/S01","status":"completed","artifactVerified":true},"causedBy":{"flowId":"e9654b40-266b-4b80-8bc0-81ad865b7163","seq":3}}
|
||||
|
||||
@@ -5,21 +5,23 @@
|
||||
## Success Criteria
|
||||
|
||||
- User can import a job found elsewhere, generate a tailored CV and cover-letter package that feels specific enough to start from, and save/edit that package inside the job workspace.
|
||||
- User can connect Gmail, import the right message or thread into a job with less cleanup than before, and see the imported correspondence reflected in that job’s timeline/workspace.
|
||||
- User can connect Gmail, import the right message or full thread into a job with less cleanup than before, and see the imported correspondence reflected in that job’s timeline/workspace.
|
||||
- After a thread is linked to a job, later inbound messages and user-sent Gmail replies appear on that job automatically without requiring the user to re-import the thread manually.
|
||||
- User can generate a follow-up or reply draft grounded in the imported correspondence and saved job/application context.
|
||||
- The daily loop of job table → follow-up/dashboard → individual job workspace feels coherent and actionable for an individual user.
|
||||
- No part of the milestone auto-sends email or auto-applies to jobs.
|
||||
|
||||
## Key Risks / Unknowns
|
||||
|
||||
- Gmail import may still feel unreliable if matching and import clarity do not improve enough to reduce manual cleanup.
|
||||
- Gmail import may still feel unreliable if matching, whole-thread import, and linked-thread refresh clarity do not improve enough to reduce manual cleanup.
|
||||
- AI draft quality may still feel generic even though the draft surfaces already exist.
|
||||
- The workflow may remain fragmented if table/dashboard/job-detail changes do not land as one coherent loop.
|
||||
- Real value may depend on live Gmail + AI + persisted job context wiring, not isolated endpoint improvements.
|
||||
- Automatic Gmail thread refresh may be harder than one-time import if Gmail history/state handling is brittle or expensive.
|
||||
|
||||
## Proof Strategy
|
||||
|
||||
- Gmail import reliability and trust → retire in S01 by proving a user can connect Gmail, review likely messages or threads for a job, and import the right correspondence into that job with clearer matching behavior.
|
||||
- Gmail import reliability and trust → retire in S01 by proving a user can connect Gmail, review likely messages or threads for a job, import the right correspondence into that job, and keep a linked thread current as new replies arrive.
|
||||
- AI draft quality and usefulness → retire in S02 by proving imported job context plus profile/CV context produce tailored drafts the user can edit and save as actual working material.
|
||||
- Reply/follow-up assistance grounded in real context → retire in S03 by proving imported correspondence and saved draft state feed a useful reply/follow-up drafting flow.
|
||||
- Workflow coherence across daily surfaces → retire in S04 and S05 by proving the table/dashboard/job workspace work as one control loop and by re-checking the whole loop end-to-end.
|
||||
@@ -29,14 +31,14 @@
|
||||
- Contract verification: backend/frontend tests, artifact checks for new endpoints and UI flows, persisted state checks, import/draft wiring verification
|
||||
- Integration verification: real Gmail OAuth/import plus live AI-service-backed draft generation exercised through the app
|
||||
- Operational verification: repeated use of the workflow across auth/config/service boundaries without dangerous outbound automation
|
||||
- UAT / human verification: whether Gmail import feels trustworthy and whether drafts feel strong enough to start from in real use
|
||||
- UAT / human verification: whether Gmail import feels trustworthy, whether linked threads stay current automatically enough for real use, and whether drafts feel strong enough to start from
|
||||
|
||||
## Milestone Definition of Done
|
||||
|
||||
This milestone is complete only when all are true:
|
||||
|
||||
- all slice deliverables are complete
|
||||
- Gmail import, correspondence state, and draft-generation surfaces are actually wired together
|
||||
- Gmail import, linked-thread continuity, correspondence state, and draft-generation surfaces are actually wired together
|
||||
- the real browser entrypoint exists and is exercised through the table/dashboard/job loop
|
||||
- success criteria are re-checked against live behavior, not just artifact presence
|
||||
- final integrated acceptance scenarios pass
|
||||
@@ -51,19 +53,19 @@ This milestone is complete only when all are true:
|
||||
## Slices
|
||||
|
||||
- [ ] **S01: Smarter Gmail import and matching** `risk:high` `depends:[]`
|
||||
> After this: User can connect Gmail, review likely messages or threads for a job, and import correspondence with much better matching confidence and less manual cleanup.
|
||||
> After this: User can connect Gmail, review likely messages or threads for a job, import a message or full thread, and trust linked Gmail threads to stay current on that job without manual re-import.
|
||||
|
||||
- [ ] **S02: Stronger AI application package drafting** `risk:high` `depends:[S01]`
|
||||
> After this: From an imported job plus profile/CV context, the app generates materially better tailored CV and cover-letter drafts that feel specific and usable.
|
||||
|
||||
- [ ] **S03: Reply and follow-up drafting from real thread context** `risk:medium` `depends:[S01,S02]`
|
||||
> After this: Inside a job, the user can generate follow-up and reply drafts grounded in imported correspondence and saved application context, then edit them before sending manually.
|
||||
> 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.
|
||||
|
||||
- [ ] **S04: Daily control loop surfaces** `risk:medium` `depends:[S01,S03]`
|
||||
> After this: The job table works as the primary overview and the follow-up/dashboard surfaces clearly show what needs attention next for an individual user.
|
||||
|
||||
- [ ] **S05: End-to-end trust and workflow polish** `risk:low` `depends:[S01,S02,S03,S04]`
|
||||
> After this: The full loop works cleanly in a real environment: import job → generate package → apply externally → import/update correspondence → draft follow-up/reply → track progress confidently.
|
||||
> After this: The full loop works cleanly in a real environment: import job → generate package → apply externally → import/update correspondence automatically from linked Gmail threads → draft follow-up/reply → track progress confidently.
|
||||
|
||||
## Boundary Map
|
||||
|
||||
@@ -72,7 +74,7 @@ This milestone is complete only when all are true:
|
||||
Produces:
|
||||
- improved Gmail import workflow in `job-tracker-ui/src/components/Correspondence.tsx` that yields job-linked imported correspondence with clearer message/thread selection behavior
|
||||
- stronger backend correspondence import surface in `JobTrackerApi/Controllers/GmailController.cs` and related persistence so imported messages reliably attach to `JobApplication` records
|
||||
- stable job/correspondence linkage that later draft-generation flows can consume as trusted context
|
||||
- linked-thread metadata and refresh behavior stable enough that later draft-generation flows can consume correspondence as trusted context rather than a stale snapshot
|
||||
|
||||
Consumes:
|
||||
- nothing (first slice)
|
||||
@@ -82,7 +84,7 @@ Consumes:
|
||||
Produces:
|
||||
- imported correspondence records tied to a specific job and available through the existing per-job correspondence/timeline surfaces
|
||||
- message/thread metadata good enough for later reply/follow-up draft context assembly
|
||||
- a verified Gmail connection/import path that downstream slices can rely on
|
||||
- a verified Gmail connection/import path that downstream slices can rely on, including ongoing thread refresh after first import
|
||||
|
||||
Consumes:
|
||||
- nothing (first slice)
|
||||
@@ -95,7 +97,7 @@ Produces:
|
||||
- clearer frontend editing/saving behavior in `job-tracker-ui/src/components/JobDetailsDialog.tsx`
|
||||
|
||||
Consumes from S01:
|
||||
- imported correspondence and job-linked message context
|
||||
- imported and auto-refreshed correspondence plus job-linked message context
|
||||
|
||||
### S03 → S04
|
||||
|
||||
@@ -105,7 +107,7 @@ Produces:
|
||||
- job-level indicators that a follow-up/reply is ready, missing context, or needs action
|
||||
|
||||
Consumes from S01:
|
||||
- Gmail-imported correspondence context
|
||||
- Gmail-imported and automatically refreshed correspondence context
|
||||
|
||||
Consumes from S02:
|
||||
- saved tailored CV / cover-letter / application package context
|
||||
@@ -118,7 +120,7 @@ Produces:
|
||||
- stable daily-use control loop to validate in final integration
|
||||
|
||||
Consumes from S01:
|
||||
- correspondence state and Gmail import outcomes
|
||||
- correspondence state, Gmail import outcomes, and linked-thread refresh outcomes
|
||||
|
||||
Consumes from S03:
|
||||
- follow-up/reply drafting signals and job-level action state
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
# S01: Smarter Gmail import and matching
|
||||
|
||||
**Goal:** Make Gmail import job-aware enough that a user reviewing one imported job sees the right candidate messages/threads first, can import them with clearer confidence signals, and ends up with job-linked correspondence that needs materially less cleanup.
|
||||
**Demo:** From a job opened in the workspace, the user connects Gmail, sees ranked thread/message suggestions built from that job’s company/recruiter context, imports either one message or a full thread, and immediately sees the imported correspondence reflected on that job without any auto-send behavior.
|
||||
**Goal:** Make Gmail import job-aware enough that a user reviewing one imported job sees the right candidate messages/threads first, can import a complete thread when that is the safer choice, and then trust the linked correspondence to stay current automatically when new Gmail replies arrive or when the user sends a reply from Gmail.
|
||||
**Demo:** From a job opened in the workspace, the user connects Gmail, sees ranked thread/message suggestions built from that job’s company/recruiter context, imports either one message or a full thread, and then sees later inbound or user-sent replies from that linked Gmail thread appear on the same job without needing to manually re-pull or re-import the thread.
|
||||
|
||||
S01 directly advances active requirements **R001** and **R002**, and it also lays the continuity foundation S04 will later rely on for **R010**. The work is split backend-first because the highest risk is the matching contract itself: if ranking, dedupe, and metadata stay client-only, the UI can look nicer while the import loop still feels untrustworthy. Once that contract exists, the frontend task can focus on presenting the ranked results cleanly instead of inventing its own heuristics.
|
||||
S01 directly advances active requirements **R001**, **R002**, and **R010**. The work remains backend-first because the highest risk is now continuity, not just initial matching: if ranking, thread identity, and linked-thread refresh stay shallow, the UI can look nicer while the real correspondence loop still feels untrustworthy. The completed tasks below established the initial matching/import contract; the remaining work extends that contract into full-thread continuity so downstream drafting and tracking slices can rely on a living thread instead of a one-time import snapshot.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- A job-scoped Gmail matching API ranks candidate messages/threads for a specific `JobApplication` using company, recruiter, title, and existing correspondence signals rather than a generic inbox search alone.
|
||||
- Gmail import persists enough metadata to preserve message/thread identity, expose already-imported state, and reduce duplicate cleanup when the user imports single messages or whole threads into a job.
|
||||
- The job workspace `Correspondence` tab shows ranked Gmail suggestions with match reasons/confidence, keeps a manual search override, and refreshes the job-linked correspondence list after import.
|
||||
- The system can import an entire Gmail thread as a job-linked correspondence history, not just isolated messages, while keeping message ordering and duplicate protection intact.
|
||||
- Already-linked Gmail threads can refresh automatically so new inbound messages and user-sent replies from Gmail show up on the job without requiring a manual re-import flow.
|
||||
- The job workspace `Correspondence` tab shows ranked Gmail suggestions with match reasons/confidence, keeps a manual search override, and refreshes the visible job-linked correspondence list after import or linked-thread sync.
|
||||
|
||||
## Proof Level
|
||||
|
||||
@@ -21,21 +23,22 @@ S01 directly advances active requirements **R001** and **R002**, and it also lay
|
||||
|
||||
- `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter GmailControllerTests`
|
||||
- `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx`
|
||||
- Failure-path inspection: hit `api/gmail/status` while disconnected and exercise the job-scoped Gmail matching endpoint with an invalid or inaccessible `jobApplicationId`; confirm the API exposes connection state plus a clear `Job application not found.` or validation error response without leaking Gmail content.
|
||||
- Manual UAT: run the app, connect a real Gmail account, open one job in the workspace, confirm ranked Gmail suggestions appear before manual search, import one message and one full thread, and verify the imported correspondence appears on that same job with duplicates skipped and no send/apply automation.
|
||||
- Failure-path inspection: hit `api/gmail/status` while disconnected; exercise the job-scoped Gmail matching endpoint with an invalid or inaccessible `jobApplicationId`; and exercise the linked-thread refresh path with an unknown thread id or stale sync cursor. Confirm the API exposes connection state plus clear validation/not-found errors without leaking Gmail content.
|
||||
- Manual UAT: run the app, connect a real Gmail account, open one job in the workspace, confirm ranked Gmail suggestions appear before manual search, import one message and one full thread, send or receive another reply in Gmail on that linked thread, and verify the new reply appears on that same job without a manual re-import step and without any auto-send behavior.
|
||||
|
||||
## Observability / Diagnostics
|
||||
|
||||
- Runtime signals: ranked match reasons/confidence returned per candidate, import result counts for imported/skipped messages, and existing request logs with trace ids around Gmail endpoints.
|
||||
- Inspection surfaces: `api/gmail/status`, the new job-scoped Gmail matching response in `JobTrackerApi/Controllers/GmailController.cs`, the correspondence list in `job-tracker-ui/src/components/Correspondence.tsx`, and backend/frontend tests covering duplicate and failure paths.
|
||||
- Failure visibility: Gmail connection state, empty/noisy candidate lists, duplicate-skip counts, and per-candidate imported/already-linked flags should remain visible enough to tell whether failure came from query construction, Gmail retrieval, dedupe, or UI wiring.
|
||||
- Redaction constraints: never expose OAuth tokens or full message bodies in logs; diagnostics should stay at message metadata, ranking reasons, and import counts.
|
||||
- Runtime signals: ranked match reasons/confidence returned per candidate, import result counts for imported/skipped messages, linked-thread sync result counts, newest synced Gmail history marker/cursor per linked thread, and existing request logs with trace ids around Gmail endpoints.
|
||||
- Inspection surfaces: `api/gmail/status`, the job-scoped Gmail matching and linked-thread refresh responses in `JobTrackerApi/Controllers/GmailController.cs`, any Gmail sync/background service introduced for linked threads, the correspondence list in `job-tracker-ui/src/components/Correspondence.tsx`, and backend/frontend tests covering duplicate and sync failure paths.
|
||||
- Failure visibility: Gmail connection state, empty/noisy candidate lists, duplicate-skip counts, stale thread-sync state, and per-candidate imported/already-linked flags should remain visible enough to tell whether failure came from query construction, Gmail retrieval, dedupe, sync cursor handling, or UI wiring.
|
||||
- Redaction constraints: never expose OAuth tokens or full message bodies in logs; diagnostics should stay at message metadata, ranking reasons, sync counts, and import results.
|
||||
|
||||
## Integration Closure
|
||||
|
||||
- Upstream surfaces consumed: `JobTrackerApi/Services/GmailOAuthService.cs`, `Data/JobTrackerContext.cs`, `Models/JobApplication.cs`, `Models/Company.cs`, `Models/Correspondence.cs`, `job-tracker-ui/src/components/JobDetailsDialog.tsx`, and `job-tracker-ui/src/components/Correspondence.tsx`.
|
||||
- New wiring introduced in this slice: a job-aware Gmail candidate contract in the API, correspondence persistence that retains Gmail thread/message identity, and job-context-driven rendering in the workspace Gmail import UI.
|
||||
- What remains before the milestone is truly usable end-to-end: later slices still need to consume the imported correspondence for stronger drafting and daily workflow surfaces, but Gmail import itself should be trustworthy after this slice.
|
||||
- Additional wiring now required by the override: a linked-thread refresh mechanism that can detect new Gmail replies for already-imported threads and merge them into the job’s correspondence timeline without forcing the user to re-run import manually.
|
||||
- What remains before the milestone is truly usable end-to-end: later slices still need to consume the imported correspondence for stronger drafting and daily workflow surfaces, but Gmail import itself must now be trustworthy both at first import and during ongoing thread updates.
|
||||
|
||||
## Tasks
|
||||
|
||||
@@ -57,6 +60,18 @@ S01 directly advances active requirements **R001** and **R002**, and it also lay
|
||||
- Do: Pass job context from `JobDetailsDialog` into `Correspondence`, replace client-side primary ranking with the server-provided candidate contract, show match reasons/confidence/import state and thread actions, keep manual query/search as a fallback override, and add a React test that proves ranked suggestions and import refresh behavior in the dialog.
|
||||
- Verify: `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx`
|
||||
- Done when: the Correspondence Gmail tab opens on ranked job-aware suggestions, still supports manual search overrides, refreshes the correspondence list after import, and the new UI test passes.
|
||||
- [ ] **T04: Add linked-thread refresh so imported Gmail threads stay current** `est:4h`
|
||||
- Why: The user’s trust bar is no longer just “can I import the right thread once?” but “does that thread continue to reflect reality after I reply or receive another response in Gmail?”
|
||||
- Files: `JobTrackerApi/Controllers/GmailController.cs`, `JobTrackerApi/Services/GmailOAuthService.cs`, `JobTrackerApi/Program.cs`, `Models/Correspondence.cs`, `JobTrackerApi.Tests/GmailControllerTests.cs`
|
||||
- Do: Add a linked-thread refresh path that can pull new Gmail messages for already-imported job threads using stored Gmail thread/message identity, dedupe against existing correspondence, import newly discovered inbound and sent replies into the same job, and expose enough sync status for the UI to know whether the thread is current.
|
||||
- Verify: `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter GmailControllerTests`
|
||||
- Done when: an already-linked Gmail thread can be refreshed without manual re-import, new sent/inbound replies land as correspondence on the same job, and focused tests prove dedupe plus stale-thread handling.
|
||||
- [ ] **T05: Surface automatic Gmail thread continuity in the workspace UI** `est:3h`
|
||||
- Why: Even with backend sync, the slice will still feel broken if the user cannot tell that a linked thread is auto-updating or whether a newly sent Gmail reply has already been incorporated.
|
||||
- Files: `job-tracker-ui/src/components/Correspondence.tsx`, `job-tracker-ui/src/components/JobDetailsDialog.tsx`, `job-tracker-ui/src/types.ts`, `job-tracker-ui/src/correspondence-gmail-import.test.tsx`
|
||||
- Do: Update the Correspondence tab to distinguish one-time suggestions from already-linked live threads, show last-sync or updating state, trigger automatic refresh on load and after manual job actions where appropriate, and extend the React test so a newly synced Gmail reply appears in the job correspondence list without a fresh import flow.
|
||||
- Verify: `CI=true npm --prefix job-tracker-ui test -- --watch=false --runTestsByPath src/correspondence-gmail-import.test.tsx`
|
||||
- Done when: the user can see that a thread is linked/live, newly synced replies appear in the workspace automatically or on lightweight refresh, and the UI test covers the no-manual-reimport continuity path.
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"taskId": "T01",
|
||||
"unitId": "M001/S01/T01",
|
||||
"timestamp": 1774350445753,
|
||||
"passed": true,
|
||||
"discoverySource": "none",
|
||||
"checks": []
|
||||
}
|
||||
Reference in New Issue
Block a user