3 Commits
Author SHA1 Message Date
davide eddee2ec44 Riscrivo il README per riflettere lo stato reale del repository
Il README precedente era la proposta iniziale del progetto (funzionalità
desiderate, comandi npm). Lo sostituisco con stack, funzionalità
effettivamente implementate e comandi bun corretti.
2026-08-28 13:17:44 +02:00
davide 49b6c8a7e9 Correggo documentazione: sync CSI e risultato scout non persistiti server-side
Il CLAUDE.md e la memory affermavano una sincronizzazione CSI e una
persistenza server-side dei risultati partita che non esistono nel
codice: la classifica è un array hardcoded (demo) e il risultato
scoutato vive solo nel localStorage di chi segna.
2026-08-28 13:15:06 +02:00
davide ebd3213a46 Aggiungo CLAUDE.md per tryhardare con claude 2026-08-28 12:09:31 +02:00
3 changed files with 192 additions and 107 deletions
+129
View File
@@ -0,0 +1,129 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this is
CrAPP — a mobile-first web app for managing an amateur volleyball team (CRAP Volley): attendance,
matches/trainings/events, live match scouting, player stats/badges, CSI league standings, push
notifications. Italian-language codebase (routes, variables, comments). Built with Lovable
(lovable.dev); pushes to `main` sync back into the Lovable editor — avoid rewriting published git
history (force-push, rebase/amend/squash of pushed commits).
## Commands
Package manager is **bun** (`bun.lock` is the lockfile; `package-lock.json` also exists but bun is
primary — see `bunfig.toml`).
```sh
bun run dev # vite dev server
bun run build # production build (nitro/vite)
bun run build:dev # development-mode build
bun run preview # preview a build
bun run lint # eslint .
bun run format # prettier --write .
```
There is no test runner configured in this repo.
Adding a dependency: `bunfig.toml` enforces a 24h supply-chain guard (`minimumReleaseAge`) on new
packages; only pre-listed `@lovable.dev/*` packages bypass it. Confirm with the user before adding
new bypass entries.
## Architecture
**Stack**: TanStack Start (React 19, file-based router) + Vite, styled with Tailwind v4 +
shadcn/radix components, data via `@supabase/supabase-js`, TanStack Query for client cache.
### Routing
File-based routing under `src/routes/` (see `src/routes/README.md`). One root layout,
`src/routes/__root.tsx`, wraps every page — preserve its `<Outlet />`. `$id.tsx` = dynamic segment,
`{-$category}.tsx` = optional segment, `$.tsx` = splat (`_splat` param). Do not hand-create
`src/pages/` or Next/Remix-style layout files. `src/routeTree.gen.ts` is auto-generated — never
edit it directly.
Server-only HTTP endpoints live under `src/routes/api/public/*.ts` (e.g. push subscription,
palloni/presenze reminders) — plain HTTP handlers, not proprietary edge functions, so they can run
under any Node host or scheduler (system cron, pg_cron, etc).
### Server entry / SSR error handling
`src/start.ts` registers global middleware: `attachSupabaseAuth` (client-side function middleware
that attaches the Supabase bearer token to every server-fn RPC — see
`src/integrations/supabase/auth-attacher.ts`, which is **auto-generated**, do not hand-edit) and an
error middleware + explicit CSRF middleware (`createCsrfMiddleware`) for server functions. Defining
`src/start.ts` opts out of Start's automatic CSRF middleware, so this file must keep re-adding it.
`src/server.ts` wraps the generated TanStack Start server entry and normalizes a specific h3
failure mode: h3 swallows in-handler throws into a 500 JSON body
(`{"unhandled":true,"message":"HTTPError"}`) that a plain try/catch never sees, so it's detected by
inspecting the response body and converted into `renderErrorPage()`'s HTML error page.
### Data layer — portability rule
The project must remain deployable on plain Node.js + PostgreSQL, not locked into Lovable Cloud
(see `docs/PORTABILITA.md`). Concretely:
- **Never query the database from components.** All data access goes through modules in
`src/lib/*.ts` (e.g. `palloni.ts`, `mvp-voti.ts`, `eventi.ts`, `presenze.ts`, `rosa.ts`,
`scout-*.ts`) — each exports TanStack Query hooks (`useX`) wrapping `supabase.from(...)`. This
keeps the backend swappable in one place.
- `src/integrations/lovable/*` (social login) is optional and unused by any screen — safe to
remove without impact.
- No provider-exclusive features: no edge functions, no Lovable-only auth as the sole login method,
no proprietary storage. Config only via standard env vars (`DATABASE_URL` / `SUPABASE_URL` +
keys, `VAPID_*`), never hardcoded.
- SQL migrations in `supabase/migrations/` must use standard PostgreSQL, no provider-exclusive
extensions.
### Cloud-efficiency rules (small paid-tier budget)
The Supabase/Lovable Cloud plan is metered (~20 credits/month, ~17 users), so these constraints are
load-bearing, not style preferences:
- No polling (`refetchInterval`) against the database; prefer local sync via
BroadcastChannel/storage.
- Global QueryClient (`src/router.tsx`) is deliberately configured for infrequent refetching:
`staleTime` 5 min, `gcTime` 30 min, `refetchOnWindowFocus/Mount/Reconnect` all off, `retry: 1`.
Don't override this per-query without a reason.
- After a mutation, update the query cache with `setQueryData` (see `useAssegnaTurno` in
`src/lib/palloni.ts` for the pattern) rather than `invalidateQueries`, to avoid an extra read.
- Stats/badges/standings are "write once, read many": computed and persisted once (e.g. at match
end), never recomputed on every page open.
- Live match scouting: only the scoring user writes; everyone else reads already-saved data.
- CSI league data is currently a **hardcoded placeholder** array in `src/lib/crapp-data.ts`
(`classifica`, `storicoMatch`), explicitly marked "(demo)" in the UI — no real sync exists yet,
this is planned/open work, not an existing pattern to copy.
- A scouted match result (`ScoutMatch`, from `scout.tsx` / `scout-store.ts`) is saved **only to
the scoring device's `localStorage`** (key `crapp-scout-v1`), never to Supabase — only the
in-progress resume state goes to the `scout_live` table. So today a match result is not shared
across devices/users at all.
- Push notifications only for high-value events (convocations, training/match reminders, ball-duty
turn, final result) — no chat/photo/video features.
### Auth
Supabase Auth (GoTrue), attached via middleware rather than per-request boilerplate — see
`auth-attacher.ts` / `auth-middleware.ts` above. Self-hostable; not tied to Lovable-proprietary
auth.
## Project memory (`mem/`)
`mem/index.md` indexes feature-level design notes (`mem/features/*.md`) — currently the portability
rule and the cloud-efficiency rules summarized above. Check there before adding a feature that
might conflict with either constraint.
## Conventions
- **Language: Italian.** Code comments and git commit messages must be written in Italian, matching
the rest of the codebase (routes, identifiers, existing comments/commits are already Italian).
- Path alias `@/*``src/*` (see `tsconfig.json`).
- Prettier: 100-char width, double quotes (`singleQuote: false`), trailing commas everywhere.
- TypeScript strict mode plus extra strictness: `noUncheckedIndexedAccess`,
`exactOptionalPropertyTypes`, `noImplicitReturns`, `noImplicitOverride`,
`noPropertyAccessFromIndexSignature`.
- `vite.config.ts` is intentionally minimal: `@lovable.dev/vite-tanstack-config` already bundles
TanStack devtools, `tanstackStart`, `viteReact`, `tailwindcss`, `tsConfigPaths`, nitro, env
injection, and the `@` alias — do not re-add any of those plugins manually or the app breaks with
duplicate plugins.
+62 -106
View File
@@ -1,118 +1,74 @@
# CRAP Volley Hub # CrAPP — CRAP Volley Hub
CrAPP App per CRAP Volley 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.
Vorrei sviluppare unapp mobile per la squadra di pallavolo CRAP Volley, con nome CrAPP, disponibile per Android e iOS. Lobiettivo è creare unapp semplice da usare, moderna, bella da vedere e più coinvolgente rispetto a SportEasy, includendo anche funzionalità normalmente a pagamento in altre app. Progetto avviato con [Lovable](https://lovable.dev): i push su `main` sincronizzano l'editor
Lovable, quindi si evita di riscrivere la history già pubblicata (niente force-push,
Funzionalità principali rebase/amend/squash di commit già pushati).
Gestione presenze/assenze
Partite
Allenamenti
Eventi extra
Stati rapidi: presente, assente, forse, in ritardo, indisponibile, infortunato
Statistiche giocatori
Presenze totali
Presenze consecutive
Gol/punti o altre statistiche specifiche della pallavolo
MVP, migliori performance, medie stagione
Statistiche partite
Risultati
Formazioni
Andamento set
Storico match
Campionato in tempo reale
Visualizzazione classifica e risultati
Dati presi direttamente dal sito del CSI
Aggiornamento automatico o importazione periodica
Calendario squadra
Allenamenti
Partite
Promemoria
Vista mensile e lista eventi
Profilo giocatore
Foto
Ruolo
Statistiche personali
Badge e obiettivi
Idea di stile
Interfaccia sportiva, pulita e moderna
Molto mobile-first
Design divertente, energico e più “premium”
Inserire in seguito il logo della squadra
Possibile uso di badge, livelli, premi e mini-gamification per rendere lapp più piacevole da usare
Extra che sarebbe bello aggiungere
Notifiche push per convocazioni e cambi orario
Chat o bacheca squadra
Report automatici dopo le partite
Sondaggi rapidi per disponibilità
Sezione “Best of the match”
Obiettivi di gruppo per presenza e continuità
Obiettivo finale
Realizzare una app che non sia solo utile per la gestione della squadra, ma anche piacevole, coinvolgente e bella da usare ogni giorno.
This project was built with [Lovable](https://lovable.dev).
**Live app**: https://volley-cronos-app.lovable.app **Live app**: https://volley-cronos-app.lovable.app
## Build with Lovable ## Stack
Continue developing this project in the [Lovable editor](https://lovable.dev/projects/8d07b0e4-6bd2-4a17-9dd2-bb2cf13f9f7c). - [TanStack Start](https://tanstack.com/start) (React 19, routing file-based) + Vite
- Tailwind v4 + componenti shadcn/radix
- [Supabase](https://supabase.com) (`@supabase/supabase-js`) per dati e auth
- TanStack Query per la cache client
- **Ship faster**: describe what you want to build and Lovable handles the code. ## Funzionalità
- **Stay in sync**: every change made in Lovable is committed straight to this repository.
- **Full ownership**: this code is yours. Push to `main` on GitHub and your changes sync back into Lovable, ready for your next prompt.
## Development - **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](CLAUDE.md)), sync reale
ancora da implementare
- **Notifiche push**: convocazioni, promemoria allenamento/partita, turno palloni, esito finale
Prefer working locally? You need Node.js and npm — [install with nvm](https://github.com/nvm-sh/nvm#installing-and-updating). ## Sviluppo
Package manager: **bun** ([installazione](https://bun.sh)).
```sh ```sh
git clone <this-repository-url> git clone https://github.com/ivancacciari1995-a11y/CRAPP.git
cd <repository-name> cd CRAPP
npm i bun install
npm run dev bun run dev # avvia il dev server su http://localhost:8080
``` ```
Serve un file `.env` con le credenziali Supabase (`VITE_SUPABASE_URL`,
`VITE_SUPABASE_PUBLISHABLE_KEY`) ed eventualmente le chiavi `VAPID_*` per le notifiche push.
Altri comandi:
```sh
bun run build # build di produzione
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.
## Continuare da Lovable
Il progetto resta modificabile anche dall'[editor Lovable](https://lovable.dev/projects/8d07b0e4-6bd2-4a17-9dd2-bb2cf13f9f7c):
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](docs/PORTABILITA.md)
per lo stato attuale e le regole da rispettare.
## Note per chi sviluppa con Claude Code
Vedi [CLAUDE.md](CLAUDE.md) per architettura dettagliata, convenzioni del repo e vincoli di
efficienza sul piano cloud a consumo.
+1 -1
View File
@@ -8,7 +8,7 @@ type: feature
- Dopo una mutazione aggiornare la cache con `setQueryData`, non `invalidateQueries` (evita riletture). - Dopo una mutazione aggiornare la cache con `setQueryData`, non `invalidateQueries` (evita riletture).
- Scout live: scrive solo l'utente che segna; gli altri leggono dati già salvati. - Scout live: scrive solo l'utente che segna; gli altri leggono dati già salvati.
- Statistiche, badge e classifiche: "write once, read many" — calcolate e salvate una volta a fine partita, mai ricalcolate a ogni apertura pagina. - Statistiche, badge e classifiche: "write once, read many" — calcolate e salvate una volta a fine partita, mai ricalcolate a ogni apertura pagina.
- Dati CSI: sincronizzazione periodica server-side salvata su tabella locale; l'app legge solo dal database interno. - Dati CSI: al momento è un array hardcoded in `src/lib/crapp-data.ts`, marcato "(demo)" in UI — nessun sync reale, da implementare. Anche il risultato di una partita scoutata (`ScoutMatch`) oggi vive solo nel `localStorage` del dispositivo di chi scouta, non su Supabase.
- Push solo per eventi importanti: convocazioni, promemoria allenamento/partita, turno palloni, esito finale. - Push solo per eventi importanti: convocazioni, promemoria allenamento/partita, turno palloni, esito finale.
- Niente foto/video/chat o funzionalità pesanti. - Niente foto/video/chat o funzionalità pesanti.
- Schema target: team_id, eventi, presenze, azioni_scout, statistiche_aggregate, classifica_csi, notifiche, con indici sui campi di filtro/relazione. - Schema target: team_id, eventi, presenze, azioni_scout, statistiche_aggregate, classifica_csi, notifiche, con indici sui campi di filtro/relazione.