longevity: verifica misure fuori range in scheda cliente, link a crea accesso

Scheda cliente ([code].astro): sezione "Misure da verificare" da
misureDaVerificare (id, range) al posto di misureFuoriRange (nessun id,
nessuna azione); ogni riga ha due form verso /api/longevity/gestionale/verifica
(conferma/scarta), messaggio dopo la decisione, e link "Crea accesso al
referto" quando il cliente non ha ancora un accesso.

gestionale.ts: rimossa misureFuoriRange (e il tipo MisuraFuoriRange), sostituita
ovunque da misureDaVerificare (misure.ts), l'unica con id e range utile alle
azioni. accesso.astro: link "Torna alla scheda" in tutti gli stati.

Refs #7
Refs #8

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 13:11:38 +00:00
parent 6cbb205064
commit 2c9a74f849
5 changed files with 67 additions and 37 deletions
@@ -8,7 +8,8 @@ import Radar from '../../../../components/longevity/Radar';
import MacroScore from '../../../../components/longevity/MacroScore.astro';
import { getLongevityDb } from '../../../../lib/longevity/db';
import { clienteDaCodice, etaDelCliente } from '../../../../lib/longevity/anagrafica';
import { sessioniDi, misureFuoriRange } from '../../../../lib/longevity/gestionale';
import { sessioniDi } from '../../../../lib/longevity/gestionale';
import { misureDaVerificare } from '../../../../lib/longevity/misure';
import { refertoDi, ultimaSessioneDi } from '../../../../lib/longevity/vista';
import { formattaNumero } from '../../../../lib/longevity/formato';
@@ -22,7 +23,7 @@ const db = getLongevityDb();
const oggi = new Date().toISOString().slice(0, 10);
const eta = etaDelCliente(cliente.client_code, oggi);
const sessioni = sessioniDi(db, cliente.client_code);
const fuoriRange = misureFuoriRange(db, cliente.client_code);
const daVerificare = misureDaVerificare(db, cliente.client_code);
const ultimaId = ultimaSessioneDi(db, cliente.client_code);
const referto = ultimaId !== null ? refertoDi(db, ultimaId) : null;
@@ -37,6 +38,13 @@ const params = Astro.url.searchParams;
const salvato = params.get('salvato');
const fuoriCount = params.get('fuori');
const errore = params.get('errore');
const verificata = params.get('verificata');
const MESSAGGIO_VERIFICA: Record<'confermata' | 'scartata', string> = {
confermata: 'Misura confermata: punteggi ricalcolati.',
scartata: 'Misura scartata.',
};
const messaggioVerifica =
verificata === 'confermata' || verificata === 'scartata' ? MESSAGGIO_VERIFICA[verificata] : null;
---
<Longevity
title={`${cliente.cognome} ${cliente.nome}`}
@@ -51,11 +59,17 @@ const errore = params.get('errore');
accesso {cliente.ha_accesso ? 'attivo' : 'non ancora attivato'}
</p>
</div>
<a class="lg-btn" href={`/longevity/gestionale/cliente/${cliente.client_code}/checkup`}>Nuovo check-up</a>
<div>
{!cliente.ha_accesso && (
<a class="lg-btn" href={`/longevity/gestionale/cliente/${cliente.client_code}/accesso`}>Crea accesso al referto</a>
)}
<a class="lg-btn" href={`/longevity/gestionale/cliente/${cliente.client_code}/checkup`}>Nuovo check-up</a>
</div>
</div>
{errore && <p class="lg-form__errore">{errore}</p>}
{salvato && <p class="lg-card">Check-up salvato (sessione #{salvato}).</p>}
{messaggioVerifica && <p class="lg-card">{messaggioVerifica}</p>}
{fuoriCount && (
<p class="lg-misura--fuori-range">
{fuoriCount} {Number(fuoriCount) === 1 ? 'misura è' : 'misure sono'} fuori dal range di
@@ -129,18 +143,33 @@ const errore = params.get('errore');
)}
</div>
{fuoriRange.length > 0 && (
{daVerificare.length > 0 && (
<div class="lg-card">
<p class="lg-score__label">Misure fuori range</p>
<p class="lg-score__label">Misure da verificare</p>
<p class="lg-muted">
Una misura confermata è un dato vero: entra nei punteggi e ricalcola quella sessione e
le successive. Una scartata è un errore di strumento o protocollo: resta fuori per sempre.
</p>
<table class="lg-table">
<thead><tr><th>Data</th><th>Test</th><th>Valore</th></tr></thead>
<thead><tr><th>Data</th><th>Test</th><th>Valore</th><th>Range atteso</th><th>Decisione</th></tr></thead>
<tbody>
{fuoriRange.map((m) => (
{daVerificare.map((m) => (
<tr>
<td>{formattaData(m.data)}</td>
<td>{m.etichetta}</td>
<td class="lg-misura--fuori-range">
{m.valore !== null ? formattaNumero(m.valore) : '—'}{m.unita ? ` ${m.unita}` : ''}
{m.valore_num !== null ? formattaNumero(m.valore_num) : '—'}{m.unita ? ` ${m.unita}` : ''}
</td>
<td>{m.range_min ?? '—'}–{m.range_max ?? '—'}</td>
<td>
<form method="post" action="/api/longevity/gestionale/verifica">
<input type="hidden" name="misura_id" value={m.id} />
<button type="submit" name="esito" value="confermata">Conferma: il dato è vero</button>
</form>
<form method="post" action="/api/longevity/gestionale/verifica">
<input type="hidden" name="misura_id" value={m.id} />
<button type="submit" name="esito" value="scartata">Scarta: è un errore</button>
</form>
</td>
</tr>
))}