BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2 或任何藍牙控制器,搭配 MyWhoosh、Rouvy、Zwift 等。iOS、Android、Windows、macOS 均可免費試用。
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A full-stack Formula 1 statistics web app: championship standings, race calendar, driver & team profiles, head-to-head comparisons, past-race telemetry, and a session replay player that plays back completed races lap-by-lap.
Live: https://paddocktimes.com
Paddock Times is a monorepo with a React SPA and an Express API. The client
only ever talks to our own backend; the backend fetches data from free public F1
sources, normalizes their verbose shapes into flat types, and caches everything in
memory. One deployed web service serves both the API (/api/*) and the built SPA.
The project covers 1950 → present for historical stats, and 2023 → present for telemetry and replays.
pageimages API (CC-BY-SA / public domain).P154, image P18) and
licence-checked on Commons — a free PD/CC logo is used when available,
otherwise a free car photo, otherwise a team-coloured tile. Trademarked / non-free
emblems are deliberately skipped.robots.txt.| Layer | Stack |
|---|---|
| Frontend | React 18, TypeScript, Vite 6, React Router 7, Recharts |
| Backend | Node 20, Express 4, TypeScript, Helmet, node-cache |
| Data | f1db (CC-BY 4.0), OpenF1, Wikimedia Commons / Wikidata |
| Hosting | Render (single web service) |
f1db-json-splitted.zip once, unzips it in memory
(adm-zip), and joins the normalized tables into our flat types. The dataset is
held in a single in-flight promise for the process lifetime.┌────────────┐ /api/* ┌──────────────┐ HTTP ┌──────────────────┐
│ React SPA │ ──────────────▶ │ Express API │ ────────▶ │ f1db · OpenF1 · │
│ (Vite) │ ◀────────────── │ normalize + │ ◀──────── │ Wikimedia · RSS │
└────────────┘ flat JSON │ cache (TTL) │ └──────────────────┘
└──────────────┘
/api/*). In dev, Vite proxies /api
to the server; in production, Express serves both the API and the built SPA.cached(key, ttlSeconds, producer) (in-memory
TTL cache) to stay well within rate limits.502 { error }.F1_Dashboard/
├── client/ # React + Vite SPA
│ ├── src/
│ │ ├── pages/ # route components (Home, Standings, Live, …)
│ │ ├── components/ # shared UI (ReplayPlayer, EntityCards, Footer, …)
│ │ ├── hooks/ # useAsync, useSeo, useSeasonRoute
│ │ ├── lib/ # f1 metadata, team colours, JSON-LD helpers
│ │ ├── api/client.ts # typed wrapper around /api
│ │ └── types/f1.ts # client-side mirror of the backend types
│ └── public/ # sitemap.xml, robots.txt, icons
└── server/ # Node + Express API
└── src/
├── routes/ # thin Express handlers (standings, live, …)
├── services/ # fetch + normalize + cache (f1db, live, teamImages, …)
├── cache/ # node-cache TTL wrapper
└── types/f1.ts # canonical normalized types
All endpoints are prefixed with /api.
| Endpoint | Description |
|---|---|
GET /health | Liveness probe |
GET /home | Weekend highlights + news headlines |
GET /standings/drivers/:season | Driver championship for a season |
GET /standings/constructors/:season | Constructor championship for a season |
GET /standings/progression/:season | Title-race progression (chart data) |
GET /calendar/:season | Season schedule + winners (sprint-flagged) |
GET /calendar/:season/:round | A single race result |
GET /calendar/:season/:round/weekend | Full weekend: race, qualifying, sprint, highlights |
GET /drivers · GET /drivers/:id | Driver list / full profile |
GET /drivers/photos | Driver photos (Wikimedia), keyed by id |
GET /constructors · GET /constructors/:id | Constructor list / full profile |
GET /constructors/images | Licence-checked team logos/photos |
GET /compare/drivers/:a/:b | Head-to-head comparison |
GET /telemetry/sessions/:season · /telemetry/drivers/:sessionKey | Telemetry metadata |
GET /live/status | Live-session status (handles OpenF1 lock) |
GET /live/races | Replayable races and sprints (2023+) |
GET /live/:sessionKey/replay · /board · /driver/:num | Replay / board / driver detail |
POST /feedback | Submit user feedback |
Requires Node 18+ (Node 20 recommended).
# Terminal 1 — backend (http://localhost:3001)
cd server
npm install
npm run dev
# Terminal 2 — frontend (http://localhost:5173)
cd client
npm install
npm run dev
Open http://localhost:5173 — the Vite dev server proxies /api to the backend.
client: npm run dev · npm run build (type-check + production build) · npm run lint
server: npm run dev (tsx watch) · npm run build (tsc) · npm start
| Variable | Purpose |
|---|---|
PORT | API port (default 3001) |
/api/home every 10 minutes, which both keeps the process awake and keeps the f1db
dataset warm in memory. (A sleeping server returning errors on robots.txt can also
stall Googlebot, so the keep-alive doubles as an SEO safeguard.)Повноцінний веб-застосунок зі статистикою Формули-1: турнірні таблиці чемпіонату, календар гонок, профілі пілотів і команд, порівняння «голова-в-голову», телеметрія минулих гонок і плеєр реплеїв сесій, що відтворює завершені гонки коло за колом.
Онлайн: https://paddocktimes.com
Paddock Times — це монорепозиторій із React SPA та Express API. Клієнт
спілкується виключно з нашим бекендом; бекенд отримує дані з безкоштовних публічних
джерел F1, нормалізує їхні громіздкі формати у плоскі типи й кешує все в пам'яті. Один
розгорнутий веб-сервіс віддає і API (/api/*), і зібраний SPA.
Проєкт охоплює історичну статистику від 1950 до сьогодні, а телеметрію й реплеї — від 2023 до сьогодні.
pageimages API (CC-BY-SA / суспільне надбання).P154, зображення
P18) із перевіркою ліцензії на Commons — вільний PD/CC логотип, якщо є, інакше
вільне фото боліда, інакше плитка в кольорі команди. Торгові марки / невільні
емблеми свідомо пропускаються.robots.txt.| Рівень | Стек |
|---|---|
| Фронтенд | React 18, TypeScript, Vite 6, React Router 7, Recharts |
| Бекенд | Node 20, Express 4, TypeScript, Helmet, node-cache |
| Дані | f1db (CC-BY 4.0), OpenF1, Wikimedia Commons / Wikidata |
| Хостинг | Render (один веб-сервіс) |
f1db-json-splitted.zip, розпаковує його в
пам'яті (adm-zip) і зшиває нормалізовані таблиці у наші плоскі типи. Датасет
тримається в єдиному проміжному промісі на весь час життя процесу.┌────────────┐ /api/* ┌──────────────┐ HTTP ┌──────────────────┐
│ React SPA │ ──────────────▶ │ Express API │ ────────▶ │ f1db · OpenF1 · │
│ (Vite) │ ◀────────────── │ нормалізація │ ◀──────── │ Wikimedia · RSS │
└────────────┘ плоский JSON │ + кеш (TTL) │ └──────────────────┘
└──────────────┘
/api/*). У розробці Vite проксує /api
на сервер; у продакшені Express віддає і API, і зібраний SPA.cached(key, ttlSeconds, producer) (кеш у
пам'яті з TTL), щоб упевнено лишатися в межах лімітів.502 { error }.F1_Dashboard/
├── client/ # React + Vite SPA
│ ├── src/
│ │ ├── pages/ # компоненти маршрутів (Home, Standings, Live, …)
│ │ ├── components/ # спільний UI (ReplayPlayer, EntityCards, Footer, …)
│ │ ├── hooks/ # useAsync, useSeo, useSeasonRoute
│ │ ├── lib/ # метадані F1, кольори команд, хелпери JSON-LD
│ │ ├── api/client.ts # типізована обгортка над /api
│ │ └── types/f1.ts # клієнтська копія бекенд-типів
│ └── public/ # sitemap.xml, robots.txt, іконки
└── server/ # Node + Express API
└── src/
├── routes/ # тонкі Express-хендлери (standings, live, …)
├── services/ # fetch + нормалізація + кеш (f1db, live, teamImages, …)
├── cache/ # обгортка node-cache з TTL
└── types/f1.ts # канонічні нормалізовані типи
Усі ендпоінти мають префікс /api.
| Ендпоінт | Опис |
|---|---|
GET /health | Перевірка доступності |
GET /home | Підсумки вікенду + новинні заголовки |
GET /standings/drivers/:season | Чемпіонат пілотів за сезон |
GET /standings/constructors/:season | Чемпіонат конструкторів за сезон |
GET /standings/progression/:season | Перебіг боротьби за титул (дані графіка) |
GET /calendar/:season | Календар сезону + переможці (з позначкою спринтів) |
GET /calendar/:season/:round | Результат однієї гонки |
GET /calendar/:season/:round/weekend | Увесь вікенд: гонка, кваліфікація, спринт, хайлайти |
GET /drivers · GET /drivers/:id | Список / повний профіль пілота |
GET /drivers/photos | Фото пілотів (Wikimedia), за id |
GET /constructors · GET /constructors/:id | Список / повний профіль конструктора |
GET /constructors/images | Логотипи/фото команд із перевіркою ліцензії |
GET /compare/drivers/:a/:b | Порівняння «голова-в-голову» |
GET /telemetry/sessions/:season · /telemetry/drivers/:sessionKey | Метадані телеметрії |
GET /live/status | Статус живої сесії (з обробкою блокування OpenF1) |
GET /live/races | Гонки та спринти для реплею (2023+) |
GET /live/:sessionKey/replay · /board · /driver/:num | Реплей / табло / деталі пілота |
POST /feedback | Надсилання зворотного зв'язку |
Потрібен Node 18+ (рекомендовано Node 20).
# Термінал 1 — бекенд (http://localhost:3001)
cd server
npm install
npm run dev
# Термінал 2 — фронтенд (http://localhost:5173)
cd client
npm install
npm run dev
Відкрий http://localhost:5173 — Vite проксує /api на бекенд.
client: npm run dev · npm run build (перевірка типів + продакшн-збірка) · npm run lint
server: npm run dev (tsx watch з перезапуском) · npm run build (tsc) · npm start
| Змінна | Призначення |
|---|---|
PORT | Порт API (за замовчуванням 3001) |
/api/home кожні 10 хвилин, що і тримає процес активним, і зберігає датасет f1db
теплим у пам'яті. (Сплячий сервер, який віддає помилки на robots.txt, також може
застопорити Googlebot, тож keep-alive слугує ще й запобіжником для SEO.)Built incrementally — standings, calendar, profiles, telemetry, F1.com-inspired design, live timing, session replays, search, media, and SEO.