75 lines
2.4 KiB
TypeScript
75 lines
2.4 KiB
TypeScript
import { createFileRoute } from "@tanstack/react-router";
|
|||
|
|
import { z } from "zod";
|
||
|
|
|
||
|
|
const schema = z.object({
|
||
|
|
id: z.string().min(1).max(50),
|
||
|
|
data: z.string().min(1).max(20),
|
||
|
|
avversario: z.string().min(1).max(80),
|
||
|
|
casa: z.boolean(),
|
||
|
|
setNostri: z.number().int().min(0),
|
||
|
|
setLoro: z.number().int().min(0),
|
||
|
|
parziali: z.array(z.tuple([z.number().int(), z.number().int()])),
|
||
|
|
mvp: z.string().max(80),
|
||
|
|
azioni: z.array(
|
||
|
|
z.object({
|
||
|
|
id: z.string(),
|
||
|
|
tipo: z.enum(["attacco", "ace", "muro", "errore", "punto_avv", "errore_avv"]),
|
||
|
|
giocatoreId: z.string().optional(),
|
||
|
|
set: z.number().int(),
|
||
|
|
ts: z.number(),
|
||
|
|
}),
|
||
|
|
),
|
||
|
|
});
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Proxy verso Strapi per il risultato finale di una partita scoutata: additivo, il localStorage
|
||
|
|
* del device resta la fonte usata da useRosa/giocatoriConScout. Best-effort: nessun retry, nessun
|
||
|
|
* upsert (un doppio invio crea al più una entry doppia in Strapi, da cancellare a mano).
|
||
|
|
*/
|
||
|
|
export const Route = createFileRoute("/api/public/scout-finale")({
|
||
|
|
server: {
|
||
|
|
handlers: {
|
||
|
|
POST: async ({ request }) => {
|
||
|
|
const parsed = schema.safeParse(await request.json());
|
||
|
|
if (!parsed.success) return new Response("Dati non validi", { status: 400 });
|
||
|
|
|
||
|
|
const strapiUrl = process.env["VITE_STRAPI_URL"];
|
||
|
|
const token = process.env["STRAPI_WRITE_TOKEN"];
|
||
|
|
if (!strapiUrl || !token) {
|
||
|
|
console.error("scout-finale: STRAPI_URL o STRAPI_WRITE_TOKEN mancanti");
|
||
|
|
return new Response("CMS non configurato", { status: 503 });
|
||
|
|
}
|
||
|
|
|
||
|
|
const m = parsed.data;
|
||
|
|
const res = await fetch(`${strapiUrl}/api/scout-match-finales`, {
|
||
|
|
method: "POST",
|
||
|
|
headers: {
|
||
|
|
"Content-Type": "application/json",
|
||
|
|
Authorization: `Bearer ${token}`,
|
||
|
|
},
|
||
|
|
body: JSON.stringify({
|
||
|
|
data: {
|
||
|
|
match_id: m.id,
|
||
|
|
data: m.data,
|
||
|
|
avversario: m.avversario,
|
||
|
|
casa: m.casa,
|
||
|
|
set_nostri: m.setNostri,
|
||
|
|
set_loro: m.setLoro,
|
||
|
|
parziali: m.parziali,
|
||
|
|
mvp: m.mvp,
|
||
|
|
azioni: m.azioni,
|
||
|
|
},
|
||
|
|
}),
|
||
|
|
});
|
||
|
|
|
||
|
|
if (!res.ok) {
|
||
|
|
console.error("scout-finale: Strapi ha risposto", res.status, await res.text());
|
||
|
|
return new Response("Salvataggio su CMS non riuscito", { status: 502 });
|
||
|
|
}
|
||
|
|
|
||
|
|
return Response.json({ ok: true });
|
||
|
|
},
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|