strat-gameplay-webapp/backend/app/api/routes/teams.py
Cal Corum a87d149788 CLAUDE: Implement game creation and lineup submission workflow
Complete implementation of pre-game setup flow allowing players to create games
and submit lineups before gameplay starts.

Backend Changes:
- Extended games.py with create game, lineup submission, and game start endpoints
- Added teams.py roster endpoint with season filtering
- Enhanced SBA API client with player data fetching and caching
- Comprehensive validation for lineup submission (position conflicts, DH rules)

Frontend Changes:
- Redesigned create.vue with improved team selection and game options
- Enhanced index.vue with active/pending game filtering and navigation
- Added lineup/[id].vue for interactive lineup builder with drag-and-drop
- Implemented auth.client.ts plugin for client-side auth initialization
- Added comprehensive TypeScript types for API contracts
- Updated middleware for better auth handling

Key Features:
- Game creation with home/away team selection
- Full lineup builder with position assignment and batting order
- DH rule validation (pitcher can be excluded from batting order)
- Season-based roster filtering (Season 3)
- Auto-start game when both lineups submitted
- Real-time game list updates

Workflow:
1. Create game → select teams → set options
2. Submit home lineup → validate positions/order
3. Submit away lineup → validate positions/order
4. Game auto-starts → navigates to game page
5. WebSocket connection → loads game state

Ready for Phase F4 - connecting gameplay UI to complete the at-bat loop.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 23:57:03 -06:00

88 lines
2.4 KiB
Python

import logging
from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel
from app.services.sba_api_client import sba_api_client
logger = logging.getLogger(f"{__name__}.teams")
router = APIRouter()
class TeamResponse(BaseModel):
"""Team information response"""
id: int
abbrev: str
sname: str
lname: str
color: str | None = None
manager_legacy: str | None = None
gmid: str | None = None
gmid2: str | None = None
division: dict | None = None
@router.get("/", response_model=list[TeamResponse])
async def get_teams(season: int = Query(..., description="Season number (e.g., 3)")):
"""
Get all active teams for a season from SBA API.
Args:
season: Season number to fetch teams for
Returns:
List of active teams (excludes IL teams)
"""
try:
logger.info(f"Fetching teams for season {season}")
teams = await sba_api_client.get_teams(season=season, active_only=True)
return [
TeamResponse(
id=team["id"],
abbrev=team["abbrev"],
sname=team["sname"],
lname=team["lname"],
color=team.get("color"),
manager_legacy=team.get("manager_legacy"),
gmid=team.get("gmid"),
gmid2=team.get("gmid2"),
division=team.get("division"),
)
for team in teams
]
except Exception as e:
logger.error(f"Failed to fetch teams: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Failed to fetch teams")
@router.get("/{team_id}/roster")
async def get_team_roster(
team_id: int,
season: int = Query(..., description="Season number (e.g., 3)"),
):
"""
Get roster for a specific team from SBA API.
Args:
team_id: Team ID
season: Season number to fetch roster for
Returns:
List of players on the team's roster
"""
try:
logger.info(f"Fetching roster for team {team_id}, season {season}")
roster = await sba_api_client.get_roster(team_id=team_id, season=season)
return {"count": len(roster), "players": roster}
except Exception as e:
logger.error(f"Failed to fetch roster for team {team_id}: {e}", exc_info=True)
raise HTTPException(
status_code=500, detail=f"Failed to fetch roster for team {team_id}"
)