Verifica che gli upsert dell'app scrivano sulla riga giusta.

Ogni salvataggio di CrAPP è un upsert con un onConflict scritto a mano nei hook
di src/lib/. Se quella chiave non corrisponde al vincolo UNIQUE della tabella
non arriva nessun errore: il database sovrascrive la riga sbagliata, e il difetto
si vede settimane dopo in una media che non torna. Nessuna delle sedici
scritture era mai stata eseguita da un test.

test/integration/scritture.test.ts ripete le stesse chiamate dei hook contro il
database locale e conta cosa resta nella tabella. Le due regole opposte che
nessuno verificava: le pagelle tengono un voto per ogni votato — se il conflitto
fosse su (match, votante) ogni voto cancellerebbe il precedente — mentre l'MVP
ne tiene uno solo per votante e partita. Più badge social per categoria, cacche,
turni palloni, risposte presenze (con l'istante che alimenta la serie di
conferme) e lo stato jsonb dello scout, che viene sostituito e non fuso. In più
i due CHECK su cui l'app conta: niente autovoto, voto fra 1 e 10.

Le righe usano il prefisso test-scritture e spariscono in un finally. La lettura
delle credenziali locali passa da test/helpers/locale.ts, ora che la usano due
file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-06 11:41:26 +02:00
co-authored by Claude Opus 5
parent 0addafa76f
commit fe0c938358
4 changed files with 326 additions and 32 deletions
+1 -19
View File
@@ -13,27 +13,9 @@
* reclamato in `giocatori_squadra` e il telefono del profilo g1.
*/
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { statoLocale } from "../helpers/locale";
import { prova, riepilogo, salta } from "../helpers/prova";
/** Credenziali dello stack locale. `null` se non è in esecuzione. */
function statoLocale(): { url: string; anon: string; servizio: string } | null {
const esito = spawnSync("npx", ["supabase", "status", "-o", "env"], {
encoding: "utf8",
timeout: 60_000,
});
if (esito.status !== 0) return null;
const leggi = (nome: string) =>
new RegExp(`^${nome}="?([^"\\n]+)"?$`, "m").exec(esito.stdout)?.[1] ?? "";
const url = leggi("API_URL");
const anon = leggi("ANON_KEY");
const servizio = leggi("SERVICE_ROLE_KEY");
if (!url || !anon || !servizio) return null;
// Cintura di sicurezza: questo file scrive, e su un database non locale non deve girare.
if (!/^https?:\/\/(127\.0\.0\.1|localhost)/.test(url)) return null;
return { url, anon, servizio };
}
const locale = statoLocale();
if (!locale) {