longevity: l'endpoint del questionario apre solo longevity, e il test anti-giunzione diventa strutturale

L'endpoint /api/longevity/questionario apriva anche identity (getIdentityDb)
per risolvere il client_code, violando la garanzia della spec (§4): un solo
modulo, anagrafica.ts, tiene insieme le due connessioni. La logica di
giunzione era gia' al posto giusto (chiamava codicePerUtente, che sta in
anagrafica.ts) ma l'APERTURA delle connessioni no.

- anagrafica.ts: nuova codicePerUtenteLoggato(userId), apre lei stessa
  identity via getIdentityDb() (e' il modulo autorizzato) e delega a
  codicePerUtente. L'endpoint chiama solo questa: apre esclusivamente
  longevity, per salvare.
- tests/longevity/anagrafica.test.ts: il test anti-giunzione cercava due nomi
  letterali (createIdentityDb/createLongevityDb) e non vedeva getIdentityDb/
  getLongevityDb, nati dopo di lui - la stessa lezione del semaforo nel Task 1
  (proteggere il nome invece della cosa). Ora e' strutturale: segnala
  qualunque file (esclusi anagrafica.ts e db.ts) che contenga sia "Identity"
  sia "Longevity", in qualunque forma. Verificato con un file finto sotto
  src/ che apriva entrambe con i nomi nuovi: il test diventa rosso, poi
  torna verde dopo la cancellazione.
This commit is contained in:
2026-08-22 14:01:33 +02:00
parent f5ca841d92
commit f0629db3c4
3 changed files with 28 additions and 6 deletions
+12
View File
@@ -4,6 +4,7 @@
// risalga alla persona (richiesta del cliente, 21/08): un secondo punto di giunzione
// la annullerebbe in silenzio. Un test in tests/longevity/anagrafica.test.ts lo verifica.
import type Database from 'better-sqlite3';
import { getIdentityDb } from './db';
/**
* Il prossimo codice libero: il massimo fra quelli già usati in identity.clienti E in
@@ -62,6 +63,17 @@ export function codicePerUtente(identity: Database.Database, userId: number): st
return r?.client_code ?? null;
}
/**
* Il codice cliente a partire dall'utente di sessione del sito: apre lei stessa la
* connessione a identity (getIdentityDb), perché QUESTO è il modulo autorizzato a farlo.
* Un endpoint che deve solo sapere "chi è" chiama questa funzione e non ha mai bisogno
* di aprire identity da sé — riceve una stringa, mai una connessione che potrebbe
* incrociarsi con quella di longevity nello stesso file.
*/
export function codicePerUtenteLoggato(userId: number): string | null {
return codicePerUtente(getIdentityDb(), userId);
}
/** L'eta' al momento della misura: è ciò che serve al motore, e non è un quasi-identificatore. */
export function etaAllaData(dataNascita: string, alla: string): number {
const n = new Date(dataNascita);
+6 -4
View File
@@ -1,6 +1,6 @@
import type { APIRoute } from 'astro';
import { getIdentityDb, getLongevityDb } from '../../../lib/longevity/db';
import { codicePerUtente } from '../../../lib/longevity/anagrafica';
import { getLongevityDb } from '../../../lib/longevity/db';
import { codicePerUtenteLoggato } from '../../../lib/longevity/anagrafica';
import { salvaDalForm } from '../../../lib/longevity/vista';
import { CAMPI_LIBERI } from '../../../lib/longevity/questionario';
@@ -11,8 +11,10 @@ const json = (status: number, body: object) =>
export const POST: APIRoute = async ({ request, locals }) => {
// Il codice cliente si ricava SEMPRE dalla sessione dell'utente loggato (spec §8), mai dal
// corpo della richiesta: qui infatti il corpo non viene mai letto per questo campo.
const codice = codicePerUtente(getIdentityDb(), locals.user!.id);
// corpo della richiesta: qui infatti il corpo non viene mai letto per questo campo. La
// risoluzione passa da anagrafica.ts (l'unico modulo autorizzato a toccare quella
// connessione): questo file apre solo longevity, per salvare.
const codice = codicePerUtenteLoggato(locals.user!.id);
if (!codice) return json(403, { error: 'Nessun fascicolo cliente associato a questo utente.' });
let data: Record<string, unknown>;