469251366e
- eta_alla_data NULL non usa più il ripiego a zero: senza età la Fitness Age è null, non un'età di forma negativa dichiarata valida. Gli assi e i macro-score restano calcolabili (non dipendono dall'età). - applicaCurva valida i parametri richiesti da ciascuna curva prima di applicarla: un registro con params vuoti/incompleti dà null, mai il punteggio pieno che dava lerp con estremi indefiniti. - calcolaSessione esclude le misure fuori_range=1 (§9 della spec): non entrano nello score finché non esiste la colonna di conferma (§12, punto aperto). - leggiScore(db, sessioneId): legge la tabella score ritipata come Punteggio, con l'ultimo calcolo per tipo+elemento esplicito nella query (MAX(id)), non l'ordine naturale delle righe — salvaScore non sovrascrive di proposito (la storia degli score si tiene, discende dal congelamento della §6). - documentata la seconda divergenza dall'oracolo, mai scritta finora: la Fitness Age esclude gli assi insufficienti, l'oracolo li include comunque. Comportamento giusto, ma cambia il numero (25,0 contro 34,8 sullo stesso profilo parziale). - nuovo test che prova che i pesi di due model_version diverse restano separati (pesiDi filtra su model_version, non li fonde). Ogni fix verificato in TDD (test rosso prima, verde dopo) e ri-rotto a mano per confermare che discrimina davvero (vedi report). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XhLbMQ1q7wHwJSykgXRwQF