Express + TypeScript API for the FreBob MVP.
cd server
cp .env.example .env
npm install
npm run devHealth: GET http://localhost:4000/v1/health
Swagger UI: http://localhost:4000/docs
OpenAPI JSON: http://localhost:4000/v1/openapi.json
Env reload: tsx watch does not reload .env. After changing GEMINI_API_KEY (or any env), stop the process and run npm run dev again. Use the same GEMINI_API_KEY value as Render (frebob-backend → Environment). Health returns a redacted geminiKeyHint (prefix + length) so you can confirm local matches production without printing the secret.
Without Supabase, send X-Demo-Mode: 1 and use business id
00000000-0000-4000-8000-000000000001. In Swagger, click Authorize, set demoMode to 1.
npm ci
npm run build # tsc → dist/
npm start # node dist/index.js- Build command:
npm ci && npm run build - Start command:
npm start - Root directory:
server - Node: 20+
- Health check path:
/v1/health - Listens on
0.0.0.0:$PORT(Render injectsPORT)
You can also deploy from render.yaml (Blueprint) with rootDir server.
| Variable | Required | Notes |
|---|---|---|
PORT |
auto | Set by Render |
HOST |
no | Defaults to 0.0.0.0 |
CORS_ORIGINS |
no | * or comma-separated origins |
SUPABASE_URL |
no | Enables Postgres persistence |
SUPABASE_SERVICE_ROLE_KEY |
no | With URL |
GEMINI_API_KEY |
no | Live extract + grounded chat; mock/rules fallback |
YARNGPT_API_KEY |
no | TTS via YarnGPT; Pidgin stays text-only |
See the full runbook: docs/SUPABASE_SETUP.md.
- Create a project.
- Run migrations in order:
001→002→003→004_auth_onboarding_rls.sql. - Set
SUPABASE_URLandSUPABASE_SERVICE_ROLE_KEYon the server. - Set
EXPO_PUBLIC_SUPABASE_URLandEXPO_PUBLIC_SUPABASE_ANON_KEYon mobile.
Without server Supabase env vars the API boots in memory mode (demo seed).
- Gemini (
GEMINI_API_KEY): multimodal extract + business-grounded chat - YarnGPT (
YARNGPT_API_KEY):POST /v1/tts— English, Yoruba, Hausa, Igbo. Pidgin voice is not claimed (returnssupported: false).
npm run dev
# other terminal
npm run smokeSet in mobile/.env:
EXPO_PUBLIC_API_URL=http://localhost:4000/v1or your Render URL ending in /v1. Restart Expo after changing. The app sends X-Demo-Mode: 1 in memory mode.
- Memory / Explore Demo: header
X-Demo-Mode: 1 - Supabase mode:
Authorization: Bearer <access_token>+ business membership - Setup:
docs/SUPABASE_SETUP.md