| MargaretP | 2 | Data Layer | Database | In the MySQL database there must be tables for user_id, exercise lists (both custom and pre-existing), each individual's workouts and the exercises saved within them.
PROMPT:
Set up a new project with HTML/CSS/PHP (as little javascript as possible), a MySQL backend using this schema: paste workout_app_schema-2.sql. Set up the DB connection and run the migrations. Add basic email/password auth (signup, login, logged-in session handling) using the users table. Don't build any other features yet — I want to verify auth works before continuing.
| Completed |
| MargaretP | 3 | Data Layer | Build the exercise library | Prompt: Using the existing schema and auth, build the exercise library: a page listing exercises from the exercises table with search and filter by exercise_type and primary_muscle. Add a form for users to create a custom exercise (sets is_custom=true and created_by to the logged-in user). Show a visual badge distinguishing custom vs. pre-built exercises in the list.
Pull the pre-existing exercise list from Github
https://raw.githubusercontent.com/yuhonas/free-exercise-db/main/dist/exercises.json
https://github.com/yuhonas/free-exercise-db/blob/main/README.md
| Completed |
| MargaretP | 4 | UI | User Interface | The home page should have the MVP Workout logo in the center top, underneath it should say "Hi, *NAME*. You've done *NUMBER* workouts this week". Then the user will have three buttons in a vertical line: "Workout", "Create New Workout", and "View Profile".
| Not Started |
| MargaretP | 5 | Basic Function | Workout Plan Builder | Sub-step 1 Prompt: Build the workout plan creation flow: users can create a plan with a name and a description.
Sub-step 2 Prompt: Search/add exercises from the library into it via plan_exercises, set target sets/reps/weight per exercise, and reorder exercises via drag-and-drop.
Sub-step 3 Prompt: Include edit and delete for existing plans. Build ability for people to share workouts with friends.
| Completed |
| MargaretP | 6 | Basic Function | Create Session Logging | Prompt: Build the "start workout" flow: user picks a plan, a new row is created in workout_sessions with status='in_progress', and they can log actual sets/reps/weight per exercise into session_exercise_logs, pre-filled from the plan's targets. Users should be able to enter heart rate, steps, and calories. Each session log should include date and time elapsed. On finish, set status='completed' and ended_at. Also let users start an ad-hoc workout with no plan. Handle the case where the app is closed mid-workout — the in-progress session should still be resumable.
| Not Started |
| MargaretP | 7 | User | Create seed data for exercise list | Create a seed script that inserts ~10 common exercises into the exercises table (is_custom=false, created_by=NULL), covering strength, cardio, and mobility types across major muscle groups. Include realistic equipment values.
| Not Started |
| MargaretP | 8 | User | Build exercise library | Build the exercise library page with a search-first layout: a prominent search bar at the top (searches exercise name), with filter chips below it for exercise_type (strength/cardio/mobility) and primary_muscle (chest, back, legs, etc.) that users can tap to narrow results without needing to know the exact exercise name. Filters should be multi-select and combinable with the search text. Show results as a list/grid with name, type, and equipment. Custom exercises (is_custom=true) get a small "Custom" badge. Make it mobile-friendly with large tap targets for the filter chips. Type filters and muscle filters can be AND'd together.
*Claude says to make styling decisions before this step
| Not Started |
| MargaretP | 9 | User | Custom exercise form | Add a "Create Custom Exercise" form accessible from the exercise library page. Required fields: name, exercise_type, measurement_type. Optional fields: muscle_group_id, equipment. On submit, insert into exercises with is_custom=true and created_by set to the logged-in user. New custom exercise should appear in the search list immediately, tagged with the "Custom" badge.
| Not Started |
| MargaretP | 10 | User | Pull pre-existing exercise list | Fetch the exercise data from https://raw.githubusercontent.com/yuhonas/free-exercise-db/main/dist/exercises.json and write a seed script to import it into the exercises table. Map fields as follows:
name → name
category → exercise_type, using this mapping: strength/powerlifting/strongman/olympic weightlifting/plyometrics → 'strength', cardio → 'cardio', stretching → 'mobility'
primaryMuscles[0] (first entry only) → primary_muscle, normalized to this fixed list: [chest, back, shoulders, biceps, triceps, forearms, abs, quads, hamstrings, glutes, calves, full_body] — map the source's more granular muscle names (e.g. "lats", "middle back", "lower back" → "back"; "abdominals" → "abs"; "quadriceps" → "quads") into this list
equipment → equipment (leave null if null in source)
- Join the
instructions array into a single description field, one sentence per line
- Set
measurement_type: 'reps_weight' for strength/powerlifting/strongman/olympic weightlifting, 'time' for stretching, 'distance' for cardio
- Set
is_custom = false and created_by = NULL for all seeded exercises
- Skip the
images, force, and level fields — not needed for v1
- Run the import and report how many exercises were inserted, and flag any rows that failed the category or muscle mapping so I can review them
| Not Started |
| MargaretP | 13 | Basic Function | Nitpicking workout log |
- When you hit “pick a plan to follow” the next page should be only pre-existing plans, no option to create a new workout
- When you are logging a workout actively there should be checkmark buttons to indicate that you have finished each set
- When you choose a plan take out the options to save and delete
- Add option to edit time in the finish workout page
•⁃Calculate calories based on each exercise through the app?
| Started |
| MargaretP | 14 | Basic Function | Create "view profile" page | Step 1: Centered on top should keep the "Hi, *Name*, you've done x workouts this week" format. There should be a vertical line of buttons: view all workout plans, view all workout logs, view custom exercises, view goals, view friends.
Step 2: When the user hits view all workout plans they should be taken to a new page where all of their workout plans are displayed, and they can click on any plan to view it in full.
Step 3: When the user hits view all workout logs they should be taken to a new page with all of their past workout logs. It should be arranged in chronological order, most recent workout at the top.
Step 4: When the user hits view custom exercises they should be given a list of their custom exercises, with the ability to filter by exercise type/body part.
| Completed |
| MargaretP | 15 | Basic Function | Create custom workout option | Add a "Create Custom Exercise" flow, accessible from the exercise library page (e.g., a button near the search bar).
Form fields:
name (required, text input)
exercise_type (required, select: strength / cardio / mobility / other)
measurement_type (required, select: reps_weight / time / distance / reps_only)
primary_muscle (optional, select dropdown — options limited to the existing ENUM: chest, back, shoulders, biceps, triceps, forearms, abs, quads, hamstrings, glutes, calves, full_body)
equipment (optional, free text input)
On submit:
- Insert a new row into
exercises with the form values, is_custom = true, and created_by set to the logged-in user's user_id.
- Validate that
name isn't empty and exercise_type/measurement_type are valid enum values before submitting.
- After a successful save, close the form and return the user to the exercise library with the new exercise visible in the list, tagged with the existing "Custom" badge, without requiring a manual page refresh.
Edge cases to handle:
- Prevent duplicate submissions if the user double-taps "Save."
- Show a clear inline error if the insert fails (e.g., a network issue), without losing the user's entered form data.
- Since
primary_muscle is an ENUM column, make sure the dropdown can only submit valid values — no free text that could violate the constraint.
Keep styling consistent with the rest of the exercise library screens.
| Not Started |
| MargaretP | 16 | Basic Function | Custom exercise function part 2 | Allow users to edit/delete custom exercises. If a custom exercise has already been used in a past workout plan, do not retroactively modify that plan.
| Not Started |
| MargaretP | 17 | Advanced Feature | Images in exercise description | this is a lot
Step 1:
Add two columns to the exercises table:
external_id (VARCHAR(100), UNIQUE, nullable) — will store the stable id field from the source exercise JSON (e.g., "Air_Bike") for pre-built exercises. Custom exercises will have external_id = NULL.
image_urls (JSON, nullable) — will store an array of image URLs per exercise. Custom exercises will have image_urls = NULL.
Don't populate these yet — just add the columns and confirm the migration runs cleanly against the existing table.
Step 2: Before making any changes, check whether any pre-built exercises (is_custom = false) are currently referenced by rows in plan_exercises or session_exercise_logs. Report which exercises (if any) are referenced, and by how many rows, so I can decide whether a full delete-and-reinsert is safe.
Step 3: Delete all rows in exercises where is_custom = false. If the foreign key constraints from plan_exercises or session_exercise_logsblock any deletions, stop immediately and report exactly which rows are blocking it, rather than partially deleting data.
Step 4:
Fetch the exercise list from https://raw.githubusercontent.com/yuhonas/free-exercise-db/main/dist/exercises.json and insert it into exercises, mapping fields as follows:
name → name
category → exercise_type (strength/powerlifting/strongman/olympic weightlifting/plyometrics → 'strength', cardio → 'cardio', stretching → 'mobility')
primaryMuscles[0] → primary_muscle, normalized to the existing ENUM (chest, back, shoulders, biceps, triceps, forearms, abs, quads, hamstrings, glutes, calves, full_body); use 'full_body' as fallback for anything unmapped
equipment → equipment as-is
instructions array joined into description
images array → image_urls, with each relative path prepended with https://raw.githubusercontent.com/yuhonas/free-exercise-db/main/exercises/ to form full URLs
id (source field) → external_id
is_custom = false, created_by = NULL
Report the total number of exercises inserted, and separately list any rows that failed the primary_muscle ENUM mapping.
Step 5: Show me 5 random exercises from the exercises table including their name, primary_muscle, external_id, and image_urls, so I can manually verify the mapping and image URLs look correct.
| Started |
| MargaretP | 18 | Advanced Feature | very basic goal setting | Step 1: The goals table already has goal_type, target_value, target_unit, start_date, and target_date. For frequency goals specifically, add a new column frequency_period (ENUM: 'week', 'month'), nullable, used only when goal_type = 'frequency'. This defines whether the goal resets/is measured on a calendar-week or calendar-month basis.
Don't build any goal creation or display logic yet — just add the column and confirm the migration runs cleanly.
Step 2: Build a "Create Goal" form, currently supporting only goal_type = 'frequency'. Fields:
- Title (required, text)
- Target count (required, number) → stored in
target_value
- Time frame (required, select: "per week" / "per month") → stored in
frequency_period
- Start date (default to today, editable) →
start_date
- Target/end date, auto-calculated from
start_date + one week or one month based on frequency_period (not manually entered) → target_date
On submit, insert into goals with user_id, goal_type = 'frequency', status = 'active', and the fields above. target_unit can be set to 'sessions' for now since only total workout count is supported.
Any completed workout session counts toward this goal — not tied to a specific plan.
Step 3:
Write a function/endpoint that calculates current progress for an active frequency goal:
- Determine the current window's start/end based on
frequency_period (calendar week or calendar month) relative to today.
- Count how many
workout_sessions rows exist for this user where status = 'completed' and started_at falls within the current window.
- Return the count alongside the goal's
target_value (e.g., "3 of 4").
Use the user's local time zone for window boundaries, not server time — [confirm how you're currently determining user time zone, e.g., browser-provided, or flag if this needs to default to UTC for now since the users table doesn't currently store one].
This should be computed fresh each time it's requested, not stored/cached in a separate table.
Step 4:
Add a "Goals" section to [wherever you want this — dashboard/home page and/or its own Goals tab]. For each active frequency goal, show:
- Title
- A progress bar or "X of Y workouts this week/month" counter, using the Step 3 calculation
- Days remaining in the current window (
target_date minus today)
List goals in order of soonest-ending first. Keep styling consistent with the rest of the app.
Step 5:
Add logic (e.g., a scheduled check, or a check-on-load) that updates a frequency goal's status once its target_date has passed:
- If the final progress count met or exceeded
target_value, set status = 'completed'.
- If it fell short, set
status = 'expired'.
- Completed/expired goals should no longer show in the active goals list, but should remain visible somewhere (e.g., a "past goals" view) showing their final result — don't delete the rows.
| Started |