strat-gameplay-webapp/frontend-sba/types/api.ts
Cal Corum d60b7a2d60 CLAUDE: Store team display info in DB and fix lineup auto-start
Backend:
- Add game_metadata to create_game() and quick_create_game() endpoints
- Fetch team display info (lname, sname, abbrev, color, thumbnail) from
  SBA API at game creation time and store in DB
- Populate GameState with team display fields from game_metadata
- Fix submit_team_lineup to cache lineup in state_manager after DB write
  so auto-start correctly detects both teams ready

Frontend:
- Read team colors/names/thumbnails from gameState instead of useState
- Remove useState approach that failed across SSR navigation
- Fix create.vue redirect from legacy /games/lineup/[id] to /games/[id]
- Update game.vue header to show team names from gameState

Docs:
- Update CLAUDE.md to note dev mode has broken auth, always use prod

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 08:43:26 -06:00

224 lines
4.0 KiB
TypeScript

/**
* REST API Types
*
* TypeScript definitions for HTTP API requests and responses.
* These complement the WebSocket events for non-real-time operations.
*/
import type { GameListItem, CreateGameRequest, CreateGameResponse } from './game'
/**
* API error response
*/
export interface ApiError {
message: string
code?: string
field?: string
errors?: Array<{
loc: string[]
msg: string
type: string
}>
}
/**
* Paginated response wrapper
*/
export interface PaginatedResponse<T> {
items: T[]
total: number
page: number
per_page: number
has_next: boolean
has_prev: boolean
}
/**
* Game filters for list queries
*/
export interface GameFilters {
status?: 'pending' | 'active' | 'completed'
league_id?: 'sba' | 'pd'
team_id?: number
date_from?: string
date_to?: string
page?: number
per_page?: number
}
/**
* Discord OAuth callback response
*/
export interface DiscordAuthResponse {
access_token: string
refresh_token: string
expires_in: number
user: DiscordUser
}
/**
* Discord user data
*/
export interface DiscordUser {
id: string // Discord snowflake ID (gmid)
username: string
discriminator: string
avatar: string | null
email?: string
}
/**
* JWT token payload
*/
export interface JwtPayload {
user_id: string
exp: number
iat: number
}
/**
* Team data (from league API)
*/
export interface Team {
id: number
name: string
owner_id: string
league_id: 'sba' | 'pd'
}
/**
* SBA Team data (from /api/teams endpoint)
*/
export interface SbaTeam {
id: number
abbrev: string
sname: string // Short name (e.g., "Geese")
lname: string // Long name (e.g., "Everett Geese")
color: string // Hex color code
thumbnail: string | null // Team logo URL
manager_legacy: string
gmid: string | null
gmid2: string | null
division: {
id: number
division_name: string
division_abbrev: string
league_name: string
league_abbrev: string
season: number
}
}
/**
* User's teams response
*/
export interface UserTeamsResponse {
teams: Team[]
}
// ============================================================================
// API Endpoint Types
// ============================================================================
/**
* POST /api/games
*/
export type CreateGameRequestData = CreateGameRequest
export type CreateGameResponseData = CreateGameResponse
/**
* GET /api/games/:id
*/
export interface GetGameResponse {
game: GameListItem
}
/**
* GET /api/games/active
*/
export type GetActiveGamesResponse = PaginatedResponse<GameListItem>
/**
* GET /api/games/completed
*/
export type GetCompletedGamesResponse = PaginatedResponse<GameListItem>
/**
* GET /api/games/:id/history
*/
export interface PlayHistoryItem {
play_number: number
inning: number
half: 'top' | 'bottom'
outs_before: number
batter_id: number
pitcher_id: number
result_description: string
runs_scored: number
outs_recorded: number
created_at: string
}
export interface GetPlayHistoryResponse {
plays: PlayHistoryItem[]
total: number
}
/**
* DELETE /api/games/:id
*/
export interface DeleteGameResponse {
message: string
game_id: string
}
/**
* POST /api/auth/discord/callback
*/
export type DiscordCallbackRequest = {
code: string
state: string
}
export type DiscordCallbackResponse = DiscordAuthResponse
/**
* GET /api/auth/me
*/
export interface GetCurrentUserResponse {
user: DiscordUser
teams: Team[]
}
/**
* POST /api/auth/refresh
*/
export interface RefreshTokenRequest {
refresh_token: string
}
export interface RefreshTokenResponse {
access_token: string
expires_in: number
}
/**
* POST /api/games/:id/lineups
*/
export interface LineupPlayerRequest {
player_id: number
position: string
batting_order: number | null // null for pitcher in DH lineup
}
export interface SubmitLineupsRequest {
home_lineup: LineupPlayerRequest[] // 9-10 players
away_lineup: LineupPlayerRequest[] // 9-10 players
}
export interface SubmitLineupsResponse {
game_id: string
message: string
home_lineup_count: number
away_lineup_count: number
}