Eura Learn is live on the App Store (v1.0, since July 22, 2026) — an iPad-first math tutor where students handwrite their work on a freehand canvas and Orion, the in-app AI tutor, checks it step by step. Shipped as a Capacitor-wrapped iOS app.
- Production: backend on AWS App Runner, auth/data/storage on Supabase. Source of
truth for architecture and current state:
HANDOFF.md. - iOS build & device testing:
testingapp.md. - Frontend tests:
cd frontend && npm test(Vitest — seefrontend/TESTING.md). - App Store history:
appstore/(checklist, privacy, listing, review replies).
The rest of this README is the local development setup.
This repo has two services that you run side by side:
backend/— FastAPI app (Python), served by uvicorn on port8000.frontend/— Vite + React + TypeScript app, served on port5173.
The frontend calls the backend at http://localhost:8000 by default, so both need to be running.
Install these once:
- Python 3.11+ —
python --version - Node.js 20+ and npm 10+ —
node --version/npm --version - Git —
git --version - An OpenAI API key (the backend will refuse to start without one).
- A Supabase project. The frontend uses it for auth + data; the backend uses it to validate access tokens. Both will refuse to start without it configured.
git clone <repo-url> EuraAI
cd EuraAIAll backend commands run from the backend/ directory.
The existing scripts expect the venv to live at backend/venv/.
PowerShell (Windows):
cd backend
python -m venv venv
.\venv\Scripts\Activate.ps1If PowerShell blocks the activation script, run this once in an admin shell:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.
Bash (macOS / Linux / Git Bash on Windows):
cd backend
python -m venv venv
source venv/Scripts/activate # Windows Git Bash
# source venv/bin/activate # macOS / LinuxYou should see (venv) in your prompt.
pip install --upgrade pip
pip install -r requirements.txtCreate backend/.env (or a .env at the repo root — both are loaded) with:
OPENAI_API_KEY=sk-...your-key-here...
SUPABASE_JWT_SECRET=...from Supabase dashboard, see below...
# Optional overrides (defaults shown):
# OPENAI_MODEL=gpt-4o-2024-08-06
# MAX_IMAGE_WIDTH=1600
# MAX_UPLOAD_BYTES=10485760
# CORS_ORIGINS=http://localhost:5173,capacitor://localhost,https://localhostSUPABASE_JWT_SECRET comes from your Supabase dashboard: Project Settings → API → JWT Secret. The backend uses it to verify the access token on every protected request (HS256). Without it, app/config.py fails fast at startup.
With the venv activated, from backend/:
uvicorn app.main:app --reload --port 8000Quick health check (in another shell):
curl http://localhost:8000/api/health
# => {"ok":true}Leave this terminal running.
Open a new terminal. All frontend commands run from the frontend/ directory.
cd frontend
npm installcp .env.local.example .env.localThen fill in frontend/.env.local:
VITE_SUPABASE_URL=https://<your-project>.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...
# VITE_API_BASE_URL=http://localhost:8000 # only if your backend lives elsewhereGet the URL and publishable API key (sb_publishable_…, not the legacy anon JWT) from the Supabase dashboard: Project Settings → API. The dev server refuses to start without these.
npm run devVite prints a local URL — usually http://localhost:5173. Open it in your browser.
If port 5173 is taken, Vite falls back to 5174, 5175, etc. The backend's CORS config already allows these.
Two terminals, both from the repo root:
Terminal 1 — backend:
cd backend
.\venv\Scripts\Activate.ps1 # PowerShell
# source venv/Scripts/activate # Bash
uvicorn app.main:app --reload --port 8000Terminal 2 — frontend:
cd frontend
npm run devThen open http://localhost:5173.
RuntimeError: Required env var OPENAI_API_KEY is not set— createbackend/.env(see step 3c) and restart uvicorn.RuntimeError: Required env var SUPABASE_JWT_SECRET is not set— addSUPABASE_JWT_SECRETtobackend/.envfrom the Supabase dashboard (Settings → API → JWT Secret).- API requests return 401
Missing Bearer token— the user isn't signed in, or the Supabase session expired. Sign in via the auth screen; the frontend attaches the access token automatically. ModuleNotFoundErroron backend start — the venv isn't activated, orpip install -r requirements.txtdidn't finish. Re-activate and re-install.Activate.ps1 cannot be loadedin PowerShell — runSet-ExecutionPolicy -Scope CurrentUser RemoteSignedonce.- Frontend loads but API calls fail (CORS or
ERR_CONNECTION_REFUSED) — confirm the backend is running on:8000and thatVITE_API_BASE_URL(if set) points at it. port 8000 already in use— either kill the other process or run uvicorn on a different port and updateVITE_API_BASE_URLaccordingly.
EuraAI/
├── backend/
│ ├── app/ # FastAPI app (routes, services, llm, storage)
│ ├── requirements.txt
│ ├── Dockerfile
│ └── venv/ # local virtualenv (gitignored)
└── frontend/
├── src/ # React + TypeScript source
├── public/
├── package.json
└── vite.config.ts