Merge next-release into main #81
No reviewers
Labels
No Label
ai-changes-requested
ai-pr-opened
ai-reviewed
ai-reviewing
ai-working
in-next-release
status/in-progress
status/pr-open
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cal/major-domo-v2#81
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "next-release"
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?
This PR merges the next-release branch into main, incorporating all changes since the last release. It includes dependency pinning, workflow improvements, and various fixes. No conflicts with recent hot-patches as the hotfix for stale roster cache is already included in next-release.
AI Code Review
Files Reviewed
.gitea/workflows/docker-build.yml(modified — multi-channel release support)CLAUDE.md(modified — branching workflow docs)bot.py(modified — maintenance mode,_compute_command_hash()refactor)utils/permissions.py(modified —is_admin()helper, reformatting)commands/admin/management.py(modified — cosmetic reformatting only)commands/injuries/management.py(modified — team ownership verification)commands/league/submit_scorecard.py(modified — read-all-before-writes, SheetsException handler)services/roster_service.py(modified — lazy import moved to top-level)services/giphy_service.py(modified — persistent aiohttp session)services/trade_builder.py,services/transaction_builder.py(modified — previously reviewed)tests/test_injury_ownership.py(added)tests/test_models_play.py(added)Findings
Correctness
Scorecard read-all-before-writes (#80): Correct and well-motivated. All three spreadsheet reads (
read_playtable_data,read_box_score,read_pitching_decisions) now happen before any DB writes in Phase 6. WP/LP validation also moved before writes, so a missing pitcher no longer leaves orphaned play rows. The newSheetsExceptioncatch block rolls back correctly usingrollback_state—GAME_PATCHEDtriggers both wipe and play deletion;PLAYS_POSTEDtriggers only play deletion. Logic is sound.Maintenance mode (#28):
self.maintenance_mode: bool = Falseis set on the bot in__init__, andtree.interaction_checkreads it. The/admin-maintenancecommand should toggleself.bot.maintenance_mode. I didn't see the toggle logic in this diff (it lives inmanagement.py), but checking the current file should confirm it was wired up correctly.is_admin()helper (#55): Clean implementation. Theisinstance(interaction.user, discord.Member)guard correctly handles DM contexts. Used in_verify_team_ownershipappropriately._compute_command_hash()refactor: Removes duplication between_should_sync_commandsand_save_command_hash— straightforward and correct.Injury ownership check (#18):
_verify_team_ownershipis correctly implemented for/injury set-newand/injury clear. Admin bypass works (isinstance guard + administrator check). Theplayer.team_idguard (returns True if no team data) is reasonable defensive coding.is_same_organizationhandles MiL affiliates correctly.Style & Conventions
Redundant lazy import in
_verify_team_ownership(commands/injuries/management.py~line 92): The PR addsfrom services.team_service import team_serviceat the top level (line 22), but_verify_team_ownershipalso containsfrom services.team_service import team_serviceas a mid-method lazy import. CLAUDE.md explicitly states "Never add lazy imports to middle of file." Since the top-level import was added in this PR, the inline import inside_verify_team_ownershipis redundant and should be removed. The pre-existing lazy imports ininjury_roll(line 510 and 700) are out-of-scope for this PR.Stale TODO comment (
commands/injuries/management.py~line 515):injury_rollstill has# TODO: Add team ownership verificationplaceholder comments from before the fix was implemented. These weren't introduced by this PR but were in scope of the ownership work — worth cleaning up.Security
No issues found. The
is_admin()guard is properly placed before bypassing ownership checks. No hardcoded credentials, no user input passed to dangerous APIs, no injection vectors.Test Coverage
tests/test_injury_ownership.py(245 lines) — thorough coverage of_verify_team_ownership: admin bypass, owner passes, non-owner blocked, no-team case, no-team-id case. Usesmodel_constructto skip Pydantic validation (correct pattern for this codebase).tests/test_models_play.py— added for the play model.Suggestions
_verify_team_ownership, deletefrom services.team_service import team_service— the top-level import added in this same PR already provides it.injury_roll: Remove the three-line "# Note / # For now / # TODO" block at line 515 since the ownership infrastructure now exists (and could be applied toinjury_rollin a follow-up if desired).Verdict: COMMENT
This is a solid release merge. The scorecard read-all-before-writes fix is well-designed and correctly implemented. The injury ownership check is thorough with good test coverage. The maintenance mode wiring is clean. The one convention issue (redundant lazy import inside
_verify_team_ownership) violates CLAUDE.md but is minor — the top-level import works correctly, the inline one is just dead weight. Not blocking.Automated review by Claude PR Reviewer