84148318494ca0e4b118a4ced6dbd08563f74ccd
- Login/Logout anchors now carry rel="external": sycamore-router intercepts same-origin anchor clicks otherwise, so the OIDC login round-trip never left the SPA (found with a real browser test) - Opponents' hidden hands render as a tidy 5x2 grid of card backs, seats have a fixed height and shrink-wrap so the table no longer jumps as cards are played - Dockerfile: cache the Rust target dir so frontend rebuilds are fast - ignore .playwright-mcp/ tooling output
scopa
Multiplayer scopone scientifico — the four-player, fixed-partnership Italian card game — as a web application:
server/— backend: Python + kaya framework, OIDC login, live games in Redis, match statistics in Postgres. See server/README.md.web/— frontend: Rust + Sycamore compiled to WebAssembly, built with Trunk. Card images are the CC0 woodcut napoletane deck traced from a 1902 Naples print (SONDLecT/woodcut-napoletane).
Run the whole stack
docker compose up --build
Postgres, Redis, a mock OIDC provider (test users alice, bob, carol,
dave), the database migrator and the app all come up together. The app —
frontend and API — listens on http://127.0.0.1:8080.
Because both the browser and the app talk to the OIDC issuer at
http://mockoauth:8180/scopa, add a host entry once:
echo "127.0.0.1 mockoauth" | sudo tee -a /etc/hosts
Development
Backend (from server/):
cd server
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/pip install -e '.[dev]'
.venv/bin/python -m unittest discover -s tests -t .
.venv/bin/mypy src
Frontend (from web/), with the backend running on :8080:
cd web
trunk serve # SPA on http://localhost:8000, /api /auth /ws proxied
Trunk proxies /api, /auth and /ws to 127.0.0.1:8080 (see
web/Trunk.toml). For the login redirect to land back on the dev server,
run the backend with:
OIDC_POST_LOGIN_REDIRECT=http://localhost:8000/ \
OIDC_POST_LOGOUT_REDIRECT=http://localhost:8000/ \
.venv/bin/granian --host 127.0.0.1 --port 8080 scopa.app:app
Card images are committed under web/assets/cards/; web/fetch-cards.sh
re-downloads them if needed.
Languages
Python
72.7%
Rust
21.3%
CSS
3.8%
Dockerfile
1.7%
Shell
0.4%
Other
0.1%