# /html-report - Generate Application Tracker Dashboard Generate a self-contained HTML dashboard from `job_search_tracker.csv` and the application archives under `documents/applications/`. The output is a single `.html` file — no server, no dependencies — that can be opened directly in a browser. ## Step 0: Parse Arguments - No argument → output to `reports/application-dashboard.html` - A path argument (e.g. `/html-report ~/Desktop/report.html`) → use that path - `--open` flag → after writing, tell the user to open the file (cannot open a browser directly) Create `reports/` if it does not exist. --- ## Step 1: Collect Data Read in parallel: 1. **`job_search_tracker.csv`** — the primary source. Parse every row into a record with fields: `date`, `company`, `sector`, `role`, `role_type`, `channel`, `status`, `contact_person`, `fit_rating`, `notes`, `cv_file`, `cover_letter_file`, `source` 2. **`documents/applications/*/outcome.md`** — for each resolved application, read the outcome file to get the exact interview stages reached (the checkboxes) and any notes. Merge this into the matching tracker row by company+role fuzzy match (lowercase, ignore punctuation). If an archive exists for a row but there is no match, attach it as extra context anyway. Status normalisation — map tracker values to five canonical buckets before computing stats: - `applied` → **Active** (resume submitted, no further signal) - `interview` → **Interview** - `offer` → **Offer** - `hired` → **Hired** - `rejected` / `no_response` / `no response` / `offer_declined` / `interview_only` / `withdrawn` → **Rejected/Closed** --- ## Step 2: Compute Summary Stats From the normalised data compute: - **Total applications** - **By status bucket:** count per bucket - **By sector:** count per unique sector value - **By channel:** online vs referral vs other - **By year/season:** group by the `date` field (which may be a year like `2025` or a full date) - **Funnel rates:** what % progressed past resume screen (reached Interview or beyond) - **Rejection rate:** Rejected/Closed ÷ Total with a resolved status (exclude Active) --- ## Step 3: Generate the HTML Write a single self-contained HTML file. All CSS is inline in a `