Zonara Trainer
Zonara Trainer – Fitness Coach: support, privacy policy and Health & Safety terms
Translation pending
12-week periodised training programme tracker
Translation pending
Sports & fitnessGitHub @sarvarkhujaOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
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 ↗A personal life-tracking dashboard (expenses, goals, habits, pills, focus, workouts) built on Next.js + Supabase.
@supabase/ssrNote on the framework: this project tracks a Next.js variant whose conventions differ from what you may be used to — e.g. the middleware lives in
src/proxy.ts(exported as a Web Handler), notmiddleware.ts. When in doubt, read the guides innode_modules/next/dist/docs/.
package-lock.json)git clone https://github.com/sarvarkhuja/personal-jarvis.git
cd personal-jarvis
npm install
cp .env.example .env.local
Then open .env.local and fill in the values from your Supabase dashboard
(Project Settings → API):
| Variable | Where to get it | Notes |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | "Project URL" | Safe to expose. |
SUPABASE_ANON_KEY | "Project API keys" → anon / public | Shipped to the browser. Must be the anon key. |
SUPABASE_SERVICE_ROLE_KEY | "Project API keys" → service_role | Server-only. Used by src/lib/supabase/admin.ts. |
NEXT_PUBLIC_APP_URL | — | http://localhost:3000 for local dev. |
🔴 Critical: anon key vs service_role key
The two keys look almost identical but their JWT
rolediffers (anonvsservice_role).
NEXT_PUBLIC_*variables are shipped to the browser.- The
service_rolekey bypasses all Row Level Security (full DB admin).- Never put the
service_rolekey inSUPABASE_ANON_KEY, or you publish an admin key to every visitor.Verify a key's role by decoding the middle JWT segment, e.g.:
echo "<jwt>" | cut -d. -f2 | base64 -d # look for "role":"anon"
Migrations live in supabase/migrations/. Apply them to your Supabase project (e.g. via the
Supabase CLI linked to your project, or by running the SQL in the dashboard's SQL editor).
# If using a local Supabase stack:
npm run db:reset # resets local DB and replays every migration
npm run db:types # regenerates src/lib/database.types.ts from the schema
npm run dev
Open http://localhost:3000. The proxy (src/proxy.ts) redirects unauthenticated requests to
/login — create an account via /signup, then you'll land on the dashboard.
The app is a standard Next.js deploy. The only required setup is the environment variables —
a missing one takes the whole site down, because src/proxy.ts runs on nearly every route.
In Vercel → Project → Settings → Environment Variables, add the same four variables as above to the Production (and Preview) environment:
| Variable | Value |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | your project URL |
SUPABASE_ANON_KEY | the anon key (role anon — never service_role) |
SUPABASE_SERVICE_ROLE_KEY | the service*role key (no NEXT_PUBLIC* prefix) |
NEXT_PUBLIC_APP_URL | your production URL, e.g. https://your-app.vercel.app |
⚠️
NEXT_PUBLIC_*variables are inlined at build time, not read at runtime. Setting them and re-running an old build will not work — you must trigger a fresh build/deploy so the values get baked into the bundle.
Trigger a new deployment (push a commit, or "Redeploy" in the Vercel dashboard) after the variables are saved.
Other hosts (Cloudflare/OpenNext, etc.): same rule — the four variables must be present in the build environment, and you must rebuild after changing them.
/login and render (no 500).anon key (not service_role).| Command | Purpose |
|---|---|
npm run dev | Start the dev server |
npm run build | Production build |
npm run start | Serve the production build |
npm run lint | ESLint |
npm run typecheck | tsc --noEmit |
npm run test:unit | Vitest unit tests |
npm run test:e2e | Playwright e2e tests |
npm run verify | typecheck + lint + unit + e2e (run before merging) |
Error: Your project's URL and Key are required to create a Supabase client!The Supabase client (in src/proxy.ts, src/lib/supabase/server.ts, src/lib/supabase/action.ts)
received undefined for the URL/key — i.e. NEXT_PUBLIC_SUPABASE_URL and/or
SUPABASE_ANON_KEY are not set in the running environment.
Fix:
.env.local exists and is filled (step 2 above), then restart npm run dev.If local dev was previously using the service_role key as the anon key, switching to the real
anon key means RLS now applies (as it does in production). Errors that appear are real policy gaps,
not regressions — fix them in supabase/migrations/.
src/
proxy.ts # Auth middleware (exported Web Handler) — runs on most routes
app/
(auth)/ # /login, /signup
(app)/ # authenticated dashboard pages (expenses, goals, habits, pills, focus, workout, today)
api/ # route handlers (e.g. /api/export)
actions/ # server actions
lib/supabase/ # server.ts / action.ts / admin.ts client factories
supabase/migrations/ # SQL migrations (source of truth for the schema)
docs/ # plans & specs