Feature 1.38.0: BGG mechanics and best-with-N data with backfill (game roulette, phase 1) #94

Merged
pyaniz merged 1 commit from staging into main 2026-10-24 23:40:38 -05:00
Owner

Type: Feature (minor) - VERSION 1.37.3 -> 1.38.0. Phase 1 of .gsd/proposals/game-roulette.md (not committed): the data the roulette needs. No visible roulette yet.

What

  • Migration V59: games.mechanics TEXT[], best_players INT[], recommended_players INT[]. NULL = not fetched yet, empty = BGG has none.
  • shared/game_details.py (pure, tested): mechanics from the boardgamemechanic links; the suggested_numplayers poll -> recommended (Best + Recommended votes outnumber Not Recommended, Best counts always included) and best (most Best votes, ties keep all); polls under 5 votes ignored; 8+ = 8. The existing category/type helpers moved here (router imports them under the old names).
  • Import and collection sync save the new fields from the /thing payload they already fetch. A sync's "known games" shortcut now also requires mechanics IS NOT NULL, so syncing refreshes games that lack them (a natural backfill for each user's collection).
  • Backfill features/games/backfill.py: next ~40 games with a BGG id and mechanics IS NULL, fetched through the existing get_game_details_many (batches of 20, backoff), stored together with missing categories/types. If BGG answers nothing the chunk is left untouched; a game BGG no longer returns is stored as 'none' so it is not retried forever.
    • GET /api/admin/game-data-status, POST /api/admin/backfill-game-data?limit=40 (global admin).
    • Admin page: new Game data tab with Refresh game data, progress bar, stop button, and a stop after three empty answers in a row.
    • backend/scripts/backfill_game_data.py for the Docker deployment.
  • Docs: docs/features/Collections.md.

Testing

  • 9 parser tests (tests/test_game_details.py) and 4 backfill tests with a fake DB and fake BGG (tests/test_backfill_game_data.py) pass; ratings and permission tests still pass; npm run build passes.
  • Not run against the real BGG or a database: the poll structure follows BGG's documented XML (poll name=suggested_numplayers, results numplayers, result value/numvotes). On staging please: apply V59, open Administration > Game data, run the refresh, and confirm the remaining count goes to 0.

🤖 Generated with Claude Code

**Type:** Feature (minor) - VERSION 1.37.3 -> 1.38.0. Phase 1 of `.gsd/proposals/game-roulette.md` (not committed): the data the roulette needs. No visible roulette yet. ## What - **Migration V59**: `games.mechanics TEXT[]`, `best_players INT[]`, `recommended_players INT[]`. `NULL` = not fetched yet, empty = BGG has none. - **`shared/game_details.py`** (pure, tested): mechanics from the `boardgamemechanic` links; the *suggested_numplayers* poll -> `recommended` (Best + Recommended votes outnumber Not Recommended, Best counts always included) and `best` (most Best votes, ties keep all); polls under 5 votes ignored; `8+` = 8. The existing category/type helpers moved here (router imports them under the old names). - **Import and collection sync** save the new fields from the `/thing` payload they already fetch. A sync's "known games" shortcut now also requires `mechanics IS NOT NULL`, so syncing refreshes games that lack them (a natural backfill for each user's collection). - **Backfill** `features/games/backfill.py`: next ~40 games with a BGG id and `mechanics IS NULL`, fetched through the existing `get_game_details_many` (batches of 20, backoff), stored together with missing categories/types. If BGG answers nothing the chunk is left untouched; a game BGG no longer returns is stored as 'none' so it is not retried forever. - `GET /api/admin/game-data-status`, `POST /api/admin/backfill-game-data?limit=40` (global admin). - Admin page: new **Game data** tab with **Refresh game data**, progress bar, stop button, and a stop after three empty answers in a row. - `backend/scripts/backfill_game_data.py` for the Docker deployment. - Docs: `docs/features/Collections.md`. ## Testing - 9 parser tests (`tests/test_game_details.py`) and 4 backfill tests with a fake DB and fake BGG (`tests/test_backfill_game_data.py`) pass; ratings and permission tests still pass; `npm run build` passes. - **Not run against the real BGG or a database**: the poll structure follows BGG's documented XML (`poll name=suggested_numplayers`, `results numplayers`, `result value/numvotes`). On staging please: apply V59, open Administration > Game data, run the refresh, and confirm the remaining count goes to 0. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Feature: store BGG mechanics and best / recommended player counts, with backfill (1.38.0)
All checks were successful
Build and Publish Containers / build-and-push (push) Successful in 45s
Mirror to GitHub / mirror (push) Successful in 23s
fc2df1a293
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
pyaniz merged commit 0ccda32256 into main 2026-10-24 23:40:38 -05:00
Sign in to join this conversation.
No description provided.