From 92e71953578dd0fdaae88c4bb1804fd0ac2552d8 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Mon, 26 Oct 2026 09:57:35 +0100 Subject: [PATCH] Migration m36: il voto MVP solo tra presenti e dopo 2 ore voto_mvp_consentito() controlla partita, presenza (presente o ritardo) di votante e votato e l'attesa di 2 ore dall'inizio. Da applicare su Supabase con db push (non ancora fatto). Co-Authored-By: Claude Sonnet 5.5 --- ...6160000_m36_voto_mvp_presenti_e_orario.sql | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 supabase/migrations/20261026160000_m36_voto_mvp_presenti_e_orario.sql diff --git a/supabase/migrations/20261026160000_m36_voto_mvp_presenti_e_orario.sql b/supabase/migrations/20261026160000_m36_voto_mvp_presenti_e_orario.sql new file mode 100644 index 0000000..4d00778 --- /dev/null +++ b/supabase/migrations/20261026160000_m36_voto_mvp_presenti_e_orario.sql @@ -0,0 +1,48 @@ +-- M36 — Il voto MVP si controlla anche sulla presenza e sull'orario (DD-051) +-- +-- Fino alla M35 il database controllava solo convocati e allenatori (`evento_permette_voto`): che +-- votante e votato fossero presenti, e che fossero passate 2 ore dall'inizio, lo faceva solo l'app. +-- Ora la policy di INSERT su `mvp_voti` usa `voto_mvp_consentito()`, che aggiunge: +-- - l'evento è una partita; +-- - votante e votato hanno risposto `presente` o `ritardo`; +-- - sono passate 2 ore dall'inizio (stesso valore di ORE_ATTESA_MVP in src/lib/mvp-voti.ts). +-- +-- È una funzione nuova e non una modifica di `evento_permette_voto`, perché questa è usata anche da +-- pagelle e badge social, che non hanno queste regole. Gli admin restano fuori (policy M11): possono +-- ancora correggere. L'ora si legge in Europe/Rome; un `ora` vuoto o non valido vale mezzanotte, +-- come in `votoMvpAperto()`. + +CREATE OR REPLACE FUNCTION public.voto_mvp_consentito( + p_match_id text, p_votante_id text, p_votato_id text +) RETURNS boolean +LANGUAGE sql STABLE AS $$ + SELECT public.evento_permette_voto(p_match_id, p_votante_id, p_votato_id, false) + AND EXISTS ( + SELECT 1 FROM public.eventi_app e + WHERE e.id = p_match_id + AND e.tipo = 'partita' + AND ((e.data + CASE WHEN e.ora ~ '^([01][0-9]|2[0-3]):[0-5][0-9]$' + THEN e.ora::time ELSE time '00:00' END) + AT TIME ZONE 'Europe/Rome') + interval '2 hours' <= now() + ) + -- votante e votato sono diversi (mvp_no_autovoto): due righe = entrambi presenti + AND ( + SELECT count(DISTINCT r.giocatore_id) + FROM public.risposte_presenze r + WHERE r.evento_id = p_match_id + AND r.giocatore_id IN (p_votante_id, p_votato_id) + AND r.stato IN ('presente', 'ritardo') + ) = 2; +$$; + +DROP POLICY "Ognuno registra il proprio voto MVP" ON public.mvp_voti; + +CREATE POLICY "Ognuno registra il proprio voto MVP" ON public.mvp_voti + FOR INSERT TO authenticated + WITH CHECK ( + EXISTS ( + SELECT 1 FROM public.giocatori_squadra g + WHERE g.id = votante_id AND g.auth_user_id = auth.uid() + ) + AND public.voto_mvp_consentito(match_id, votante_id, votato_id) + );