Session 41: P0 audit fixes — MLB stat_types, broken routes, tier mismatch, self-hosted fonts (1940 tests)

- Backend: whitelist MLB stat_types in analyze.js + scan.js gates (mirrors
  python validation.py); fixes MLB scans 400ing.
- Routes: /settings -> /profile, /report -> /blog redirect pages.
- Profile: read tier from useAuth().tier (nav's source) to kill the
  Free-vs-DESK mismatch.
- Fonts: self-host Inter/JetBrains Mono/IBM Plex Mono via next/font, drop the
  503ing fonts.googleapis.com <link>; rewire literal font-family refs to vars.
- Kept /settings/security (real MFA page) intact — NOT clobbered to a redirect.
- +33 tests (1907 -> 1940), 149 suites; web build clean (exit 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-06-17 21:55:40 -04:00
parent e453c24d2c
commit 32069863dc
17 changed files with 318 additions and 41 deletions
+47 -3
View File
@@ -1,11 +1,55 @@
# VYNDR — Build State
## Last Updated
2026-06-16
2026-06-17
## Current Phase
SHIP BUILD v39.0 — VYNDR 2.0 design system, Phase H: QA pass — §13 parity
verified, conversion COMPLETE (Session 39)
SHIP BUILD v41.0 — P0 audit fixes (MLB stat gate, broken routes, profile tier,
self-hosted fonts). Design conversion (3339) remains COMPLETE.
## Session 41 (2026-06-17) — SHIPPED ✅ P0 AUDIT FIXES
The Chrome audit's P0 list only. No features. Backend 1907 → **1940 tests**
(+33), 149 suites, all green. Web build clean (compiled successfully, exit 0).
### Fixes
1. **MLB stat_type gate (BACKEND)** — the Scan frontend sends MLB IDs (`hits`,
`strikeouts`, `total_bases`, `rbi`, `home_runs`, `earned_runs`, `hits_allowed`,
`innings_pitched`, `runs`, `walks`, `stolen_bases`) but `VALID_STAT_TYPES` in
`src/routes/analyze.js` + `src/routes/scan.js` only whitelisted the NBA/soccer
set, so every MLB scan 400'd. Added the MLB set to both gates, mirroring the
already-correct `python/utils/validation.py` `VALID_STAT_TYPES.mlb`. The live
grade path is the generic engine1 feature pipeline (note: `mlbGrader.js` is
dead code — required nowhere), which keys off these exact stat names.
2. **/settings → /profile, /report → /blog** — new server-component `redirect()`
pages (`app/settings/page.tsx`, `app/report/page.tsx`). `/profile` is the
canonical account surface; `/blog` is where "The Report" lives.
3. **Profile tier mismatch**`app/profile/page.tsx` showed "Free" (from the
`/api/user/profile` fetch) while the nav showed the real tier (from
`useAuth().tier`). Profile now derives the displayed tier from
`useAuth().tier` (`authTier || profile.tier || 'free'`); the fetch still
supplies scan_count/subscription_*/founder.
4. **Self-hosted fonts** — replaced the runtime `fonts.googleapis.com`
stylesheet `<link>` (503 in prod, ~4s page load) with `next/font/google`:
Inter→`--font-sans`, JetBrains_Mono→`--font-mono`, IBM_Plex_Mono→`--font-ibm`,
variables set on `<html>`. globals.css `:root` maps `--sans`/`--mono`/
`--ibm-mono` onto them. Because next/font obfuscates family names, literal
`'JetBrains Mono'`/`'IBM Plex Mono'` references in CSS + inline component
styles were rewired to the variables (Hero, upgrade/desk, NotificationBell,
responsible-gambling, globals.css wordmark/.lines).
### Deviations from the spec (flagged)
- **Did NOT overwrite `/settings/security`.** The spec said redirect it to
`/profile` too, but that route is a working MFA enrollment flow — clobbering it
would be a security-feature regression. Left intact; only the bare `/settings`
404 was fixed.
- **`/report` link doesn't exist in current code** — Nav's "The Report" already
points to `/blog`. The redirect is harmless defensive coverage (PWA shortcut /
external / stale share links).
- **ShareCard canvas** still uses literal `"JetBrains Mono"`/`"Instrument Sans"`
(canvas `ctx.font` can't read CSS vars). Out of P0 scope; pre-existing.
## Session 39 (2026-06-16) — SHIPPED ✅ DESIGN CONVERSION COMPLETE
## Session 39 (2026-06-16) — SHIPPED ✅ DESIGN CONVERSION COMPLETE