Compare commits
3
Commits
main
...
eddee2ec44
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eddee2ec44 | ||
|
|
49b6c8a7e9 | ||
|
|
ebd3213a46 |
@@ -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.
|
||||
@@ -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 un’app mobile per la squadra di pallavolo CRAP Volley, con nome CrAPP, disponibile per Android e iOS. L’obiettivo è creare un’app semplice da usare, moderna, bella da vedere e più coinvolgente rispetto a SportEasy, includendo anche funzionalità normalmente a pagamento in altre app.
|
||||
|
||||
Funzionalità principali
|
||||
|
||||
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 l’app 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).
|
||||
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,
|
||||
rebase/amend/squash di commit già pushati).
|
||||
|
||||
**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.
|
||||
- **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.
|
||||
## Funzionalità
|
||||
|
||||
## 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
|
||||
git clone <this-repository-url>
|
||||
cd <repository-name>
|
||||
npm i
|
||||
npm run dev
|
||||
git clone https://github.com/ivancacciari1995-a11y/CRAPP.git
|
||||
cd CRAPP
|
||||
bun install
|
||||
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.
|
||||
|
||||
@@ -8,7 +8,7 @@ type: feature
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
Reference in New Issue
Block a user