BikeControl (SwiftControl)
Use Zwift Click, Zwift Play, Shimano Di2, or any Bluetooth controller with MyWhoosh, Rouvy, Zwift, and more. Free to try on iOS, Android, Windows, and macOS.
Ứng dụng của CLB chạy bộ CLR
Translation pending
Sports & fitnessTypeScript · PLpgSQLGitHub @iamcotOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Webapp (PWA) cho CLB chạy bộ CLR: đăng nhập bằng Strava, thống kê, challenge, thưởng phạt, event, quỹ. Kế hoạch và tiến độ nằm trong plans/.
Yêu cầu: Node 24 (nvm use), Docker (cho Supabase local).
npm ci
cp .env.example .env.local
npx supabase start # in ra URL và key local, điền vào .env.local
npx supabase db reset # chạy migration + seed
npm run dev # http://localhost:3000
Trang kiểm tra (chỉ có khi chạy dev): /dev/theme (bảng màu), /dev/db (đọc bảng settings).
Kiểm tra trước khi commit: npm run typecheck && npm run lint && npm test.
Sinh lại kiểu DB sau khi đổi schema: npm run db:types (ghi src/lib/types/database.generated.ts, không sửa tay). Code import Database từ @/lib/types/database, file này thu hẹp các cột text có check constraint thành union; thêm giá trị vào constraint thì sửa union ở đó.
Tự động: khi merge vào main có file mới trong supabase/migrations/, workflow Migrate production chạy supabase db push lên project production. Cần 3 secret trong GitHub (Settings → Secrets and variables → Actions): SUPABASE_ACCESS_TOKEN (tạo ở supabase.com/dashboard/account/tokens), SUPABASE_DB_PASSWORD (mật khẩu database của project production), SUPABASE_PROJECT_REF (project ref của clr). Có thể chạy lại tay ở tab Actions.
Preview (clr-preview) vẫn chạy tay:
npx supabase login
npx supabase link --project-ref <project-ref-preview>
npx supabase db push
Migration chỉ thêm file mới (supabase/migrations/000N_*.sql), không sửa file đã chạy.
Vercel: preview cho mỗi PR, production từ main. Biến môi trường khai báo theo .env.example (URL công khai là APP_URL, không có tiền tố NEXT_PUBLIC_), tách Preview và Production (Preview dùng project Supabase riêng).
STRAVA_WEBHOOK_VERIFY_TOKEN và CRON_SECRET trên Vercel (Production và Preview), thêm secret APP_URL và CRON_SECRET vào GitHub Actions để workflow Strava cron gọi /api/cron/*.npm run strava:subscribe -- create (đọc .env.local; Strava gọi GET /api/strava/webhook để xác thực). list xem subscription, delete <id> xoá. Mỗi app Strava chỉ có một subscription.img.clr.vn), tạo API token quyền Object Read & Write cho đúng bucket.R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET, R2_PUBLIC_BASE_URL trên Vercel (Production và Preview).[
{
"AllowedOrigins": ["https://<domain-app>", "http://localhost:3000"],
"AllowedMethods": ["PUT", "GET"],
"AllowedHeaders": ["Content-Type"],
"MaxAgeSeconds": 3600
}
]
Ảnh event nằm dưới events/{eventId}/; ảnh giấy chứng nhận (task 5.2) sẽ dùng prefix riêng.