Remove unused `player_name` param from `_execute_refractor_test` and
unused `final` param from `update_embed` closure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Closes#147
Adds a "Refractor Progress" field to the game summary embed showing:
- Cards that tiered up during this game (⬆ Name → Tier Name)
- Cards currently ≥80% toward their next tier on either team (◈ Name (pct%))
The field is omitted entirely when there is nothing to show.
Implementation:
- _run_post_game_refractor_hook() now returns evo_result (or None on failure)
- New _build_refractor_progress_text() fetches close-to-tier cards from both
teams via refractor/cards?progress=close and formats the combined output
- complete_game() adds the field between Rewards and Highlights sections
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#144
- build_tier_up_embed() accepts optional image_url and calls set_image() when provided
- notify_tier_completion() accepts optional image_url and passes it through
- _trigger_variant_renders() now captures the render response image_url per player and returns a player_id->image_url dict
- _run_post_game_refractor_hook() triggers renders first (to obtain image URLs), then sends notifications with card art included
- Updated test_post_game_refractor_hook.py to reflect new render-before-notify ordering and image_url kwarg in notify calls
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract _run_post_game_refractor_hook() from complete_game() so the hook
logic can be tested directly without a live game session. Add 13 tests
covering endpoint ordering, tier-up notification dispatch, variant render
triggers, and non-fatal error handling.
Closes#148
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#98
Replace sequential await-in-list-comprehension with asyncio.gather() so
all card embed fetches run concurrently. Cuts 50 sequential DB round-trips
(5 packs × 5 cards × 2 calls each) down to ~2 concurrent batches.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#101
Replace sequential for-loop with asyncio.gather() so all scout
opportunities are created concurrently. Remove asyncio.sleep(2) that
added ~8s of post-display delay for multi-pack opens. create_scout_opportunity()
already guards against empty pack_cards with an early return.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces bare `except Exception: pass` with `logging.debug(..., exc_info=True)`
so badge lookup failures are traceable in logs without affecting card display.
Closes#150
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix incorrect command names (/card→/player, /roster→/team, /buy→/buy card-by-name,
/openpack→/open-packs, /scout→/scout-tokens). Update execution checklist with full
Playwright test session results — API tests, filter tests, pagination, edge cases
all passing. Note badge propagation design gap and REF-22 fix (discord#141).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adminer is exposed on host port 8080, shadowing the bot health endpoint.
Change health server default to 8081 to avoid the conflict.
Closes#130
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When page exceeds total pages, API returns empty items but non-zero
count. Now detects this case and re-fetches the last valid page.
Closes#141
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Closes#138
The test suite passes `team` to _build_refractor_response but the
function signature did not accept it. Adds `team: dict = None` so
tests for the refractor card image collection view pass without
changing any existing behavior.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use `variant is None` instead of `not variant` to avoid skipping
variant 0 tier-ups (0 is falsy in Python)
- Remove unused `team` parameter from _build_refractor_response
- Update tests to match
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds optional refractor_tier parameter to the /player slash command.
When provided: looks up the user's team refractor data, shows the
evolved card image if available, triggers on-demand render if image
not yet generated, or shows top 5 refractor cards as fallback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After refractor tier-ups, the bot hits the card render URL for each
variant card to trigger Playwright render + S3 upload as a side
effect. Fire-and-forget — failures are logged but never raised.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tier boosts shipped in Phase 2 — the teaser field in the T4 tier-up
embed was outdated. Remove it and update tests + test plan to match.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
docker-compose.yml contains hardcoded credentials (BOT_TOKEN, API_TOKEN,
RESTART_WEBHOOK_URL) and should never be committed. The *compose.yml gitignore
rule already excluded it but docker-compose.example.yml was not provided as a
reference for contributors.
- Add !docker-compose.example.yml negation to .gitignore so example is tracked
- Add docker-compose.example.yml with placeholder values for all secrets
Closes paper-dynasty-database#9
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Document all required environment variables for running the Discord bot,
including bot token, API credentials, database config, and webhook URL.
References paper-dynasty-database#9