Stu Mason
Stu Mason

Activity

Pull Request Opened

PR #117 opened: feat(ux): phase 6 — content polish (index card upgrade)

Scope

Phase 6 of the UX overhaul (plan / audit / tokens / brief).

/reports index cards gain a category tag, panel count, and a single cached teaser stat per report — sets expectations + adds glanceable signal without slowing the index load.

What's in

  • Report::summary() — extended with category, panelCount, and teaserStat (default null). Defaults on base class so reports gracefully degrade if they don't override.
  • All 5 reports override category() and teaserStat():
    • HnPredictor → LIVE PREDICTION · pipeline size
    • Predictions → PREDICTION SCORECARD · 30d prediction count
    • Scoreboard → BACKTEST · 7d caught-by-hour-3 ratio
    • AnthropicVsOpenAi → MINDSHARE · peak Anthropic/OpenAI ratio
    • ClaudeCodeWars → COMPETITIVE INTEL · Claude Code weekly peak
  • reports/index.tsx — eyebrow combines category + panel count + refresh time; teaser block (mono value + overline label) below the tagline, separated by a hairline.
  • 4 new Pest cases for summary shape, defaults, overrides, and teaser caching.

Pragmatic notes from the agent

  • category() / teaserStat() are default-implemented (not abstract) so future reports won't be forced to implement either.
  • Each teaserStat() is wrapped in try/catch (Throwable) and caches its result (30 min TTL) — protects the index from PostgreSQL-only syntax failing in test runs and from cold-cache crashes.
  • Predictions::panels() already calls computeStats(), so count($this->panels()) from summary() fires SQL on that one report. Out of scope here; flagged for follow-up.

Test plan

  • vendor/bin/pint --dirty --format agent clean
  • npm run build clean
  • php artisan test --compact — 186 pass, 26 skipped, 2 pre-existing LinkedIn failures (unrelated)
  • Post-deploy Playwright on /reports — cards show category, panel count, teaser stat
+442
additions
-4
deletions
9
files changed