70 lines
2.1 KiB
Markdown
70 lines
2.1 KiB
Markdown
---
|
|
id: TASK-163
|
|
title: Add player personal stats endpoint
|
|
status: done
|
|
type: backend
|
|
team: Backend Senior
|
|
supporting_teams: [Arquitecto de Base de Datos, Arquitecto Python]
|
|
roadmap_item: foundation
|
|
priority: medium
|
|
---
|
|
|
|
# TASK-163 - Add player personal stats endpoint
|
|
|
|
## Goal
|
|
|
|
Implementar únicamente el endpoint backend de estadísticas personales:
|
|
`GET /api/stats/players/{player_id}`.
|
|
|
|
Use existing RCON materialized data for weekly/monthly context.
|
|
|
|
## Files modified
|
|
|
|
- `backend/app/rcon_historical_player_stats.py` (nuevo)
|
|
- `backend/app/payloads.py`
|
|
- `backend/app/routes.py`
|
|
|
|
## Endpoint created
|
|
|
|
- `GET /api/stats/players/{player_id}`
|
|
- Parámetros:
|
|
- `server_id` (opcional, alias `server`)
|
|
- `timeframe` (`weekly` | `monthly`, validación en ruta)
|
|
- Respuesta:
|
|
- `status`
|
|
- `data.player_id`
|
|
- `data.player_name`
|
|
- `data.matches_considered`
|
|
- `data.kills`
|
|
- `data.deaths`
|
|
- `data.teamkills`
|
|
- `data.kd_ratio`
|
|
- `data.kills_per_match`
|
|
- `data.deaths_per_match`
|
|
- `data.window_start`
|
|
- `data.window_end`
|
|
- `data.window_kind`
|
|
- `data.weekly_ranking`
|
|
- `data.monthly_ranking`
|
|
- `data.source`
|
|
|
|
## Validaciones realizadas
|
|
|
|
- `python -m compileall backend/app`
|
|
- `scripts/run-integration-tests.ps1`
|
|
- Endpoint manual con backend levantado y `Invoke-WebRequest`:
|
|
- Query corta: `/api/stats/players/a?timeframe=weekly` => `200 OK`
|
|
- Query normal: `/api/stats/players/valid-player-uuid?timeframe=monthly` => `200 OK`
|
|
- Sin resultados: `/api/stats/players/nonexistent-9999?timeframe=weekly` => `200 OK` con métricas en cero
|
|
- Rechazo de timeframe inválido: `/api/stats/players/a?timeframe=yearly` => `400 Bad Request`
|
|
|
|
## Limitaciones conocidas
|
|
|
|
- El ranking semanal/mensual incluye solo jugadores con `kills > 0`.
|
|
- `source_range` puede ir en `null` cuando no hay datos materializados.
|
|
- `player_name` se resuelve al `player_id` si no hay nombre persistido en el rango solicitado.
|
|
|
|
## Siguiente task recomendada
|
|
|
|
- Endpoint de vista inicial de estadísticas personales del jugador en frontend (consumo del contrato `GET /api/stats/players/{player_id}`).
|