BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2,或任何藍牙控制器搭配 MyWhoosh、Rouvy、Zwift 等。可於 iOS、Android、Windows 與 macOS 免費試用。
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
A two-person NFL league scored against the spread. Each week a coin flip
decides who drafts first; the two of you draft 5 sides from that week's slate,
and whoever finishes the season with the most ATS wins takes it.檢視完整 README ↗A two-person NFL league scored against the spread. Each week a coin flip decides who drafts first; the two of you draft 5 sides from that week's slate, and whoever finishes the season with the most ATS wins takes it.
SEA -3.5, not "Seattle."SEA -3.5, NE +3.5 isn't available to your
opponent either.5 - P.Next.js (App Router) + TypeScript + Tailwind, Prisma + Postgres (Neon), hosted on Vercel. Slate, spreads, and final scores come from ESPN's public scoreboard endpoint — no API key.
You need a free Neon Postgres database — there's no local SQLite file any more, so local development talks to the same database as production.
npm install
cp .env.example .env # paste your Neon URLs + pick a league password
npx prisma migrate dev
npm run db:seed # creates the two players
npm run dev
Open http://localhost:3000. Player names are set in
prisma/seed.ts — edit them before seeding.
DATABASE_URL must be Neon's pooled string (the host contains -pooler)
and DIRECT_URL the unpooled one. Serverless functions open a connection per
invocation, so queries go through the pooler, while prisma migrate needs a
direct connection.
DATABASE_URL, DIRECT_URL,
ADMIN_PASSWORD, and CRON_SECRET (generate with openssl rand -hex 32).CRON_SECRET value as a GitHub Actions repository secret
(Settings → Secrets and variables → Actions → New repository secret) so the
automated spread sync can authenticate — see How spreads freeze below.npx prisma migrate deploy and npm run db:seed once against Neon.package.json runs prisma generate on postinstall because Vercel caches
node_modules — without it the deployed Prisma Client can silently go stale
against a changed schema.
ESPN drops the odds once a game goes final — a line that isn't captured before kickoff is gone for good. So each game's spread stays live — re-syncing keeps it current with the market — right up until that game's own kickoff, then it locks permanently. Both players are always graded against that one frozen line, which guarantees exactly one side covers (or it's a push); no after-the-fact line movement can change that.
If ESPN has no line for a game, that game isn't draftable until you set one by hand under Games missing a spread in Admin.
Nothing needs to stay open for this — the site and database are fully hosted and run on their own 24/7. Re-syncing does need to be triggered, though, which .github/workflows/sync-spreads.yml does automatically:
Both call /api/cron/sync-spreads, authenticated with CRON_SECRET. This runs
on GitHub Actions rather than Vercel's own Cron Jobs because Vercel's Hobby
plan caps cron jobs at once per day — nowhere near frequent enough here.
You can still click Sync slate in Admin any time; it does the same thing manually, and is the only way to load a week that hasn't been synced yet (the automation only refreshes weeks that already exist).
With homeSpread stored as the home team's line (negative = home favored):
adjusted = homeScore + homeSpread - awayScore
adjusted > 0 → home side covers
adjusted < 0 → away side covers
adjusted = 0 → push
ADMIN_PASSWORD is a single shared league password. It gates entering picks
and every admin action; viewing the week and the standings is open to anyone
with the link. It keeps strangers out, but it does not stop the two of you
from entering each other's picks — there are no per-player logins.