Skip to content

fix: clamp calorie deficit targets to a safe floor and guard BMI math#909

Open
Anexus5919 wants to merge 1 commit into
Somil450:mainfrom
Anexus5919:fix/fitness-calc-safe-bounds
Open

fix: clamp calorie deficit targets to a safe floor and guard BMI math#909
Anexus5919 wants to merge 1 commit into
Somil450:mainfrom
Anexus5919:fix/fitness-calc-safe-bounds

Conversation

@Anexus5919

Copy link
Copy Markdown
Contributor

📌 Related Issue

Fixes #872


📝 Description

Two unguarded numeric paths in src/utils/fitnessCalculations.ts:

  • Unsafe deficit targets (reachable): getCalorieRecommendations subtracted a flat 300/500 from TDEE with no lower bound, so smaller/sedentary users were shown deficit targets below the ~1200 kcal safe minimum (e.g. TDEE 1427 gives an aggressive deficit of 927), and these render in the Deficit tab.
  • BMI Infinity/NaN (defensive): calculateBMI divided by height with no guard (Infinity for height 0, NaN for non-numeric input). Both current callers already validate height >= 100, so this is a robustness gap in the exported helper rather than a live UI bug.

🔹 What has been changed?

  • Added MIN_SAFE_CALORIES = 1200 and clamped deficitMild/deficitAggressive to it; coerced a non-finite TDEE to 0.
  • Guarded calculateBMI so non-finite weight or non-positive height yields 0, keeping the result and gauge finite.
  • Added unit tests for both functions (src/utils/__tests__/fitnessCalculations.test.ts).

🔹 Why are these changes needed?

  • Recommending a calorie target below the commonly cited ~1200 kcal/day minimum is a safety problem for smaller or sedentary users. Clamping to a floor keeps the recommendation safe, while surplus targets and normal-range deficits are unchanged.

🛠️ Type of Change

  • 🐛 Bug Fix

🧪 Testing

✅ Tests Performed

  • Tested locally
  • npx vitest run src/utils/__tests__/fitnessCalculations.test.ts -> 6 tests pass.
  • npx tsc --noEmit: changed file clean; npx eslint on the changed files: 0 problems.
  • Verified surplus targets and normal-range (above-floor) deficits are unchanged.

🌐 Browsers Tested

Not applicable (pure calculation logic; verified via unit tests).


📷 Screenshots / Demo (if applicable)

Not applicable.


📋 Checklist

  • I have read the project's CONTRIBUTING guidelines
  • My code follows the project style guidelines
  • I have performed a self-review of my code
  • I have tested my changes locally
  • I have added/updated documentation where necessary (not applicable)
  • My changes do not introduce new warnings or errors
  • This PR is linked to an existing issue

💬 Additional Notes

Branched from latest upstream/main (5464425). The deficit clamp is the reachable safety fix; the calculateBMI guard is defensive (both current callers already validate height), framed as such above.

@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown

@Anexus5919 is attempting to deploy a commit to the somiljain2024-4175's projects Team on Vercel.

A member of the Team first needs to authorize it.

@Anexus5919

Copy link
Copy Markdown
Contributor Author

@Somil450 @diksha78dev Kindly have a review on this pr. Thanks!

getCalorieRecommendations subtracted a flat 300/500 from TDEE with no
lower bound, so smaller or sedentary users were shown deficit targets
below the 1200 kcal safe minimum. Clamp both deficits to MIN_SAFE_CALORIES
and coerce a non-finite TDEE to 0.

calculateBMI divided by height with no guard, returning Infinity for a
zero height and NaN for non-numeric input. Return 0 for those cases so
the result and gauge stay finite.
@Anexus5919 Anexus5919 force-pushed the fix/fitness-calc-safe-bounds branch from 27b4106 to 739aaad Compare June 23, 2026 17:34
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.

Calorie deficit recommendations can fall below the safe minimum; calculateBMI can return Infinity/NaN

1 participant