F1ReplayTiming
F1 리플레이와 실시간 트랙 데이터·텔레메트리를 시각화
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Live stat tracker for 'Bobby's Triple Threat' on Food Network
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Fan-made stat tracker for Food Network's Bobby's Triple Threat. Live at triple-threat.vercel.app.
Titan Tracker is a data-driven Next.js app that presents performance analytics for the show's titans, including rankings, records, per-round performance, and best score breakdowns. The page is generated statically at build time from PostgreSQL so it loads fast and remains cache-friendly, and it regenerates on demand when a new episode is entered through a password-gated admin portal.
.sql files, one TypeScript type per table, components that only render/admin) for entering episodes, with a dry-run preview (a real transaction, rolled back) before anything is writtenpg) on Neonapp/
layout.tsx # Root layout shared by every route: <html>, <body>, global CSS
styles/ # Global CSS: design tokens (variables.css) and base styles
(public)/ # Route group (not part of the URL) for the public site
layout.tsx # Header, footer, site metadata, analytics
page.tsx # The homepage ("/"): fetches data and composes sections
admin/ # /admin route: layout + page (password-gated episode entry)
metadata.ts # SEO / OG metadata
robots.ts, sitemap.ts
components/
Layout/ # Site header, nav, footer
Cards/ # Win/loss, leaderboard, per-titan cards, notes
Admin/ # Admin portal UI: login, episode form, review panel (+ shared.module.css)
HeroBanner.tsx, Section.tsx, ShareButtons.tsx
lib/
db.ts # PostgreSQL pool (+ parsing COUNT/AVG results as numbers)
queries.ts # Public-site data access: runs lib/queries/*.sql, shapes results
queries/ # The SQL, one file per query (+ sql-loader.cjs, see below)
types.ts # One row type per table, plus shaped view types
ranking.ts # Rank labels and the active/inactive split
format.ts # Display formatting (averages, win %, name slugs)
admin/ # Admin logic: auth, server actions, data access, validation, draft autosave
*.test.ts # Unit tests, next to the code they cover
docs/
DATABASE.md # Schema, keys, rules, handy queries, schema history
ADMIN.md # How the admin portal works
.githooks/pre-push # tsc + ESLint + Prettier + tests before every push
.github/workflows/ # The same checks in CI
lib/queries/**/*.sql and are built into the bundle as strings (a small Turbopack loader, lib/queries/sql-loader.cjs, wired up in next.config.mjs).lib/queries.ts runs them and shapes the rows into typed objects and lookup maps (getTitans, getWinLoss, getAvgScores, …).app/(public)/page.tsx calls those in parallel at build time; app/(public)/layout.tsx adds the header, footer, site metadata and analytics.force-static: built once, served from the CDN. Committing an episode through /admin calls revalidatePath("/"), so new stats appear within seconds without a redeploy.lib/queries.ts (public) and lib/admin/queries.ts (admin) expose get* functions that return render-ready data. getTitans is wrapped in React's cache(), so the page and the site header share one query per render..sql files that can be opened and run in a SQL client. They're compiled into the bundle rather than read from disk at runtime, which matters because on-demand regeneration runs in a serverless function where loose files aren't guaranteed to exist. Postgres returns COUNT/AVG results as strings by default; lib/db.ts parses them as numbers once, so the SQL needs no JavaScript-motivated casts.lib/types.ts has one type per table (Titan, Episode, Round); query and view types are built from them with Pick/Omit, so a column is described in one place.NOT NULL and value rules (scores within range, max score by round, one round per titan per episode), so bad data can't get in from anywhere. The admin form validates the same rules first to show friendly, specific messages. See docs/DATABASE.md.(public) route group gives the public site its header, footer, metadata and analytics; /admin uses only the minimal root layout, so it never runs the header's query or loads analytics.docs/DATABASE.md rather than managed by a migration tool.Create .env.local:
POSTGRES_URL=postgres://username:password@host/database
ADMIN_PASSWORD=choose-a-password # gates /admin; also set in Vercel project settings
next build prerenders the homepage from the database, so POSTGRES_URL must be set for builds too (a missing value makes pg fall back to a local Postgres and fail with relation "titan_rounds" does not exist). Vars pulled with vercel env pull land in .env.development.local, which next dev reads but next build doesn't; a local, gitignored .envrc (direnv) can export them for builds.
Requires Node 24 (pinned in .nvmrc).
npm install
npm run dev
The app runs at http://localhost:3000.
npm run dev # dev server
npm run build # production build
npm start # serve the production build
npm run lint # ESLint (Next.js + TypeScript rules)
npm test # unit tests (Vitest)
npm run test:watch # tests in watch mode
npm run format # format with Prettier
npm run format:check # check formatting
A tracked pre-push hook (.githooks/pre-push) type-checks with tsc, lints with ESLint, checks formatting and runs the tests before every push; npm install enables it (the prepare script sets core.hooksPath). GitHub Actions runs the same checks on every push and pull request.
Titan Tracker showcases practical full-stack analytics work: SQL modeling and database integrity, a strongly typed data-access layer, stat-focused frontend presentation, and a rendering strategy that keeps a static site fresh.