smooth-app
전 세계 식품의 성분·영양·정보를 자유롭게 협업하고 공개하는 데이터베이스
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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