尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Pick every game of the NFL Season through the Super Bowl. Compete with friends. Have a great time.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗Pick every game of the NFL season through the Super Bowl. Compete with friends. Have a great time.
Each game takes one pick — who wins, and roughly by how much — and the leaderboard scores the winner as results come in. Your picks also build your own version of the season: division and conference standings resolved with the league's real tiebreakers, and a 14-team playoff bracket seeded from them.
Live at https://nfl-season-predictions.vercel.app/.
Weekly picks. Pick a winner and roughly how big the margin will be. Point spreads are shown beside each side as context but are not pickable. Picks lock at each game's kickoff, enforced on the server.
Leaderboard. One point per game whose winner you called, plus one more where the margin bucket landed. Filterable by week or season to date.
Postseason bonus. Your bracket is paid per club that actually reached each round, doubling as it goes — 2 for the field, 4 divisional, 8 conference championship, 16 Super Bowl, 32 for the champion. A club you had going all the way is worth 62; a perfect bracket is 156, against 544 for a flawless regular season. The real bracket is derived from ESPN's postseason schedule, not entered by hand.
All five numbers live in POSTSEASON_POINTS in lib/seasonScore.ts and are
the whole tuning surface for how much January matters — everything else,
including the on-page copy, is derived from them.
Standings. Division and conference tables from your picks, or from the real results, with the league's published tiebreaking procedure applied and the deciding step named wherever one was actually needed.
Playoffs. Four division winners and three wild cards per conference, a bye for the top seed, and a divisional round that reseeds the way the real one does.
Provision Postgres and put the connection string in DATABASE_URL. On Vercel:
Storage → Create → Neon, then vercel env pull .env.local to get it
locally. A pooled endpoint is what you want; lib/db.ts already sets
prepare: false for it.
npm install
cp .env.example .env.local # fill in DATABASE_URL and AUTH_SECRET
npm run db:migrate
npm run seed:teams
npm run seed:schedule
db:migrate applies lib/db/schema.sql, which is idempotent — re-running it
is safe and is how schema changes are rolled out.
In the Google Cloud console, create an OAuth 2.0 Client ID (Web application) and add both redirect URIs:
https://nfl-season-predictions.vercel.app/api/auth/callback/google
http://localhost:3000/api/auth/callback/google
Put the client id and secret in AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET, and
generate AUTH_SECRET with openssl rand -base64 32.
Set every variable from .env.example in the Vercel project, then push. The
cron in vercel.json pulls fresh scores and lines daily; it authenticates with
CRON_SECRET and refuses to run without it.
The daily cron syncs a window of weeks — the previous one (a Monday night game finishes after the week has rolled over, and ESPN sometimes corrects a score after the fact), the current one, and the next two, which is roughly how far ahead lines are posted.
To repair something by hand:
curl -X POST "$URL/api/admin/sync?what=teams" -H "x-admin-secret: $ADMIN_SECRET"
curl -X POST "$URL/api/admin/sync?what=week&week=3" -H "x-admin-secret: $ADMIN_SECRET"
A whole season is 18 sequential ESPN calls and will usually exceed the
60-second function limit, so run that from a terminal instead:
npm run seed:schedule.
Rules code fails silently — it produces a plausible order that happens to be wrong, and nobody notices until a division is decided incorrectly in December. So there is a check that replays a finished season through the same functions the app uses and diffs the result against ESPN's own seeds:
node --import tsx scripts/verify-tiebreakers.ts 2025
Both 2025 and 2024 come back 14/14. Those two seasons happen to cover the cases
that actually exercise the rules: an 8-9 division winner seeded above two 12-5
wild cards, two 11-6 division winners split by a tiebreaker, a 9-7-1 club with
a real tie, and three 10-7 clubs competing for two wild-card spots. Run it
after touching anything in lib/tiebreakers.ts or lib/playoffs.ts.
Two steps of the published procedure are deliberately not implemented, and both are documented at their position in the list rather than silently skipped: net touchdowns (a pick records a margin bucket, not a box score) and the final coin toss, replaced by a stable alphabetical order so a page does not reshuffle itself between visits.
ESPN's public endpoints — schedule, kickoff times, live scores, logos, team
colours and DraftKings point spreads. There is no free official NFL feed, so
lib/espn.ts reads every field defensively and a shape change degrades rather
than throws.
The spread's sign is verified against ESPN's favourite flags rather than trusted. Nothing is scored against the line, but "Fill week" defaults from it, so a mis-signed line would hand every auto-filled game to the wrong team.
lib/espn.ts ESPN client
lib/ingest.ts upserts ESPN data into Postgres
lib/standings.ts tallies results into records and points
lib/tiebreakers.ts the league's published tiebreaking procedure
lib/playoffs.ts seeding and the reseeding bracket
lib/grade.ts how one pick settles (pure -- the client imports this)
lib/seasonScore.ts scoring constants and the postseason bonus (pure)
lib/postseason.ts real bracket from the DB, predicted bracket per user
lib/scoring.ts leaderboard totals
lib/queries.ts everything else that touches the database
lib/grade.ts is split out from lib/scoring.ts on purpose: the pick UI is a
client component and needs the same settlement rules, and importing them from
the scoring module pulled the Postgres driver into the browser bundle.
Not affiliated with or endorsed by the National Football League. Team names and logos are trademarks of their respective owners. Point spreads are shown for reference only — nothing here takes a wager.