2026-08-06 08:36:47 +02:00
|
|
|
import { createFileRoute } from "@tanstack/react-router";
|
2026-09-06 12:15:39 +02:00
|
|
|
import { z } from "zod";
|
|
|
|
|
import { richiediAdmin } from "@/lib/auth-route.server";
|
2026-09-03 10:16:52 +02:00
|
|
|
import { nomeCompleto } from "@/lib/giocatori-squadra";
|
|
|
|
|
import { leggiGiocatoriSquadra } from "@/lib/giocatori-squadra.server";
|
2026-09-06 12:15:39 +02:00
|
|
|
import { avvisiPalloniEvento, completaTurni } from "@/lib/palloni-core";
|
2026-08-06 08:36:47 +02:00
|
|
|
import { inviaPush } from "@/lib/webpush.server";
|
|
|
|
|
import { leggiEventi } from "@/lib/eventi.server";
|
|
|
|
|
|
2026-09-06 12:15:39 +02:00
|
|
|
const schema = z.object({ eventoId: z.string().min(1).max(50) });
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Promemoria del turno palloni per un evento: lo fa partire un admin dalla pagina
|
2026-09-06 14:24:07 +02:00
|
|
|
* dell'evento (DD-025). Il testo viaggia cifrato dentro la push.
|
2026-09-06 12:15:39 +02:00
|
|
|
*/
|
2026-08-06 08:36:47 +02:00
|
|
|
export const Route = createFileRoute("/api/public/promemoria-palloni")({
|
|
|
|
|
server: {
|
|
|
|
|
handlers: {
|
2026-09-06 12:05:39 +02:00
|
|
|
POST: async ({ request }) => {
|
2026-09-06 12:15:39 +02:00
|
|
|
const negato = await richiediAdmin(request);
|
2026-09-06 12:05:39 +02:00
|
|
|
if (negato) return negato;
|
|
|
|
|
|
2026-09-06 12:15:39 +02:00
|
|
|
const parsed = schema.safeParse(await request.json());
|
|
|
|
|
if (!parsed.success) return new Response("Dati non validi", { status: 400 });
|
|
|
|
|
|
|
|
|
|
const eventi = await leggiEventi();
|
|
|
|
|
const evento = eventi.find((e) => e.id === parsed.data.eventoId);
|
|
|
|
|
if (!evento) return new Response("Evento non trovato", { status: 404 });
|
|
|
|
|
|
2026-08-06 08:36:47 +02:00
|
|
|
const { supabaseAdmin } = await import("@/integrations/supabase/client.server");
|
|
|
|
|
|
|
|
|
|
const { data: righe } = await supabaseAdmin
|
|
|
|
|
.from("turni_palloni")
|
|
|
|
|
.select("evento_id, giocatore_id");
|
|
|
|
|
const salvati: Record<string, string> = {};
|
|
|
|
|
for (const riga of righe ?? []) salvati[riga.evento_id] = riga.giocatore_id;
|
2026-09-06 12:15:39 +02:00
|
|
|
|
2026-09-03 10:16:52 +02:00
|
|
|
const squadra = await leggiGiocatoriSquadra();
|
|
|
|
|
const rosa = squadra
|
|
|
|
|
.filter((g) => g.attivo)
|
|
|
|
|
.map((g) => ({ id: g.id, nome: nomeCompleto(g) }));
|
|
|
|
|
const turni = completaTurni(salvati, eventi, rosa);
|
2026-08-06 08:36:47 +02:00
|
|
|
|
2026-09-06 12:15:39 +02:00
|
|
|
const avvisi = avvisiPalloniEvento(turni, eventi, evento.id);
|
|
|
|
|
if (avvisi.length === 0) return Response.json({ inviate: 0, destinatari: 0 });
|
2026-08-06 08:36:47 +02:00
|
|
|
|
|
|
|
|
const { data: iscrizioni } = await supabaseAdmin
|
|
|
|
|
.from("push_subscriptions")
|
2026-09-06 14:24:07 +02:00
|
|
|
.select("endpoint, giocatore_id, p256dh, auth")
|
2026-09-06 12:15:39 +02:00
|
|
|
.in(
|
|
|
|
|
"giocatore_id",
|
|
|
|
|
avvisi.map((a) => a.giocatoreId),
|
|
|
|
|
);
|
2026-08-06 08:36:47 +02:00
|
|
|
|
|
|
|
|
let inviate = 0;
|
|
|
|
|
for (const iscrizione of iscrizioni ?? []) {
|
2026-09-06 12:15:39 +02:00
|
|
|
const avviso = avvisi.find((a) => a.giocatoreId === iscrizione.giocatore_id);
|
|
|
|
|
if (!avviso) continue;
|
2026-08-06 08:36:47 +02:00
|
|
|
try {
|
2026-09-06 14:24:07 +02:00
|
|
|
const { stato } = await inviaPush(iscrizione, avviso.titolo, avviso.testo);
|
2026-08-06 08:36:47 +02:00
|
|
|
if (stato === 404 || stato === 410) {
|
|
|
|
|
await supabaseAdmin
|
|
|
|
|
.from("push_subscriptions")
|
|
|
|
|
.delete()
|
|
|
|
|
.eq("endpoint", iscrizione.endpoint);
|
|
|
|
|
} else if (stato >= 200 && stato < 300) {
|
|
|
|
|
inviate += 1;
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("promemoria-palloni", error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-06 12:15:39 +02:00
|
|
|
return Response.json({ inviate, destinatari: (iscrizioni ?? []).length });
|
2026-08-06 08:36:47 +02:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-09-01 09:39:09 +02:00
|
|
|
});
|