# Missing Backend API Data This document outlines data that the frontend expects but is not currently provided by the backend API. These features would enhance the match analysis experience. --- ## Impact Summary | Field | Severity | Status | Impact | | --------------- | ------------ | ------------- | ----------------------------- | | KAST % | **Critical** | Missing | Players display 0% KAST | | ADR | **Critical** | Missing | Statistics incomplete | | Weapon Kills | **High** | Missing | Weapon stats show 0 kills | | Round Winner | **High** | Missing | No round outcome analysis | | Win Reason | **High** | Missing | Can't show how rounds ended | | Headshot % | Medium | Partial | Sometimes missing | | Damage Stats | Medium | Not extracted | Data sent but unused | | Utility Stats | Medium | Missing | Grenade analysis unavailable | | Per-Round Stats | Medium | Missing | No round-by-round performance | | Loss Bonus | Low | Missing | Economy analysis incomplete | --- ## 1. Critical: KAST Percentage **Endpoint**: `GET /match/{id}` (player stats) **Location in Frontend**: `src/lib/api/players.ts:49-76` **Issue**: KAST (Kill/Assist/Survive/Trade) is completely unavailable. Frontend returns placeholder 0. ```typescript // Current workaround in players.ts const totalKast = recentMatches.reduce((sum, _m) => { // KAST is a percentage, we need to calculate it // For now, we'll use a placeholder return sum + 0; }, 0); ``` **Affected Components**: - `/player/[id]/+page.svelte` - Player profile stats chart - `/match/[id]/+page.svelte:28-29` - Team average KAST - Match scoreboard KAST% column **Expected Format**: ```json { "players": [ { "kast": 72.5 } ] } ``` **Backend Implementation**: Calculate per player per match: ``` KAST% = (Rounds with Kill + Rounds with Assist + Rounds Survived + Rounds Traded) / Total Rounds * 100 ``` --- ## 2. Critical: Average Damage per Round (ADR) **Endpoint**: `GET /match/{id}` (player stats) **Location in Frontend**: `src/lib/types/Match.ts:114-115` **Issue**: ADR not provided. Components use `player.adr || 0` fallback. **Affected Components**: - `/match/[id]/+page.svelte:27, 44, 83` - Team and player ADR - `/match/[id]/damage/+page.svelte` - Damage analysis page - `/player/[id]/+page.svelte:280` - Player profile **Expected Format**: ```json { "players": [ { "adr": 85.3 } ] } ``` **Backend Implementation**: ``` ADR = Total Damage to Enemies / Rounds Played ``` --- ## 3. High: Weapon Kill Counts **Endpoint**: `GET /match/{id}/weapons` **Location in Frontend**: `src/lib/api/transformers/weaponsTransformer.ts:85-87` **Issue**: Backend provides damage/hits but NOT kill counts. All weapons show 0 kills. ```typescript // Current workaround weapon_stats.push({ // Kill data not available - API only provides hit/damage events kills: 0, // HARDCODED ZERO - should be from backend damage: stats.damage, hits: stats.hits }); ``` **Expected Format**: ```json { "weapons": { "7": { "kills": 12, "damage": 1847, "hits": 45 } } } ``` **Backend Implementation**: Correlate `player_hurt` events with `player_death` events to determine which weapon dealt the killing blow. --- ## 4. High: Round Winner & Win Reason **Endpoint**: `GET /match/{id}/rounds` **Location in Frontend**: `src/lib/api/transformers/roundsTransformer.ts:71-76` **Issue**: Backend only returns economy data, not round outcomes. ```typescript // Current hardcoded placeholders rounds.push({ round: roundNum + 1, winner: 0, // HARDCODED - should be 2 (T) or 3 (CT) win_reason: '', // HARDCODED - should be enum players }); ``` **Currently Returns**: ```json { "0": { "player_id": [bank, equipment, spent] }, "1": { "player_id": [bank, equipment, spent] } } ``` **Expected Format**: ```json { "0": { "winner": 2, "win_reason": "bomb_exploded", "players": { "player_id": [bank, equipment, spent] } } } ``` **Win Reason Values**: | Value | Description | |-------|-------------| | `elimination` | All enemies killed | | `bomb_defused` | CT defused the bomb | | `bomb_exploded` | Bomb detonated (T win) | | `time` | Round timer expired (CT win) | | `target_saved` | Hostage rescued (rare) | **Backend Implementation**: Extract from `RoundEnd` game events in demo parser. --- ## 5. Medium: Damage Statistics (dmg_enemy, dmg_team) **Endpoint**: `GET /match/{id}` (player stats) **Location in Frontend**: `src/lib/api/transformers.ts:96` **Issue**: Backend sends `dmg` as `Record` but fields aren't extracted. ```typescript // In transformer - data received but not mapped dmg?: Record; // NOT EXTRACTED to dmg_enemy/dmg_team ``` **Type Definition** (`src/lib/types/Match.ts:134-135`): ```typescript dmg_enemy?: number; // Damage dealt to enemies dmg_team?: number; // Damage dealt to team (friendly fire) ``` **Expected Format**: ```json { "players": [ { "dmg": { "enemy": 2847, "team": 45 } } ] } ``` **Fix**: Either: 1. Backend returns flat `dmg_enemy` and `dmg_team` fields, OR 2. Frontend transformer extracts from `dmg.enemy` and `dmg.team` --- ## 6. Medium: Utility/Grenade Statistics **Endpoint**: `GET /match/{id}` (player stats) **Location in Frontend**: `src/lib/types/Match.ts:144-148` **Issue**: Not provided by backend at all. **Missing Fields**: ```typescript ud_he?: number; // HE grenade damage dealt ud_flames?: number; // Molotov/Incendiary damage dealt ud_flash?: number; // Flash grenades thrown (count) ud_smoke?: number; // Smoke grenades thrown (count) ud_decoy?: number; // Decoy grenades thrown (count) ``` **Expected Format**: ```json { "players": [ { "ud_he": 156, "ud_flames": 89, "ud_flash": 8, "ud_smoke": 12, "ud_decoy": 2 } ] } ``` **Backend Implementation**: Count grenade events and sum damage from `player_hurt` events where weapon is HE/molotov/incendiary. --- ## 7. Medium: Per-Round Player Statistics **Endpoint**: `GET /match/{id}/rounds` **Issue**: No per-round performance data for players. **Missing Fields per Player per Round**: ```typescript kills_in_round?: number; // Kills in this specific round damage_in_round?: number; // Damage dealt this round assists_in_round?: number; // Assists this round ``` **Expected Format**: ```json { "1": { "winner": 2, "win_reason": "elimination", "players": { "76561198012345678": { "bank": 4000, "equipment": 3750, "spent": 2900, "kills": 2, "damage": 187, "assists": 1 } } } } ``` **Backend Implementation**: Aggregate `player_death` and `player_hurt` events per round, grouped by attacker. --- ## 8. Low: Loss Bonus Tracking **Endpoint**: `GET /match/{id}/rounds` **Issue**: Not tracked in backend. **Missing Fields per Team per Round**: ```typescript loss_streak?: number; // Consecutive round losses (0-4) loss_bonus?: number; // Current loss bonus amount ``` **CS2 Loss Bonus Scale**: | Consecutive Losses | Bonus | |-------------------|-------| | 0 | $1,400 | | 1 | $1,900 | | 2 | $2,400 | | 3 | $2,900 | | 4+ | $3,400 | **Backend Implementation**: Track `RoundEnd` events and maintain loss counter per team, resetting on win. --- ## 9. Optional Fields (Expected Gaps) These fields are intentionally optional due to data availability: | Field | Reason | | ------------ | ---------------------------------------------------------- | | `replay_url` | Only available for matches < 4 weeks old (Valve retention) | | `share_code` | Not all matches have share codes | | `tick_rate` | May not be in older demos | | `game_mode` | Legacy CS:GO matches don't have this | | `avg_ping` | Not always recorded in demos | --- ## Backend Implementation Checklist ### Priority 1: Critical - [ ] Add KAST calculation per player per match - [ ] Add ADR calculation per player per match - [ ] Add weapon kill tracking (correlate damage with death events) - [ ] Add round winner from `RoundEnd` events - [ ] Add win_reason enumeration from `RoundEnd` events ### Priority 2: High - [ ] Extract `dmg_enemy` and `dmg_team` in player stats - [ ] Add utility grenade statistics (ud_he, ud_flames, ud_flash, ud_smoke, ud_decoy) - [ ] Ensure `hs_percent` is always calculated ### Priority 3: Medium - [ ] Add per-round player stats (kills, damage, assists per round) - [ ] Add loss bonus tracking per team per round - [ ] Ensure `tick_rate` is always provided when available --- ## Frontend Readiness The frontend already has: - Type definitions for all fields (`src/lib/types/`) - Components ready to display data (using fallbacks currently) - Transformers prepared to extract nested data - UI for all features (showing placeholders/zeros) Once backend provides this data, frontend will automatically display it. --- ## API Response Examples ### Ideal Match Response ```json { "match_id": "123456", "players": [ { "id": "76561198012345678", "name": "Player1", "kills": 25, "deaths": 18, "assists": 4, "kast": 72.5, "adr": 85.3, "hs_percent": 45.2, "dmg_enemy": 2847, "dmg_team": 12, "ud_he": 156, "ud_flames": 89, "ud_flash": 8, "ud_smoke": 12 } ] } ``` ### Ideal Rounds Response ```json { "1": { "winner": 2, "win_reason": "bomb_exploded", "t_loss_streak": 0, "ct_loss_streak": 1, "players": { "76561198012345678": { "bank": 4000, "equipment": 3750, "spent": 2900, "kills": 2, "damage": 187 } } } } ``` ### Ideal Weapons Response ```json { "weapons": { "7": { "name": "AK-47", "kills": 12, "damage": 1847, "hits": 45, "headshots": 8 } } } ```