English ยท Espaรฑol
Open the app at the gym, pick your training split and goal, and get an instant, personalized workout โ with suggested weights, rest timers, set-by-set tracking and automatic progression.
๐ Live demo: burnout.minuesa.es ยท No sign-up required, works on mobile.
- Input โ You select a split (Upper Body, Lower Body, Full Body), a goal (Fat Loss, Hypertrophy, Stay Active) and your biophysical profile (weight, height, age, sex, experience).
- Generation โ The API builds a structured routine: warm-up โ 5โ6 exercise blocks โ cooldown, drawn from a library of 56 classified exercises with video demos.
- Smart defaults โ Starting weights are calculated per exercise from your body weight, sex and experience using standard strength ratios, rounded to 2.5 kg plates.
- Training โ You log real weight, reps and RPE per set. Completing a set fires a rest timer tuned to your goal (60/90/120 s). Don't like an exercise or the machine is busy? Re-roll swaps it for another one targeting the same muscle group, without touching the rest of the routine.
- Progression โ Workout history is persisted and fed back to the API: the next routine applies double progression (more reps โ more weight) per exercise, and the UI shows a progression direction badge on each card.
Also: workout summary (total volume, completed sets, average RPE), training streak, and offline mode โ the active routine survives refreshes and connection loss via LocalStorage, with emergency client-side generation if the server is unreachable.
The parts I'd want you to look at as a reviewer:
- Layered backend architecture โ
Routes โ Controllers โ Services โ Repositories, with dependency injection at composition time (routineRoutes.ts). Business logic lives in services and is framework-agnostic. - Repository pattern for a painless DB migration โ exercises are currently served from static JSON behind an
IExerciseRepositoryinterface. Swapping in MongoDB (planned Phase 3) means writing one new repository class; the service layer doesn't change. - Input validation with Zod โ every endpoint validates its payload against a schema before it reaches business logic (
userProfile.schema.ts). - 68 automated tests (42 backend + 26 frontend, Vitest) covering the routine generation algorithm, the progression engine and the history logic. Core logic is written as pure functions (
frontend/src/lib/history.ts) precisely so it can be tested without mocking React or Express. - Custom hooks for separation of concerns โ
useWorkout,useStreak,useRestTimer,useHistorykeepApp.tsxdeclarative and each concern independently testable. - Shared domain types โ the
WorkoutRoutine/RoutineSetcontracts are typed end to end in TypeScript on both sides of the API.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/routines/generate |
Generate a routine from split + goal + user profile (+ workout history for progression) |
POST |
/api/routines/reroll |
Replace one exercise with another from the same muscle group, excluding those already in the routine |
| Layer | Tech |
|---|---|
| Frontend | React 19, TypeScript, Vite, custom hooks, CSS (mobile-first, dark mode) |
| Backend | Node.js, Express, TypeScript, Zod |
| Testing | Vitest (backend + frontend) |
| Data | Static JSON behind a repository interface (MongoDB-ready) |
| Deploy | Vercel (frontend, custom domain) + Render (Express API) |
git clone https://github.com/Mariomin23/BurnOut.git
cd BurnOut
npm run install:all # installs backend + frontend deps
npm run dev # starts API and Vite dev server togetherRun the tests:
npm test --prefix backend # 42 tests
npm test --prefix frontend # 26 tests- โ Phase 1 โ Routine generation, re-roll, rest timer, suggested weights, offline mode, streaks
- โ Phase 2A โ Workout history + automatic double-progression algorithm
- ๐ Phase 2B โ Progress charts per exercise (weight vs. weeks)
- ๐ฎ Phase 3 โ MongoDB + auth (JWT) for per-user history, full PWA
Built by Mario Minuesa (@Mariomin23) as a full-stack portfolio project: product design, architecture, implementation, testing and deployment, end to end.

