Gym Buddy AI is a mobile-first AI workout planner and tracker built to remove decision fatigue from training.
The product goal is simple:
From "I don't know what to do today" -> to "I just open the app and follow the plan."
It is designed for:
- beginners who need confidence and clarity
- intermediate users who want progression without too much logging friction
- advanced users who want structured control and performance-focused recommendations
- Project Summary
- Problem the App Solves
- Core Features
- User Flow
- Technology Used
- Technical Working
- Database Design
- Project Structure
- Installation and Local Setup
- Supabase Setup
- Environment Variables
- Available Scripts
- Deployment
- Testing Guidance
- Project Scope
- Known Limitations
- Future Improvements
- Maintainer Notes
Gym Buddy AI combines:
- authentication and persistent user accounts
- onboarding with long-term training preferences
- AI-generated daily workouts
- workout history tracking
- day-by-day continuity tracking for missed days, off-app workouts, and rest days
- deterministic progression logic for repeated exercises
- feedback-based load guidance
- mobile-first workout cards and calendar views
The app is currently a web application optimized for mobile browsers, while still working well on desktop and iOS browsers. The codebase is also structured so it can later be packaged as an Android application without replacing the current website.
Most workout apps fail in one of two ways:
- they are too generic and do not adapt meaningfully
- they expect users to behave like disciplined spreadsheet loggers
Gym Buddy AI takes a different approach:
- it remembers the user's profile and context
- it asks about missed days before generating the next plan
- it supports both lightweight and detailed workout logging
- it makes progression visible instead of hiding it in vague coaching language
The idea is not just to generate workouts, but to reduce overthinking and make the app feel like a practical coach.
- the first page is sign up / sign in
- unauthenticated users are redirected to
/auth - authenticated users are routed to onboarding or dashboard based on profile state
- route-level loading states help the app feel responsive on mobile
Each user has one main training profile containing:
- full name
- age
- fitness goal
- experience level
- training days per week
- session length
- preferred training location
- available equipment
- limitations
- long-term special requests
This profile becomes the foundation for workout generation.
Workout cards change based on the user's experience level:
- beginner: simple cues, lower information density, easier alternatives
- intermediate: progression support, previous performance, direct next-step guidance
- advanced: tighter performance control, tempo, intensity targets, and structured logging
The app intentionally scales information complexity, not just workout difficulty.
The app generates daily workout recommendations using:
- the saved profile
- recent workout history
- older session summaries
- day-level activity logs
- today's optional special request
Recommendations are stored so the user can return to them later the same day.
Progression decisions are not left entirely to the language model.
For repeated exercises, the backend applies consistent rules so the user gets a clear next-step action such as:
- increase load
- reduce load
- maintain load
- start at a baseline range
This keeps progression consistent across exercises and across sessions.
Each exercise card supports lightweight or detailed feedback:
- done only
- difficulty feedback
- logged weight
- logged reps
- logged sets
- logged RPE
- notes
This stored feedback is later used to inform future workout suggestions.
The app tracks continuity in two ways:
- completed in-app sessions
- day-level logs for off-app workouts, planned rest days, and missed days
If the recent timeline has gaps, the app asks the user to classify those dates before generating the next workout. This helps the system avoid assuming perfect training consistency.
Instead of one cluttered monthly grid, the calendar page is split into:
OverviewWeeksLog
This keeps it more usable on smaller screens.
The current user journey works like this:
- User opens the app.
- If not authenticated, the user lands on
/auth. - After sign in, the app checks whether a profile exists.
- If no profile exists, the user completes onboarding on
/onboarding. - The user lands on
/dashboard. - The dashboard loads recent history, calendar continuity data, and today's recommendation if one exists.
- If recent dates are unresolved, the app prompts the user to classify them.
- The user generates a workout or opens the saved one.
- The user performs the workout and submits exercise-level feedback.
- The completed workout is stored in Supabase and later used for progression and planning.
Next.js 15React 19TypeScriptTailwind CSS
Supabase AuthSupabase PostgresSupabase Row Level Security (RLS)
OpenAI Responses APIZod
ESLintPostCSSAutoprefixerTypeScript compiler
This section explains how the system works internally.
Authentication is handled through Supabase Auth.
The app checks the current session server-side and routes users based on profile state:
- no session ->
/auth - session without profile ->
/onboarding - session with profile ->
/dashboard
The onboarding flow stores a single profile per user.
That profile includes the user's:
- training goals
- experience level
- routine preferences
- equipment context
- limitations
- special requests
The app uses an upsert-style workflow, so the same account edits its existing profile instead of creating duplicates.
When the user asks for a workout, the backend gathers:
- the current user profile
- recent detailed workout sessions
- older summarized sessions
- recent day-level activity logs
- today's special request, if any
That context is passed to the OpenAI Responses API using a structured output schema.
After the AI response returns:
- the response is validated
- the structure is normalized
- progression logic is applied
- the final recommendation is stored in the database
One of the most important design choices in this project is that repeated exercise progression is enforced in backend logic instead of being left entirely to the model.
Examples of the current rule style:
too_easy-> increase load one clear steptoo_hard-> reduce load one clear stepjust_rightand top rep target achieved -> increase load- missing load data -> use fallback behavior
- no history -> show a baseline starting instruction
This gives the user direct actions instead of vague suggestions like "consider increasing."
Exercise cards collect post-set or post-session information such as:
- completion status
- difficulty feedback
- weight used
- reps completed
- sets completed
- RPE
- notes
Those values are saved with completed exercises and later used to personalize future recommendations.
The app does not only look at completed GymBuddy sessions. It also stores day-level records for:
- outside workouts
- planned rest days
- missed days
This allows the AI to reason about gaps in training rhythm and adjust future sessions accordingly.
Generated workouts are stored per date so the app does not have to regenerate the same day's session every time the dashboard loads.
This improves user experience and keeps the app more stable during a given day.
The UI is optimized around smaller screens by using:
- card-based layouts
- compact hero sections
- touch-friendly controls
- route loading states
- smaller information chunks
- calendar views divided into manageable windows
The main schema lives in supabase/schema.sql.
Stores the main training identity for each authenticated user.
Stores limitations, injuries, dislikes, or constraints linked to a profile.
Stores long-term planning preferences that should stay in memory.
Stores completed workout sessions.
Stores each exercise inside a completed workout, along with feedback and load-related data.
Stores day-level continuity records such as:
- worked out outside the app
- planned rest day
- missed day
Stores the AI-generated recommendation for a specific user and date.
The project uses Supabase Row Level Security across user-owned tables.
RLS policies ensure a user can only read and write their own:
- profile
- limitations
- special requests
- workout sessions
- workout exercises
- workout day logs
- AI workout recommendations
Key areas of the codebase:
-
app/auth/page.tsx Authentication screen.
-
app/onboarding/page.tsx Onboarding route.
-
app/dashboard/page.tsx Main home screen and workout entry point.
-
app/calendar/page.tsx Dedicated calendar and activity history screen.
-
components/workout-card.tsx Exercise card UI, progression display, and feedback controls.
-
components/generate-workout-button.tsx Workout generation UI and unresolved-day prompt flow.
-
lib/actions/workouts.ts Server actions for generating workouts, saving logs, and finishing sessions.
-
lib/data/workouts.ts Reads workout and calendar data from Supabase.
-
lib/ai/generate-workout.ts Calls OpenAI and applies post-processing.
-
lib/ai/workout-prompt.ts Prompt structure and response schema.
-
lib/workout-personalization.ts Deterministic progression and personalization logic.
-
supabase/schema.sql Full database schema.
-
supabase/migrations/20260429_add_exercise_feedback_fields.sql Adds exercise feedback and logging fields.
-
supabase/migrations/20260429_add_workout_day_logs.sql Adds day-level workout continuity tracking.
You need:
Node.jsnpm- a Supabase project
- an OpenAI API key
git clone <your-repository-url>
cd GymBuddynpm installCopy .env.example into .env.local and fill in the values.
Run the SQL in supabase/schema.sql in your Supabase SQL Editor.
If your project already had an older schema, also apply:
- supabase/migrations/20260429_add_exercise_feedback_fields.sql
- supabase/migrations/20260429_add_workout_day_logs.sql
npm run devThen open:
- Create a Supabase project.
- Enable email authentication or your preferred auth provider.
- Run the SQL schema in Supabase SQL Editor.
- Confirm RLS is enabled for the user-owned tables.
- Copy the project keys into
.env.local.
When Supabase warns that a new table will not have RLS, that warning can still be expected if the same SQL script also enables RLS later in the file.
For this project, the schema explicitly enables RLS and creates policies for the main user-owned tables. If Supabase shows a choice while executing the SQL, use the option that keeps RLS enabled.
The project currently expects the following values in .env.local:
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
OPENAI_API_KEY=-
NEXT_PUBLIC_SUPABASE_URLSupabase project URL used by the client. -
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYPublic key used for client-side Supabase access. -
NEXT_PUBLIC_SUPABASE_ANON_KEYAnonymous client key used by the app. -
SUPABASE_SERVICE_ROLE_KEYServer-side privileged key for backend operations that require elevated access. -
OPENAI_API_KEYAPI key used for AI workout generation.
From package.json:
npm run dev
npm run build
npm run start
npm run lint
npm run typecheck-
npm run devStarts the local development server. -
npm run buildBuilds the app for production. -
npm run startStarts the production build. -
npm run lintRuns linting checks. -
npm run typecheckRuns TypeScript type checking without emitting files.
The simplest low-cost deployment setup is:
- frontend and Next.js hosting:
Vercel - backend, auth, and database:
Supabase
- Push the code to GitHub.
- Import the repository into Vercel.
- Add all environment variables in Vercel.
- Point the app to your production Supabase project.
- Run the schema and migrations in that Supabase project.
- Deploy.
This is currently the easiest path for sharing the app with test users.
For a realistic test pass:
- Open
/authand create an account. - Complete onboarding.
- Generate today's workout.
- Use the quick-request controls if needed.
- Submit exercise feedback on a few cards.
- Mark the workout complete.
- Leave some dates unresolved and return later.
- Verify the app asks whether those dates were off-app workouts, rest days, or missed days.
- Generate the next workout and verify progression decisions are explicit.
- Open
/calendarand review continuity across views.
Because the profile is tied to the authenticated user_id, one account updates its own profile instead of creating duplicates.
To test multiple user scenarios:
- use multiple sign-in accounts
- use email aliases
- reset profile rows in Supabase for a clean onboarding run
The project currently covers:
- authentication
- onboarding and long-term profile memory
- AI-generated daily workouts
- workout session persistence
- per-exercise feedback and logging
- progression logic for repeated exercises
- missed-day and outside-workout tracking
- dedicated calendar page
- mobile-first web experience
The app is moving toward:
- adaptive coaching rather than static workouts
- lower-friction logging for casual users
- stronger progression support for serious users
- a web-first product that can later be packaged for Android
- workout generation currently depends on an external OpenAI API call
- recommendation quality improves when workout feedback is actually logged
- the system is focused on recent-history adaptation, not full long-term periodization
- Android packaging is a future step and is not part of the current repository
- monetization is not implemented yet
- progression logic is stronger now, but it still needs dedicated automated tests
Likely future work includes:
- automated tests for progression rules and workout flows
- stronger caching for faster dashboard loads
- richer progress analytics and charts
- Android packaging using a native shell strategy
- notification and reminder support
- offline-friendly workout execution
- subscription or revenue model
- trainer or coach sharing workflows
Update this README whenever any of the following changes:
- environment variables
- Supabase schema or migrations
- workout generation flow
- progression rules
- route structure
- deployment setup
- authentication flow
- mobile strategy
If the app behavior changes materially and the README does not, new collaborators will get the wrong mental model of the product.