From 6630be7a02f6062396057caf49af046eae5595dd Mon Sep 17 00:00:00 2001 From: AdrianoDev Date: Sat, 22 Aug 2026 14:32:43 +0200 Subject: [PATCH] longevity: la prova sul congelamento ora discrimina davvero il ricalcolo Il peso mutato prima era l'unico sotto-dominio del suo asse (questionario_lifestyle, 1.00 in Stile di Vita & Sonno): in una media pesata a un solo elemento disponibile il peso si semplifica sia al numeratore sia al denominatore, quindi il test restava verde anche se refertoDi avesse ricalcolato invece di leggere gli score congelati. Sostituita con il peso di un sotto-dominio ASSENTE in un asse a piu' elementi con copertura parziale non nulla (hrv in Recupero & Sistema Nervoso): li' un ricalcolo sposta davvero la copertura oltre soglia. Verificato rosso col ricalcolo forzato, verde ripristinato. --- tests/longevity/referto.test.ts | 47 ++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/tests/longevity/referto.test.ts b/tests/longevity/referto.test.ts index 574d93f..c128885 100644 --- a/tests/longevity/referto.test.ts +++ b/tests/longevity/referto.test.ts @@ -20,6 +20,27 @@ function conCompilazione() { return { db, s }; } +/** + * Come conCompilazione, con IN PIU' una risposta di questionario_sonno (q_riposato). + * Serve solo alla prova sul congelamento, che ha bisogno di un asse con PIU' sotto-domini + * pesati e copertura parziale non nulla — vedi il commento sopra la mutazione qui sotto per + * il perche' conCompilazione da sola non basta. + */ +function conCoperturaParziale() { + const db = createLongevityDb(':memory:'); + seedRegistro(db); seedPesi(db, MODEL_VERSION); + db.prepare(`INSERT INTO soggetti (client_code, sesso) VALUES ('ISL-0001','F')`).run(); + const s = salvaCompilazione(db, { + client_code: 'ISL-0001', data: '2026-08-22', eta: 35, + risposte: { + q_attivita: 5, q_alimentazione: 8, q_sigarette: 0, q_alcol_life: 2, q_luce: 2, q_schermi: 10, + q_riposato: 8, + }, + }); + salvaScore(db, s, calcolaSessione(db, s)); + return { db, s }; +} + describe('il referto del cliente', () => { it('restituisce i sette assi', () => { const { db, s } = conCompilazione(); @@ -46,10 +67,30 @@ describe('il referto del cliente', () => { }); it('legge i punteggi congelati, non li ricalcola al volo', () => { - const { db, s } = conCompilazione(); - // se rileggesse le misure invece degli score salvati, cambiare i pesi cambierebbe il referto + const { db, s } = conCoperturaParziale(); const prima = JSON.stringify(refertoDi(db, s)); - db.prepare(`UPDATE pesi SET peso = 0.99 WHERE model_version = ? AND elemento = 'questionario_lifestyle'`).run(MODEL_VERSION); + // ATTENZIONE alla scelta della mutazione: non una qualunque, una che DISCRIMINA + // davvero un ricalcolo da una lettura congelata. + // + // 'Recupero & Sistema Nervoso' pesa QUATTRO sotto-domini (hrv 0.50, pressione 0.15, + // hrr 0.15, questionario_sonno 0.20); questa sessione ne misura UNO solo + // (questionario_sonno, via q_riposato in conCoperturaParziale) — copertura vera + // 0.20/1.00=0.20, sotto COPERTURA_MINIMA (0.4): l'asse e' 'insufficiente', ma con + // disponibili.length===1, non 0 — la formula del peso viene davvero eseguita, non + // bypassata dalla scorciatoia "nessun dato disponibile" di aggrega() in cascata.ts. + // Azzerando il peso di 'hrv' (un sotto-dominio ASSENTE) il totale scende a 0.50 e la + // copertura vera diventa 0.20/0.50=0.40: attraversa la soglia, l'asse passerebbe da + // insufficiente a ok SE il referto ricalcolasse (provato: vedi task-3-report.md). + // + // Una mutazione come questa NON discrimina, ed e' un errore da non ripetere: + // il peso dell'UNICO sotto-dominio di un asse a un solo elemento (es. + // 'questionario_lifestyle', 1.00 in 'Stile di Vita & Sonno') si semplifica sempre, + // sia al numeratore sia al denominatore della media pesata — cambiarlo non altera + // ne' il valore ne' la copertura, quindi il test resterebbe verde anche se + // refertoDi ricalcolasse davvero (era il bug di questo stesso test, corretto qui). + db.prepare( + `UPDATE pesi SET peso = 0 WHERE model_version = ? AND livello='asse' AND contenitore='Recupero & Sistema Nervoso' AND elemento='hrv'` + ).run(MODEL_VERSION); expect(JSON.stringify(refertoDi(db, s))).toBe(prima); });