# scrabble-game Multiplatform Scrabble game. Players arrive from a platform (Telegram first; later VK/MAX/iOS/Android) or from standalone web (email / guest). The game supports English Scrabble, Russian Scrabble and Эрудит. ## Components - **`gateway`** — the only public ingress: anti-abuse, platform authentication (resolves the player and injects `X-User-ID`), routing to `backend`, and an admin surface behind Basic Auth. *(added in a later stage)* - **`backend`** — internal-only service that owns every domain concern and embeds the [`scrabble-solver`](../scrabble-solver) engine library in-process. - **`ui`** — pure-HTML5 client (plain Svelte 5 + TypeScript + Vite) over Connect-RPC + FlatBuffers, embeddable in platform webviews and packageable to native via Capacitor. See [`ui/README.md`](ui/README.md). - **`platform/*`** — per-platform side-services (e.g. the Telegram bot). *(added in a later stage)* ## Documentation (sources of truth) - [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — global architecture, transport, security, cross-service contracts. - [`docs/FUNCTIONAL.md`](docs/FUNCTIONAL.md) (+ [`_ru`](docs/FUNCTIONAL_ru.md)) — per-domain user stories. - [`docs/TESTING.md`](docs/TESTING.md) — test layers and the per-stage CI gate. - [`PLAN.md`](PLAN.md) — the staged implementation plan and stage tracker. - [`CLAUDE.md`](CLAUDE.md) — project guide and the mandatory per-stage workflow. ## Build & test ```sh go build ./backend/... ./pkg/... ./gateway/... # per module (the workspace spans several) go vet ./backend/... ./pkg/... ./gateway/... gofmt -l . # must print nothing go test -count=1 ./backend/... ./pkg/... ./gateway/... # unit tests go test -tags=integration -count=1 -p=1 ./backend/... # + Postgres (needs Docker) ``` The `integration`-tagged tests start a throwaway `postgres:17-alpine` container via testcontainers-go and require a reachable Docker daemon; they live in the `backend` module. The wire contracts in `pkg` and the Connect edge in `gateway` have committed generated code (regenerate dev-time with `make -C pkg gen` / `make -C gateway gen`). ## Run the backend locally The backend now owns persistence, so it needs Postgres and applies its embedded migrations at startup: ```sh docker run -d --name scrabble-pg -e POSTGRES_PASSWORD=dev -p 5432:5432 postgres:17-alpine BACKEND_POSTGRES_DSN='postgres://postgres:dev@localhost:5432/postgres?search_path=backend&sslmode=disable' \ go run ./backend/cmd/backend # HTTP API + probes on :8080, push gRPC on :9090 ``` ## Run the gateway locally The gateway is the public edge; point it at a running backend: ```sh GATEWAY_BACKEND_HTTP_URL=http://localhost:8080 \ GATEWAY_BACKEND_GRPC_ADDR=localhost:9090 \ go run ./gateway/cmd/gateway # Connect/h2c edge on :8081 ``` Key environment: `BACKEND_HTTP_ADDR` (default `:8080`), `BACKEND_LOG_LEVEL` (`debug|info|warn|error`, default `info`), `BACKEND_POSTGRES_DSN` (**required**). The full configuration surface and the go-jet regeneration step live in [`backend/README.md`](backend/README.md). ## Run the UI locally ```sh cd ui && pnpm install pnpm start # mock mode: lobby -> game with no backend, on http://localhost:5173 pnpm dev # against a running gateway (Vite proxies the RPC path to :8081) ``` `pnpm check` (type-check), `pnpm test:unit` (Vitest), `pnpm test:e2e` (Playwright smoke vs the mock), `pnpm build` (static bundle). Details — including the committed edge codegen (`pnpm codegen`) — are in [`ui/README.md`](ui/README.md). ## Deploy (`deploy/`) The full contour is [`deploy/docker-compose.yml`](deploy/docker-compose.yml): `backend` + `gateway` (with the UI embedded via `go:embed`, baked in by its node build stage) + Postgres + the Telegram connector (with a VPN sidecar) + an observability stack (OTel Collector → Prometheus + Tempo → Grafana) + a front **caddy** that owns a single `/_gm` Basic-Auth (admin console + Grafana). The Go services build from multi-stage distroless `*/Dockerfile`. ```sh docker build -f backend/Dockerfile -t scrabble-backend . # pulls the DAWG release artifact docker build -f gateway/Dockerfile -t scrabble-gateway . # node stage builds + embeds the UI docker compose -f deploy/docker-compose.yml config # validate (needs the TEST_/PROD_ env) ``` CI auto-deploys the **test contour** on a PR into — or push to — `development` (`.gitea/workflows/ci.yaml`); the **prod contour** is a manual deploy after `development → master` (Stage 18). Env reference: [`deploy/.env.example`](deploy/.env.example); the topology and the two-contour model are in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) §13.