major-domo-v2/models/injury.py
Cal Corum 82abf3d9e6 CLAUDE: Add toggleable stats to /player command and injury system improvements
Add interactive PlayerStatsView with toggle buttons to show/hide batting and
pitching statistics independently in the /player command. Stats are hidden by
default with clean, user-friendly buttons (💥 batting,  pitching) that update
the embed in-place. Only the command caller can toggle stats, and buttons
timeout after 5 minutes.

Player Stats Toggle Feature:
- Add views/players.py with PlayerStatsView class
- Update /player command to use interactive view
- Stats hidden by default, shown on button click
- Independent batting/pitching toggles
- User-restricted interactions with timeout handling

Injury System Enhancements:
- Add BatterInjuryModal and PitcherRestModal for injury logging
- Add player_id extraction validator to Injury model
- Fix injury creation to merge API request/response data
- Add responders parameter to BaseView for multi-user interactions

API Client Improvements:
- Handle None values correctly in PATCH query parameters
- Convert None to empty string for nullable fields in database

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 23:26:08 -05:00

71 lines
2.5 KiB
Python

"""
Injury model for tracking player injuries
Represents an injury record with game timeline and status information.
"""
from typing import Optional, Any, Dict
from pydantic import Field, model_validator
from models.base import SBABaseModel
class Injury(SBABaseModel):
"""Injury model representing a player injury."""
# Override base model to make id required for database entities
id: int = Field(..., description="Injury ID from database")
season: int = Field(..., description="Season number")
player_id: int = Field(..., description="Player ID who is injured")
total_games: int = Field(..., description="Total games player will be out")
@model_validator(mode='before')
@classmethod
def extract_player_id(cls, data: Any) -> Any:
"""
Extract player_id from nested player object if present.
The API returns injuries with a nested 'player' object:
{'id': 123, 'player': {'id': 456, ...}, ...}
This validator extracts the player ID before validation:
{'id': 123, 'player_id': 456, ...}
"""
if isinstance(data, dict):
# If player_id is missing but player object exists, extract it
if 'player_id' not in data and 'player' in data:
if isinstance(data['player'], dict) and 'id' in data['player']:
data['player_id'] = data['player']['id']
return data
# Injury timeline
start_week: int = Field(..., description="Week injury started")
start_game: int = Field(..., description="Game number injury started (1-4)")
end_week: int = Field(..., description="Week player returns")
end_game: int = Field(..., description="Game number player returns (1-4)")
# Status
is_active: bool = Field(True, description="Whether injury is currently active")
@property
def return_date(self) -> str:
"""Format return date as 'w##g#' string."""
return f'w{self.end_week:02d}g{self.end_game}'
@property
def start_date(self) -> str:
"""Format start date as 'w##g#' string."""
return f'w{self.start_week:02d}g{self.start_game}'
@property
def duration_display(self) -> str:
"""Return a human-readable duration string."""
if self.total_games == 1:
return "1 game"
return f"{self.total_games} games"
def __str__(self):
status = "Active" if self.is_active else "Cleared"
return f"Injury (Season {self.season}, {self.duration_display}, {status})"