Files
jobtrackingapp/.gsd/milestones/M001/slices/S06/S06-RESEARCH.md
T
2026-03-27 08:54:34 +01:00

262 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# S06 Research — Live environment stabilization and integrated acceptance rerun
## Summary
S06 is primarily an environment-proof and acceptance-artifact slice, not a new feature slice. The product loop from S01S05 is already implemented and mostly works against the local seeded dataset once the live backend is actually running and the browser is authenticated. The real blockers for a true live rerun are environmental:
1. the frontend hard-calls `http://localhost:5202/api` in localhost dev (`job-tracker-ui/src/api.ts`), so the UI immediately fails with `ERR_CONNECTION_REFUSED` if the API is not already up
2. auth is required in the local dev environment (`JobTrackerApi/appsettings.Development.json`), so a live rerun also needs a valid token/session before `/jobs`, `/dashboard`, and `/reminders` are usable
3. Gmail live continuity cannot be fully re-checked in this environment because Gmail OAuth is only partially configured: `Auth:GoogleClientId` exists, but `Google:GmailClientSecret` / redirect config are absent, so `/api/gmail/status` reports `connected:false` and `/api/admin/system` reports `gmailConfigured:false`
4. the seeded local dataset is minimal (1 job / 1 company) and does not exercise the full S05 trust loop naturally: the sample job opens from reminders and the workspace/follow-up flow works, but the dashboard does not currently expose a useful job-level action card, and correspondence only has one linked external thread message plus one locally logged follow-up
This means S06 should likely split into: **environment bring-up/diagnostics**, then **seed/data conditioning for acceptance**, then **real browser rerun + recorded artifact**.
## Active Requirements To Target
### R008 — manual-send boundary stays explicit
S06 must re-prove this in the live browser, especially because Follow-up draft already renders a real `Send and log email` button in `JobDetailsDialog` while generation remains separate.
### R009 — individual-first daily loop
S06 must prove the same job can be worked from overview surfaces without needing admin-only or multi-record complexity. The current local dataset is individual-friendly but too thin to prove all overview semantics.
## Skills Discovered
- Existing installed skills used for approach guidance:
- `debug-like-expert` — informed the evidence-first, no-assumption investigation approach
- `agent-browser` — informed the browser verification workflow
- Newly installed during research:
- `gmail` (`odyssey4me/agent-skills@gmail`)
- Tried but not usable for this slice:
- `jezweb/claude-skills@google-workspace` search result did not expose a directly installable `google-workspace` skill name from that repo
## What Exists Now
### Runtime and config surfaces
- `job-tracker-ui/src/api.ts`
- On `localhost`, defaults API traffic to `http://localhost:5202/api`
- In production/non-localhost, defaults to `/api`
- No CRA dev proxy file exists; dev depends on direct cross-origin API access
- `JobTrackerApi/Program.cs`
- CORS policy defaults to `http://localhost:3000`
- `app.UseCors("AllowReact")` is already wired
- auth + migrations + admin seeding happen at startup
- `JobTrackerApi/appsettings.Development.json`
- `Auth:Require=true`
- local CORS allowlist includes `http://localhost:3000`
- placeholder local admin + JWT values exist
- `Auth:GoogleClientId` placeholder exists, which makes Google auth look enabled even when Gmail OAuth is not actually fully configured
- `README.md`
- already documents the exact dev topology: UI on `:3000`, API on `:5202`, UI defaulting to `http://localhost:5202/api`
- `JobTrackerApi/Controllers/AdminSystemController.cs`
- best existing operational probe for S06
- exposes database, auth, Gmail-configured, and AI-health status in one call
- `job-tracker-ui/src/pages/AdminSystemPage.tsx`
- already renders the above status in the UI
### Auth and entry behavior
- `JobTrackerApi/Controllers/AuthController.cs`
- `/api/auth/config` truthfully reports `requireAuth`, `googleEnabled`, `localEnabled`, `allowRegistration`
- local login is still standard username/password
- `job-tracker-ui/src/App.tsx`
- fetches `/auth/config` and redirects to `/login` when auth is required and no token exists
- `job-tracker-ui/src/pages/LoginPage.tsx`
- uses `/auth/login` or `/auth/register`
- `allowRegistration` is only exposed if backend allows it
- `job-tracker-ui/src/auth.ts`
- token key is `authToken`
### Daily-loop/workspace surfaces already in place
- `job-tracker-ui/src/components/JobTable.tsx`
- `job-tracker-ui/src/components/DashboardView.tsx`
- `job-tracker-ui/src/components/RemindersView.tsx`
- `job-tracker-ui/src/components/JobDetailsDialog.tsx`
- `job-tracker-ui/src/components/Correspondence.tsx`
- `job-tracker-ui/src/end-to-end-trust-loop.test.tsx`
The S05 contract is real: the workspace tabs, follow-up generation, reminders open path, and correspondence/follow-up tabs are all present in the running UI.
## Evidence From Live Investigation
### 1. The original frontend blockage is real and immediate
When the browser opened `http://localhost:3000/login` before the API was up, the first failing request was:
- `GET http://localhost:5202/api/auth/config → net::ERR_CONNECTION_REFUSED`
This matches the carried-forward gotcha exactly: if port `5202` is not serving, the shell UI loads but the real app loop is blocked.
### 2. Backend works once started correctly
Running from the API project directory with the explicit dotnet path succeeds:
- `ASPNETCORE_ENVIRONMENT=Development ASPNETCORE_URLS=http://127.0.0.1:5202 /home/pi/.gsd/agent/bin/dotnet run --no-launch-profile`
Observed runtime facts:
- API listens on `http://127.0.0.1:5202`
- DB migrations are already up to date
- local SQLite DB is present and readable
- the prior bg-shell failure was a process-launch/cwd/runtimeconfig issue, not an application-code crash
Important planning note: the generic `bg_shell start` cwd is not the user-mandated worktree by default in this harness. Absolute paths or an explicit shell `cd` are safer when scripting S06 verification.
### 3. Admin/system status gives the clearest stabilization checklist
`GET /api/admin/system` returned:
- database: configured + connectable
- auth: required, JWT key present
- Google login configured: true
- Gmail configured: false
- AI healthy: true
- storage has only 1 company / 1 job
This is the most useful pre-UAT gate to run before any browser rerun.
### 4. Live data is too thin for a full acceptance rerun
Current seeded API state:
- `GET /api/jobapplications` returns exactly 1 job: `Acme Browser QA / Backend Developer`
- `workflowSignal.actionKey = review-readiness`
- `needsFollowUp = false`
- `GET /api/jobapplications/reminders` still returns the same job under reminders, but only as an “Other reminders” case
- dashboard renders analytics and aggregate cards, but with this dataset it does **not** expose the richer job-level action surface that S04/S05 were meant to re-check
This means the current local DB is enough to prove the app runs, but not enough to strongly prove the milestones intended `/jobs` → workspace → Gmail continuity → follow-up → dashboard/reminders loop.
### 5. Follow-up drafting and manual-send boundary are live
In the running browser, opening the sample job from `/reminders` succeeded and the job workspace rendered.
On the **Follow-up draft** tab, live UI showed:
- generated subject/body from `/api/jobapplications/1/followup-draft`
- recruiter recipient prefilled (`maria@acme.test`)
- explicit `Send and log email` button
- separate generation/loading behavior from the send action
This supports R008: drafting is live, but send is still an explicit separate action.
### 6. Correspondence continuity UI is only partially exercised locally
`Correspondence.tsx` does contain the linked-thread continuity panel and manual refresh flow, but the local sample data does not currently expose it meaningfully:
- `GET /api/correspondence/1` has one imported-style external thread message and one locally logged sent-style message
- `GET /api/gmail/status` returns `connected:false`
- because Gmail is disconnected and the second message lacks external thread metadata, the real linked-thread refresh loop cannot be demonstrated live here
So S06 cannot honestly claim Gmail continuity rerun in this environment until Gmail config + account linking are present.
## Implementation Landscape
### Natural task seams
#### Seam 1 — environment bring-up and diagnostics
Focus files/surfaces:
- `JobTrackerApi/Program.cs`
- `JobTrackerApi/appsettings.Development.json`
- `job-tracker-ui/src/api.ts`
- `README.md`
- `JobTrackerApi/Controllers/AdminSystemController.cs`
- `job-tracker-ui/src/pages/AdminSystemPage.tsx`
Goal:
- make the live local topology easy to start and verify before browser UAT begins
- likely produce or tighten a repeatable runbook/checklist rather than large code changes
#### Seam 2 — acceptance seed/data conditioning
Focus surfaces:
- existing API endpoints / local DB seed path
- possibly task-local scripts or documented setup steps
Goal:
- ensure at least one job truly exercises:
- overview action from `/jobs`
- meaningful reminder/dashboard action
- saved package state
- linked correspondence state
- follow-up draft grounding
This is the riskiest seam because the current one-job dataset is operational but not acceptance-rich.
#### Seam 3 — browser rerun and artifact capture
Focus surfaces:
- browser verification itself
- `.gsd` UAT/summary artifact output for S06
- likely downstream dependency for S07
Goal:
- record what was actually exercised live
- distinguish clearly between:
- fully live checks
- blocked checks
- mocked/not-possible checks
## Recommendation
1. **Build a hard preflight gate first.** Before any browser rerun, check:
- API reachable on `:5202`
- `/api/auth/config` reachable
- admin/system status healthy for DB + AI
- Gmail-configured status truthfully known
2. **Do not start with browser fixes.** The main current failure mode is not React routing; it is environment readiness.
3. **Treat Gmail as an explicit acceptance branch.** If Gmail remains unconfigured, S06 should record that the full Gmail continuity rerun is blocked and either:
- add a safe local config/setup task, or
- scope S06 to environment stabilization plus non-Gmail integrated rerun, leaving Gmail closure to a follow-up task/slice
4. **Augment the local acceptance dataset before claiming success.** The present single sample job does not naturally prove dashboard/reminders/job-table coherence strongly enough.
5. **Use the S05 integrated regression as the contract oracle.** If live behavior diverges from `job-tracker-ui/src/end-to-end-trust-loop.test.tsx`, investigate the environment/data first before changing UI logic.
## Risks / Constraints
- **Gmail is the biggest live blocker.** `googleConfigured=true` does not mean Gmail import is usable; `gmailConfigured=false` in admin/system is the truer signal for S06.
- **Auth can block all browser checks.** Since dev auth is required, any UAT runbook must include token/login setup.
- **The dataset currently biases toward a low-urgency readiness case.** This can make dashboard/reminders look less actionable than they were designed to be.
- **Do not infer success from shell render.** The login page and app shell can render even while API traffic is broken.
## Verification Plan
### Preflight
- Start API from `JobTrackerApi/` and verify `GET /api/auth/config`
- Verify `GET /api/admin/system` as an admin token/session
- Confirm these fields before browser UAT:
- `database.canConnect = true`
- `ai.healthy = true`
- `auth.required = true/false` understood
- `auth.gmailConfigured = true` if Gmail continuity is in scope
### Browser rerun
For one chosen acceptance job:
1. `/jobs` opens the correct workspace
2. `/reminders` opens the same job/workspace semantics
3. `/dashboard` exposes and opens the same job/workspace semantics
4. **Tailored CV** shows saved package state clearly
5. **Correspondence** shows linked-thread continuity state
6. **Follow-up draft** shows grounded context and explicit manual-send boundary
7. Do **not** click send unless outbound mail is intentionally pointed at a safe sink
### Contract spot checks
Useful endpoints to compare against live UI:
- `GET /api/jobapplications`
- `GET /api/jobapplications/reminders`
- `GET /api/jobapplications/{id}`
- `GET /api/correspondence/{jobId}`
- `GET /api/jobapplications/{id}/followup-draft`
- `GET /api/gmail/status`
- `GET /api/admin/system`
## Planner Notes
- This slice is not mainly a coding problem unless the planner finds a missing preflight/diagnostic surface. It is mostly an **environment + proof** problem.
- The first executable task should probably be a stabilization/proof task, not a product-feature task.
- If the planner wants a high-confidence S06 outcome, it should require a decision on whether Gmail live acceptance is actually achievable in this environment before promising full milestone rerun coverage.
- S07 depends on S06 producing truthful acceptance evidence. If S06 cannot execute Gmail live, that limitation must be recorded explicitly rather than papered over.