feat: WP-14 tier completion notification embeds #94
No reviewers
Labels
No Label
ai-changes-requested
ai-failed
ai-pr-opened
ai-reviewed
ai-reviewing
ai-working
ai-working
bug
enhancement
feature
in-queue
performance
security
tech-debt
todo
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cal/paper-dynasty-discord#94
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/wp14-tier-notifications"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #79 (cal/paper-dynasty-database)
Summary
helpers/evolution_notifs.pywithbuild_tier_up_embed()andnotify_tier_completion()Embed Design
#2ecc71#f1c40f#9b59b6#1abc9cTest plan
tests/test_evolution_notifications.py— 23 unit tests, all passingchannel.sendraises → no exception propagates🤖 Generated with Claude Code
LGTM — reviewed by automation.
AI Code Review
Files Reviewed
helpers/evolution_notifs.py(added)tests/test_evolution_notifications.py(added)Findings
Correctness
build_tier_up_embedcorrectly handles the T1–T3 standard path and the T4 fully-evolved path. Thenew_tier >= 4condition is correctly future-proofed (handles a hypothetical tier 5+). TheTIER_COLORS.get(new_tier, 0x2ECC71)fallback is unreachable for tier 4 (the>= 4branch runs first and hardcodes the teal color), but the fallback for truly unknown tiers is a reasonable default.old_tierandcurrent_valueare documented in the dict contract but unused in the embed builder. This is intentional — they are available to callers who need them (e.g., for logging or future use) and do not affect the embed output.notify_tier_completioncorrectly swallows all exceptions and usestier_up.get(...)with safe defaults in the error log, so a bad dict will not cause a secondary KeyError inside the except block.Security
Style & Conventions
logger = logging.getLogger("discord_app")matches the project-wide convention.helpers/evolution_notifs.pyis not exported fromhelpers/__init__.py. This is consistent with the module being a targeted utility that callers import directly rather than a broadly re-exported symbol. Not a defect.0x2ECC71) rather than the string hex pattern used inutilities/embeds.py(int(color, 16)). Both forms are valid; integer literals are the simpler and more idiomatic choice here, and the embeds module's string form is specific to that function's API design.Suggestions
@pytest.mark.asyncioon the async test methods is redundant givenasyncio_mode = autoinpytest.ini(as established by prior PRs). The decorators are harmless and tests will pass, but they can be removed for consistency with other async tests in the project that omit them.test_no_tier_ups_means_no_sendstests the calling loop pattern rather than the function itself (the loop body never executes for an empty list, sonotify_tier_completionis never called). This is a reasonable guard against accidental unconditional sends being introduced, but the docstring already explains the intent clearly.Verdict: APPROVED
Clean, well-structured addition. The module design is correct — non-fatal send, proper logging, sensible dict contract. 23 tests cover all specified paths including the T4 special case, failure path, and empty-list guard. No blocking issues.
Automated review by Claude PR Reviewer