Ilia Denisov 85baabe4ba
Tests · Go / test (push) Successful in 6s
Tests · Integration / integration (push) Successful in 10s
Tests · Go / test (pull_request) Successful in 5s
Tests · Integration / integration (pull_request) Successful in 10s
Stage 5: robot opponent (pool, seed-derived strategy, move driver, matchmaker substitution)
- internal/robot: durable kind='robot' account pool (migration 00004); every
  per-game and per-turn choice derived deterministically from the game seed
  (restart-stable FNV mix); a background move driver; margin targeting (band
  1-30, closest-to-band); right-skewed [2,90]min delays (median ~10m);
  opponent-anchored sleep with +/-3h drift; daytime nudge reply + proactive
  12h nudge; friend/chat blocked via profile toggles.
- engine.Candidates (decoded ranked plays); game.Candidates + RobotTurns;
  social.LastNudgeAt.
- matchmaker: 10s wait then robot substitution (reaper) + Poll delivery seam.
- config (BACKEND_ROBOT_DRIVE_INTERVAL, BACKEND_LOBBY_ROBOT_WAIT,
  BACKEND_LOBBY_REAPER_INTERVAL); main wiring + boot-time pool provisioning.
- metrics: robot account_stats (authoritative balance) + robot_games_finished_total
  OTel counter + per-finish log.
- docs: PLAN, ARCHITECTURE, FUNCTIONAL(+ru), TESTING, README; account.go comment.
- tests: robot strategy units, matchmaker reaper/Poll, engine.Candidates; inttest
  robot full-game / substitution / proactive-nudge.
2026-06-02 21:02:20 +02:00

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 engine library in-process.
  • ui — pure-HTML5 client (plain Svelte + Vite), embeddable in platform webviews and packageable to native via Capacitor. (added in a later stage)
  • platform/* — per-platform side-services (e.g. the Telegram bot). (added in a later stage)

Documentation (sources of truth)

Build & test

go build ./backend/...  # per module (the workspace spans several modules)
go vet ./backend/...
gofmt -l .              # must print nothing
go test -count=1 ./backend/...                       # 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.

Run the backend locally

The backend now owns persistence, so it needs Postgres and applies its embedded migrations at startup:

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     # serves /healthz and /readyz on :8080

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.

S
Description
No description provided
Readme 7.3 MiB
Languages
Go 64.7%
TypeScript 26.1%
Svelte 7.4%
Go Template 0.9%
CSS 0.5%
Other 0.2%