longevity: anagrafica, unico punto di giunzione fra identita e clinica
Implementa il modulo che unisce i due database (identity e longevity) rispettando la separazione richiesta dal cliente: pseudonimizzazione dei dati clinici. Il modulo esporta tre funzioni: - creaCliente: registra un soggetto con il suo codice progressivo ISL-NNNN - codicePerUtente: risale dal user_id del sito al client_code - etaAllaData: calcola l'eta' al momento della misura (non la data di nascita) Un test verifica che nessun altro modulo apra entrambe le connessioni, preservando il firewall fra dati clinici e identita'. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// QUESTO è l'unico modulo autorizzato ad aprire insieme identity e longevity.
|
||||
// La separazione dei due database è la garanzia che chi legge i dati clinici non
|
||||
// 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';
|
||||
|
||||
export function creaCliente(
|
||||
identity: Database.Database,
|
||||
longevity: Database.Database,
|
||||
dati: {
|
||||
nome: string; cognome: string; sesso: 'M' | 'F';
|
||||
data_nascita?: string; email?: string; telefono?: string; user_id?: number;
|
||||
}
|
||||
): string {
|
||||
const ultimo = identity.prepare(
|
||||
`SELECT client_code FROM clienti ORDER BY client_code DESC LIMIT 1`
|
||||
).get() as { client_code: string } | undefined;
|
||||
const n = ultimo ? Number(ultimo.client_code.slice(4)) + 1 : 1;
|
||||
const code = `ISL-${String(n).padStart(4, '0')}`;
|
||||
|
||||
identity.prepare(
|
||||
`INSERT INTO clienti (client_code, user_id, nome, cognome, data_nascita, email, telefono)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)`
|
||||
).run(code, dati.user_id ?? null, dati.nome, dati.cognome,
|
||||
dati.data_nascita ?? null, dati.email ?? null, dati.telefono ?? null);
|
||||
|
||||
longevity.prepare(`INSERT INTO soggetti (client_code, sesso) VALUES (?, ?)`).run(code, dati.sesso);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
export function codicePerUtente(identity: Database.Database, userId: number): string | null {
|
||||
const r = identity.prepare(`SELECT client_code FROM clienti WHERE user_id = ?`).get(userId) as
|
||||
{ client_code: string } | undefined;
|
||||
return r?.client_code ?? null;
|
||||
}
|
||||
|
||||
/** 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);
|
||||
const d = new Date(alla);
|
||||
let eta = d.getFullYear() - n.getFullYear();
|
||||
const m = d.getMonth() - n.getMonth();
|
||||
if (m < 0 || (m === 0 && d.getDate() < n.getDate())) eta--;
|
||||
return eta;
|
||||
}
|
||||
Reference in New Issue
Block a user