longevity: atomicità compilazione questionario con transazione unica
This commit is contained in:
@@ -19,37 +19,40 @@ export function salvaCompilazione(
|
||||
liberi?: Record<string, string>;
|
||||
}
|
||||
): number {
|
||||
// Validare PRIMA di aprire la sessione: altrimenti un id sbagliato lascia
|
||||
// in giro una sessione vuota.
|
||||
// Validare PRIMA della transazione: se un test_id è sconosciuto, non apriamo
|
||||
// nemmeno una sessione. La validazione non è nel corpo della transazione.
|
||||
for (const id of Object.keys(input.risposte)) {
|
||||
if (!esisteTest(db, id)) throw new Error(`test_id non nel registro: ${id}`);
|
||||
}
|
||||
|
||||
const sessioneId = apriSessione(db, {
|
||||
client_code: input.client_code,
|
||||
data: input.data,
|
||||
tipo: 'questionario',
|
||||
eta_alla_data: input.eta,
|
||||
quest_version: QUEST_VERSION,
|
||||
});
|
||||
// Avvolgi le tre scritture (apertura sessione, registra misure, inserisci note)
|
||||
// in un'unica transazione: tutto o niente, senza tracce parziali su dati sanitari.
|
||||
const tx = db.transaction(() => {
|
||||
const sessioneId = apriSessione(db, {
|
||||
client_code: input.client_code,
|
||||
data: input.data,
|
||||
tipo: 'questionario',
|
||||
eta_alla_data: input.eta,
|
||||
quest_version: QUEST_VERSION,
|
||||
});
|
||||
|
||||
registraMisure(
|
||||
db, sessioneId, 'questionario',
|
||||
Object.entries(input.risposte).map(([test_id, valore_num]) => ({ test_id, valore_num }))
|
||||
);
|
||||
|
||||
if (input.liberi) {
|
||||
const ins = db.prepare(
|
||||
`INSERT INTO profilo_note (client_code, sessione_id, campo_id, testo) VALUES (?, ?, ?, ?)`
|
||||
registraMisure(
|
||||
db, sessioneId, 'questionario',
|
||||
Object.entries(input.risposte).map(([test_id, valore_num]) => ({ test_id, valore_num }))
|
||||
);
|
||||
const tx = db.transaction(() => {
|
||||
for (const [campo, testo] of Object.entries(input.liberi!)) {
|
||||
|
||||
if (input.liberi) {
|
||||
const ins = db.prepare(
|
||||
`INSERT INTO profilo_note (client_code, sessione_id, campo_id, testo) VALUES (?, ?, ?, ?)`
|
||||
);
|
||||
for (const [campo, testo] of Object.entries(input.liberi)) {
|
||||
if (testo.trim() === '') continue;
|
||||
ins.run(input.client_code, sessioneId, campo, testo);
|
||||
}
|
||||
});
|
||||
tx();
|
||||
}
|
||||
}
|
||||
|
||||
return sessioneId;
|
||||
return sessioneId;
|
||||
});
|
||||
|
||||
return tx();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user