diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 296226e..b1d5295 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -6,6 +6,15 @@ qui: sta in [ROADMAP.md](ROADMAP.md).
## Versione attuale — agosto 2026
+### Lo Scout Live si apre dalla pagina della partita
+
+- Tolto dalla home, era rimasto senza nessun link: `/scout` si raggiungeva solo scrivendo
+ l'URL. Ora la card `ScoutEntry` sta in `/partita/$id`, sezione «Scout live».
+- Si accende solo se la partita aperta è quella di oggi (nuova prop `eventoId`), altrimenti
+ resta grigia con «Si attiva il giorno della partita». Lock di sessione invariato.
+- Non è più riservato agli admin: può scoutare chiunque sia autenticato, uno per volta grazie
+ al lock. Sparisce il messaggio «Scout riservato».
+
### Il sondaggio pre-partita apre alle 8:00 del giorno della partita
- Prima era sempre votabile, anche settimane prima: ora la card resta chiusa con l'avviso di
diff --git a/docs/modules/scout-live.md b/docs/modules/scout-live.md
index a77eea0..40ed2a4 100644
--- a/docs/modules/scout-live.md
+++ b/docs/modules/scout-live.md
@@ -30,10 +30,21 @@ aggiornato da qualunque dispositivo.
## Chi può usarlo
-Solo gli admin lato UI: `ScoutEntry.tsx` e `scout.tsx` bloccano i non-admin con il messaggio
-"Scout riservato". **Il controllo non è imposto a livello database**: le policy RLS di
-`scout_sessioni`/`scout_live`/`scout_partite` sono aperte a qualunque utente autenticato, non
-solo agli admin — la migration M4 toglie l'accesso solo al ruolo `anon`.
+Chiunque sia autenticato: non è più riservato agli admin. A tenere l'ordine basta il lock di
+sessione — scoutizza uno per volta, gli altri vedono "In uso da …". Questo allinea l'interfaccia
+alle policy RLS di `scout_sessioni`/`scout_live`/`scout_partite`, che sono sempre state aperte a
+qualunque utente autenticato (la migration M4 toglie l'accesso solo al ruolo `anon`).
+
+---
+
+## Da dove ci si arriva
+
+`ScoutEntry.tsx` è l'unico accesso a `/scout`: sta nella pagina della partita
+(`partita.$id.tsx`, sezione «Scout live»), visibile a tutta la squadra. Si accende solo se
+**quella** partita è quella di oggi — la prop `eventoId` confronta l'evento aperto con
+`partitaDiOggi()` — e se nessun altro ha il lock; negli altri casi resta una card grigia non
+cliccabile («Si attiva il giorno della partita» / «In uso da …»). Dalla home è stato tolto
+perché occupava spazio 6 giorni su 7.
---
@@ -104,7 +115,8 @@ calcolati a runtime).
## Limiti noti
-- Controllo "solo admin" non imposto dal database (vedi sopra).
+- Scout aperto a tutta la squadra: nessun filtro su chi può registrare le azioni, l'unica
+ garanzia è il lock di sessione (vedi sopra).
- Possibile, per quanto improbabile, doppio "successo" applicativo nel prendere il lock:
lettura e upsert non sono atomici.
- `scout_partite` si inserisce ma non si corregge dall'interfaccia: solo eliminazione totale.
@@ -116,4 +128,3 @@ calcolati a runtime).
## Evoluzioni possibili
- Realtime (Supabase Realtime) per aggiornare la sessione condivisa senza refresh manuale.
-- Restringere le policy RLS al solo ruolo admin.
diff --git a/src/components/crapp/ScoutEntry.tsx b/src/components/crapp/ScoutEntry.tsx
index 8becdd1..c892bdb 100644
--- a/src/components/crapp/ScoutEntry.tsx
+++ b/src/components/crapp/ScoutEntry.tsx
@@ -3,36 +3,33 @@ import { ChevronRight, Lock, Radio } from "lucide-react";
import { cn } from "@/lib/utils";
import { sessioneScaduta, usePartitaDiOggi, useSessioneScout } from "@/lib/scout-live";
import { useGiocatoreCorrente } from "@/lib/user-store";
-import { useIsAdmin } from "@/lib/ruoli";
-/** Accesso allo scout live: attivo solo il giorno della partita e se nessun altro lo sta usando. */
-export function ScoutEntry({ variante = "grande" }: { variante?: "grande" | "compatto" }) {
- const { pronto, partita } = usePartitaDiOggi();
+/**
+ * Accesso allo scout live: attivo solo il giorno della partita e se nessun altro lo sta usando.
+ * Con `eventoId` si accende solo se quella partita è proprio quella di oggi.
+ */
+export function ScoutEntry({
+ variante = "grande",
+ eventoId,
+}: {
+ variante?: "grande" | "compatto";
+ eventoId?: string;
+}) {
+ const { pronto, partita: diOggi } = usePartitaDiOggi();
+ const partita = eventoId && diOggi?.id !== eventoId ? null : diOggi;
const io = useGiocatoreCorrente();
- const admin = useIsAdmin();
const { data: sessione } = useSessioneScout(partita?.id ?? null);
- // Strumento tecnico: solo i referenti/allenatori scoutizzano la partita.
- const abilitato = admin;
-
const attiva = sessione && !sessioneScaduta(sessione) ? sessione : null;
const occupato = !!attiva && attiva.giocatore_id !== io?.id;
- const disponibile = abilitato && pronto && !!partita && !occupato;
+ const disponibile = pronto && !!partita && !occupato;
- const titolo = !abilitato
- ? "Scout live"
- : !partita
- ? "Scout live non attivo"
- : occupato
- ? "Scout occupato"
- : "Scout live";
- const sottotitolo = !abilitato
- ? "Riservato ad allenatori e referenti"
- : !partita
- ? "Si attiva il giorno della partita"
- : occupato
- ? `In uso da ${attiva!.giocatore_nome}`
- : "Segna punti, ace e muri in tempo reale";
+ const titolo = !partita ? "Scout live non attivo" : occupato ? "Scout occupato" : "Scout live";
+ const sottotitolo = !partita
+ ? "Si attiva il giorno della partita"
+ : occupato
+ ? `In uso da ${attiva!.giocatore_nome}`
+ : "Segna punti, ace e muri in tempo reale";
const contenuto = (
<>
diff --git a/src/routes/partita.$id.tsx b/src/routes/partita.$id.tsx
index 47468b8..9105fc1 100644
--- a/src/routes/partita.$id.tsx
+++ b/src/routes/partita.$id.tsx
@@ -9,6 +9,7 @@ import { useCsi } from "@/lib/csi";
import { matchDaPartitaCsi, partiteGiocate } from "@/lib/csi-core";
import { Pagelle } from "@/components/crapp/Pagelle";
import { SondaggioCacche } from "@/components/crapp/SondaggioCacche";
+import { ScoutEntry } from "@/components/crapp/ScoutEntry";
import { useScoutMatches, totaliPerGiocatore, totaliSquadra } from "@/lib/scout-store";
import { csvScoutMatch, scaricaCsv } from "@/lib/scout-export";
import { useGiocatoreCorrente } from "@/lib/user-store";
@@ -204,6 +205,10 @@ function PartitaDetail() {
)}
+
+
diff --git a/src/routes/scout.tsx b/src/routes/scout.tsx
index f65a3f4..994bb06 100644
--- a/src/routes/scout.tsx
+++ b/src/routes/scout.tsx
@@ -8,7 +8,6 @@ import { formatData } from "@/lib/crapp-data";
import type { Evento } from "@/lib/eventi";
import { useRosa } from "@/lib/rosa";
import { useGiocatoreCorrente } from "@/lib/user-store";
-import { useIsAdmin } from "@/lib/ruoli";
import { usePresenzeEvento } from "@/lib/presenze";
import {
statoIniziale,
@@ -83,7 +82,6 @@ function Blocco({
function Scout() {
const { pronto, partita } = usePartitaDiOggi();
const io = useGiocatoreCorrente();
- const admin = useIsAdmin();
const sessione = useSessioneScout(partita?.id ?? null);
const statoSalvato = useStatoScout(partita?.id ?? null);
const apri = useApriSessioneScout();
@@ -102,16 +100,6 @@ function Scout() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [controllo, partita?.id, io?.id]);
- if (io && !admin) {
- return (
- }
- titolo="Scout riservato"
- testo="Lo scout live è uno strumento tecnico per allenatori e referenti della squadra."
- />
- );
- }
-
if (!pronto || sessione.isLoading || statoSalvato.isLoading) {
return (
} titolo="Scout live" testo="Caricamento…" />