From eec4ef0526bd8ef6c462cd7bedf56c7adcf2bdbd Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Tue, 12 May 2026 12:22:39 +0200 Subject: [PATCH] chore: aggiunge CLAUDE.md con architettura e comandi del progetto --- CLAUDE.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..5b2a326 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,66 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Purpose + +**Segnapunti Anto** is a real-time volleyball scoreboard PWA. An Express/WebSocket server hosts the game state; two separate web interfaces — a **display** (public scoreboard) and a **controller** (operator panel) — stay in sync via WebSocket. A terminal CLI (`cli.js`) provides an alternative controller interface. + +## Commands + +```bash +npm run dev # Vite dev server — display: :5173, controller: :5173/controller.html (proxied on :3001) +npm run serve # Build + run production — display: :3000, controller: :3001 +npm run cli # Terminal controller (connects to production :3000) +npm run cli:dev # Terminal controller (connects to dev :5173) + +npm run test # Vitest watch mode +npm run test:all # All Vitest suites once (unit, integration, component, stress) +npm run test:unit # Unit + integration only +npm run test:component # Vue component tests +npm run test:stress # Load tests (50+ concurrent clients) +npm run test:e2e # Playwright E2E (requires servers to be running via npm run serve) +npm run test:e2e:ui # Playwright with interactive UI +``` + +## Architecture + +``` +Controller (Vue) ──WebSocket──┐ +Display (Vue) ──WebSocket──┤── websocket-handler.js ── gameState.js +CLI (Node) ──WebSocket──┘ +``` + +All game logic lives in `src/gameState.js` as three pure functions: +- `createInitialState()` — returns the initial state +- `applyAction(state, action)` — immutable reducer (deep-clones via `JSON.parse/stringify`) +- `checkVittoria(state)` — volleyball win conditions (25-point sets with 2-point margin, 15-point final set) + +`src/websocket-handler.js` receives actions, validates that the sender is a registered controller (not just a display), calls `applyAction`, then broadcasts the new state to all clients. + +Two production HTTP servers are started by `server.js` (Express): port 3000 serves `dist/index.html` (display), port 3001 serves `dist/controller.html` (controller). Both share a single WebSocket endpoint at `/ws`. + +In development, `vite-plugin-websocket.js` is a custom Vite plugin that embeds the WebSocket server inside the Vite dev server and proxies port 3001 traffic back to Vite. + +## Key Design Constraints + +- **All game rules on the server** — clients are pure UI; the server is the source of truth. +- **Role-based WebSocket** — clients register as `display` or `controller`; only controllers may send actions. +- **Immutable state** — `applyAction` never mutates; always returns a new state object. +- **Single-controller intent** — the design targets one active controller and one display; no conflict resolution exists for simultaneous controllers. + +## Test Layout + +| Suite | Path | 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) | + +E2E tests run serially (`workers: 1`) to avoid WebSocket state races. Run `npm run serve` before `npm run test:e2e`. + +## Simplification Goals (Current Work) + +The intended architecture is: **one host acts as both WebSocket server and display; one connected device acts as controller**. Complexity reduction should be evaluated against this constraint — anything that supports multi-controller scenarios, complex client topologies, or unneeded abstractions is a candidate for removal.