STACK_TORNEOS - Documentación para Desarrolladores
Descripción General
Stack principal de torneos para usuarios finales de MAS10. Es el stack más grande (~35 servicios, 70+ endpoints). Gestiona partidos (carga de resultados con estadísticas, firmas, árbitro), fixtures, tablas de posiciones (5 tipos con materialized views), sistema completo de picaditos (partidos casuales con grupos, miembros, filtros), postulaciones de jugadores/equipos (mercado de pases), invitaciones con push notifications, credenciales de liga, documentos, items favoritos, y torneos demo para onboarding.
Arquitectura
STACK_TORNEOS/
├── torneos.yaml # Template SAM (~70 funciones Lambda)
├── build_torneos.sh
├── layer/
│ ├── database_torneos/ # Lógica de dominio pesada
│ │ └── database.py
│ ├── querys_torneos/
│ │ └── query.py
│ └── utils_torneos/
│ └── utils.py
├── perfiles/ # Endpoints públicos de perfil/torneo
│ ├── torneo/
│ │ ├── statistics/ # Estadísticas públicas (cron 4min)
│ │ └── teams/ # Equipos públicos
└── services/
├── current-localitys/ # Localidades
├── data-api-football/ # Datos de fútbol externo
├── favourite-items/ # Favoritos CRUD
├── ficha-partido/ # Feed de noticias v1
├── ficha-partido-v3/ # Feed de noticias v3
├── fixture-matches/ # Estructura de fixture
├── get-note-type/ # Tipos de notas
├── get-team-user/ # Usuarios de equipo
├── invitation/ # Invitaciones con FCM
├── league-by-user/ # Liga del usuario
├── leave-team/ # Abandonar equipo
├── match/ # Carga de resultados (POST/PUT)
├── match-details/ # Sponsors, liga, fecha
├── match-veedor/ # Carga del árbitro
├── match-v2/ # Carga flexible (legacy 3.9)
├── my-postulation/ # CRUD postulaciones (800s!)
├── pi-create-match/ # Crear picadito
├── pi-group/ # Grupos de picadito
├── pi-matches/ # Buscar picaditos (200s)
├── pi-members-match/ # Miembros de picadito
├── pi-my-matches/ # Mis picaditos
├── postulations/ # Buscar postulaciones (filtros)
├── rancking-fans-by-tournament/ # Ranking de fans
├── score/ # Score de equipo
├── select-team/ # Seleccionar equipo
├── send-code/ # Unirse con código
├── statistics_v2/ # Tablas posiciones (200s/1024MB)
├── statistics-details/ # Detalle de estadísticas
├── tournament-demo/ # Demo (cron dominical)
├── tournament-friendly/ # Torneos amistosos
├── user-by-type/ # Usuarios por tipo
├── validate_credential/ # Credenciales de liga
└── document-user-edition/ # Documentos (apto médico, TyC, permiso)
Runtime y Configuración
| Propiedad | Valor |
|---|---|
| Python | 3.13 (excepto match-v2: 3.9) |
| Arquitectura | ARM64 |
| Timeout default | 10s |
| Memoria default | 512MB |
| Auth | Cognito JWT (mayoría) |
Funciones con configuración especial:
| Función | Timeout | Memoria | Notas |
|---|---|---|---|
| ficha-partido / feed_mas10 | 100s | 1024MB | Feed completo con sponsors |
| statistics / statistics_v2 | 200s | 1024MB | Materialized views |
| my-postulation (all methods) | 800s | 512MB | Queries geolocalización pesados |
| pi-matches GET | 200s | 512MB | Búsqueda geolocalizada |
| match POST | 30s | 1024MB | Carga de resultado completa |
| match-v2 POST | 15s | 1024MB | Python 3.9 legacy |
| credential / documents | 200s | 512MB | CRUD documentación |
| perfiles/torneo/statistics | 200s | 1024MB | Público + cron cada 4min |
Carga de Resultado de Partido
POST /match:
Operación crítica que carga resultado completo:
{
"tournament": 101,
"finished": true,
"team_1": {
"team_id": 10,
"players": [
{"id": 1, "goal": 2, "yellow_card": 0, "red_card": 0, "assistence": 1, "position": "Delantero"},
{"id": 2, "goal": 0, "yellow_card": 1, "red_card": 0, "assistence": 0, "position": "Defensor"}
]
},
"team_2": { /* mismo formato */ },
"signature_1": "base64...", // Firma capitán local
"signature_2": "base64...", // Firma capitán visitante
"referee_image": "base64...", // Foto árbitro
"comment": "Partido sin incidentes"
}
Flujo interno:
- Valida match existente y no finalizado
- Guarda/actualiza jugadores con estadísticas en
tournament_match_player - Sube firmas y foto a S3 como blobs
- Actualiza
fixture_infocon resultado - Sync con DynamoDB (datos del partido)
- Si
finished=true→ actualiza tablas de posiciones
POST /v2/match (Python 3.9 legacy):
Versión más flexible que acepta múltiples formatos:
player(individual)players(array)team_id+teams(por equipo)suspendedflag
PUT /match-veedor:
El árbitro/veedor puede:
- Cargar firmas de capitanes
- Subir foto del árbitro
- Finalizar partido
- Agregar comentarios
Sistema de Estadísticas
5 tipos de tabla:
- points — Tabla de posiciones (PJ, PG, PE, PP, GF, GC, DG, PTS)
- playoff — Bracket de eliminación directa
- fairplay — Fair play (menos tarjetas)
- goal — Tabla de goleadores
- goalkeeper — Tabla de arqueros (valla invicta)
- cards — Ranking de tarjetas
Materialized Views:
Las estadísticas usan materialized views de PostgreSQL para performance:
-- Se refrescan cuando se carga un resultado
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_tournament_standings;
Estadísticas Públicas (/perfiles/torneo/statistics/):
- Sin autenticación (para perfiles web)
- Cron EventBridge cada 4 minutos:
0/4 * ? * * * - Misma data que la autenticada pero cacheada
Sistema de Picaditos
Jerarquía:
Grupo (pi-group) → Partidos (pi-create-match) → Miembros (pi-members-match)
Flujo completo:
- Crear grupo → Genera código único + canal de chat
- Crear partido → Fecha, hora, lugar (lat/long), tamaño cancha, público/privado
- Unirse → Por ID o código, con status (confirmed/unconfirmed/not_play)
- Admin gestiona → Actualiza estados, agrega miembros externos
- Buscar → Filtros: público, hora, tipo_fecha (24hs/1week), field_size
pi-members-match estados:
confirmed— Confirmado para jugarunconfirmed— Pendientenot_play— No juega
Eliminación en cascada:
DELETE /pi-group elimina: grupo → partidos → miembros → canal chat
Sistema de Postulaciones
Mercado de pases:
- Jugadores buscan equipo: posición, tamaño cancha, género, ubicación
- Equipos buscan jugadores: mismos filtros
Filtros avanzados de búsqueda (GET /postulations):
- Edad (
age_min,age_max) - Distancia geográfica (
distanceen km) - Posición específica
- Tamaño de cancha (
field_size) - País/Provincia/Localidad
- Género
- Tipo (user/team)
Timeout 800s:
Las postulaciones tienen timeout de 800s por los queries geo-espaciales complejos con PostGIS.
Invitaciones con Push
POST /invitation:
- Crea invitación en BD
- Obtiene token FCM del contactado
- Envía push notification Firebase
- Retorna éxito
PUT /invitation (responder):
- Estados:
Aceptada|Rechazada|Cancelada|Pendiente - Si acepta → retorna
id_channelpara iniciar chat
Credenciales y Documentos
Credenciales (/credential/):
- Registro de usuario en liga específica
- Avatar de credencial (base64/URL → S3)
- Validación/bloqueo/rechazo por admin
- Público (sin auth)
Documentos (/documents/):
- Por edición de torneo
- Tipos:
tyc|medical_fit|permission_play - Base64 (PDF o imagen) → S3
- Auth JWT requerida
Torneo Demo
Sistema de onboarding con torneo de demostración:
- POST: Crea torneo demo
- PUT: Actualización automática (cron dominical 4PM UTC)
- DELETE: Eliminación en cascada completa
Cron: 0 16 ? * 7 * (EventBridge)
Tablas de Base de Datos
PostgreSQL (principales):
tournament/tournament_fixture/tournament_matchtournament_team/tournament_team_userprofiletournament_match_player— Estadísticas por jugador por partidoplayer_stats— Estadísticas agregadasfixture_info— Resultados de fixturepostulation— Postulaciones (mercado de pases)invitation— Invitaciones entre jugadorespicadito_group— Grupos de picaditopicadito_match— Partidos casualespicadito_member— Miembros de picaditocredential— Credenciales de ligadocument_user_edition— Documentosfavourite_item— Items favoritoscountry,province,locality— Geografía
DynamoDB:
- Sync de datos de partido al crear/actualizar resultado
- Cache de información de fixture
Materialized Views:
mv_tournament_standings— Posicionesmv_tournament_goalscorers— Goleadoresmv_tournament_fairplay— Fair playmv_tournament_cards— Tarjetas
Endpoints Públicos (sin auth):
/perfiles/torneo/statistics/— Estadísticas (cron)/perfiles/torneo/teams/— Equipos/credential/— Credenciales (GET/POST/PUT)/data-api-football/— Datos externos/my-postulation/external— Postulación (API Key)
Build y Deploy
cd STACK_TORNEOS
sudo bash ./build_torneos.sh 1 -d # Dev local
sudo bash ./build_torneos.sh 2 -d # Dev deploy
sudo bash ./build_torneos.sh 2 -q # QA deploy
sudo bash ./build_torneos.sh 2 -p # Prod deploy