davide 3fdbfefa62 Documento setup dev e deploy in produzione self-hosted
Passo-passo per avviare lo stack Supabase in locale e per il deploy in
produzione (dominio unico con routing /api/*, migrazioni, build/avvio
Node, job pianificati), coerente con i file infra aggiunti nel commit
precedente.
2026-08-28 14:23:31 +02:00
2026-08-06 08:36:47 +02:00
2026-08-07 11:41:04 +02:00
2026-08-06 08:36:47 +02:00
2026-08-06 08:36:47 +02:00

CrAPP — CRAP Volley Hub

App mobile-first per la gestione della squadra amatoriale di pallavolo CRAP Volley: presenze, partite/allenamenti/eventi, scouting live, statistiche giocatori, badge, classifica CSI, notifiche push.

Progetto avviato con Lovable: i push su main sincronizzano l'editor Lovable, quindi si evita di riscrivere la history già pubblicata (niente force-push, rebase/amend/squash di commit già pushati).

Live app: https://volley-cronos-app.lovable.app

Stack

  • TanStack Start (React 19, routing file-based) + Vite
  • Tailwind v4 + componenti shadcn/radix
  • Supabase (@supabase/supabase-js) per dati e auth
  • TanStack Query per la cache client

Funzionalità

  • Presenze: RSVP rapido (presente / assente / forse / in ritardo / infortunato) su ogni evento
  • Eventi: partite, allenamenti, eventi sociali, con calendario e lista
  • Scouting live: registrazione azioni punto-per-punto durante la partita (riservato agli admin)
  • Statistiche giocatori: presenze totali/consecutive, badge, obiettivi squadra, medie pagelle
  • Votazioni post-partita: MVP, pagelle 1-10 tra compagni, voti "social"/goliardici
  • Turno palloni: rotazione automatica di chi porta i palloni, con promemoria push
  • Classifica CSI: al momento un dato demo hardcoded (vedi CLAUDE.md), sync reale ancora da implementare
  • Notifiche push: convocazioni, promemoria allenamento/partita, turno palloni, esito finale

Sviluppo (locale)

Package manager: bun (installazione).

git clone https://github.com/ivancacciari1995-a11y/CRAPP.git
cd CRAPP
bun install

1. Avvia un backend Supabase

Serve un'istanza Supabase (cloud o self-hosted) a cui puntare. Per lavorare in locale senza toccare dati reali, nel repo c'è uno stack self-hosted pronto in infra/supabase/docker/:

cd infra/supabase/docker
cp .env.example .env
sh utils/generate-keys.sh --update-env   # genera JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY, ecc.

Poi avvia lo stack (con docker-compose.prod.yml si tengono su solo i servizi che CrAPP usa davvero — vedi la sezione Produzione più sotto):

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
docker compose ps   # verifica che tutti i container siano "healthy"

Applica le migrazioni del progetto al database appena creato:

cd ../../..   # torna alla root del repo
for f in supabase/migrations/*.sql; do
  docker exec -i supabase-db psql -U postgres -d postgres -v ON_ERROR_STOP=1 < "$f"
done

2. Configura .env di CrAPP

Nella root del repo, crea .env con le chiavi lette da infra/supabase/docker/.env:

VITE_SUPABASE_URL=http://localhost:8000
VITE_SUPABASE_PUBLISHABLE_KEY=<ANON_KEY dello stack self-hosted>
SUPABASE_SERVICE_ROLE_KEY=<SERVICE_ROLE_KEY dello stack self-hosted>

Facoltative per testare le notifiche push (senza non si rompe nulla, semplicemente niente push):

VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...
VAPID_SUBJECT=mailto:tuamail@esempio.it

3. Avvia l'app

bun run dev          # http://localhost:8080

Le tabelle sono vuote al primo avvio: crea un giocatore/evento dall'app stessa per avere dati di test. Dashboard Supabase Studio raggiungibile su http://localhost:8000 (credenziali DASHBOARD_USERNAME/DASHBOARD_PASSWORD in infra/supabase/docker/.env).

Altri comandi:

bun run build:dev    # build in modalità development
bun run preview      # anteprima di una build
bun run lint         # eslint .
bun run format       # prettier --write .

Non è configurato un test runner.

Produzione (self-hosted, Node + Docker)

bun run build usa Nitro (tramite @lovable.dev/vite-tanstack-config), che di default compilerebbe per Cloudflare Workers — in vite.config.ts il preset è forzato a node-server per generare un server Node standard, deployabile su qualunque host (coerente con docs/PORTABILITA.md).

Passo passo, sul server di produzione:

  1. Dominio/DNS: un solo hostname pubblico basta — Caddyfile.example instrada /api/* verso il gateway Supabase (path stripped) e tutto il resto verso l'app, sullo stesso dominio.
    • Con un dominio vero (DNS proprio): tuodominio.it.
    • Con un dominio gratuito No-IP (ddns.net, ecc.): un hostname singolo basta e avanza (il piano free ne dà fino a 3, ma qui ne serve uno solo), es. crapp.ddns.net.
    • Serve un client DDNS attivo sul server (o supporto nel router) che aggiorni l'IP: gli hostname No-IP gratuiti scadono dopo ~30 giorni di inattività se non confermati.
    • Verifica di non essere dietro CGNAT (IP pubblico condiviso dall'ISP): in quel caso nessuna porta è raggiungibile da internet e serve un tunnel (es. Cloudflare Tunnel) al posto dell'esposizione diretta.
  2. Stack Supabase self-hosted:
    cp infra/supabase/docker/.env.production.example infra/supabase/docker/.env
    cd infra/supabase/docker
    sh utils/generate-keys.sh --update-env   # secret NUOVI, non riusare quelli di sviluppo
    
    Modifica nel .env appena creato: SUPABASE_PUBLIC_URL/API_EXTERNAL_URL (dominio del punto 0 + /api), SITE_URL (dominio del punto 0), DASHBOARD_PASSWORD, e l'SMTP se servono email vere. Poi avvia:
    docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
    
    docker-compose.prod.yml fa due cose, pensate anche per girare su hardware limitato (es. Raspberry Pi 4): non espone porte pubblicamente (solo 127.0.0.1, dietro il reverse proxy — vedi Caddyfile.example nella stessa cartella), e disattiva i servizi Supabase che CrAPP non usa (Realtime, Storage, imgproxy, Edge Functions, pooler) — restano solo db, auth, rest, api-gw, più studio+meta per guardare/gestire il database via interfaccia grafica (raggiungibile su <dominio>/api, con le credenziali DASHBOARD_USERNAME/ DASHBOARD_PASSWORD). Da 11 container si scende a 6.
  3. Migrazioni:
    cd ../..   # root del repo
    for f in supabase/migrations/*.sql; do
      docker exec -i supabase-db psql -U postgres -d postgres -v ON_ERROR_STOP=1 < "$f"
    done
    
  4. Reverse proxy TLS: copia infra/supabase/docker/Caddyfile.example in Caddyfile, sostituisci il dominio del punto 0, poi caddy run --config Caddyfile (o come container). Gestisce automaticamente il certificato Let's Encrypt.
  5. Env dell'app:
    cp .env.production.example .env
    
    Compila VITE_SUPABASE_URL (dominio del punto 0 + /api), VITE_SUPABASE_PUBLISHABLE_KEY (= ANON_KEY dello stack), SUPABASE_SERVICE_ROLE_KEY (= SERVICE_ROLE_KEY), e le chiavi VAPID_* reali (npx web-push generate-vapid-keys).
  6. Build e avvio:
    bun run build
    node .output/server/index.mjs   # ascolta su PORT (default 3000)
    
    Tienilo vivo con un process manager (pm2/systemd) — il Caddy del punto 3 lo espone via TLS sull'hostname app.
  7. Job pianificati — gli endpoint src/routes/api/public/promemoria-palloni.ts e sollecita-presenze.ts vanno richiamati periodicamente via HTTP POST da un cron di sistema o pg_cron: non partono da soli.

Continuare da Lovable

Il progetto resta modificabile anche dall'editor Lovable: le modifiche fatte lì vengono committate direttamente su questo repository, e viceversa i push su main sincronizzano l'editor.

Portabilità

Il progetto è pensato per restare deployabile su un normale server Node.js + PostgreSQL, senza dipendenze esclusive da Lovable Cloud — vedi docs/PORTABILITA.md per lo stato attuale e le regole da rispettare.

Note per chi sviluppa con Claude Code

Vedi CLAUDE.md per architettura dettagliata, convenzioni del repo e vincoli di efficienza sul piano cloud a consumo.

S
Description
App del CRAP, ottimizzazione di sporteasy adattata alle esigenze della squadra, campionato e extra
https://crapp-iv11.vercel.app
Readme
2.3 MiB
Languages
TypeScript 94.4%
PLpgSQL 3.5%
CSS 1.8%
JavaScript 0.3%