BERACE
Pronostici su Formula 1 e MotoGP da sfidare con gli amici
Incasso mensile: 2100 USD (fonte indicata nella scheda)
Cosa fa
App per appassionati di motori: si fanno pronostici sulle gare e si gareggia con gli amici in una classifica. Nessuna scommessa con soldi.
Come guadagna
Ha entrate ricorrenti ogni mese, verificate su TrustMRR. Prezzi e piani esatti sono indicati sul sito del progetto.
Rendilo tuo
- La stessa formula per la Serie A, il Giro d'Italia o Sanremo.
- Leghe private per gruppi di amici o colleghi, con premi simbolici.
Le frasi da scrivere all'AI
1. Base del sito e grafica
Crea un'app web in italiano chiamata "Pole Amici": permette agli appassionati di Formula 1 e MotoGP di fare pronostici sulle gare e sfidarsi con gli amici in classifiche private. Nessuna scommessa e nessun premio in denaro. Usa React, Vite, TypeScript e Tailwind CSS.
Pagine da creare:
1. Pagina iniziale con la prossima gara, il conto alla rovescia e come si gioca
2. Registrazione e scelta del campionato
3. Pronostico della gara: podio, giro veloce, pole, primo ritirato
4. Classifica generale e delle leghe tra amici
5. Crea o entra in una lega con un codice
Stile: da paddock: sfondo nero #0B0B0B, rosso corsa #E10600, bianco, carattere "Titillium Web", bandiera a scacchi come motivo grafico. Nessuna immagine generica di stock.
Tutto deve funzionare perfettamente da telefono. Tutti i testi in italiano, chiari e senza parole tecniche.
2. Database, account e sicurezza
Collega il progetto a Supabase e attiva la registrazione con email e password.
Crea queste tabelle:
- "gare": campionato, nome, data e ora di partenza, risultati ufficiali (inseriti dagli amministratori)
- "pronostici": le scelte dell'utente per una gara, i punti ottenuti
- "leghe" e "membri_lega": leghe private con un codice d'invito
Regole di sicurezza obbligatorie:
- i pronostici si possono inserire e modificare solo prima della partenza: lo controlla il database
- i pronostici degli altri si vedono solo dopo la partenza
- i risultati e i punti li scrivono solo gli amministratori e le funzioni del server
Usa esattamente il codice SQL che trovi nei "Dettagli tecnici" di questa scheda: eseguilo nel SQL Editor di Supabase prima di continuare, poi collega le pagine alle tabelle.
3. Pronostici e punteggio
Per ogni gara l'utente sceglie: primo, secondo, terzo, pole position, giro più veloce e primo ritirato, dall'elenco dei piloti. Il pronostico si può cambiare fino alla partenza; dopo il database lo blocca (regola nei Dettagli tecnici).
Quando un amministratore inserisce i risultati ufficiali, una funzione calcola i punti di tutti: 10 per il vincitore esatto, 5 per ogni pilota sul podio nella posizione giusta, 2 se è sul podio ma in un'altra posizione, 3 per pole, giro veloce e ritirato. Le classifiche si aggiornano subito.
Specifica nelle condizioni che è un gioco tra amici: nessuna puntata, nessun premio in denaro.
4. Leghe tra amici
Chiunque può creare una lega privata: riceve un codice di 6 lettere e un link da condividere su WhatsApp. La pagina della lega mostra la classifica, i pronostici di tutti dopo la partenza, e chi ha fatto il pronostico migliore della gara.
Notifica la sera prima della gara a chi non ha ancora fatto il pronostico.
5. Pagamenti con Stripe
Aggiungi un abbonamento a 2,99 € al mese per stagione. Gratis l'utente ha: classifica generale e una lega con massimo 5 amici. Con il piano Pro sblocca: leghe illimitate fino a 50 persone, statistiche dei pronostici e badge.
A pagamento riuscito il webhook porta l'utente al piano Pro; se l'abbonamento viene disdetto o non rinnovato lo riporta al piano gratuito.
Per la sessione di pagamento e il webhook segui la guida "Pagamenti con Stripe" di Fattibile.
6. Controlli specifici di questo progetto
Oltre ai controlli della guida "Controllo finale", verifica in particolare:
1. Orari: prova a modificare un pronostico un minuto dopo la partenza chiamando direttamente il database: deve essere rifiutato.
Correggi quello che non va e scrivimi cosa hai cambiato.
Dettagli tecnici
Pronostici bloccati alla partenza
Le regole di sicurezza controllano l'orario della gara: dopo la partenza il pronostico non si cambia più, e quelli degli altri diventano visibili.
create table gare (
id uuid primary key default gen_random_uuid(),
campionato text not null check (campionato in ('f1', 'motogp')),
nome text not null,
partenza timestamptz not null,
risultati jsonb -- inserito dagli amministratori
);
alter table gare enable row level security;
create policy "gare pubbliche" on gare for select using (true);
create table pronostici (
utente_id uuid not null references auth.users(id) on delete cascade,
gara_id uuid not null references gare(id) on delete cascade,
scelte jsonb not null, -- { primo, secondo, terzo, pole, giro_veloce, ritirato }
punti int,
primary key (utente_id, gara_id)
);
alter table pronostici enable row level security;
-- Inserisco e modifico il mio solo prima della partenza, e senza punti
create policy "inserisco prima della partenza" on pronostici for insert
with check (auth.uid() = utente_id and punti is null
and now() < (select partenza from gare g where g.id = gara_id));
create policy "modifico prima della partenza" on pronostici for update
using (auth.uid() = utente_id and now() < (select partenza from gare g where g.id = gara_id))
with check (punti is null);
-- Vedo il mio sempre, quelli degli altri dopo la partenza
create policy "vedo i pronostici" on pronostici for select using (
auth.uid() = utente_id or now() >= (select partenza from gare g where g.id = gara_id));Calcolo dei punti
Confronta ogni pronostico con i risultati ufficiali e assegna i punti. La chiama solo il server, dopo l'inserimento dei risultati.
create function calcola_punti(gara uuid) returns void
language plpgsql security definer set search_path = public as $
declare r jsonb;
begin
select risultati into r from gare where id = gara;
if r is null then raise exception 'Risultati non ancora inseriti'; end if;
update pronostici p set punti =
(case when p.scelte->>'primo' = r->>'primo' then 10
when p.scelte->>'primo' in (r->>'secondo', r->>'terzo') then 2 else 0 end)
+ (case when p.scelte->>'secondo' = r->>'secondo' then 5
when p.scelte->>'secondo' in (r->>'primo', r->>'terzo') then 2 else 0 end)
+ (case when p.scelte->>'terzo' = r->>'terzo' then 5
when p.scelte->>'terzo' in (r->>'primo', r->>'secondo') then 2 else 0 end)
+ (case when p.scelte->>'pole' = r->>'pole' then 3 else 0 end)
+ (case when p.scelte->>'giro_veloce' = r->>'giro_veloce' then 3 else 0 end)
+ (case when p.scelte->>'ritirato' = r->>'ritirato' then 3 else 0 end)
where p.gara_id = gara;
end $;
revoke execute on function calcola_punti(uuid) from public, anon, authenticated;
grant execute on function calcola_punti(uuid) to service_role;
Pezzi comuni a tutti i progetti
Glossario
- JSONB
- Un tipo di colonna che contiene dati strutturati flessibili, come un piccolo documento.
- Lega privata
- Una classifica solo tra amici, a cui si entra con un codice d'invito.