# SBA API Models Specification

**Purpose**: Pydantic models that exactly match SBA API responses

**File**: `backend/app/models/api_models.py` (SBA section)

---

## Overview

SBA player data comes from **1 API call**:
- `/players/:player_id?short_output=false` - Player with nested team data

Much simpler than PD - no separate ratings calls needed.

---

## Base URL

```python
SBA_API_BASE_URL = "https://api.sba.manticorum.com/"
```

---

## Model Hierarchy

```
SbaPlayerApi (player data)
  └─ team: SbaTeamApi
       ├─ manager1: SbaManagerApi
       ├─ manager2: Optional[SbaManagerApi]
       └─ division: SbaDivisionApi
```

---

## Nested Models

### SbaManagerApi

**JSON Example**:
```json
{
    "id": 3,
    "name": "Cal",
    "image": null,
    "headline": null,
    "bio": null
}
```

**Pydantic Model**:
```python
class SbaManagerApi(BaseModel):
    """SBA Manager (nested in team response)"""
    id: int
    name: str
    image: Optional[str] = None
    headline: Optional[str] = None
    bio: Optional[str] = None
```

### SbaDivisionApi

**JSON Example**:
```json
{
    "id": 41,
    "division_name": "Big Chungus",
    "division_abbrev": "BBC",
    "league_name": "SBa",
    "league_abbrev": "SBa",
    "season": 12
}
```

**Pydantic Model**:
```python
class SbaDivisionApi(BaseModel):
    """SBA Division (nested in team response)"""
    id: int
    division_name: str
    division_abbrev: str
    league_name: str
    league_abbrev: str
    season: int
```

### SbaTeamApi

**JSON Example**:
```json
{
    "id": 499,
    "abbrev": "WV",
    "sname": "Black Bears",
    "lname": "West Virginia Black Bears",
    "manager_legacy": null,
    "division_legacy": null,
    "gmid": "258104532423147520",
    "gmid2": null,
    "manager1": {
        "id": 3,
        "name": "Cal",
        "image": null,
        "headline": null,
        "bio": null
    },
    "manager2": null,
    "division": {
        "id": 41,
        "division_name": "Big Chungus",
        "division_abbrev": "BBC",
        "league_name": "SBa",
        "league_abbrev": "SBa",
        "season": 12
    },
    "mascot": null,
    "stadium": "https://i.postimg.cc/rpRZ2NNF/wvpark.png",
    "gsheet": null,
    "thumbnail": "https://i.postimg.cc/HjDc8bBF/blackbears-transparent.png",
    "color": "6699FF",
    "dice_color": null,
    "season": 12,
    "auto_draft": null
}
```

**Pydantic Model**:
```python
class SbaTeamApi(BaseModel):
    """SBA Team (nested in player response)"""
    id: int
    abbrev: str
    sname: str  # Short name
    lname: str  # Long name
    manager_legacy: Optional[str] = None
    division_legacy: Optional[str] = None
    gmid: str  # Discord Guild/Manager ID
    gmid2: Optional[str] = None
    manager1: SbaManagerApi
    manager2: Optional[SbaManagerApi] = None
    division: SbaDivisionApi
    mascot: Optional[str] = None
    stadium: Optional[str] = None
    gsheet: Optional[str] = None
    thumbnail: Optional[str] = None
    color: str  # Hex color without #
    dice_color: Optional[str] = None
    season: int
    auto_draft: Optional[bool] = None
```

---

## Player Model

### SbaPlayerApi

**API Endpoint**: `GET /players/:player_id?short_output=false`

