Rename the app from scopa to tavolo
CI / Build and push docker image (push) Successful in 3m12s

The platform now hosts multiple card games, with scopone scientifico as
the first one. Rename the brand wherever it is not a game rule:

- move the Python package to server/src/tavolo and update imports
- rename the Postgres database/user, OIDC issuer path, client id and
  Redis key prefixes to tavolo (clean break: existing pgdata volumes and
  live games are not migrated)
- rename the Cargo package to tavolo-web and set the page title to Tavolo
- update docs and the Docker image path to woggioni/tavolo

The scopa game term (clearing the table) in the engine, state and web UI
is intentionally left untouched.
This commit is contained in:
2026-09-16 21:46:06 +08:00
parent 89cf0a4c96
commit 6932a3272c
46 changed files with 141 additions and 140 deletions
+17 -16
View File
@@ -1,8 +1,9 @@
# scopa
# tavolo
A multiplayer backend for **scopone scientifico** (the four-player,
fixed-partnership variant of the classic Italian card game), built on the
[kaya](../kaya) framework.
The backend for a multiplayer card-game platform, built on the
[kaya](../kaya) framework. The first game implemented is **scopone
scientifico**, the four-player, fixed-partnership variant of the classic
Italian card game.
Players authenticate with the configured **OIDC** provider. Live game state
is kept in **Redis** (with real-time play over WebSocket), and completed
@@ -24,7 +25,7 @@ serves the Sycamore/WASM frontend (built from `../web/` by the Docker
image), so the UI is available at that address.
Because the browser and the app both talk to the OIDC issuer at
`http://mockoauth:8180/scopa`, add a host entry once:
`http://mockoauth:8180/tavolo`, add a host entry once:
```sh
echo "127.0.0.1 mockoauth" | sudo tee -a /etc/hosts
@@ -43,10 +44,10 @@ All configuration comes from environment variables (see `.env.example`):
| Variable | Default | Description |
|---|---|---|
| `DATABASE_URL` | `postgres://scopa:scopa@localhost:5432/scopa` | Postgres DSN for match statistics |
| `DATABASE_URL` | `postgres://tavolo:tavolo@localhost:5432/tavolo` | Postgres DSN for match statistics |
| `REDIS_URL` | unset | Redis DSN for sessions + live games. Unset falls back to in-memory stores |
| `OIDC_ISSUER` | `http://localhost:8180/scopa` | OIDC issuer URL |
| `OIDC_CLIENT_ID` | `scopa` | OIDC client id |
| `OIDC_ISSUER` | `http://localhost:8180/tavolo` | OIDC issuer URL |
| `OIDC_CLIENT_ID` | `tavolo` | OIDC client id |
| `OIDC_CLIENT_SECRET` | unset | OIDC client secret |
| `OIDC_REDIRECT_URI` | `http://localhost:8080/auth/callback` | Login callback URL |
| `GAME_TTL_SECONDS` | `86400` | Sliding TTL of a live game in Redis |
@@ -58,13 +59,13 @@ All configuration comes from environment variables (see `.env.example`):
### Redis (live games)
- `scopa:game:<uuid>` — the whole match as JSON: players (seat 0/2 = team A,
- `tavolo:game:<uuid>` — the whole match as JSON: players (seat 0/2 = team A,
1/3 = team B), hands, table, captured piles, scope, current turn, dealer,
scores, phase (`lobby``playing``finished`). Sliding TTL
(`GAME_TTL_SECONDS`).
- `scopa:code:<JOINCODE>` — the 6-character join code → game id index.
- `scopa:game:<uuid>:lock` — a short-lived lock serializing every mutation.
- `scopa:game:<uuid>:events` — a pub/sub channel carrying "state changed"
- `tavolo:code:<JOINCODE>` — the 6-character join code → game id index.
- `tavolo:game:<uuid>:lock` — a short-lived lock serializing every mutation.
- `tavolo:game:<uuid>:events` — a pub/sub channel carrying "state changed"
signals; every open WebSocket reloads the state and pushes the
personalized view to its player.
@@ -178,11 +179,11 @@ for Redis, a fake OIDC user patched onto the mixins, and `httpx` /
The Postgres schema is owned by aerich migrations in `migrations/`. The
`db-migrate` compose service runs `aerich upgrade` before the app starts.
To add a migration after changing `src/scopa/models.py`:
To add a migration after changing `src/tavolo/models.py`:
```sh
DATABASE_URL=postgres://scopa:scopa@localhost:5432/scopa .venv/bin/aerich migrate
DATABASE_URL=postgres://scopa:scopa@localhost:5432/scopa .venv/bin/aerich upgrade
DATABASE_URL=postgres://tavolo:tavolo@localhost:5432/tavolo .venv/bin/aerich migrate
DATABASE_URL=postgres://tavolo:tavolo@localhost:5432/tavolo .venv/bin/aerich upgrade
```
(`aerich init-db` produces sqlite-flavored DDL when pointed at sqlite;
@@ -194,7 +195,7 @@ baseline.)
Everything lives under `server/`:
```
src/scopa/
src/tavolo/
├── app.py # composition root: session/OIDC/Tortoise/OpenAPI mixins
├── config.py # env -> frozen Settings
├── auth.py # auth helpers (HTTP + WebSocket)