Release: Scouting feature + bug fixes + cleanup #74

Merged
cal merged 16 commits from next-release into main 2026-03-09 13:26:17 +00:00
Owner

Summary

New Features

  • Scouting — Wonder Pick-style social pack opening: scout a pack to reveal cards for yourself and others to claim
    • Limited to Standard and Premium packs
    • Simplified scout view with rarity symbols aligned to system colors
    • Cards link to player details; pack_id tracked on scouted cards
    • Discord timestamps for expiration display

Bug Fixes

  • API logging — Removed hardcoded master_debug = True flag that flooded production logs with full request/response payloads (#28)
  • API error handling — Catch aiohttp.ClientError in all API call functions to prevent unhandled crashes on network failures (#29)
  • Sheets import — Removed duplicate sheets.open_by_key() call in get_full_roster_from_sheets (#30)
  • Owner check — Updated owner_only decorator to use correct Discord user ID
  • Scouting fixes — Fixed missing test fixtures, PR review bugs, and consolidation cleanup

Cleanup

  • Deleted stale cogs/players.py.backup (#35)
  • Fixed test suite: test_error_handling_and_logging now invokes actual cog callbacks (#39)

CI/CD

  • Docker build workflow fixes (3 commits)

Resolved Issues

Closes #28, #29, #30, #35, #39

## Summary ### New Features - **Scouting** — Wonder Pick-style social pack opening: scout a pack to reveal cards for yourself and others to claim - Limited to Standard and Premium packs - Simplified scout view with rarity symbols aligned to system colors - Cards link to player details; `pack_id` tracked on scouted cards - Discord timestamps for expiration display ### Bug Fixes - **API logging** — Removed hardcoded `master_debug = True` flag that flooded production logs with full request/response payloads (#28) - **API error handling** — Catch `aiohttp.ClientError` in all API call functions to prevent unhandled crashes on network failures (#29) - **Sheets import** — Removed duplicate `sheets.open_by_key()` call in `get_full_roster_from_sheets` (#30) - **Owner check** — Updated `owner_only` decorator to use correct Discord user ID - **Scouting fixes** — Fixed missing test fixtures, PR review bugs, and consolidation cleanup ### Cleanup - Deleted stale `cogs/players.py.backup` (#35) - Fixed test suite: `test_error_handling_and_logging` now invokes actual cog callbacks (#39) ### CI/CD - Docker build workflow fixes (3 commits) ## Resolved Issues Closes #28, #29, #30, #35, #39
cal added 22 commits 2026-03-09 13:20:52 +00:00
When a player opens a pack, a scout opportunity is posted to #pack-openings
with face-down card buttons. Other players can blind-pick one card using
daily scout tokens (2/day), receiving a copy. The opener keeps all cards.

New files:
- discord_ui/scout_view.py: ScoutView with dynamic buttons and claim logic
- helpers/scouting.py: create_scout_opportunity() and embed builder
- cogs/economy_new/scouting.py: /scout-tokens command and cleanup task

Modified:
- helpers/main.py: Hook into open_st_pr_packs() after display_cards()
- paperdynasty.py: Register scouting cog

Requires new API endpoints in paper-dynasty-database (scout_opportunities).
Tracks #44.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Consolidate SCOUT_TOKENS_PER_DAY and get_scout_tokens_used() into
  helpers/scouting.py (was duplicated across 3 files)
- Add midnight_timestamp() utility to helpers/utils.py
- Remove _build_scouted_ids() wrapper, use self.claims directly
- Fix build_scout_embed return type annotation
- Use Discord <t:UNIX:R> relative timestamps for scout window countdown
- Add 66-test suite covering helpers, ScoutView, and cog

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix int_timestamp() no-arg path returning seconds instead of
  milliseconds, which would silently break the daily scout token cap
  against the real API
- Acknowledge double-click interactions with ephemeral message instead
  of silently returning (Discord requires all interactions to be acked)
- Reorder scout flow: create card copy before consuming token so a
  failure doesn't cost the player a token for nothing
- Move build_scouted_card_list import to top of scout_view.py
- Remove unused asyncio import from helpers/scouting.py
- Fix footer text inconsistency ("One scout per player" everywhere)
- Update tests for new operation order and double-click behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reviewed-on: #50
fix: update owner_only to use Cal's correct Discord ID
All checks were successful
Build Docker Image / build (push) Successful in 1m22s
ed00a97c0d
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix: align scouting rarity symbols with system colors
All checks were successful
Build Docker Image / build (push) Successful in 1m22s
77c3f3004c
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix: add pack_id to scouted card creation, enhance embed with card links
All checks were successful
Build Docker Image / build (push) Successful in 1m16s
8e605c2140
- Include pack_id in db_post("cards") payload (API requires it)
- Player names now link to card image URLs in scout embed
- Display format: "🟡 All-Star — [2023 Mike Trout](card_image_url)"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix: add missing pack, description, image fields to scouting test fixtures
All checks were successful
Build Docker Image / build (push) Successful in 51s
e160be4137
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: limit scouting to Standard/Premium packs, simplify scout view
All checks were successful
Build Docker Image / build (push) Successful in 1m17s
da55cbe4d4
- Add SCOUTABLE_PACK_TYPES env var (default: Standard,Premium) to control
  which pack types offer scout opportunities
- Unify embed construction into build_scout_embed() — removes 3 near-duplicate
  embed builders across scout_view.py and scouting.py
- Replace manual total_scouts counter with derived property from claims dict
- Remove redundant db_get("current") API call per scout click — use PD_SEASON
- Remove duplicate expiry computation in create_scout_opportunity
- Move send_to_channel to top-level import, remove redundant local import
- Update tests to match simplified code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backup file was checked in with unused imports (requests, pygsheets),
adding noise to git grep, IDEs, and code review.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous test patched api_calls.db_get and pygsheets.authorize then
called those mocks directly—never invoking any cog method. The test
passed even when all cog code was deleted.

Replace with a test that retrieves the real pull_roster_command.callback
from the cog instance, patches dependencies at the correct module-level
names, calls the callback, and asserts ctx.send was called with the
expected error message. If the cog cannot be imported, the test skips
gracefully via pytest.skip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DNS failures and refused connections raised raw aiohttp errors to Discord
users. Added except aiohttp.ClientError handlers to db_get, db_patch,
db_post, db_put, and db_delete — each logs the error and raises
DatabaseError for consistent handling upstream.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove master_debug = True and replace all conditional INFO/DEBUG log
calls with unconditional logger.debug(). Also switches log_return_value
to logger.debug and removes the associated dead commented-out code.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reviewed-on: #53
Reviewed-on: #54
Reviewed-on: #56
Reviewed-on: #57
Merge pull request 'fix: remove hardcoded master_debug flag from api_calls.py (#28)' (#58) from ai/paper-dynasty-discord-28 into next-release
All checks were successful
Build Docker Image / build (push) Successful in 1m5s
Build Docker Image / build (pull_request) Successful in 1m33s
1c3ef0935e
Reviewed-on: #58
cal force-pushed next-release from 1c3ef0935e to 096176fe63 2026-03-09 13:23:04 +00:00 Compare
cal merged commit 5ce270d183 into main 2026-03-09 13:26:17 +00:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cal/paper-dynasty-discord#74
No description provided.