BikeControl (SwiftControl)
Zwift Click과 Shimano 컨트롤러를 MyWhoosh와 Rouvy와 Zwift에서 쓴다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 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.