fix: include exercise calories in diet adherence calculation
All checks were successful
CI / update (push) Successful in 3m55s
All checks were successful
CI / update (push) Successful in 3m55s
Adherence was comparing intake against the flat calorie goal, ignoring burned workout calories. Now the per-day target is goal + exercise kcal. Also expanded workout query from 7 to 30 days to cover the full adherence window.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "homepage",
|
"name": "homepage",
|
||||||
"version": "1.23.2",
|
"version": "1.23.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const GET: RequestHandler = async ({ locals }) => {
|
|||||||
const thirtyDaysAgo = new Date(todayStart);
|
const thirtyDaysAgo = new Date(todayStart);
|
||||||
thirtyDaysAgo.setUTCDate(thirtyDaysAgo.getUTCDate() - 30);
|
thirtyDaysAgo.setUTCDate(thirtyDaysAgo.getUTCDate() - 30);
|
||||||
|
|
||||||
const [entries30d, goal, weightMeasurements, workoutSessions7d] = await Promise.all([
|
const [entries30d, goal, weightMeasurements, workoutSessions30d] = await Promise.all([
|
||||||
FoodLogEntry.find({
|
FoodLogEntry.find({
|
||||||
createdBy: user.nickname,
|
createdBy: user.nickname,
|
||||||
date: { $gte: thirtyDaysAgo, $lt: todayStart },
|
date: { $gte: thirtyDaysAgo, $lt: todayStart },
|
||||||
@@ -34,7 +34,7 @@ export const GET: RequestHandler = async ({ locals }) => {
|
|||||||
{ date: 1, weight: 1, _id: 0 }
|
{ date: 1, weight: 1, _id: 0 }
|
||||||
).sort({ date: 1 }).lean() as any[],
|
).sort({ date: 1 }).lean() as any[],
|
||||||
WorkoutSession.find(
|
WorkoutSession.find(
|
||||||
{ createdBy: user.nickname, startTime: { $gte: sevenDaysAgo, $lt: todayStart }, 'kcalEstimate.kcal': { $gt: 0 } },
|
{ createdBy: user.nickname, startTime: { $gte: thirtyDaysAgo, $lt: todayStart }, 'kcalEstimate.kcal': { $gt: 0 } },
|
||||||
{ startTime: 1, 'kcalEstimate.kcal': 1, _id: 0 }
|
{ startTime: 1, 'kcalEstimate.kcal': 1, _id: 0 }
|
||||||
).lean() as any[],
|
).lean() as any[],
|
||||||
]);
|
]);
|
||||||
@@ -121,9 +121,9 @@ export const GET: RequestHandler = async ({ locals }) => {
|
|||||||
return bmr * neatMult;
|
return bmr * neatMult;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group workout kcal by date for the 7-day window
|
// Group workout kcal by date for the 30-day window
|
||||||
const workoutKcalByDate = new Map<string, number>();
|
const workoutKcalByDate = new Map<string, number>();
|
||||||
for (const s of workoutSessions7d) {
|
for (const s of workoutSessions30d) {
|
||||||
const key = new Date(s.startTime).toISOString().slice(0, 10);
|
const key = new Date(s.startTime).toISOString().slice(0, 10);
|
||||||
workoutKcalByDate.set(key, (workoutKcalByDate.get(key) ?? 0) + (s.kcalEstimate?.kcal ?? 0));
|
workoutKcalByDate.set(key, (workoutKcalByDate.get(key) ?? 0) + (s.kcalEstimate?.kcal ?? 0));
|
||||||
}
|
}
|
||||||
@@ -196,9 +196,10 @@ export const GET: RequestHandler = async ({ locals }) => {
|
|||||||
yesterday.setUTCDate(yesterday.getUTCDate() - 1);
|
yesterday.setUTCDate(yesterday.getUTCDate() - 1);
|
||||||
const totalDays = Math.round((yesterday.getTime() - firstDate.getTime()) / 86400000) + 1;
|
const totalDays = Math.round((yesterday.getTime() - firstDate.getTime()) / 86400000) + 1;
|
||||||
|
|
||||||
const lower = dailyCalorieGoal * 0.9;
|
const withinRange = dailyTotals.filter(d => {
|
||||||
const upper = dailyCalorieGoal * 1.1;
|
const dayGoal = dailyCalorieGoal + (workoutKcalByDate.get(d.date) ?? 0);
|
||||||
const withinRange = dailyTotals.filter(d => d.calories >= lower && d.calories <= upper).length;
|
return d.calories >= dayGoal * 0.9 && d.calories <= dayGoal * 1.1;
|
||||||
|
}).length;
|
||||||
adherenceDays = totalDays;
|
adherenceDays = totalDays;
|
||||||
adherencePercent = Math.round(withinRange / totalDays * 100);
|
adherencePercent = Math.round(withinRange / totalDays * 100);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -295,8 +295,8 @@
|
|||||||
{#if showAdherenceInfo}
|
{#if showAdherenceInfo}
|
||||||
<div class="card-info-tooltip">
|
<div class="card-info-tooltip">
|
||||||
{lang === 'en'
|
{lang === 'en'
|
||||||
? 'Percentage of days where calories eaten were within ±10% of your goal. Days without tracking count as misses.'
|
? 'Percentage of days where calories eaten were within ±10% of your goal (adjusted for exercise calories burned). Days without tracking count as misses.'
|
||||||
: 'Prozent der Tage, an denen die gegessenen Kalorien innerhalb von ±10 % deines Ziels lagen. Nicht erfasste Tage zählen als verfehlt.'}
|
: 'Prozent der Tage, an denen die gegessenen Kalorien innerhalb von ±10 % deines Ziels lagen (bereinigt um verbrannte Trainings\u00ADkalorien). Nicht erfasste Tage zählen als verfehlt.'}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user