**JSON Example**:
```json
{
    "id": 12288,
    "name": "Ronald Acuna Jr",
    "wara": 0.0,
    "image": "https://sba-cards-2024.s3.us-east-1.amazonaws.com/2024-cards/ronald-acuna-jr.png",
    "image2": null,
    "team": {
        "id": 499,
        "abbrev": "WV",
        "sname": "Black Bears",
        "lname": "West Virginia Black Bears",
        "manager_legacy": null,
        "division_legacy": null,
        "gmid": "258104532423147520",
        "gmid2": null,
        "manager1": {
            "id": 3,
            "name": "Cal",
            "image": null,
            "headline": null,
            "bio": null
        },
        "manager2": null,
        "division": {
            "id": 41,
            "division_name": "Big Chungus",
            "division_abbrev": "BBC",
            "league_name": "SBa",
            "league_abbrev": "SBa",
            "season": 12
        },
        "mascot": null,
        "stadium": "https://i.postimg.cc/rpRZ2NNF/wvpark.png",
        "gsheet": null,
        "thumbnail": "https://i.postimg.cc/HjDc8bBF/blackbears-transparent.png",
        "color": "6699FF",
        "dice_color": null,
        "season": 12,
        "auto_draft": null
    },
    "season": 12,
    "pitcher_injury": null,
    "pos_1": "RF",
    "pos_2": null,
    "pos_3": null,
    "pos_4": null,
    "pos_5": null,
    "pos_6": null,
    "pos_7": null,
    "pos_8": null,
    "last_game": null,
    "last_game2": null,
    "il_return": null,
    "demotion_week": 16,
    "headshot": null,
    "vanity_card": null,
    "strat_code": "Acuna,R",
    "bbref_id": "acunaro01",
    "injury_rating": "5p30",
    "sbaplayer": null
}
```

**Pydantic Model**:
```python
class SbaPlayerApi(BaseModel):
    """SBA Player API response"""
    id: int
    name: str
    wara: float  # Wins Above Replacement Average
    image: str  # Card image URL
    image2: Optional[str] = None
    team: SbaTeamApi
    season: int

    # Positions (up to 8)
    pos_1: Optional[str] = None
    pos_2: Optional[str] = None
    pos_3: Optional[str] = None
    pos_4: Optional[str] = None
    pos_5: Optional[str] = None
    pos_6: Optional[str] = None
    pos_7: Optional[str] = None
    pos_8: Optional[str] = None

    # Injury/status tracking
    pitcher_injury: Optional[str] = None
    last_game: Optional[str] = None
    last_game2: Optional[str] = None
    il_return: Optional[str] = None  # Injured list return date
    demotion_week: Optional[int] = None

    # Additional metadata
    headshot: Optional[str] = None
    vanity_card: Optional[str] = None
    strat_code: Optional[str] = None  # Strat-O-Matic code
    bbref_id: str  # Baseball Reference ID
    injury_rating: Optional[str] = None  # e.g., "5p30"
    sbaplayer: Optional[int] = None  # Link to another player record?
```

---

## Usage Example

```python
import httpx
from app.models.api_models import SbaPlayerApi

# Fetch and deserialize player
async with httpx.AsyncClient() as client:
    response = await client.get(
        "https://api.sba.manticorum.com/players/12288?short_output=false"
    )
    player = SbaPlayerApi(**response.json())

    # Access nested data with full type safety
    print(f"{player.name} plays for {player.team.lname}")
    print(f"Manager: {player.team.manager1.name}")
    print(f"Division: {player.team.division.division_name}")
```

---

## Differences from PD

| Aspect | SBA | PD |
|--------|-----|-----|
| **API Calls** | 1 call | 3 calls (player + batting + pitching) |
| **Primary Key** | `id` | `player_id` |
| **Name Field** | `name` | `p_name` |
| **Team Data** | Full nested object | Just `mlbclub` string |
| **Ratings** | None (simplified gameplay) | Detailed outcome probabilities |
| **Complexity** | Simple | Complex |

---

## Notes

1. **Single API call**: Much simpler than PD - all data in one response
2. **Rich team data**: Full team/manager/division hierarchy included
3. **No ratings**: SBA uses simplified result charts, not detailed probabilities
4. **Position handling**: Same pos_1-8 pattern as PD
5. **Injury tracking**: Additional fields for roster management (IL, demotion)

---

**Next**: See [game-models.md](./game-models.md) for game-optimized player models
