# Merge Request — Wave 0 quick wins + Tier-1/Tier-2 features

**Branch:** `chore/wave0-quick-wins` → `main`
**Scope:** 24 commits · 62 files · +3,165 / −489
**Status:** all tests green (backend 135, frontend 23 suites / 54 tests), production build compiles.

> Prepared for human review. Do **not** auto-merge. One operator action is required after merge
> (DataProtection key rotation — see *Known limitations*).

---

## Summary

Delivers the first two roadmap tiers plus the engineering-health groundwork, developed as small
conventional commits. Two design principles run through it:

1. **Deterministic over "AI-guessy."** Match scoring, status suggestions, and pipeline logic are
   pure/deterministic — instant, reproducible, and safe (the user confirms every state change). This
   directly answers the market's most common complaint (hallucinated/generic AI output).
2. **One pathway, not two.** The bookmarklet and the PWA share-target feed a single `/?add=` capture
   flow rather than parallel implementations.

## What's included

**Engineering health (Wave 0)**
- `security:` untracked committed DataProtection keys + daily exports; removed dead legacy controllers.
- `feat:` automated daily SQLite backups (`VACUUM INTO`, retention, startup catch-up) — prod previously
  had **no** automated backup on Linux.
- `ci:` run the **entire** frontend suite (the old whitelist was hiding 3 broken suites, now fixed).
- `feat:` dev-only OpenAPI at `/openapi/v1.json`; `feat:` structured salary fields.

**Tier-1 features**
- **Match score** (`GET /jobapplications/{id}/match-score`) — deterministic CV↔job keyword coverage
  (0–100) + matched/missing keywords + section coverage. Instant panel on the Candidate Fit tab.
- **Canonical pipeline** — `JobPipeline` single source of truth; status normalized on write (custom
  values preserved); UI deduped across 5 files; `GET .../pipeline`.
- **Analytics v2** — time-in-stage medians (from `StatusChanged` history) + funnel driven by the
  pipeline (fixes a bug that omitted the Waiting stage).
- **Status suggestions** — deterministic email→status classifier surfaced as a human-confirmed banner.

**Tier-2 features**
- **Bookmarklet** quick-capture (Settings) reusing `jobimport/preview`.
- **Installable PWA** with a mobile share-target into the same capture flow.

**Quality**
- Phase-6 security review (`docs/SECURITY_REPORT.md`): tenant isolation on new endpoints verified +
  regression-tested; no injection/ReDoS; dev-only OpenAPI.
- Bug fixes: `SkillTagger` C#/.NET regex (silently missed those skills everywhere), a React
  stale-closure, a duplicated DB query, and 3 pre-existing hidden test failures.

## Test coverage added

New pure/unit-tested services: `JobCvMatchService` (7), `JobPipeline` (14), `StageAnalytics` (4),
`EmailStatusClassifier` (7). New endpoint integration + authorization tests (match-score,
status-suggestion). New frontend tests: match-score panel, status-suggestion banner, pipeline,
quick-capture, capture-url resolution.

## Docs

New: `docs/SYSTEM_OVERVIEW.md`, `docs/PRODUCT_RESEARCH.md`, `docs/ROADMAP.md`,
`docs/SECURITY_REPORT.md`. README updated with the new endpoints, backup/pipeline config, and
quick-capture/PWA notes.

## Known limitations / follow-ups

- **ACTION REQUIRED (security):** the removed DataProtection key XMLs remain in git **history**.
  Rotate them on the production host after merge (see `SECURITY_REPORT.md` §6).
- **Per-user custom pipeline stages** were deliberately deferred (unproven demand; large surface).
- **No offline service worker** by design — the app deploys frequently and an aggressive cache would
  risk serving stale builds. The PWA is installable and share-capable without it.
- Not yet done (future branches): interview hub (M3), contacts CRM (M4), god-controller decomposition,
  performance pass, Vite migration.

## Reviewer notes

- Repo quirk: controllers/services compile via the `JobTrackerBackend` library, **not** the
  `JobTrackerApi` host project (see `docs/SYSTEM_OVERVIEW.md` §2).
- All AI-adjacent features are deterministic and make no model calls.
