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:
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* GET /api/team/:abbr?sport=mlb (Session 51) — the Team Hub payload (roster +
|
||||
* per-player archetype/stats/props). Public, cache-backed (15 min). Returns 404
|
||||
* for an unknown MLB team; NBA/WNBA degrade to a snapshot-built roster.
|
||||
*/
|
||||
|
||||
const express = require('express');
|
||||
const { createRateLimit } = require('../middleware/rateLimit');
|
||||
const { getTeamHub } = require('../services/teamService');
|
||||
|
||||
const router = express.Router();
|
||||
router.use(createRateLimit({ windowMs: 60_000, max: 60 }));
|
||||
|
||||
router.get('/:abbr', async (req, res) => {
|
||||
const sport = String(req.query.sport || 'mlb').toLowerCase();
|
||||
const abbr = String(req.params.abbr || '');
|
||||
try {
|
||||
const hub = await getTeamHub(sport, abbr);
|
||||
if (!hub) {
|
||||
return res.status(404).json({ error: `No ${sport.toUpperCase()} team for "${abbr}". Check the abbreviation.` });
|
||||
}
|
||||
res.set('Cache-Control', 'public, max-age=300');
|
||||
return res.json(hub);
|
||||
} catch (err) {
|
||||
console.error('[team]', err.message);
|
||||
return res.status(503).json({ error: 'Team service temporarily unavailable' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user