LEVELS is a public workout showcase and private single-owner training tracker. The production topology is a React/Vite site on GitHub Pages, a Flask/Gunicorn API on Render, and a Turso Cloud database.
The product contract and requirements live in docs/levels_product_handoff/levels_product_handoff. The locked delivery sequence is in IMPLEMENTATION_PLAN_LOCKED.md.
- Node.js 22.12 or newer and npm 10 or newer
- Python 3.13
- uv
- GNU Make (optional wrapper; every command also has an npm equivalent)
- Docker with a running daemon (optional Compose workflow)
git clone https://github.com/BrandanBurgess/levels.git
cd levels
Copy-Item .env.example .env
npm run bootstrap
npm run devOpen http://localhost:5173. The API runs at http://localhost:8000.
Keep local secret values in .env only and never commit that file. Generate an Argon2 owner-password hash without echoing the password with uv run --project apps/api python -m levels_api.scripts.hash_password; use a separate random JWT secret of at least 32 characters.
| Goal | Cross-platform command | Make wrapper |
|---|---|---|
| Install locked dependencies | npm run bootstrap |
make bootstrap |
| Run API and web | npm run dev |
make dev |
| Lint | npm run lint |
make lint |
| Type-check | npm run typecheck |
make typecheck |
| Unit/integration tests | npm run test |
make test |
| Build frontend | npm run build |
make build |
| Seed database | npm run seed |
make seed |
| Browser tests | npm run e2e |
make e2e |
| Full local gate | npm run verify |
make verify |
make e2e runs the complete Playwright journey suite, including 375×812 mobile, iPhone 13 (390×844), and 1440×900 desktop verification. The iPhone check also audits browser errors, failed requests, 5xx responses, horizontal overflow, mobile navigation, and owner settings controls.
With Docker Desktop or another Docker daemon running:
Copy-Item .env.example .env
docker compose up --buildCompose persists the local SQLite database in a named volume. Production never uses a Render-local database file.
apps/web: React/TypeScript/Vite frontendapps/api: Flask Python packagepackages/api-client: generated OpenAPI client package (LVL-104)e2e: Playwright journeys (LVL-1004)scripts: repository automation.github/workflows: CI and deployments (LVL-003 onward)
Provider configuration and the Pages workflow contract are documented in docs/DEPLOYMENT.md. The frontend deploys only after successful main CI and requires the public VITE_API_BASE_URL repository variable; backend and database secrets never enter the frontend build.
All work follows docs/levels_product_handoff/levels_product_handoff/18_GIT_WORKFLOW.md: one ticket branch, Conventional Commits, pull request, required checks, squash merge, and branch deletion. Do not work directly on main.