Skip to content

Latest commit

 

History

1,255 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Control Scout

Free-forever FTC scouting and predictions for every team.

Live Demo — controlscout.org

React 19 TypeScript Vite Tailwind CSS Node.js 22 SQLite via libSQL GPL-3.0

Search any team, event or match; read OPR breakdowns and trends; ask the prediction lab who wins a what-if alliance or how likely a team is to advance from any event — and check the public track record of how often those predictions came true.

Sister app of Control Point (team management). Same design language, and the same prediction engine: both apps run @control-scout/predict-engine, one versioned package, so predictions can never be better in one app than the other.

Screenshots

Home Team page
Control Scout home Control Scout team page

Features

Scout

  • Instant search across every team, event and match
  • Team pages with full season history and event results
  • Event pages with rankings, matches and insights

Analyze

  • OPR breakdowns (auto, teleop, endgame) computed by least squares over quals only
  • Season trends and per-event performance charts
  • Stat tables with sorting and CSV export

Predict

  • Prediction lab: what-if alliances, head-to-head win odds
  • Advancement likelihood for any team at any event
  • Public calibration ledger — every prediction scored against reality

Access

  • Free forever, no paywall
  • No account needed for core features; personal data stays on your device
  • Offline data packs (lite < 10 MB for predictions, full packs per season)

Stack (and why)

Layer Choice Why
Server Node 22+ · Express · TypeScript run by tsx Same as Control Point: one runtime, one mental model, no build step for the server.
Database SQLite through @libsql/client A local file in development and on a single box; the same client talks to Turso if hosting ever needs a networked database. Zero ops.
Web React 19 · Vite · Tailwind v4 · Radix (shadcn-style components copied into src/components/ui) · Motion · Recharts Control Point's exact UI stack and theme tokens, so the two apps feel like family.
Predictions packages/predict-engine (pure TS) Runs identically on the server and in the browser — offline predictions from the lite pack need no server.
Deploy Plain Node on the Oracle VM (Dockerfile too) Portable: the VM or a Mac mini cluster are all just "run the app".

Run it locally

npm install
cp .env.example .env        # add FIRST Events API credentials (optional but recommended)
npm run seed:scout          # optional: import a local FTC Scout cache for instant history
npm run sync                # pull events/teams/matches from FIRST (resumable)
npm run stats               # compute OPR + ratings + calibration ledger
npm run packs               # optional: build the offline packs served at /packs
npm run dev                 # API on :3000, web on :5173

npm test runs every test; npm run lint type-checks.

npm run sync needs FIRST credentials (it lists events from FIRST, and falls back to FTC Scout per event when FIRST has no data for one). Without them, the app still starts but shows empty states until data arrives via seed:scout or a copied database. Without a Resend key, sign-in is hidden and everything personal stays on the device.

Tools

Command What it does
npm run shots -- /teams/18360 --both Screenshots for PRs (real servers, 2x, waits for data). See AGENTS.md.
npm run audit The self-audit sweep: every route at desktop + mobile, console, overflow, labels, loading and API-down states (docs/self-audit.md).
npm run db:export A consistent single-file copy of the database (for moving it to a server).

Hosting

How data flows

FIRST Events API (primary) ─┐
FTC Scout API (fallback)  ──┴─> sync job ─> SQLite ─> stats job ─┬─> REST API ─> web app
                                                                 ├─> prediction ledger (track record)
                                                                 └─> pack builder ─> /packs/*.db + latest.json
  • Sync is idempotent and resumable. Finished seasons are frozen once complete; only the current season refreshes (daily, every 15 min on event days on the VM).
  • Stats recomputes per-team, per-event OPR (least squares, quals only, surrogates excluded) and the engine's rating book; it also writes a prediction for every not-yet-played match into the calibration ledger before the match happens, and scores it afterwards.
  • Packs: a lite pack (team ratings, < 10 MB) runs predictions fully offline; per-season full packs hold every event, match and team. Downloaded online, run only offline: returning visitors get the lite pack in the background (src/lib/packSync.tsx, rules in src/lib/packPolicy.ts) and "Save offline" stores a season, but both only store bytes. Nothing opens, decodes or queries a pack (and sql.js never loads) while the server answers; the app switches to them only when the browser is offline or a read the pack could answer gets a network error or no answer within 4 s, shows an "Offline, showing saved data" badge, and switches back on the next server answer (src/lib/api.ts).

Repository layout

packages/predict-engine/   shared prediction engine (Control Scout + Control Point)
server/                    API, sync, stats, ledger, auth
src/                       web app
scripts/                   one-off and scheduled jobs (sync, stats, packs, backtests)
docs/                      methodology and runbooks
DECISIONS.md               every judgment call made without the product owner

License

GPL-3.0-only, same as Control Point. Data © FIRST and FTC Scout contributors; see the About page for attribution.

Releases

Packages

Contributors

Languages