Skip to main content

STACK_BACKOFFICE_TOURNAMENT - Documentación para Desarrolladores

Descripción General

Stack de administración de torneos desde el backoffice. Gestiona ediciones de torneo por categoría/temporada, partidos (matches), formato de fases (liga/playoff), equipos y vinculación/desvinculación masiva de jugadores a equipos de torneo.

Arquitectura

STACK_BACKOFFICE_TOURNAMENT/
├── botournament.yaml # Template SAM (producción)
├── botournamentDev313.yaml # Template SAM (dev, Python 3.13)
├── build_botournament.sh
├── layer/
│ ├── database_botournament/ # Lógica de dominio
│ │ └── database.py
│ ├── querys_botournament/ # Templates SQL
│ │ └── query.py
│ ├── response_formatter_botournament/
│ │ └── response_formatter.py
│ └── utils_botournament/
│ └── utils.py # verify_avatar(), paginación
└── services/
├── category/ # Torneos por categoría/temporada
├── category-fixture/ # Fixtures por categoría
├── edition/ # CRUD ediciones de torneo
├── edition-detail/ # Detalle de edición
├── edition-detail-team/ # Equipos en edición
├── edition-format/ # Formato de torneo (fases)
├── edition-format-detail/ # Detalle fixture por fase (100s/512MB)
├── matches/ # Partidos: GET/PUT/DELETE
├── players-teams-link/ # Vincular jugadores batch (CTE/JSONB)
├── players-teams-unlink/ # Desvincular jugadores batch
└── team/ # Equipos con búsqueda/paginación

Runtime y Configuración

PropiedadValor
Python3.13
ArquitecturaARM64
Timeout default10s
Memoria default256MB
AuthAWS Cognito JWT

Funciones con configuración especial:

FunciónTimeoutMemoriaNotas
edition_format_detail GET100s512MBQueries complejos de fixture
matches GET/PUT/DELETE100s256MBOperaciones batch
category_fixture GET100s256MBPaginación de fixtures
players_teams_link PUT100s256MBBatch JSONB CTE
players_teams_unlink PUT100s256MBBatch JSONB CTE

Warming configurado:

  • EditionGet — EventBridge warming para anti-cold-start

Es la operación más compleja del stack. Usa PostgreSQL JSONB + CTEs:

# Input:
{
"link": [
{"edition_id": 101, "team_id": 10, "players": [1, 2, 3]},
{"edition_id": 101, "team_id": 11, "players": [4, 5]}
]
}

# SQL Pattern - JSONB UPSERT con CTE:
# 1. Deserializa array JSONB en filas
# 2. JOIN con tournament_team para resolver IDs
# 3. INSERT ON CONFLICT DO UPDATE en tournament_team_userprofile
# 4. Crea registros player_stats

Mismo patrón pero sets status = 'canceled' en tournament_team_userprofile.

Validaciones:

  • Solo usuarios con rol webuser pueden ejecutar link/unlink
  • Retorna breakdown detallado: linked/failed, summary por equipo

Gestión de Partidos (Matches)

GET:

  • Paginado con total_elements, total_pages
  • Filtra por torneo, grupo, número de fecha

PUT:

  • Individual (match_id específico) o batch (toda la fecha)
  • Solo actualiza partidos no jugados
  • Sincroniza cambios con DynamoDB

DELETE:

  • Retorna 400 si algún partido de la fecha ya fue jugado
  • Elimina por tournament + group_id + match_number

Sistema de Ediciones

Jerarquía:

Liga → Categoría → Temporada → Edición → Fases → Fixtures → Partidos

Endpoints de edición:

  • edition — CRUD principal con paginación por temporada
  • edition_detail — Detalle con verify_avatar
  • edition_format — Fases configuradas (league/playoff)
  • edition_format_detail — Fixtures de una fase específica (heavy query)

Tablas de Base de Datos

PostgreSQL:

  • tournament — Torneos/ediciones
  • tournament_fixture — Fixtures de torneo
  • tournament_match — Partidos
  • tournament_team — Equipos en torneo
  • tournament_team_userprofile — Jugadores en equipos de torneo
  • player_stats — Estadísticas de jugadores
  • team — Datos de equipos
  • team_userprofile — Relación general jugador-equipo
  • league — Ligas
  • category — Categorías
  • season — Temporadas

⚠️ Issues Conocidos

1. Imports incorrectos

edition/post.py y edition/delete.py importan de database_nutrition en vez de database_botournament:

# ❌ Actual (incorrecto)
import database_nutrition.database as database_source

# ✅ Debería ser
import database_botournament.database as database_source

2. Riesgo de SQL Injection

Algunos queries usan f-strings para interpolar valores en vez de executeQueryNotInjection:

# ❌ Vulnerable
sql = f"SELECT * FROM tournament WHERE id = {id}"

# ✅ Seguro
sql = "SELECT * FROM tournament WHERE id = %(id)s"
common_source.executeQueryNotInjection(sql, {"id": id})

3. League ID hardcodeado

Un query tiene id_league = 665 hardcodeado. Debería ser parámetro.

Build y Deploy

cd STACK_BACKOFFICE_TOURNAMENT
sudo bash ./build_botournament.sh 1 -d # Dev local
sudo bash ./build_botournament.sh 2 -d # Dev deploy
sudo bash ./build_botournament.sh 2 -q # QA deploy
sudo bash ./build_botournament.sh 2 -p # Prod deploy