The product owner decided on 2026-09-20 that PlatePilot should support explicit goals (lose weight, maintain, build muscle, general health) with a daily calorie and protein target, should generate the week to hit that target, and should show the adult whether a day is under, on track, or over. The earlier decision to collect only a qualitative focus (ADR-0010) is therefore superseded for targets. The calm, non-judgmental content stance (ADR-0006, UX content guidance) still applies: targets are estimates and progress is information, never a warning.
Computing a target needs body facts (sex for the formula, height, weight, activity level) and age. These are health-related personal data.
computeDailyTargets in packages/contracts/src/goals.ts is
pure and shared by the API and the app: Mifflin–St Jeor resting energy × activity factor gives
maintenance; lose weight subtracts 250/500/750 kcal by pace; build muscle adds 200/350/500 kcal;
protein is 1.2–2.0 g/kg by goal; fat 25–30% of calories; carbohydrate the remainder; fibre
14 g per 1,000 kcal; water 33 ml/kg. Targets are derived on every read and never stored, so a
formula correction applies at once.cautions (calorie_floor_applied,
low_bmi, high_bmi, age_unknown, body_profile_missing, deficit_capped) and the verbatim
estimateNotice (“not medical advice”, talk to a professional when pregnant, under care, or with a
history of disordered eating). The app must show the notice wherever a target appears.targetsSource says computed, manual, mixed, or
unavailable.targetProgress (calories, protein, fibre, water) on diary days and
plan days reports consumed, remaining, percent, and a status of under, on_track (±5%), or
over. The app renders these as neutral facts (“a little over”) and never as a red error; alerts
still do not send goal warnings.MealPlanGenerationRequest.dailyTargets is optional; the
deterministic provider scales each day’s four meals to land within ±5% of the calorie target
(portion scale clamped 0.6–1.6) and prefers protein-rich recipes when protein is at least 30% of
calories. A real provider receives the same numbers.adult_goals (one row per adult, cascade delete),
included in the export, removed on deletion, never logged, and never shared with a household peer.
Sex is collected only for the formula and offers unspecified.unitSystem.