# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Scopo del progetto **Segnapunti Anto** è una PWA per il segnapunti pallavolo in tempo reale. Un server Express/WebSocket gestisce lo stato di gioco; due interfacce Vue separate — **display** (tabellone pubblico) e **controller** (pannello operatore) — si sincronizzano via WebSocket. ## Comandi ```bash npm run dev # Vite dev server — display: :5173/display, controller: :5173/controller npm run serve # Build + avvio produzione — display: :3000/display, controller: :3000/controller npm run test # Vitest in modalità watch npm run test:all # Tutte le suite Vitest in una sola esecuzione npm run test:unit # Solo unit + integration npm run test:component # Test componenti Vue (happy-dom) npm run test:stress # Load test (50+ client concorrenti) npm run test:e2e # Playwright E2E (richiede npm run serve attivo) npm run test:e2e:ui # Playwright con UI interattiva ``` Per eseguire un singolo file di test: `npx vitest run tests/unit/gameState.test.js` ## Architettura ``` Controller (Vue) ──WebSocket──┐ Display (Vue) ──WebSocket──┤── websocket-handler.js ── gameState.js │ │ │ └── persist.js ── .segnapunti/state.json ``` **Tutta la logica di gioco** è in `src/gameState.js` come tre funzioni pure esportate: - `createInitialState()` — restituisce lo stato iniziale - `applyAction(state, action)` — reducer immutabile (deep-clone via `structuredClone`) - `checkVittoria(state)` — condizioni di vittoria set (25 punti, vantaggio di 2; 15 punti nel set decisivo) `src/websocket-handler.js` riceve i messaggi WebSocket, valida che il mittente sia un `controller` (non un `display`), chiama `applyAction`, fa il broadcast del nuovo stato a tutti i client, poi invoca `onStateChange` per persistere su disco. `server.js` (Express) serve entrambe le interfacce sulla porta 3000: `/display` → `dist/index.html`, `/controller` → `dist/controller.html`. Singolo endpoint WebSocket su `/ws`. In sviluppo, `vite-plugin-websocket.js` incorpora il server WebSocket dentro il dev server Vite con middleware di URL rewrite per `/display` e `/controller`. ## Vincoli di design - **Tutta la logica sul server** — i client sono pura UI; il server è l'unica source of truth. - **WebSocket role-based** — i client si registrano come `display` o `controller`; solo i controller possono inviare azioni. - **Stato immutabile** — `applyAction` non muta mai lo stato, restituisce sempre un nuovo oggetto. - **Un solo controller** — il design prevede un controller e un display attivi; non esiste conflict resolution per controller simultanei. - **Stato persistente** — `src/persist.js` salva lo stato in `.segnapunti/state.json` dopo ogni azione e lo carica all'avvio del server. ## Layout dei test | Suite | Percorso | Runner | |-------|----------|--------| | Unit | `tests/unit/` | Vitest + Node | | Integration | `tests/integration/` | Vitest + Node | | Component | `tests/component/` | Vitest + Happy-DOM | | Stress | `tests/stress/` | Vitest + Node | | E2E | `tests/e2e/` | Playwright (Chromium, Firefox, Mobile Chrome) | I test E2E girano in serie (`workers: 1`) per evitare race condition sullo stato WebSocket. Eseguire `npm run serve` prima di `npm run test:e2e`. ## Deploy Il progetto si distribuisce tramite Docker. L'immagine è pubblicata sul registry Gitea self-hosted (`santantonio.sytes.net`): ```bash docker compose up -d # Avvia con immagine dal registry privato (porta 3000) ``` Il volume `./.segnapunti` persiste lo stato tra i riavvii del container. ## Istruzioni operative - Per ogni nuova funzionalità: analizza come si inserisce nel flusso `action → applyAction → broadcast`, poi decidi se aggiungere un nuovo tipo di action o estendere uno esistente. - Qualsiasi modifica alle regole di gioco va fatta esclusivamente in `src/gameState.js`. - Qualsiasi modifica al protocollo WebSocket va fatta in `src/websocket-handler.js`. - Aggiungere test unit in `tests/unit/gameState.test.js` per ogni nuovo action type o regola di gioco. - Il codice deve essere scritto in italiano per commenti e nomi di variabili di dominio (es. `servHome`, `striscia`, `nomi`), ma in inglese per nomi tecnici standard (`state`, `action`, `handler`).