Session 51: Complete Team Hub (2234 tests)
Research-depth team view: /team/[abbr] with roster, archetypes, stats, props.
- Team API: mlbStatsAdapter.getTeams/resolveTeam/getTeamRoster (statsapi, abbr→id
+ active roster, cached). teamService.getTeamHub assembles roster → per-player
season stats (bounded concurrency) + archetype (snapshot grade or classify) +
tonight's graded props from grades:{sport}; whole hub cached 15min. MLB real;
NBA/WNBA graceful snapshot roster. GET /api/team/:abbr (404 unknown) + proxy.
- Team Hub page: server page.tsx (generateMetadata) + TeamHub client — header,
sort (archetype/graded/A-Z), archetype filter chips, roster rows (archetype +
player link + position + stats + graded props + parlay "+"), "No active props"
greyed state, loading/error.
- Game cards: team abbreviations are now TeamLinks → /team/:abbr?sport= (green
hover, stops propagation). Team Hub has "← Back to Slate".
Backend 2215 -> 2234 tests (+19), 190 suites. Web build clean (exit 0).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -556,6 +556,27 @@ snapshot, locked to the line, and read from cache.
|
||||
then-missing `/grade` endpoint). Floating badge bottom-right when closed; free
|
||||
tier blurs the payout with a `window.__goPaywall` upsell.
|
||||
|
||||
## Team Hub (Session 51 — non-obvious)
|
||||
- **`teamService.getTeamHub(sport, abbr)`** is the single payload builder for
|
||||
`/team/:abbr`. MLB is the real path: `mlbStatsAdapter.resolveTeam` (abbr→id via
|
||||
the cached `/teams` list) → `getTeamRoster` → per-player `getSeasonAverages(id)`
|
||||
(bounded concurrency 8, reuses `playerIntelService._internals` mappers) →
|
||||
archetype (the snapshot grade's locked archetype, else `classify`) → graded
|
||||
props from `grades:{sport}`. The whole hub is cached 15 min (`teamhub:{sport}:
|
||||
{abbr}`); each player's season stats cache 6h. NBA/WNBA have no free roster
|
||||
feed → it returns a partial roster built from tonight's graded players + a note.
|
||||
All deps injectable for tests.
|
||||
- **To add a sport's roster**, add a real roster source in `getTeamHub` (the MLB
|
||||
branch is the template); abbr→id mapping is fetched live from statsapi (no
|
||||
hardcoded team table to maintain).
|
||||
- **`GET /api/team/:abbr`** (public, cached) 404s an unknown MLB team. Browser
|
||||
must use the Next proxy `app/api/team/[abbr]`.
|
||||
- **Page split:** `team/[abbr]/page.tsx` is a server wrapper (for
|
||||
`generateMetadata`) rendering the `TeamHub` client component (sort/filter/parlay
|
||||
are interactive). Player names → `playerHref`; team abbrs on game cards →
|
||||
`vyndr/GameCard`'s `TeamLink` (stops propagation from the open-game handler).
|
||||
The roster "+" reuses the Parlay Lab (`useParlay`/`legKey`).
|
||||
|
||||
## Active Skills
|
||||
- vyndr-voice (all user-facing output)
|
||||
- prop-analysis (grading methodology)
|
||||
|
||||
Reference in New Issue
Block a user