longevity: la connessione a identity non e' piu' raggiungibile fuori da anagrafica.ts

Il revisore ha dimostrato che il test anti-giunzione si aggira senza malizia:
tre file (uno riesporta la connessione a identity, uno quella a longevity, un
terzo le importa da entrambi e le usa insieme) e nessuno dei tre contiene
singolarmente le due parole cercate. Un controllo testuale file-per-file non
puo' vedere una giunzione che attraversa piu' file - quindi la risposta non
e' un test piu' furbo, e' rendere la cosa impossibile invece di sorvegliarla.

- db.ts: rimossa l'esportazione di getIdentityDb. Resta solo getLongevityDb
  (il database senza nomi, puo' usarlo chiunque) e createIdentityDb (serve ai
  test per aprire database in memoria - li' la giunzione e' voluta ed
  evidente, il problema era il singleton condiviso, non la fabbrica).
- anagrafica.ts: getIdentityDb torna dentro, privata (non esportata) e usata
  solo da codicePerUtenteLoggato. Verificato che il bypass a tre file del
  revisore ora fallisce gia' a tsc --noEmit ('has no exported member named
  getIdentityDb'), non solo a un test che lo sorveglia.
- tests/longevity/anagrafica.test.ts: il test anti-giunzione resta come rete
  secondaria, con un commento che dichiara onestamente cosa non vede (una
  giunzione via re-export su piu' file) invece di promettere una garanzia che
  non mantiene.

Due correzioni minori dalla stessa revisione:
- api/longevity/questionario.ts: salvaDalForm (via salvaCompilazione) lancia
  se una risposta porta un test_id sconosciuto al registro; ora e' avvolta in
  try/catch e risponde 400 pulito invece di un 500 generico, come gia' fa
  src/pages/api/contact.ts per l'invio email.
- components/longevity/Questionario.tsx: un campo con tipo_valore='txt' nel
  registro ora rende un input testuale (non piu' sempre "number"), e in
  invio i campi testuali non vengono convertiti in NaN e scartati in
  silenzio - restano fuori esplicitamente, con un commento che dice perche'.
This commit is contained in:
2026-08-22 14:12:43 +02:00
parent f0629db3c4
commit 8c980750c0
5 changed files with 75 additions and 28 deletions
+17 -9
View File
@@ -88,15 +88,23 @@ describe('anagrafica pseudonimizzata', () => {
expect(id.prepare(`SELECT * FROM clienti WHERE nome = 'Errato'`).get()).toBeUndefined();
});
it('nessun file in src/ (escluso anagrafica.ts e db.ts) fa riferimento sia a identity sia a longevity', () => {
// Non cerchiamo due nomi di funzione precisi (createIdentityDb/createLongevityDb): un
// domani qualcuno aggiunge getIdentityDb, o un terzo accessore con un nome diverso, e
// l'elenco invecchia senza che nessuno se ne accorga (è già successo: getIdentityDb e
// getLongevityDb sono nati DOPO questo test e sono passati indisturbati). Il verso
// giusto è strutturale: qualunque accesso alle due connessioni passa comunque per una
// funzione esportata da db.ts il cui nome contiene "Identity" o "Longevity" — quindi
// basta cercare quei due riferimenti letterali, in QUALUNQUE forma compaiano, e
// segnalare i file che li hanno tutti e due.
it('rete secondaria: nessun file in src/ (escluso anagrafica.ts e db.ts) fa riferimento sia a identity sia a longevity', () => {
// ⚠️ QUESTO TEST NON È LA GARANZIA. La garanzia vera è che getIdentityDb non è più
// esportata da db.ts (vive privata dentro anagrafica.ts): non esiste, da nessuna
// parte del codice fuori da lì, un nome da importare per ottenere quella connessione.
// Un controllo testuale come questo non può bastare da solo — è stato dimostrato:
// tre file, uno che riesporta la connessione a identity, uno che riesporta quella a
// longevity, un terzo che importa da entrambi e le usa insieme, e NESSUNO dei tre
// contiene singolarmente le due parole. Un controllo file-per-file non vede una
// giunzione che attraversa più file, e non c'è formulazione di questo test che lo
// possa vedere: la risposta era rendere la cosa impossibile, non sorvegliarla meglio.
// Questo test resta come rete secondaria — cattura il caso comune (una giunzione
// dentro un solo file) e protegge contro un domani in cui getIdentityDb tornasse
// esportata per errore — non come prova che la giunzione non possa esistere.
// Cerca i due riferimenti letterali "Identity"/"Longevity" (con l'iniziale maiuscola,
// come compaiono in qualunque accessore camelCase) invece di un elenco chiuso di nomi:
// un elenco di nomi vietati invecchia (è già successo qui: getIdentityDb/getLongevityDb
// sono nati dopo la prima versione di questo test e sono passati indisturbati).
const srcDir = join(process.cwd(), 'src');
const colpevoli: string[] = [];