尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證AI-powered fitness tracking app — Next.js, TypeScript, Supabase, Prisma, Gemini AI
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A workout and nutrition tracker for Indian gym-goers, with offline set logging, Indian food data, and AI-assisted logging.
Live app → · Django service repo →
Built with Next.js 16, Django and Postgres. 410 unit tests pass, and offline set retries are deduplicated in the database.
Trying it? Use Continue with Google, the fastest way in. It's installable on Android from the landing page.
Live workout logging
Indian food logging
Weight trend and strength progress
Daily targets
Screenshots show fictional demo data from the development environment.檢視完整 README ↗A workout and nutrition tracker for Indian gym-goers, with offline set logging, Indian food data, and AI-assisted logging.
Live app → · Django service repo →
Built with Next.js 16, Django and Postgres. 410 unit tests pass, and offline set retries are deduplicated in the database.
Trying it? Use Continue with Google, the fastest way in. It's installable on Android from the landing page.
Screenshots show fictional demo data from the development environment.
Two services and one Postgres database. Application data always goes through same-origin Next.js routes.
flowchart LR
subgraph Device["User's device"]
UI["React app (installable PWA)"]
IDB[("IndexedDB<br/>offline set queue")]
end
subgraph Vercel["Vercel · syd1"]
P["proxy.ts<br/>JWT check · cookie refresh"]
API["Route handlers<br/>auth → Zod → service"]
SVC["Services · Repositories<br/>(Prisma)"]
end
subgraph Supabase["Supabase · Sydney"]
AUTH["Auth"]
PG[("Postgres")]
end
DJ["Django + DRF<br/>(Render)"]
LLM["LLM chain<br/>Gemini → Groq → OpenRouter"]
RL["Upstash Redis<br/>rate limits"]
UI -->|"same-origin HTTPS<br/>httpOnly cookie"| P --> API --> SVC -->|"SQL via pooler"| PG
UI --- IDB
IDB -.->|"sync when online"| P
API -->|"sign-in"| AUTH
API -->|"user's JWT forwarded"| DJ -->|"its own tables"| PG
API --> LLM
API --> RL
httpOnly cookie (cookie-options.ts).Gym Wi-Fi drops, taps get doubled, and two tabs can be open at once. Logging a set goes through these steps:
SELECT … FOR UPDATE checks ownership, existence and that the workout is still open. A replayed request id returns the row that's already saved, and the set number is assigned as max + 1 under the lock. Unique constraints back up both rules (workout.repository.ts).There's a regression test for the hardest case: a set that commits just as the workout is finished (add-set-replay.test.ts).
Saving one set took ~2.9 s in production. The X-Vercel-Id header (bom1::iad1) showed the request entering in Mumbai but running in Washington DC, while the database is in Sydney. The save path makes several sequential database round trips, and each one paid that distance.
Functions are now pinned to syd1, next to the database (vercel.json). The investigation and latency estimates are in DEPLOY_REGION.md.
The Django service owns share_links in the same Postgres, and a stray Prisma command could otherwise treat those tables as drift and drop them. Instead of relying on discipline, permissions are split across database roles (db/roles):
| Role | Can | Cannot |
|---|---|---|
fitlog_app (runtime) | read and write app tables | change the schema · read Django's tables · delete users |
fitlog_migrate (migrations) | change Prisma's own tables | drop the schema · directly alter Django-owned tables |
fitlog_deleter | run one account-deletion function | access application tables directly |
postgres as the explicit break-glass exception.public have RLS on with no policies, so the anon and authenticated roles can't read any rows. An event trigger also tries to switch RLS on for every new public table (000_rls_auto_enable.sql).| Layer | Tools |
|---|---|
| App | Next.js 16 (App Router) · React 19 · TypeScript (strict) · Tailwind CSS 4 |
| Data | Supabase Postgres + Auth · Prisma 7 with @prisma/adapter-pg · TanStack Query · Zustand |
| Offline / PWA | IndexedDB (idb) · Web Locks · BroadcastChannel · service worker · web app manifest |
| Second service | Django 5 · Django REST Framework · fitlog-django |
| Platform | Vercel (syd1) · Render · Upstash Redis · Sentry · Cloudflare Turnstile |
| Quality | Vitest · ESLint · GitHub Actions |
main and on pull requests targeting main (ci.yml): type-check → lint → tests → Prisma validation → a migration drift check, which replays every migration into a throwaway Postgres 16 and diffs it against the schema → production build.npm test # unit tests
# integration tests: apply the migrations to a disposable Postgres first, then
TEST_DATABASE_URL=postgresql://… npm test
You need: Node.js 22 and a Supabase project (Postgres + Auth).
git clone https://github.com/VaibhavGarg2003/FitLog.git
cd FitLog
npm install
cp .env.local.example .env.local # then fill in the values below
npx prisma generate # generate the Prisma client
npx prisma migrate deploy # create the schema
npm run db:seed # foods + exercises catalog
npm run dev # http://localhost:3000
The Settings "sign-in methods" card needs the private.user_has_password() helper, and account deletion needs private.delete_user_account(). Both live in the SQL under db/roles, which also sets up the production roles. Apply those scripts in the order that README describes, relative to the migrations.
| Variable | Needed for |
|---|---|
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY | Auth |
DATABASE_URL (pooler) · DIRECT_URL (direct, for migrations) | Database |
GEMINI_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEY | AI parsing and reports (at least one provider) |
UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN | Rate limits (disabled if unset) |
DJANGO_URL | Share links (the Django service) |
ACCOUNT_DELETION_DATABASE_URL | Optional: account deletion (needs the dedicated role and function) |
SENTRY_DSN, NEXT_PUBLIC_SENTRY_DSN | Optional: server and browser error reporting |
SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT | Optional: source-map uploads |
NEXT_PUBLIC_TURNSTILE_SITE_KEY | Optional: CAPTCHA on sign-in |
CRON_SECRET | Optional: protects /api/health |
app/ pages (App Router) and API route handlers (app/api)
lib/engine/ calorie and macro engine: pure functions
lib/services/ business rules
lib/repositories/ business-data access (Prisma, transactions, locks)
lib/offline/ IndexedDB outbox, drainer, cross-tab lock
lib/ai/ LLM clients, fallback chain, exercise matching
prisma/ schema, migrations, seed data
db/roles/ least-privilege roles and database guards
proxy.ts session refresh and route protection for matched requests
Built by Vaibhav Garg · GitHub