CourtSide is a full-stack analytics dashboard for NCAA D1 Men's Volleyball that scrapes live statistical data from the NCAA, normalizes it into a PostgreSQL database, and serves an interactive dashboard with AI-powered match predictions.
The core engineering challenge: the NCAA has no public API for men's volleyball โ data is scattered across server-rendered HTML tables behind Akamai bot protection. CourtSide solves this with a custom multi-source scraping pipeline that pulls from 7 national ranking endpoints, normalizes 329+ player stat profiles across 71 teams, and funnels everything into a typed Prisma schema. A weighted logistic regression model then predicts match outcomes between any two teams using 7 performance features.
Built as a personal project combining competitive volleyball experience with full-stack engineering.
| Feature | Description |
|---|---|
| ๐ Coaches Poll Rankings | Accurate top-20 rankings with overall and conference-grouped standings views |
| ๐ Player Leaderboards | Sortable across 14 stat categories with conference filtering, search, and pagination |
| โก Player Comparison | Side-by-side stat profiles for up to 4 players with radar chart visualization |
| ๐ Team Comparison | Head-to-head team analytics with aggregated roster stats and radar charts |
| ๐ฎ Match Predictions | Weighted logistic regression model across 7 features with confidence levels and key factor explanations |
| ๐ก Live Scraper Progress | WebSocket-powered real-time progress bar during NCAA data refreshes |
| ๐ Universal Search | Search players and teams from any page via the navbar |
| ๐ Championship History | National title counts and years for 13 historically winning programs |
| ๐ Shareable Compare URLs | Pre-populated comparison links via query parameters |
| ๐ฑ Responsive Dark UI | Broadcast-style dark theme optimized for desktop and mobile |
The match predictor uses a weighted logistic regression with 7 input features to compute win probability between any two teams:
| Feature | Weight | Rationale |
|---|---|---|
| Win % | 4.0 | Strongest single predictor of team quality |
| Hitting % | 2.5 | Volleyball's most predictive offensive metric โ kill efficiency minus errors |
| Kills/Set | 1.0 | Raw offensive output volume |
| Blocks/Set | 0.8 | Net defense differentiator at the D1 level |
| Aces/Set | 0.6 | Free-point serving advantage |
| Assists/Set | 0.4 | Ball distribution and setter quality indicator |
| Rank Diff | 0.3 | Coaches' poll reputation tiebreaker โ weighted low to avoid circular reasoning |
Predictions include confidence levels (high >70%, medium 60-70%, low <60%) and 3-4 human-readable key factor explanations. Featured matchups are auto-generated and ranked by competitiveness (closest to 50/50). The model runs entirely in TypeScript โ no external ML library, just sigmoid(weighted_sum) over stat differentials. Predictions compute in <100ms with in-memory team profile caching.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ React 18 Frontend โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Home โ โ Matches โ โStandings โ โ Compare โ โ
โ โ(Spotlightโ โ(Predictorโ โ(Rankings โ โ(Players + โ โ
โ โ + Stats) โ โ+ Builder)โ โ+ Confrnc)โ โ Teams + Radarโ โ
โ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโโโโโฌโโโโโโโโ โ
โ โ โ โ โ โ
โ โโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโ โ
โ โ Typed API Client (fetch wrapper) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ REST + WebSocket
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Fastify API Server โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Teams โ โ Players โ โStandings โ โ Predict โ โ
โ โ Routes โ โ Routes โ โ Routes โ โ Routes โ โ
โ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโโโฌโโโโโโ โโโโโโโโฌโโโโโโโโ โ
โ โ โ โ โ โ
โ โโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโ โ
โ โ Prisma ORM (typed queries, zero raw SQL) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ML Predictor Engine (sigmoid + weighted features) โ โ
โ โ WebSocket Manager (live scraper broadcast) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโผโโโโโโโโ
โ PostgreSQL โ
โ (Neon Cloud) โ
โโโโโโโโโฌโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ NCAA Scraper Pipeline โ
โ โ
โ stats.ncaa.org โโโ Cheerio HTML Parser โโโ Normalizer โ
โ (7 ranking (team list, W-L (fuzzy name โ
โ endpoints) records, player matching, โ
โ stat tables) type coercion) โ
โ โ โ
โ Coaches Poll (hardcoded) โโโ Rank Applicator โโโโโค โ
โ Championship History โโโโโโโ Title Applicator โโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Multi-Source Scraping Pipeline
The NCAA has no public API for men's volleyball. Individual team pages are protected by Akamai bot detection. CourtSide works around this by pulling from 7 national ranking endpoints (stats.ncaa.org/rankings/national_ranking) โ kills, hitting %, assists, aces, digs, blocks, points โ and cross-referencing player records across all categories to build complete stat profiles. The pipeline is idempotent (safe to re-run via upserts) and completes in ~8 seconds.
Weighted Logistic Regression Rather than importing a heavy ML library, the predictor is pure TypeScript math โ a sigmoid function over weighted stat differentials. Team profiles are cached in memory on first request and recomputed only when data is refreshed. This keeps prediction latency under 100ms while running on a free-tier server.
WebSocket Live Progress When a data refresh is triggered (via the dashboard or CLI), the server spawns the scraper as a child process and broadcasts structured progress events over WebSocket. Connected clients render a real-time progress bar without polling โ a genuine use of WebSockets, not a fabricated one.
Hardcoded Authoritative Data Coaches Poll rankings and championship history are intentionally hardcoded rather than scraped. These come from official NCAA sources that are either JS-rendered (unscrapeable) or static historical records. Hardcoding ensures accuracy and eliminates a fragile scraping dependency for data that changes weekly at most.
| Technology | Purpose |
|---|---|
| React 18 | UI framework with hooks |
| TypeScript | Strict mode, zero any types |
| Tailwind CSS | Dark broadcast-style theme |
| Recharts | Radar charts, data visualizations |
| Vite | Build tool & dev server |
| React Router v7 | Client-side routing (9 pages) |
| Technology | Purpose |
|---|---|
| Fastify 5 | REST API framework (8 route modules) |
| Prisma 6 | Type-safe PostgreSQL ORM |
| PostgreSQL 17 | Primary database (Neon cloud) |
| WebSocket (ws) | Live scraper progress broadcast |
| Cheerio | HTML parsing for NCAA scraping |
| Node.js | Scraper pipeline runtime |
| Technology | Purpose |
|---|---|
| Vercel | Frontend hosting (free tier) |
| Render | Backend hosting (free tier) |
| Neon | Managed PostgreSQL (free tier) |
- Node.js 18+
- PostgreSQL database (Neon free tier works)
git clone https://github.com/riyonp23/CourtSide.git
cd CourtSide
npm installcp .env.example server/.env
# Edit server/.env with your Neon connection stringcd server && npx prisma migrate dev --name init && cd ..
npm run scrapenpm run dev:allThe client runs on http://localhost:5173 and the API on http://localhost:3001.
CourtSide/
โโโ client/ React 18 + Vite + Tailwind
โ โโโ src/
โ โ โโโ components/ 19 reusable components
โ โ โ โโโ PredictionBar Animated win probability visualization
โ โ โ โโโ MatchupCard Full matchup display with key factors
โ โ โ โโโ FeaturedMatchups Spotlight hero section for Home page
โ โ โ โโโ PlayerTable Sortable stat table with mobile scroll
โ โ โ โโโ NavSearch Universal player + team search
โ โ โ โโโ AnimatedNumber Count-up animation (easeOutExpo)
โ โ โ โโโ ...
โ โ โโโ pages/ 9 page components
โ โ โ โโโ Home Dashboard with spotlight + stats + top 10
โ โ โ โโโ Matches Featured predictions + matchup builder
โ โ โ โโโ Standings Overall rankings + conference view tabs
โ โ โ โโโ Players Paginated leaderboard (14 stat categories)
โ โ โ โโโ Compare Player + team comparison with radar charts
โ โ โ โโโ PlayerDetail Percentile bars across all D1 players
โ โ โ โโโ TeamDetail Roster + championship history
โ โ โ โโโ ...
โ โ โโโ lib/api.ts Typed fetch wrapper (10 API functions)
โ โ โโโ types.ts Shared TypeScript interfaces
โ โโโ public/favicon.svg
โ
โโโ server/ Fastify 5 + Prisma + WebSocket
โ โโโ src/
โ โ โโโ routes/ 8 route modules
โ โ โ โโโ teams.ts GET /api/teams, /api/teams/:id
โ โ โ โโโ players.ts GET /api/players (paginated, filterable, searchable)
โ โ โ โโโ standings.ts GET /api/standings (conference grouping)
โ โ โ โโโ compare.ts GET /api/compare?ids=...
โ โ โ โโโ predict.ts GET /api/predict, /api/predict/featured
โ โ โ โโโ scraper.ts POST /api/scrape (async + WebSocket progress)
โ โ โ โโโ health.ts GET /api/health
โ โ โโโ lib/
โ โ โโโ predictor.ts Weighted logistic regression engine
โ โ โโโ prisma.ts Singleton Prisma client
โ โ โโโ ws.ts WebSocket broadcast manager
โ โโโ prisma/schema.prisma 4 models: Team, Player, Match, PlayerSeasonStats
โ
โโโ scraper/ NCAA data pipeline
โ โโโ src/
โ โ โโโ teams.ts Team list + W-L record scraper
โ โ โโโ roster.ts Player stats from 7 ranking endpoints
โ โ โโโ rankings.ts Coaches Poll + championship history
โ โ โโโ utils.ts Retry logic, rate limiting, User-Agent
โ โ โโโ index.ts Pipeline orchestrator with progress callbacks
โ โโโ package.json
โ
โโโ docs/
โ โโโ banner.svg
โ โโโ screenshot.png
โโโ .env.example
โโโ .gitignore
โโโ render.yaml Render deployment blueprint
โโโ README.md
All statistics sourced from stats.ncaa.org national ranking pages for the 2025-26 NCAA D1 Men's Volleyball season. The dataset covers 71 teams, 329+ players, and 6 conferences. Coaches Poll rankings sourced from the AVCA weekly poll. Championship history verified against official NCAA records spanning 1970-2025.
Riyon Praveen โ Computer Science, University of South Florida (Class of 2027)
This project is licensed under the MIT License โ see LICENSE for details.
