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.