spec: i sei punti emersi costruendo lo strato dati, piu' la curva x10_inv che mancava

This commit is contained in:
2026-08-21 20:34:49 +02:00
parent 763e5611e6
commit 52ff28b69d
+50 -1
View File
@@ -145,7 +145,7 @@ CREATE TABLE registro_test (
etichetta TEXT NOT NULL, etichetta TEXT NOT NULL,
unita TEXT, unita TEXT,
tipo_valore TEXT NOT NULL CHECK (tipo_valore IN ('num','txt')), tipo_valore TEXT NOT NULL CHECK (tipo_valore IN ('num','txt')),
curva TEXT, -- 'bell','lin_dec','inc_plateau','x10','decstep','incstep' curva TEXT, -- 'bell','lin_dec','inc_plateau','x10','x10_inv','decstep','incstep'
params TEXT, -- JSON dei parametri della curva params TEXT, -- JSON dei parametri della curva
asse TEXT, -- uno dei 7 assi; NULL = non entra nello score asse TEXT, -- uno dei 7 assi; NULL = non entra nello score
sotto_dominio TEXT, -- a QUALE sotto-dominio contribuisce; il peso sta in `pesi` sotto_dominio TEXT, -- a QUALE sotto-dominio contribuisce; il peso sta in `pesi`
@@ -384,6 +384,55 @@ capita.
confermata. L'HRV entra nel motore come passthrough, quindi senza quel canale confermata. L'HRV entra nel motore come passthrough, quindi senza quel canale
va inserito a mano. va inserito a mano.
## 12. Cosa l'implementazione ha scoperto — da chiudere prima del motore
Lo strato dati è stato costruito il 21/08 (ramo `feat/longevity`, 19 commit, 241 test).
Costruirlo ha fatto emergere sei punti che questo documento non aveva previsto o su cui
si contraddiceva. **Nessuno è bloccante per lo strato dati; tutti lo diventano per il
motore di calcolo.**
1. **La conferma delle misure fuori range non ha dove stare.** La §9 dice che una misura
marcata «non entra nello score finché qualcuno non la conferma», ma lo schema della §5
non prevede nessuna colonna che registri quella conferma. Le due sezioni si
contraddicono: va aggiunta la colonna o riscritta la regola.
2. **`registraMisure` valida l'esistenza del test, non il valore.** Oggi accetta una
misura senza nessun valore, un testo dove il registro dichiara un numero, e un `NaN`
(che viene scritto come nullo e **non** marcato fuori range, perché ogni confronto con
NaN è falso). Una riga vuota conta come «test presente» ai fini della copertura del 40%.
3. **`seedRegistro` rilanciato disfa il registro.** Usa `INSERT OR REPLACE` e riazzera
`attivo_a` e le note: disattivare un test e poi rilanciare il seed lo riattiva. È
esattamente l'opposto della promessa della §5, dove disattivare un test è valorizzare
`attivo_a`.
4. **`MODEL_VERSION` non esiste.** `QUEST_VERSION` sta in `questionario.ts`; la gemella
che versiona curve e pesi non è dichiarata da nessuna parte, e `seedPesi` la riceve
come parametro che solo i test valorizzano. Finché non esiste, il congelamento del §6
ha metà del suo significato.
5. **La soglia del 40% è una costante di codice**, non un parametro nel registro come
chiede la §11.3 — e nessuno la consuma ancora.
6. **Registro e pesi sono disallineati per costruzione.** Il registro contiene oggi i 20
campi del questionario; i pesi citano handgrip, vo2max, plank, flamingo — sotto-domini
che nessun test ancora alimenta. Con i dati attuali sei assi su sette resterebbero
permanentemente «insufficiente». È atteso, perché i test fisici arrivano col piano degli
import, ma va saputo: il primo che lancia il motore lo legge come un difetto.
⚠️ **Una trappola già armata per il piano delle API.** Nelle regole di accesso, tutto ciò
che sta sotto `/api/longevity/` e non sotto `/api/longevity/gestionale/` è raggiungibile da
**ogni** cliente. Oggi è innocuo perché non esiste nessun endpoint, ma significa che la
scelta dei nomi delle rotte è una questione di sicurezza, non di stile: un domani
`/api/longevity/clienti` sarebbe l'elenco di tutti, aperto a tutti.
⚠️ **Due limiti noti dell'anagrafica**, accettati con cognizione: se fallisse anche la
cancellazione compensativa su identity, l'errore diagnostico verrebbe mascherato e
resterebbe un cliente senza pendant clinico; e i codici sono ordinati come stringhe,
quindi oltre `ISL-9999` l'ordinamento sbaglia e un codice potrebbe essere riusato.
📌 **Da dire a Nicola, non ancora detto:** il plank pesa su due assi — `core` in *Forza &
Struttura* (0.15) e `plank` in *Stabilità & Mobilità* (0.20). È lo stesso doppio conteggio
che lui dichiara per l'handgrip nella Fitness Age, ma questo non è dichiarato da nessuna
parte.
---
## 12. Decisioni prese, e da chi ## 12. Decisioni prese, e da chi
| Decisione | Chi | Quando | | Decisione | Chi | Quando |