Files
gravl/.planning/phases/02-flexible-sets/02-02-SUMMARY.md
T
clawd 396c438a70 docs(02-02): complete DELETE logs endpoint plan — summary and state update
- 02-02-SUMMARY.md: backend DELETE endpoint + frontend deleteLog wiring
- STATE.md: phase 2 marked complete, decisions added, position advanced to phase 3 ready
2026-02-21 18:46:26 +01:00

4.9 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established duration completed
02-flexible-sets 02 api
express
postgres
react
fetch
delete
workout-logs
phase plan provides
02-flexible-sets 01 ExerciseCard with handleDeleteSet calling optional onDeleteSet prop (stub — wired here)
DELETE /api/logs endpoint in backend/src/index.js
deleteLog function in App.jsx calling DELETE /api/logs
onDeleteSet prop wired from App.jsx -> WorkoutPage -> ExerciseCard
03-custom-workouts
backend-logging
added patterns
DELETE endpoint with composite key (user_id
program_exercise_id
date
set_number)
optimistic local state removal mirrors DB delete
created modified
backend/src/index.js
frontend/src/App.jsx
frontend/src/pages/WorkoutPage.jsx
No authMiddleware on DELETE /api/logs — consistent with existing POST /api/logs which also passes user_id in body
deleteLog silently ignores 404 responses — backend handles non-existent row gracefully (unlogged sets deleted mid-session)
Local logs state updated optimistically after DELETE regardless of 404 — ensures UI stays consistent even for never-logged sets
Composite-key delete: (user_id, program_exercise_id, date, set_number) is the unique identifier for a workout set log row
Prop threading: deleteLog lives in App.jsx, flows as onDeleteSet -> WorkoutPage -> ExerciseCard without intermediate handlers
2min 2026-02-21

Phase 2 Plan 02: Flexible Sets — Backend DELETE Endpoint and Frontend Wiring Summary

DELETE /api/logs endpoint deletes workout_logs rows by composite key; deleteLog in App.jsx propagates through WorkoutPage to ExerciseCard, removing orphaned set rows from DB when user deletes a set

Performance

  • Duration: ~2 min
  • Started: 2026-02-21T17:44:02Z
  • Completed: 2026-02-21T17:45:45Z
  • Tasks: 2
  • Files modified: 3

Accomplishments

  • Backend DELETE /api/logs endpoint: deletes matching workout_logs row by composite key (user_id, program_exercise_id, date, set_number), returns 200+id on success, 404 if not found
  • deleteLog async function added to App.jsx alongside logSet: sends DELETE fetch, removes entry from local logs state on success
  • Full prop chain wired: App.jsx onDeleteSet={deleteLog} -> WorkoutPage signature updated to accept onDeleteSet -> ExerciseCard receives onDeleteSet prop (was already calling it if provided from plan 01)
  • Frontend build passes cleanly after changes

Task Commits

Each task was committed atomically:

  1. Task 1: Add DELETE /api/logs endpoint to backend - f9eb6cc (feat)
  2. Task 2: Wire deleteLog through App.jsx and WorkoutPage to ExerciseCard - 175434f (feat)

Plan metadata: committed with docs commit (docs)

Files Created/Modified

  • backend/src/index.js - Added DELETE /api/logs route (21 lines) after POST /api/logs, same composite key pattern
  • frontend/src/App.jsx - Added deleteLog function (20 lines), added onDeleteSet={deleteLog} prop to WorkoutPage render
  • frontend/src/pages/WorkoutPage.jsx - Updated function signature to accept onDeleteSet, passed onDeleteSet to each ExerciseCard

Decisions Made

  • No auth on DELETE /api/logs: POST /api/logs has no authMiddleware — DELETE matches that pattern for consistency; user_id from body provides identity
  • Silent 404 handling: If a set was never logged (user added then immediately deleted without completing), the DELETE returns 404. deleteLog catches silently — the row never existed, no cleanup needed
  • Optimistic state update: Local logs state is always updated (filter out the set_number) regardless of whether the DELETE returned 200 or 404, since in both cases the set should not appear in the UI

Deviations from Plan

None — plan executed exactly as written.

Issues Encountered

None — build passed cleanly after both tasks. Backend syntax verified with node --check.

User Setup Required

None - no external service configuration required.

Next Phase Readiness

  • Phase 2 (Flexible Sets) is now complete: ExerciseCard supports dynamic set lists (plan 01), and deleting a logged set removes it from the database (plan 02)
  • Ghost sets can no longer reappear after page reload — deleted sets are removed from both frontend state and backend DB
  • Phase 3 (Custom Workouts) requires new DB tables (custom_workouts, custom_workout_exercises) and a source_type column on workout_logs — schema migration needed before Phase 3 planning

Self-Check: PASSED

  • backend/src/index.js: FOUND
  • frontend/src/App.jsx: FOUND
  • frontend/src/pages/WorkoutPage.jsx: FOUND
  • 02-02-SUMMARY.md: FOUND
  • Commit f9eb6cc (Task 1): FOUND
  • Commit 175434f (Task 2): FOUND
  • DELETE /api/logs in backend: FOUND
  • deleteLog in App.jsx: FOUND
  • onDeleteSet prop wired through WorkoutPage: FOUND

Phase: 02-flexible-sets Completed: 2026-02-21