feat: Initial project structure for WebTriviasMulti
- 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>
This commit is contained in:
659
docs/plans/2026-01-26-webtriviasmulti-design.md
Normal file
659
docs/plans/2026-01-26-webtriviasmulti-design.md
Normal file
@@ -0,0 +1,659 @@
|
||||
# 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*
|
||||
Reference in New Issue
Block a user