Introduce PocketBase come sostituto di Supabase solo per l'ambiente di sviluppo locale (docs/PORTABILITA.md): docker-compose.pocketbase.yml, schema iniziale in pocketbase/pb_migrations/ (collection equivalenti alle tabelle Supabase, con le stesse API rule dove esprimibili) e la logica procedurale che in Postgres viveva in trigger/funzioni riscritta come hook JS in pocketbase/pb_hooks/ (claim slot giocatore, blocco autovoto, convocati/pagelle chiuse, immutabilità di risposto_il). Il superuser e il provider Google OAuth2 si ricreano da soli a ogni avvio da variabili d'ambiente (script scripts/pocketbase-reset.sh), così un reset non richiede passaggi manuali da dashboard. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
138 lines
5.2 KiB
JavaScript
138 lines
5.2 KiB
JavaScript
/// <reference path="../pb_data/types.d.ts" />
|
|
//
|
|
// Equivalente di evento_permette_voto() + i CHECK "no autovoto" (M12/M13): applicato a
|
|
// mvp_voti, pagelle_voti, badge_social_voti su create/update. Gli admin non hanno questi
|
|
// vincoli (possono correggere un voto anche fuori convocazione/dopo la chiusura pagelle).
|
|
// convocati vuoto = "tutta la rosa" (stessa convenzione di convocatiEvento() in eventi.ts).
|
|
//
|
|
// La validazione è ripetuta in ciascun callback (non estratta in una funzione condivisa a
|
|
// livello di file): ogni hook di PocketBase viene eseguito nel proprio contesto JS isolato,
|
|
// che non vede le funzioni dichiarate fuori dal callback stesso (verificato empiricamente:
|
|
// una funzione condivisa causa "ReferenceError: ... is not defined" a runtime).
|
|
|
|
onRecordCreateRequest((e) => {
|
|
const isAdmin = e.hasSuperuserAuth() || (e.auth && e.auth.get("role") === "admin");
|
|
if (!isAdmin) {
|
|
const votanteId = e.record.get("votante");
|
|
const votatoId = e.record.get("votato");
|
|
if (votanteId === votatoId) {
|
|
throw new BadRequestError("Non puoi votare te stesso");
|
|
}
|
|
const evento = e.app.findRecordById("eventi_app", e.record.get("evento"));
|
|
const convocati = evento.get("convocati") || [];
|
|
if (
|
|
convocati.length > 0 &&
|
|
(convocati.indexOf(votanteId) === -1 || convocati.indexOf(votatoId) === -1)
|
|
) {
|
|
throw new BadRequestError("Votante e votato devono essere convocati all'evento");
|
|
}
|
|
}
|
|
e.next();
|
|
}, "mvp_voti");
|
|
|
|
onRecordUpdateRequest((e) => {
|
|
const isAdmin = e.hasSuperuserAuth() || (e.auth && e.auth.get("role") === "admin");
|
|
if (!isAdmin) {
|
|
const votanteId = e.record.get("votante");
|
|
const votatoId = e.record.get("votato");
|
|
if (votanteId === votatoId) {
|
|
throw new BadRequestError("Non puoi votare te stesso");
|
|
}
|
|
const evento = e.app.findRecordById("eventi_app", e.record.get("evento"));
|
|
const convocati = evento.get("convocati") || [];
|
|
if (
|
|
convocati.length > 0 &&
|
|
(convocati.indexOf(votanteId) === -1 || convocati.indexOf(votatoId) === -1)
|
|
) {
|
|
throw new BadRequestError("Votante e votato devono essere convocati all'evento");
|
|
}
|
|
}
|
|
e.next();
|
|
}, "mvp_voti");
|
|
|
|
onRecordCreateRequest((e) => {
|
|
const isAdmin = e.hasSuperuserAuth() || (e.auth && e.auth.get("role") === "admin");
|
|
if (!isAdmin) {
|
|
const votanteId = e.record.get("votante");
|
|
const votatoId = e.record.get("votato");
|
|
if (votanteId === votatoId) {
|
|
throw new BadRequestError("Non puoi votare te stesso");
|
|
}
|
|
const evento = e.app.findRecordById("eventi_app", e.record.get("evento"));
|
|
const convocati = evento.get("convocati") || [];
|
|
if (
|
|
convocati.length > 0 &&
|
|
(convocati.indexOf(votanteId) === -1 || convocati.indexOf(votatoId) === -1)
|
|
) {
|
|
throw new BadRequestError("Votante e votato devono essere convocati all'evento");
|
|
}
|
|
if (evento.get("pagelle_chiuse")) {
|
|
throw new BadRequestError("Le pagelle per questo evento sono chiuse");
|
|
}
|
|
}
|
|
e.next();
|
|
}, "pagelle_voti");
|
|
|
|
onRecordUpdateRequest((e) => {
|
|
const isAdmin = e.hasSuperuserAuth() || (e.auth && e.auth.get("role") === "admin");
|
|
if (!isAdmin) {
|
|
const votanteId = e.record.get("votante");
|
|
const votatoId = e.record.get("votato");
|
|
if (votanteId === votatoId) {
|
|
throw new BadRequestError("Non puoi votare te stesso");
|
|
}
|
|
const evento = e.app.findRecordById("eventi_app", e.record.get("evento"));
|
|
const convocati = evento.get("convocati") || [];
|
|
if (
|
|
convocati.length > 0 &&
|
|
(convocati.indexOf(votanteId) === -1 || convocati.indexOf(votatoId) === -1)
|
|
) {
|
|
throw new BadRequestError("Votante e votato devono essere convocati all'evento");
|
|
}
|
|
if (evento.get("pagelle_chiuse")) {
|
|
throw new BadRequestError("Le pagelle per questo evento sono chiuse");
|
|
}
|
|
}
|
|
e.next();
|
|
}, "pagelle_voti");
|
|
|
|
onRecordCreateRequest((e) => {
|
|
const isAdmin = e.hasSuperuserAuth() || (e.auth && e.auth.get("role") === "admin");
|
|
if (!isAdmin) {
|
|
const votanteId = e.record.get("votante");
|
|
const votatoId = e.record.get("votato");
|
|
if (votanteId === votatoId) {
|
|
throw new BadRequestError("Non puoi votare te stesso");
|
|
}
|
|
const evento = e.app.findRecordById("eventi_app", e.record.get("evento"));
|
|
const convocati = evento.get("convocati") || [];
|
|
if (
|
|
convocati.length > 0 &&
|
|
(convocati.indexOf(votanteId) === -1 || convocati.indexOf(votatoId) === -1)
|
|
) {
|
|
throw new BadRequestError("Votante e votato devono essere convocati all'evento");
|
|
}
|
|
}
|
|
e.next();
|
|
}, "badge_social_voti");
|
|
|
|
onRecordUpdateRequest((e) => {
|
|
const isAdmin = e.hasSuperuserAuth() || (e.auth && e.auth.get("role") === "admin");
|
|
if (!isAdmin) {
|
|
const votanteId = e.record.get("votante");
|
|
const votatoId = e.record.get("votato");
|
|
if (votanteId === votatoId) {
|
|
throw new BadRequestError("Non puoi votare te stesso");
|
|
}
|
|
const evento = e.app.findRecordById("eventi_app", e.record.get("evento"));
|
|
const convocati = evento.get("convocati") || [];
|
|
if (
|
|
convocati.length > 0 &&
|
|
(convocati.indexOf(votanteId) === -1 || convocati.indexOf(votatoId) === -1)
|
|
) {
|
|
throw new BadRequestError("Votante e votato devono essere convocati all'evento");
|
|
}
|
|
}
|
|
e.next();
|
|
}, "badge_social_voti");
|