UserWorkoutSession and WorkoutLog modules to record actual workout activity in real time.PlanDetailScreen (active plan with day selector and session start) and WorkoutSessionScreen (fully interactive live workout experience).| Day | Task | Start Date | Completion Date | Reference Material |
|---|---|---|---|---|
| 2 | - Build UserWorkoutSession entity + Fields: user (@ManyToOne), userWorkoutPlan (@ManyToOne), workoutDate (LocalDate), isActive (default true), weekIndex, dayIndex + Cascade to WorkoutLog via @OneToMany(cascade = ALL) |
02/10/2026 | 02/10/2026 | |
| 3 | - Build WorkoutLog entity + Fields: userWorkoutSession (@ManyToOne), exercise (@ManyToOne), setNumber, reps, weight (Float), durationSeconds |
02/11/2026 | 02/11/2026 | |
| 3 | - Build UserWorkoutSessionController (/api/sessions) + POST / — create session + GET /{id}, GET /user/{userId}, GET /user/{userId}/by-date?date= + GET /user/{userId}/active — fetch currently active session + PATCH /{sessionId}/deactivate — mark session completed + POST /{sessionId}/logs — log an exercise set |
02/11/2026 | 02/11/2026 | |
| 4 | - Build PlanDetailScreen (Frontend) + Display active plan name and description + Day-of-week selector (Mon–Sun) — shows exercises for selected day + “Start Workout” button: create session via POST /api/sessions, navigate to WorkoutSessionScreen + Show active session banner if session already in progress + Navigate to SessionCalendar for history |
02/12/2026 | 02/12/2026 | |
| 5 | - Build workoutSessionSlice (Redux) + State: sessionId, planId, exercises[], currentExIndex, currentSet, completedSets[], phase (workout/rest/done), restSeconds, isSavingLog + Actions: initializeSession, restoreSessionState, logSetStart/Success/Failure, finishRest, skipExercise, skipSet, resetSession + Persist session to AsyncStorage on every set — restore on app reload |
02/13/2026 | 02/13/2026 | |
| 6 | - Build WorkoutSessionScreen (Frontend) + ActiveExerciseCard: shows exercise name, set progress, reps target + LogSetSheet: input actual reps + weight → addWorkoutLog API call + RestTimer: countdown timer with auto-advance to next exercise/set after rest + Finish: deactivateSession → resetSession → navigate to WorkoutSuccessScreen - Build WorkoutSuccessScreen + Trophy screen with exercise summary (exercises done, sets, total reps) + Blocks hardware back button → force navigate to Home |
02/14/2026 | 02/14/2026 |
UserWorkoutSession + WorkoutLog entities persisted correctly with cascade DELETE.POST /api/sessions creates a session linked to a plan and user; PATCH /{id}/deactivate marks it done.POST /api/sessions/{id}/logs records individual set logs (exercise, set number, reps, weight).GET /user/{userId}/active correctly returns the in-progress session or null.GET /by-date?date= working for session history retrieval.PlanDetailScreen loads active plan; day selector filters exercises by dayOfWeek.workoutSessionSlice — persisted to AsyncStorage for crash recovery.WorkoutSessionScreen guides user through all exercises/sets with automatic rest timer.addWorkoutLog API call before advancing.WorkoutSuccessScreen shows achieved stats and prevents accidental back navigation.Self-study — AWS Cognito Authentication Flow (End-to-End)
This week I documented the complete Cognito OAuth2 auth flow to support the team’s Cognito integration work:
STEP 1 — User Login: Frontend redirects the user to the Cognito Hosted UI:
GET /oauth2/authorize?client_id=...&response_type=code&scope=openid+profile+email&redirect_uri=...
Cognito shows the login page and verifies username/password directly (the backend never sees the password).
STEP 2 — Authorization Code returned: After successful login, Cognito redirects back to the app:
https://yourapp.com/callback?code=AUTH_CODE_123
This code is short-lived (~1 minute) and is NOT the token yet.
STEP 3 — Exchange Code for Tokens: Frontend calls Cognito:
POST /oauth2/token
grant_type=authorization_code&code=AUTH_CODE_123&client_id=...&redirect_uri=...
Cognito responds with access_token, id_token, refresh_token, and expires_in.
Token types and roles:
Authorization: Bearer header to the backend. Backend verifies this token.sub, email, name). Used by the frontend to know who the user is. NOT sent to the backend for authorization.How the backend verifies Cognito tokens (RS256 / JWKS):
https://cognito-idp.<region>.amazonaws.com/<userPoolId>/.well-known/jwks.jsonspring.security.oauth2.resourceserver.jwt.issuer-uri=https://cognito-idp.<region>.amazonaws.com/<userPoolId>Why asymmetric signing (RS256) is safer than symmetric (HS256):
Limitations and mitigations:
POST /oauth2/revoke.Image entity, S3 integration, and ImageController for associating images with exercises, foods, and workout plans.SessionDetailScreen (past workout recap) and SessionCalendarScreen (monthly calendar with session dots).