- Backend: FastAPI + Python-SocketIO + SQLAlchemy - Models for categories, questions, game sessions, events - AI services for answer validation and question generation (Claude) - Room management with Redis - Game logic with stealing mechanics - Admin API for question management - Frontend: React + Vite + TypeScript + Tailwind - 5 visual themes (DRRR, Retro, Minimal, RGB, Anime 90s) - Real-time game with Socket.IO - Achievement system - Replay functionality - Sound effects per theme - Docker Compose for deployment - Design documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
660 lines
22 KiB
Markdown
660 lines
22 KiB
Markdown
# WebTriviasMulti - Documento de Diseño
|
||
|
||
**Fecha:** 2026-01-26
|
||
**Versión:** 1.0
|
||
**Estado:** Aprobado
|
||
|
||
---
|
||
|
||
## 1. Visión General
|
||
|
||
### 1.1 Descripción
|
||
WebTriviasMulti es una aplicación web de trivia multiplayer en tiempo real, inspirada en el formato de Jeopardy. Permite partidas entre 2 equipos de hasta 4 jugadores cada uno, con preguntas organizadas por categorías y niveles de dificultad.
|
||
|
||
### 1.2 Características Principales
|
||
- Partidas en tiempo real con WebSockets
|
||
- 8 categorías temáticas: Nintendo, Xbox, PlayStation, Anime, Música, Películas, Libros, Historia-Cultura
|
||
- Tablero estilo Jeopardy (5 niveles de dificultad por categoría)
|
||
- Sistema de "robo" de puntos entre equipos
|
||
- Validación de respuestas mediante IA (Claude)
|
||
- Generación automática de preguntas con aprobación de administrador
|
||
- 5 temas visuales intercambiables
|
||
- Sistema de logros
|
||
- Replays de partidas
|
||
- Sonidos temáticos
|
||
|
||
---
|
||
|
||
## 2. Mecánicas del Juego
|
||
|
||
### 2.1 Flujo de Partida
|
||
|
||
1. **Creación de sala**: Un jugador crea sala y recibe código de 6 caracteres
|
||
2. **Lobby**: Jugadores se unen con el código, eligen equipo (máx 4 por equipo), ingresan nombre
|
||
3. **Inicio**: El host inicia cuando hay al menos 1 jugador por equipo
|
||
4. **Tablero**: Se muestra el tablero con 8 categorías × 5 preguntas (100-500 pts)
|
||
5. **Turno**: El jugador en rotación del equipo activo selecciona una pregunta
|
||
6. **Respuesta**: Tiene X segundos (según dificultad) para escribir respuesta
|
||
7. **Validación IA**: Claude valida si la respuesta es correcta
|
||
8. **Robo opcional**: Si falla, equipo contrario decide si intenta robar
|
||
9. **Siguiente turno**: El equipo ganador elige siguiente pregunta
|
||
10. **Final**: Partida termina cuando se agotan las preguntas
|
||
|
||
### 2.2 Sistema de Turnos
|
||
- **Rotación obligatoria**: Cada pregunta la responde un miembro diferente del equipo
|
||
- **El que acierta elige**: El equipo que responde correctamente (o roba) elige la siguiente pregunta
|
||
|
||
### 2.3 Sistema de Puntos y Tiempo
|
||
|
||
| Dificultad | Puntos | Tiempo |
|
||
|------------|--------|--------|
|
||
| 1 (Fácil) | 100 | 15 seg |
|
||
| 2 | 200 | 20 seg |
|
||
| 3 (Media) | 300 | 25 seg |
|
||
| 4 | 400 | 35 seg |
|
||
| 5 (Difícil)| 500 | 45 seg |
|
||
|
||
### 2.4 Mecánica de Robo
|
||
- **Voluntario**: El equipo contrario decide si intenta robar o pasar
|
||
- **Penalización**: Si fallan el robo, pierden la mitad de los puntos de la pregunta
|
||
- **Tiempo reducido**: El equipo que roba tiene la mitad del tiempo original
|
||
|
||
### 2.5 Formato de Respuestas
|
||
- Respuesta abierta (el jugador escribe libremente)
|
||
- Validación semántica con IA (acepta sinónimos, variaciones, errores de ortografía menores)
|
||
|
||
---
|
||
|
||
## 3. Arquitectura Técnica
|
||
|
||
### 3.1 Stack Tecnológico
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ FRONTEND (React) │
|
||
│ - Vite + React 18 + TypeScript │
|
||
│ - Tailwind CSS + Framer Motion (animaciones) │
|
||
│ - Socket.io-client (tiempo real) │
|
||
│ - Zustand (estado global) │
|
||
│ - 5 temas visuales intercambiables │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ BACKEND (Python FastAPI) │
|
||
│ - FastAPI + Uvicorn │
|
||
│ - python-socketio (WebSockets) │
|
||
│ - SQLAlchemy (ORM) │
|
||
│ - Anthropic SDK (validación IA) │
|
||
│ - APScheduler (tareas programadas) │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
│
|
||
┌───────────────┼───────────────┐
|
||
▼ ▼ ▼
|
||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||
│PostgreSQL│ │ Redis │ │ Claude │
|
||
│(datos) │ │ (estado) │ │ (IA) │
|
||
└──────────┘ └──────────┘ └──────────┘
|
||
```
|
||
|
||
### 3.2 Responsabilidades por Componente
|
||
|
||
- **PostgreSQL**: Preguntas, categorías, historial de partidas, configuración, logros
|
||
- **Redis**: Estado de salas activas, turnos, temporizadores, sesiones WebSocket
|
||
- **Claude API**: Validar respuestas, generar preguntas nuevas
|
||
|
||
---
|
||
|
||
## 4. Modelo de Datos
|
||
|
||
### 4.1 PostgreSQL
|
||
|
||
```sql
|
||
-- Categorías
|
||
CREATE TABLE categories (
|
||
id SERIAL PRIMARY KEY,
|
||
name VARCHAR(100) NOT NULL,
|
||
icon VARCHAR(50),
|
||
color VARCHAR(7)
|
||
);
|
||
|
||
-- Preguntas
|
||
CREATE TABLE questions (
|
||
id SERIAL PRIMARY KEY,
|
||
category_id INTEGER REFERENCES categories(id),
|
||
question_text TEXT NOT NULL,
|
||
correct_answer VARCHAR(500) NOT NULL,
|
||
alt_answers TEXT[], -- Respuestas alternativas válidas
|
||
difficulty INTEGER CHECK (difficulty BETWEEN 1 AND 5),
|
||
points INTEGER NOT NULL,
|
||
time_seconds INTEGER NOT NULL,
|
||
date_active DATE,
|
||
status VARCHAR(20) DEFAULT 'pending', -- pending, approved, used
|
||
fun_fact TEXT,
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- Sesiones de juego
|
||
CREATE TABLE game_sessions (
|
||
id SERIAL PRIMARY KEY,
|
||
room_code VARCHAR(6) UNIQUE NOT NULL,
|
||
status VARCHAR(20) DEFAULT 'waiting', -- waiting, playing, finished
|
||
team_a_score INTEGER DEFAULT 0,
|
||
team_b_score INTEGER DEFAULT 0,
|
||
current_team VARCHAR(1), -- 'A' o 'B'
|
||
questions_used INTEGER[],
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
finished_at TIMESTAMP
|
||
);
|
||
|
||
-- Eventos de juego (para replays)
|
||
CREATE TABLE game_events (
|
||
id SERIAL PRIMARY KEY,
|
||
session_id INTEGER REFERENCES game_sessions(id),
|
||
event_type VARCHAR(50) NOT NULL,
|
||
player_name VARCHAR(100),
|
||
team VARCHAR(1),
|
||
question_id INTEGER REFERENCES questions(id),
|
||
answer_given TEXT,
|
||
was_correct BOOLEAN,
|
||
was_steal BOOLEAN DEFAULT FALSE,
|
||
points_earned INTEGER,
|
||
timestamp TIMESTAMP DEFAULT NOW()
|
||
);
|
||
|
||
-- Administradores
|
||
CREATE TABLE admins (
|
||
id SERIAL PRIMARY KEY,
|
||
username VARCHAR(100) UNIQUE NOT NULL,
|
||
password_hash VARCHAR(255) NOT NULL,
|
||
created_at TIMESTAMP DEFAULT NOW()
|
||
);
|
||
```
|
||
|
||
### 4.2 Redis (Estado Volátil)
|
||
|
||
```
|
||
room:{code} → {
|
||
players: [{name, team, position, socketId}],
|
||
teams: {A: [], B: []},
|
||
currentTeam: 'A',
|
||
currentPlayerIndex: {A: 0, B: 0},
|
||
status: 'waiting|playing|finished',
|
||
timer: timestamp,
|
||
canSteal: false,
|
||
currentQuestion: questionId
|
||
}
|
||
|
||
player:{socket_id} → {name, room, team, position}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Sistema de IA
|
||
|
||
### 5.1 Validación de Respuestas
|
||
|
||
```python
|
||
VALIDATION_PROMPT = """
|
||
Eres un validador de trivia. Determina si la respuesta del jugador
|
||
es correcta comparándola con la respuesta oficial.
|
||
|
||
Pregunta: {question}
|
||
Respuesta correcta: {correct_answer}
|
||
Respuestas alternativas válidas: {alt_answers}
|
||
Respuesta del jugador: {player_answer}
|
||
|
||
Considera válido si:
|
||
- Es sinónimo o variación de la respuesta correcta
|
||
- Tiene errores menores de ortografía
|
||
- Usa abreviaciones comunes (ej: "BOTW" = "Breath of the Wild")
|
||
- Es conceptualmente equivalente
|
||
|
||
Responde SOLO con JSON: {"valid": true/false, "reason": "breve explicación"}
|
||
"""
|
||
```
|
||
|
||
### 5.2 Generación de Preguntas
|
||
|
||
```python
|
||
GENERATION_PROMPT = """
|
||
Genera 5 preguntas de trivia para la categoría {category}.
|
||
Dificultad: {difficulty} (1=muy fácil, 5=muy difícil)
|
||
|
||
Formato JSON por pregunta:
|
||
{
|
||
"question": "texto de la pregunta",
|
||
"correct_answer": "respuesta principal",
|
||
"alt_answers": ["variación1", "variación2"],
|
||
"fun_fact": "dato curioso opcional"
|
||
}
|
||
|
||
Requisitos:
|
||
- Las preguntas deben ser verificables y precisas
|
||
- Evitar ambigüedades
|
||
- Ajustar complejidad según dificultad
|
||
- Para gaming: incluir referencias a juegos, personajes, mecánicas
|
||
- Para cultura: hechos históricos, arte, literatura
|
||
"""
|
||
```
|
||
|
||
### 5.3 Flujo de Aprobación
|
||
|
||
1. Admin solicita generar preguntas desde panel
|
||
2. Claude genera batch de preguntas
|
||
3. Quedan en estado `pending`
|
||
4. Admin revisa, edita si necesario, aprueba o rechaza
|
||
5. Preguntas aprobadas se asignan a fecha futura
|
||
|
||
---
|
||
|
||
## 6. Temas Visuales
|
||
|
||
### 6.1 Temas Disponibles
|
||
|
||
| Tema | Paleta Principal | Características |
|
||
|------|------------------|-----------------|
|
||
| **DRRR (Dollars)** | Negro, amarillo neón (#FFE135), cyan (#00FFFF) | Chat estilo Dollars, efectos glitch, tipografía urbana, bordes neón pulsantes |
|
||
| **Retro Arcade** | Púrpura (#9B59B6), rosa (#E91E63), cyan pixelado | Pixel art UI, tipografía 8-bit (Press Start 2P), scanlines, efectos CRT |
|
||
| **Moderno Minimalista** | Blanco (#FFFFFF), grises, acento azul (#3498DB) | Limpio, sombras suaves, tipografía sans-serif, transiciones elegantes |
|
||
| **Gaming RGB** | Negro (#0D0D0D) con gradientes RGB | Efectos de luz LED, gradientes animados, bordes brillantes, estilo "gamer" |
|
||
| **Anime Clásico 90s** | Pasteles, rosa (#FFB6C1), lavanda (#E6E6FA) | Estrellas brillantes, efectos sparkle, bordes redondeados, estilo shoujo |
|
||
|
||
### 6.2 Implementación
|
||
|
||
```
|
||
/src/themes/
|
||
├── ThemeProvider.tsx # Context para tema activo
|
||
├── index.ts # Exporta todos los temas
|
||
├── drrr/
|
||
│ ├── variables.css
|
||
│ ├── components.tsx
|
||
│ └── sounds/
|
||
├── retro-arcade/
|
||
├── minimal/
|
||
├── gaming-rgb/
|
||
└── anime-90s/
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Sistema de Sonidos
|
||
|
||
### 7.1 Eventos con Sonido
|
||
|
||
| Evento | DRRR | Retro | Minimal | RGB | Anime 90s |
|
||
|--------|------|-------|---------|-----|-----------|
|
||
| Correcto | Glitch digital | 8-bit coin | Soft chime | Synth rise | Sparkle |
|
||
| Incorrecto | Static buzz | 8-bit fail | Low tone | Bass drop | Comedic |
|
||
| Robo | Suspense | Power-up | Click | Laser | Drama sting |
|
||
| Timer (tick) | Heartbeat | Beeps | Ticks | Pulse | Tension |
|
||
| Timer (urgente) | Fast heartbeat | Fast beeps | Fast ticks | Fast pulse | Panic |
|
||
| Victoria | Epic synth | Fanfare | Elegant | EDM drop | Anime victory |
|
||
| Derrota | Glitch fade | Game over | Soft close | Power down | Sad piano |
|
||
| Selección | Click neón | 8-bit select | Pop | RGB sweep | Cute pop |
|
||
|
||
### 7.2 Almacenamiento
|
||
- Archivos en formato WebM/OGG para compatibilidad
|
||
- Precargados al seleccionar tema
|
||
- Volumen configurable por usuario
|
||
|
||
---
|
||
|
||
## 8. Sistema de Logros
|
||
|
||
### 8.1 Lista de Logros
|
||
|
||
| ID | Nombre | Condición | Icono |
|
||
|----|--------|-----------|-------|
|
||
| 1 | Primera Victoria | Ganar tu primera partida | 🏆 |
|
||
| 2 | Racha de 3 | Responder 3 correctas seguidas | 🔥 |
|
||
| 3 | Racha de 5 | Responder 5 correctas seguidas | 🔥🔥 |
|
||
| 4 | Ladrón Novato | Primer robo exitoso | 🦝 |
|
||
| 5 | Ladrón Maestro | 5 robos exitosos en una partida | 🦝👑 |
|
||
| 6 | Especialista Nintendo | 10 correctas en Nintendo | 🍄 |
|
||
| 7 | Especialista Xbox | 10 correctas en Xbox | 🎮 |
|
||
| 8 | Especialista PlayStation | 10 correctas en PlayStation | 🎯 |
|
||
| 9 | Especialista Anime | 10 correctas en Anime | ⛩️ |
|
||
| 10 | Especialista Música | 10 correctas en Música | 🎵 |
|
||
| 11 | Especialista Películas | 10 correctas en Películas | 🎬 |
|
||
| 12 | Especialista Libros | 10 correctas en Libros | 📚 |
|
||
| 13 | Especialista Historia | 10 correctas en Historia-Cultura | 🏛️ |
|
||
| 14 | Invicto | Ganar sin fallar ninguna pregunta | ⭐ |
|
||
| 15 | Velocista | Responder correctamente en menos de 3 segundos | ⚡ |
|
||
| 16 | Comeback | Ganar estando 500+ puntos abajo | 🔄 |
|
||
| 17 | Dominio Total | Responder las 5 preguntas de una categoría correctamente | 👑 |
|
||
| 18 | Arriesgado | Responder correctamente 3 preguntas de 500 pts | 🎰 |
|
||
|
||
### 8.2 Almacenamiento
|
||
- localStorage por navegador (sin cuentas)
|
||
- Estructura: `{odooId: {achievements: [...], stats: {...}}}`
|
||
- Mostrados al final de cada partida (nuevos desbloqueados)
|
||
|
||
---
|
||
|
||
## 9. Sistema de Replays
|
||
|
||
### 9.1 Datos Capturados
|
||
|
||
Usando la tabla `game_events`, cada evento registra:
|
||
- Tipo de evento (question_selected, answer_submitted, steal_attempted, etc.)
|
||
- Jugador y equipo
|
||
- Pregunta seleccionada
|
||
- Respuesta dada
|
||
- Resultado (correcto/incorrecto)
|
||
- Puntos ganados/perdidos
|
||
- Timestamp preciso
|
||
|
||
### 9.2 Reproducción
|
||
|
||
1. Al finalizar partida, opción "Ver Replay"
|
||
2. Carga eventos ordenados por timestamp
|
||
3. Reproduce animación acelerada (x2, x4, x8)
|
||
4. Muestra:
|
||
- Tablero con preguntas revelándose
|
||
- Respuestas de jugadores
|
||
- Marcador actualizándose
|
||
- Momentos de robo
|
||
5. Controles: Play/Pause, velocidad, timeline scrubber
|
||
|
||
### 9.3 Compartir
|
||
- Código único de replay (basado en session_id)
|
||
- URL compartible: `/replay/{code}`
|
||
|
||
---
|
||
|
||
## 10. Panel de Administración
|
||
|
||
### 10.1 Funcionalidades
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ PANEL ADMINISTRADOR │
|
||
├─────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ 📊 Dashboard │
|
||
│ - Partidas activas en tiempo real │
|
||
│ - Estadísticas del día │
|
||
│ - Preguntas pendientes de aprobación │
|
||
│ │
|
||
│ ❓ Gestión de Preguntas │
|
||
│ - CRUD de preguntas por categoría │
|
||
│ - Generar con IA (botón por categoría/dificultad) │
|
||
│ - Cola de aprobación │
|
||
│ - Asignar a fechas │
|
||
│ - Importar/exportar CSV │
|
||
│ │
|
||
│ 📅 Calendario │
|
||
│ - Vista mensual de preguntas programadas │
|
||
│ - Alertas de días sin contenido │
|
||
│ │
|
||
│ 🎮 Monitor │
|
||
│ - Salas activas │
|
||
│ - Cerrar salas problemáticas │
|
||
│ │
|
||
│ ⚙️ Configuración │
|
||
│ - Tiempos y puntos por dificultad │
|
||
│ - Penalización de robo │
|
||
│ - API keys │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 10.2 Autenticación
|
||
- Login con usuario/contraseña
|
||
- JWT para sesiones
|
||
- Rutas protegidas `/admin/*`
|
||
|
||
---
|
||
|
||
## 11. Comunicación en Partida
|
||
|
||
### 11.1 Chat de Equipo
|
||
- Visible solo para miembros del mismo equipo
|
||
- Mensajes en tiempo real via WebSocket
|
||
- Historial durante la partida
|
||
|
||
### 11.2 Reacciones Globales
|
||
- Emojis predefinidos que todos pueden ver
|
||
- Limitado para evitar spam (1 cada 3 segundos)
|
||
- Emojis disponibles: 👏 😮 😂 🔥 💀 🎉 😭 🤔
|
||
|
||
---
|
||
|
||
## 12. Estructura del Proyecto
|
||
|
||
```
|
||
WebTriviasMulti/
|
||
├── backend/
|
||
│ ├── app/
|
||
│ │ ├── __init__.py
|
||
│ │ ├── main.py
|
||
│ │ ├── config.py
|
||
│ │ ├── models/
|
||
│ │ │ ├── __init__.py
|
||
│ │ │ ├── category.py
|
||
│ │ │ ├── question.py
|
||
│ │ │ ├── game_session.py
|
||
│ │ │ ├── game_event.py
|
||
│ │ │ └── admin.py
|
||
│ │ ├── schemas/
|
||
│ │ │ ├── __init__.py
|
||
│ │ │ ├── question.py
|
||
│ │ │ ├── game.py
|
||
│ │ │ └── admin.py
|
||
│ │ ├── services/
|
||
│ │ │ ├── __init__.py
|
||
│ │ │ ├── ai_validator.py
|
||
│ │ │ ├── ai_generator.py
|
||
│ │ │ ├── game_manager.py
|
||
│ │ │ └── room_manager.py
|
||
│ │ ├── api/
|
||
│ │ │ ├── __init__.py
|
||
│ │ │ ├── admin.py
|
||
│ │ │ ├── game.py
|
||
│ │ │ └── replay.py
|
||
│ │ └── sockets/
|
||
│ │ ├── __init__.py
|
||
│ │ └── game_events.py
|
||
│ ├── requirements.txt
|
||
│ ├── Dockerfile
|
||
│ ├── alembic.ini
|
||
│ └── alembic/
|
||
│ └── versions/
|
||
│
|
||
├── frontend/
|
||
│ ├── src/
|
||
│ │ ├── components/
|
||
│ │ │ ├── game/
|
||
│ │ │ │ ├── Board.tsx
|
||
│ │ │ │ ├── QuestionCard.tsx
|
||
│ │ │ │ ├── Timer.tsx
|
||
│ │ │ │ ├── ScoreBoard.tsx
|
||
│ │ │ │ └── AnswerInput.tsx
|
||
│ │ │ ├── lobby/
|
||
│ │ │ │ ├── CreateRoom.tsx
|
||
│ │ │ │ ├── JoinRoom.tsx
|
||
│ │ │ │ ├── TeamSelect.tsx
|
||
│ │ │ │ └── PlayerList.tsx
|
||
│ │ │ ├── chat/
|
||
│ │ │ │ ├── TeamChat.tsx
|
||
│ │ │ │ └── EmojiReactions.tsx
|
||
│ │ │ ├── replay/
|
||
│ │ │ │ ├── ReplayPlayer.tsx
|
||
│ │ │ │ └── ReplayControls.tsx
|
||
│ │ │ ├── achievements/
|
||
│ │ │ │ ├── AchievementPopup.tsx
|
||
│ │ │ │ └── AchievementList.tsx
|
||
│ │ │ └── ui/
|
||
│ │ │ ├── Button.tsx
|
||
│ │ │ ├── Modal.tsx
|
||
│ │ │ ├── Input.tsx
|
||
│ │ │ └── Toast.tsx
|
||
│ │ ├── themes/
|
||
│ │ │ ├── ThemeProvider.tsx
|
||
│ │ │ ├── index.ts
|
||
│ │ │ ├── drrr/
|
||
│ │ │ ├── retro-arcade/
|
||
│ │ │ ├── minimal/
|
||
│ │ │ ├── gaming-rgb/
|
||
│ │ │ └── anime-90s/
|
||
│ │ ├── hooks/
|
||
│ │ │ ├── useSocket.ts
|
||
│ │ │ ├── useGame.ts
|
||
│ │ │ ├── useSound.ts
|
||
│ │ │ └── useAchievements.ts
|
||
│ │ ├── stores/
|
||
│ │ │ ├── gameStore.ts
|
||
│ │ │ ├── themeStore.ts
|
||
│ │ │ └── soundStore.ts
|
||
│ │ ├── pages/
|
||
│ │ │ ├── Home.tsx
|
||
│ │ │ ├── Lobby.tsx
|
||
│ │ │ ├── Game.tsx
|
||
│ │ │ ├── Replay.tsx
|
||
│ │ │ ├── Results.tsx
|
||
│ │ │ └── admin/
|
||
│ │ │ ├── Dashboard.tsx
|
||
│ │ │ ├── Questions.tsx
|
||
│ │ │ ├── Calendar.tsx
|
||
│ │ │ ├── Monitor.tsx
|
||
│ │ │ └── Settings.tsx
|
||
│ │ ├── services/
|
||
│ │ │ ├── socket.ts
|
||
│ │ │ └── api.ts
|
||
│ │ ├── types/
|
||
│ │ │ └── index.ts
|
||
│ │ ├── App.tsx
|
||
│ │ └── main.tsx
|
||
│ ├── public/
|
||
│ │ └── sounds/
|
||
│ ├── package.json
|
||
│ ├── Dockerfile
|
||
│ ├── vite.config.ts
|
||
│ ├── tailwind.config.js
|
||
│ └── tsconfig.json
|
||
│
|
||
├── docker-compose.yml
|
||
├── .env.example
|
||
├── .gitignore
|
||
├── README.md
|
||
└── docs/
|
||
└── plans/
|
||
└── 2026-01-26-webtriviasmulti-design.md
|
||
```
|
||
|
||
---
|
||
|
||
## 13. Despliegue
|
||
|
||
### 13.1 Docker Compose
|
||
|
||
```yaml
|
||
version: '3.8'
|
||
|
||
services:
|
||
frontend:
|
||
build: ./frontend
|
||
ports:
|
||
- "3000:3000"
|
||
environment:
|
||
- VITE_API_URL=http://localhost:8000
|
||
- VITE_WS_URL=ws://localhost:8000
|
||
|
||
backend:
|
||
build: ./backend
|
||
ports:
|
||
- "8000:8000"
|
||
environment:
|
||
- DATABASE_URL=postgresql://trivia:trivia@db:5432/trivia
|
||
- REDIS_URL=redis://redis:6379
|
||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||
- JWT_SECRET=${JWT_SECRET}
|
||
depends_on:
|
||
- db
|
||
- redis
|
||
|
||
db:
|
||
image: postgres:15
|
||
volumes:
|
||
- postgres_data:/var/lib/postgresql/data
|
||
environment:
|
||
- POSTGRES_DB=trivia
|
||
- POSTGRES_USER=trivia
|
||
- POSTGRES_PASSWORD=trivia
|
||
|
||
redis:
|
||
image: redis:7-alpine
|
||
volumes:
|
||
- redis_data:/data
|
||
|
||
cloudflared:
|
||
image: cloudflare/cloudflared:latest
|
||
command: tunnel run
|
||
environment:
|
||
- TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
|
||
depends_on:
|
||
- frontend
|
||
- backend
|
||
|
||
volumes:
|
||
postgres_data:
|
||
redis_data:
|
||
```
|
||
|
||
### 13.2 Variables de Entorno
|
||
|
||
```env
|
||
# Backend
|
||
DATABASE_URL=postgresql://trivia:trivia@db:5432/trivia
|
||
REDIS_URL=redis://redis:6379
|
||
ANTHROPIC_API_KEY=sk-ant-...
|
||
JWT_SECRET=your-secret-key
|
||
|
||
# Frontend
|
||
VITE_API_URL=https://trivia.tudominio.com/api
|
||
VITE_WS_URL=wss://trivia.tudominio.com
|
||
|
||
# Cloudflare
|
||
CLOUDFLARE_TUNNEL_TOKEN=your-tunnel-token
|
||
```
|
||
|
||
---
|
||
|
||
## 14. Roadmap Futuro
|
||
|
||
### Fase 3 - Competitivo
|
||
- Ranking global (requiere cuentas opcionales)
|
||
- Torneos programados
|
||
- Temporadas con recompensas
|
||
|
||
### Fase 4 - Social
|
||
- Compartir resultados en redes
|
||
- Salas recurrentes
|
||
- Desafíos diarios
|
||
|
||
### Fase 5 - Contenido
|
||
- Categorías rotativas por eventos
|
||
- Preguntas de la comunidad
|
||
- Modo "Experto"
|
||
|
||
### Fase 6 - Técnico
|
||
- PWA instalable
|
||
- API pública
|
||
- Modo offline
|
||
|
||
---
|
||
|
||
## 15. Referencias
|
||
|
||
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
|
||
- [Socket.IO](https://socket.io/)
|
||
- [Anthropic Claude API](https://docs.anthropic.com/)
|
||
- [React](https://react.dev/)
|
||
- [Tailwind CSS](https://tailwindcss.com/)
|
||
- [Framer Motion](https://www.framer.com/motion/)
|
||
|
||
---
|
||
|
||
*Documento generado el 2026-01-26*
|