Files
gravl/.planning/research/ARCHITECTURE.md
T
2026-02-15 22:48:57 +01:00

3.1 KiB

Architecture: Custom Workouts & Flexible Sets

Project: Gravl — PPL Workout Tracker Researched: 2026-02-15

Current State

Fixed program structure:

Users → Programs (hardcoded id=1) → Program Days (6) → Program Exercises (fixed sets) → Workout Logs

Proposed: Dual Data Paths

Two parallel workout sources:

  1. Program Workouts (existing): Fixed PPL structure, unchanged
  2. Custom Workouts (new): User-built workouts with flexible sets

Schema Additions

-- User-created workout templates
CREATE TABLE custom_workouts (
  id SERIAL PRIMARY KEY,
  user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
  name VARCHAR(100) NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);

-- Exercises in custom workouts
CREATE TABLE custom_workout_exercises (
  id SERIAL PRIMARY KEY,
  custom_workout_id INTEGER REFERENCES custom_workouts(id) ON DELETE CASCADE,
  exercise_id INTEGER REFERENCES exercises(id),
  sets INTEGER DEFAULT 3,
  sort_order INTEGER DEFAULT 0
);

Enhanced workout_logs:

  • Add source_type column ('program' | 'custom') — defaults to 'program' for backward compat
  • Add custom_workout_exercise_id column (nullable FK)

Frontend Components

New pages:

  • CustomWorkoutBuilder.jsx — search exercises, build workout, save template
  • ModifyWorkoutPage.jsx — fork a program workout into custom

New components:

  • ExerciseSearchInput.jsx — searchable exercise list
  • SetCountEditor.jsx — +/- controls for set count
  • StepperInput.jsx — number input with +/- buttons and unit label

Enhanced:

  • WorkoutSelectPage.jsx — show both program and custom workouts
  • WorkoutPage.jsx — flexible set count, stepper inputs

Backend Endpoints

New:

  • POST /api/custom-workouts — create custom workout
  • GET /api/custom-workouts — list user's custom workouts
  • GET /api/custom-workouts/:id — get custom workout with exercises
  • PUT /api/custom-workouts/:id — update custom workout
  • DELETE /api/custom-workouts/:id — delete custom workout
  • GET /api/exercises — list all exercises (for search/selection)

Enhanced:

  • POST /api/logs — accept both program_exercise_id and custom_workout_exercise_id

Data Flow

  1. Program Workout (unchanged): Dashboard → WorkoutSelectPage → WorkoutPage → logs
  2. Custom Workout Build: Dashboard → CustomWorkoutBuilder → search exercises → save → POST /api/custom-workouts
  3. Modify Program Workout: WorkoutPage → "Modify" → fork to custom workout → edit exercises/sets
  4. Flexible Sets: User clicks "+Set" → local state adds entry → logs all sets on save

Build Order

  1. Input UX fixes — stepper inputs, validation, units (no backend changes)
  2. Flexible sets — local state for set count, backend accepts variable sets
  3. Exercise list endpoint — GET /api/exercises for search
  4. Custom workout CRUD — new tables + endpoints
  5. Custom workout builder UI — frontend page + components
  6. Modify program workout — fork program workout to custom

Each phase builds on the previous. Phase 1 can ship independently.