Skip to content

fix: use effective bodyweight load for exercise display and 1RM (#684)#685

Merged
9thLevelSoftware merged 7 commits into
mainfrom
fix/684-bodyweight-pr-weight-display
Jul 26, 2026
Merged

fix: use effective bodyweight load for exercise display and 1RM (#684)#685
9thLevelSoftware merged 7 commits into
mainfrom
fix/684-bodyweight-pr-weight-display

Conversation

@9thLevelSoftware

Copy link
Copy Markdown
Owner

Summary

Fixes the display-path bug where Exercise Detail / Personal Records shows the configured nominal cable weight instead of the bodyweight-derived effective load for bodyweight exercises (e.g. Decline Push Up).

Root Cause

ExerciseDetailScreen.kt and ResolveCurrentOneRepMaxUseCase.kt read session.weightPerCableKg (the configured/nominal machine load) in 4 display paths. For bodyweight exercises, the correct effective load is persisted in session.heaviestLiftKg during the workout, and effectiveHeaviestKgPerCable() already provides the backward-compatible accessor (heaviestLiftKg ?: weightPerCableKg).

Volume was already correct because it uses effectiveTotalVolumeKg() — this fix aligns the weight and 1RM display paths with the same pattern.

Changes

File Change
ExerciseDetailScreen.kt weightTrendData, ExerciseHistoryTable weight column, SessionHistoryRow: weightPerCableKgeffectiveHeaviestKgPerCable()
ResolveCurrentOneRepMaxUseCase.kt estimatedOneRepMaxPerCableOrNull(): same switch
ResolveCurrentOneRepMaxUseCaseTest.kt New regression test for bodyweight sessions with effective load, weighted-vest sessions, and legacy fallback

What this does NOT change

  • Bodyweight volume calculation (BodyweightVolumeCalculator)
  • PR persistence / gamification write path
  • Session save contract
  • Cable multiplier semantics
  • Legacy sessions without heaviestLiftKg (they fall through to weightPerCableKg via the existing accessor)

Testing

  • New test session helper uses effectiveHeaviestKgPerCable for bodyweight sessions covers:
    • Bodyweight session (configured=0, effective=40kg) → 1RM from 40kg
    • Weighted-vest session (configured=5kg, effective=40kg) → 1RM from 40kg
    • Legacy session (no heaviestLiftKg) → 1RM from configured weight
  • Blocker: No Java Runtime on the CI host; Gradle tests cannot be run locally. CI should verify.

Fixes #684

…y and 1RM

ExerciseDetailScreen was reading weightPerCableKg (configured/nominal load)
for weight trend, history table, and session history row. For bodyweight
exercises, this field contains the nominal cable value (e.g. 11.0 lb) instead
of the bodyweight-derived effective load that was correctly persisted during
the workout session.

The 1RM helper (estimatedOneRepMaxPerCableOrNull) had the same issue,
producing 1RM estimates from the nominal load rather than the effective load.

Fix: switch all 4 display/read paths to use effectiveHeaviestKgPerCable(),
which prefers the persisted heaviestLiftKg and falls back to weightPerCableKg
for legacy sessions without that field.

Closes #684

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fcdc7bba9f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Address Codex P2 review: when heaviestLiftKg=0f (measured zero but
summary metrics exist), effectiveHeaviestKgPerCable() returns 0 instead
of falling back to weightPerCableKg. This mirrors the SQL
selectExerciseWeightHistory behavior that treats nonpositive heaviestLiftKg
as absent.

Added test case covering heaviestLiftKg=0f edge case.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 49a31e32c8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…Kg=0f

Address Codex P2 review on ExerciseDetailScreen: added
displayHeaviestKgPerCable() helper that falls back to weightPerCableKg
when effectiveHeaviestKgPerCable() returns 0 (from heaviestLiftKg=0f).
Applied to weight trend chart, history table weight column, and session
history row — matching the SQL selectExerciseWeightHistory fallback.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 41f6d847c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Local extension function inside composable was unreachable from nested
composable lambdas (Compose compiler transform). Moved to top-level
private extension function at file bottom.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a5ada65f56

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 092d3cceba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread shared/src/commonMain/kotlin/com/devil/phoenixproject/domain/model/Models.kt Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a27d32db4e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 766c25e1e9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

suspend operator fun invoke(
exerciseId: String,
profileId: String,
isBodyweight: Boolean = false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass bodyweight context from Profile insights

When the selected exercise is bodyweight, counterweight clamps a session's effective load to zero, and no velocity or assessment result exists, ProfileViewModel.loadInsights still invokes the resolver with only (exerciseId, profileId). This new default therefore supplies false, causing the session fallback to replace the legitimate zero with the configured load and show a nonzero current 1RM on the Profile screen. Fresh evidence after the earlier bodyweight-zero thread is the unchanged two-argument call at ProfileViewModel.kt:831; pass exercise.isBodyweight there rather than silently defaulting the new parameter.

Useful? React with 👍 / 👎.

@9thLevelSoftware
9thLevelSoftware merged commit 893ed47 into main Jul 26, 2026
9 of 10 checks passed
@9thLevelSoftware
9thLevelSoftware deleted the fix/684-bodyweight-pr-weight-display branch July 26, 2026 00:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect weight in bodyweight exercise Personal Records (Decline Push Up)

1 participant