feat: composizione corporea, deficit dinamico, condizioni mediche (PRD §5.1)

Tre leve per migliorare l'accuratezza del piano oltre Mifflin-St Jeor.

1. Composizione corporea (US Navy + Katch-McArdle)
   - Profile: neckCm/waistCm/hipsCm opzionali in input
   - bodyFatPct calcolato lato server con la formula US Navy metrica
     (Hodgdon-Beckett 1984) e cifrato at-rest come dato sanitario
   - BMR usa Katch-McArdle (FFM-based) quando bodyFatPct è noto, Mifflin
     altrimenti — più accurato del 5-10% sui casi fuori-norma
   - Test: estimateBodyFatPercentageUSNavy + calculateBmrKatchMcArdle

2. Deficit dinamico
   - Profile.targetWeeklyLossKg (kg/settimana, opzionale)
   - computeDailyKcalTarget calcola il deficit da kg/sett ×7700/7 con due cap
     di sicurezza: 30% TDEE (Schoenfeld 2014) e 1% peso/sett (Helms 2014)
   - plan.routes lo usa al posto del -500/-200 hard-coded
   - Test: 6 casi (mantenimento, transizione, intensiva, cap peso, cap TDEE,
     default mancante)

3. Condizioni mediche strutturate
   - Profile.medicalConditions (array JSON cifrato)
   - 11 condizioni: 7 adattabili (tiroide → BMR -10%, diabete II, IBS,
     dislipidemia, ipertensione, reni → cap proteine 0.8 g/kg, fegato →
     1.0 g/kg) + 4 escludenti (gravidanza, allattamento, diabete I, disturbi
     alimentari)
   - PATCH /me/profile/conditions per salvataggio mirato dall'onboarding
   - hasExcludingCondition: plan.routes restituisce 409 medical_block se
     attiva una condizione incompatibile

Onboarding allargato a 6 step: aggiunto "Condizioni mediche" tra Profile
e Preferences. Step labels e numeri rinumerati.

Schema migration 20260429203451_add_profile_health_fields.

44/44 unit test verdi.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
lucianoandClaude Opus 4.7 committed 2026-04-29 22:44:16 +02:00
1 parent feb54c1f9a
commit 9401497f03
15 files changed
+744 -26

No files matched your search

+29
View File
@@ -177,10 +177,32 @@
"steps": {
"goal": "L'obiettivo",
"profile": "Anagrafica e attività",
"conditions": "Condizioni mediche",
"preferences": "Esclusioni e cucine",
"notifications": "Promemoria",
"done": "Pronti a partire"
},
"conditionsHeading": "Qualcosa di te che dovremmo sapere?",
"conditionsHint": "Indica le condizioni che ti riguardano. Servono ad adattare i calcoli e a segnalarti i casi in cui meglio consultare un medico prima di proseguire.",
"conditionsAdaptive": "Condizioni adattabili",
"conditionsExcluding": "Condizioni che richiedono il medico",
"conditionsExcludingHint": "Se selezioni una di queste l'app non genera piani autonomamente: vai dal tuo medico.",
"conditionsSaveError": "Non è stato possibile salvare. Riprova fra poco.",
"blockedEyebrow": "Importante",
"blockedMessage": "KetoPath non è uno strumento adatto a questa condizione. Ti consigliamo di rivolgerti al tuo medico curante prima di continuare. Puoi comunque proseguire l'esplorazione, ma il piano non verrà generato automaticamente.",
"conditionLabel": {
"THYROID_HYPO": "Ipotiroidismo",
"DIABETES_T2": "Diabete tipo 2",
"IBS": "Intestino irritabile",
"DYSLIPIDEMIA": "Colesterolo / trigliceridi alti",
"HYPERTENSION": "Ipertensione",
"KIDNEY_ISSUES": "Problemi renali",
"LIVER_ISSUES": "Problemi epatici",
"PREGNANCY": "Gravidanza",
"BREASTFEEDING": "Allattamento",
"DIABETES_T1": "Diabete tipo 1",
"EATING_DISORDER": "Disturbi alimentari"
},
"goalHeading": "Perché sei qui?",
"goalHint": "Scegli il motivo principale: ci aiuterà a parlarti nel modo giusto. Potrai sempre cambiarlo.",
"goals": {
@@ -430,6 +452,13 @@
"weightCurrentKg": "Attuale",
"weightGoalKg": "Obiettivo",
"activityLevel": "Livello di attività",
"measurementsTitle": "Circonferenze (cm) — opzionali",
"measurementsHint": "Se inserisci collo, vita e (per le donne) fianchi, calcoliamo la tua composizione corporea con la formula US Navy e usiamo Katch-McArdle invece di Mifflin: BMR più accurato.",
"neckCm": "Collo",
"waistCm": "Vita",
"hipsCm": "Fianchi",
"targetWeeklyLossKg": "Velocità di calo (kg/settimana)",
"targetWeeklyLossKgHint": "Suggerito: 0.4–0.7 kg/settimana. Oltre 1% del peso corporeo è considerato troppo aggressivo.",
"selectPlaceholder": "Seleziona…",
"save": "Salva profilo",
"saving": "Salvataggio…",