尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
GitHub Desktop tutorial repository
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Fortifie ton corps. Grandis dans la foi.
A production Progressive Web App that unites fitness, nutrition, and faith into one daily rhythm — guided training, Scripture, prayer, and Barnabas, an AI faith & fitness coach. Bilingual (English / French, with a warm tutoiement voice in French).
It runs on a real backend — Supabase Auth + Postgres (with row-level security), Stripe subscriptions, and the Anthropic API for Barnabas — and still boots with zero configuration: with no environment variables it falls back to a typed mock-data "demo mode" so you can run and explore every screen locally without any keys.
/api/coach, real Anthropic responses when a key is
set and a warm in-voice offline fallback otherwise. Server-built user context,
per-user conversation memory, a persistent daily message limit, and a crisis
safety protocol (self-harm / eating disorder / medical → stops coaching and
points to help; Canada 988 / 911)./join/<code>) with a
referral counter, and Web Share story images./api/account/export) and delete your account (type SUPPRIMER
to confirm) — the server action removes the Auth user and all data (ON DELETE
CASCADE), best-effort deletes the Stripe customer, signs out and redirects home.is_premium,
billing portal, premium gating. APP_FREE_MODE runs a free-beta where everyone
is premium and /pricing shows a free banner.is_admin-gated console (KPIs, users, content, payments, logs)./api/csp-report); see "Security" below.@theme tokens)@supabase/ssr) — Auth + Postgres + RLSUI language is chosen by the ka_locale cookie (fr default) and served by
getLocale() / getDictionary(). src/i18n/dictionaries/en.ts is the source of
truth for keys; fr.ts must expose exactly the same keys. Two guard tests keep
it honest: key parity + "no French value identical to English" (proper-noun
allowlist), and "no hardcoded metadata.title in a page".
npm install
cp .env.example .env.local # optional — the app runs with no keys (demo mode)
npm run dev # http://localhost:3000
Scripts: npm run dev · npm run build · npm run start · npm run lint ·
npm test · npm run e2e
npm test): pure helpers (XP/level math, nutrition targets,
week plan & rest-day streaks, quests, coach safety, cohort dates, reading-plan
passages, i18n guards, …).npm run e2e): marketing, auth, dashboard, the Barnabas
coach, a protected-route → /login redirect, the /pricing free banner, the
EN/FR toggle, and the 7-day plan. Runs two servers from one build (a demo
server and a "Supabase-configured-but-unreachable" server for the auth guard);
specs set an explicit ka_locale=en cookie.With no Supabase env vars the app runs on mock data and auth is a demo redirect, so nothing is required locally. To go live:
# 1. Create a project at supabase.com, then set in .env.local:
# NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY
# 2. Apply the schema, RLS, and seed data:
supabase db reset # runs supabase/migrations/* then supabase/seed.sql
# 3. In Supabase Auth settings add the redirect URL <site>/auth/callback
# and enable the Google provider if desired.
Migrations live in supabase/migrations/ (initial schema + RLS through the
latest additive migrations: coach messages, training profile, Bible
bookmarks/highlights, cohorts, local recipes). All user-data tables use
owner-only RLS and FK ON DELETE CASCADE, which is what makes account deletion
clean. Regenerate types after schema changes:
supabase gen types typescript --local > src/types/database.ts.
Security headers are set in next.config.ts for every route:
X-Content-Type-Options, Referrer-Policy, X-Frame-Options: DENY,
Permissions-Policy, HSTS, and a Content-Security-Policy allowlisting the
origins the app uses (Supabase, Stripe, PostHog, Sentry, bible.helloao.org,
exercise images). Violations are reported to /api/csp-report via the
report-to / report-uri directives.
The CSP ships in Report-Only by default and switches to enforcing when
CSP_ENFORCE=1 (reversible by unsetting it). In production this is set to 1.
src/
├─ app/
│ ├─ (auth)/ # login, signup, password reset
│ ├─ (app)/ # authenticated shell: dashboard, fitness, nutrition,
│ │ # spiritual (+ bible), coach, community, challenges,
│ │ # habits, journal, focus, profile
│ ├─ (admin)/admin/ # is_admin-gated console
│ ├─ api/ # coach, stripe/*, account/export, csp-report,
│ │ # verse-image, share-image
│ ├─ join/[code]/ # cohort invite landing
│ ├─ blog/ pricing/ privacy/ terms/ … # marketing + legal
│ └─ layout.tsx globals.css
├─ components/ # ui primitives + feature components
├─ data/ # typed seed/mock data (demo mode)
├─ i18n/ # dictionaries (en/fr) + helpers + guard tests
├─ lib/ # pure helpers, queries (data-access), supabase clients
└─ types/ # domain model + generated database types
Pure logic lives in lib/* (unit-tested, no server imports); lib/queries/*
is the typed data-access layer with a mock fallback when Supabase is
unconfigured.
Deployed on Vercel (see DEPLOYMENT.md and vercel.json). CI runs on GitHub
Actions: Lint · Typecheck · Test · Build and E2E (Playwright).
Discipline of body, steadiness of soul.