Query-Hub es una plataforma para crear, publicar y evaluar ejercicios de SQL. Un profesor define retos, los estudiantes envían sus consultas y el sistema las ejecuta en un entorno aislado para comparar el resultado real contra el esperado.
El proyecto está pensado para funcionar completo con Docker Compose. La idea es que, después de preparar el archivo de entorno una sola vez, la forma normal de levantar todo sea ejecutar este comando desde la raíz del repositorio:
docker compose -f infra/docker-compose.yml up --build- API en NestJS para autenticación, usuarios, cursos, retos, envíos y evaluaciones.
- Worker en segundo plano para procesar las correcciones SQL.
- PostgreSQL para persistir datos.
- Redis para la cola de trabajos.
- Frontend web para usar la plataforma desde el navegador.
- Seed automático con datos de ejemplo para poder probar el sistema apenas arranca.
La plataforma cubre el flujo típico de una materia de bases de datos:
- El profesor crea cursos y retos.
- El profesor publica los retos para que estén disponibles.
- El estudiante inicia sesión y revisa los retos publicados.
- El estudiante envía una consulta SQL.
- El worker ejecuta la consulta en un contenedor temporal.
- El sistema compara la salida con la respuesta esperada y guarda la evaluación.
- Docker Desktop instalado y funcionando.
- Docker Compose disponible.
- Acceso a una terminal en la carpeta raíz del repositorio.
No necesitas instalar Node.js para usar el proyecto en modo normal con Docker.
Antes del primer arranque, verifica que exista el archivo infra/.env. Si no existe, créalo copiando el ejemplo:
Copy-Item infra\.env.example infra\.envDespués, desde la raíz del proyecto, levanta todo con:
docker compose -f infra/docker-compose.yml up --buildEse comando construye las imágenes, crea la base de datos si todavía no existe y arranca todos los servicios en conjunto.
El compose levanta estos servicios:
postgres: base de datos principal en el puerto5432.redis: cola de trabajos en el puerto6379.api: backend principal en el puerto3000.worker: procesa las evaluaciones de SQL en segundo plano.web: interfaz visual disponible en el puerto80.
La API ejecuta el seed automáticamente al iniciar, así que la primera vez que levantes el proyecto ya tendrás datos de prueba cargados.
- API:
http://localhost:3000 - Swagger:
http://localhost:3000/api/docs - Web:
http://localhost
Si no ves la interfaz todavía, espera a que termine el build inicial. La primera ejecución puede tardar más porque Docker tiene que construir varias imágenes.
El seed crea usuarios listos para usar:
| Rol | Contraseña | |
|---|---|---|
| ADMIN | admin@queryhub.com |
Admin123! |
| PROFESSOR | maria.garcia@universidad.edu |
Prof1234! |
| STUDENT | carlos.lopez@universidad.edu |
Estudiante1! |
| STUDENT | ana.martinez@universidad.edu |
Estudiante1! |
También crea cursos, inscripciones y retos SQL de ejemplo para que puedas probar todo sin preparar datos manualmente.
- Entra a la web en
http://localhosto usa Swagger enhttp://localhost:3000/api/docs. - Inicia sesión con uno de los usuarios del seed.
- Como profesor, crea o publica retos SQL.
- Como estudiante, abre un reto y envía tu consulta.
- Revisa la evaluación y el detalle del resultado.
| Método | Ruta | Descripción |
|---|---|---|
| POST | /api/auth/login |
Inicia sesión y devuelve un JWT |
| Método | Ruta | Descripción |
|---|---|---|
| POST | /api/users |
Crea un usuario |
| GET | /api/users |
Lista usuarios |
| GET | /api/users/:id |
Consulta un usuario por ID |
| DELETE | /api/users/:id |
Elimina un usuario |
| Método | Ruta | Descripción |
|---|---|---|
| POST | /api/courses |
Crea un curso |
| GET | /api/courses |
Lista cursos |
| GET | /api/courses/:id |
Consulta un curso |
| PATCH | /api/courses/:id |
Actualiza un curso |
| DELETE | /api/courses/:id |
Elimina un curso |
| Método | Ruta | Descripción |
|---|---|---|
| POST | /api/challenges |
Crea un reto en estado borrador |
| GET | /api/challenges |
Lista retos públicos o filtrados |
| GET | /api/challenges/:id |
Consulta un reto por ID |
| PATCH | /api/challenges/:id |
Actualiza un reto |
| DELETE | /api/challenges/:id |
Elimina un reto |
| PATCH | /api/challenges/:id/publish |
Publica un reto |
| POST | /api/challenges/:id/schema |
Actualiza el schema SQL del reto |
| POST | /api/challenges/:id/seed |
Actualiza el seed SQL del reto |
| Método | Ruta | Descripción |
|---|---|---|
| POST | /api/submissions |
Envía una consulta SQL para evaluación |
| GET | /api/submissions/:id |
Consulta un envío y su evaluación |
| GET | /api/submissions |
Lista envíos por estudiante |
| Método | Ruta | Descripción |
|---|---|---|
| POST | /api/evaluations |
Crea una evaluación parcial |
| GET | /api/evaluations/:id |
Consulta una evaluación |
| GET | /api/evaluations |
Lista evaluaciones por curso |
| POST | /api/evaluations/:id/challenges |
Asocia retos a una evaluación |
Query-Hub/
├── apps/
│ ├── api/ # Backend NestJS
│ ├── web/ # Interfaz web
│ └── worker/ # Procesador de evaluaciones SQL
├── infra/ # Docker Compose y variables de entorno
├── 1-documentation/ # Documentación técnica y guías detalladas
└── README.md
Copia la plantilla y edítala con tus valores reales (el archivo infra/.env no se sube a Git):
Copy-Item infra\.env.example infra\.envLa referencia completa está en infra/.env.example. Resumen por grupo:
| Grupo | Variables | Uso |
|---|---|---|
| PostgreSQL | POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, POSTGRES_HOST, POSTGRES_PORT |
Base de datos (Compose usa los valores del ejemplo en local). |
| Redis | REDIS_HOST, REDIS_PORT |
Cola de evaluaciones. |
| API | PORT |
Puerto del backend (por defecto 3000). |
| JWT | JWT_SECRET, JWT_EXPIRES_IN |
Firma de tokens; en local puedes dejar el ejemplo, en producción usa un secreto largo y único. |
| Azure OpenAI | AZURE_OPENAI_* |
Funciones de IA (ver sección siguiente). |
Para arrancar sin IA, basta con copiar el ejemplo y dejar los valores por defecto de Postgres, Redis y JWT. Las recomendaciones post-envío y el asistente de retos para profesores requieren credenciales válidas de Azure OpenAI.
Query-Hub usa Azure OpenAI (no OpenAI directo). Hay dos capacidades:
| Capacidad | Quién la usa | Qué hace |
|---|---|---|
| Asesor post-evaluación | Estudiante (tras enviar SQL) | Tras corregir la submission, el worker pide al modelo una explicación y una consulta sugerida; se guarda en ai_recommendations. |
| Asistente de retos | Profesor | Ayuda a bosquejar retos (POST /api/challenges/ai/suggest) y generar configuración de datos (POST /api/challenges/:id/generate-data-ai). |
La API y el worker leen las mismas variables desde infra/.env (montado por Docker Compose). Documentación técnica completa (arquitectura, flujos, endpoints, seguridad):
1-documentation/AI-COMPONENT.md
Endpoints relacionados en Swagger: módulos Submissions (recomendación) y Challenges (rutas .../ai/...).
| Variable | Obligatoria | Descripción |
|---|---|---|
AZURE_OPENAI_ENDPOINT |
Sí | URL del recurso (sin barra final), p. ej. https://<nombre>.openai.azure.com o https://<nombre>.services.ai.azure.com. |
AZURE_OPENAI_API_KEY |
Sí | Clave del recurso. |
AZURE_OPENAI_DEPLOYMENT_NAME |
Sí | Nombre exacto del deployment del modelo en Azure (no el nombre del modelo en catálogo). |
AZURE_OPENAI_API_VERSION |
Recomendada | Versión REST; el proyecto usa por defecto 2025-04-01-preview si no la defines. |
AZURE_OPENAI_ENABLED |
No | Si es false, el asesor no llama a Azure y devuelve mensajes genéricos. |
AZURE_OPENAI_HEALTHCHECK_ENABLED |
No | Worker: prueba de conexión al arranque; false para desactivarla. |
Ejemplo en .env (sustituye por tus valores):
AZURE_OPENAI_ENDPOINT=https://mi-recurso.openai.azure.com
AZURE_OPENAI_API_KEY=tu-clave-aqui
AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4.1-mini
AZURE_OPENAI_API_VERSION=2025-04-01-previewNecesitas una suscripción de Azure con acceso a Azure OpenAI (a veces hay que solicitar acceso la primera vez).
-
Crear el recurso
- Entra a Azure Portal → Crear un recurso → busca Azure OpenAI (o Azure AI services / Foundry según tu suscripción).
- Elige región, grupo de recursos y crea el recurso.
-
AZURE_OPENAI_ENDPOINTyAZURE_OPENAI_API_KEY- Abre el recurso → menú Keys and Endpoint (Claves y punto de conexión).
- Endpoint → copia la URL en
AZURE_OPENAI_ENDPOINT. - Key 1 o Key 2 → copia en
AZURE_OPENAI_API_KEY.
-
AZURE_OPENAI_DEPLOYMENT_NAME- En el mismo recurso, abre Azure OpenAI Studio o Model deployments / Implementaciones.
- Create new deployment (o usa una existente): elige un modelo (p. ej.
gpt-4.1-mini,gpt-4o-mini, según disponibilidad en tu región). - El nombre de la implementación que asignes es el valor de
AZURE_OPENAI_DEPLOYMENT_NAME(debe coincidir carácter a carácter).
-
AZURE_OPENAI_API_VERSION- Usa la del ejemplo (
2025-04-01-preview) o la que indique la documentación de tu recurso en Studio → View code / ejemplos de la API. - Si las llamadas fallan por versión, prueba la versión que muestre Azure para chat completions en tu región.
- Usa la del ejemplo (
-
Aplicar y reiniciar
- Guarda
infra/.env. - Reinicia los contenedores para que API y worker carguen las variables:
docker compose -f infra/docker-compose.yml up --build
- Guarda
-
Comprobar que funciona
- Envía una submission como estudiante y, cuando el worker termine, consulta
GET /api/submissions/:id(debe incluiraiRecommendation). - Script de prueba:
scripts/test-submission-ai-recommendation.ps1. - Logs del worker:
docker compose -f infra/docker-compose.yml logs -f worker(busca errores deAZURE_OPENAI_*o conectividad).
- Envía una submission como estudiante y, cuando el worker termine, consulta
Sin credenciales válidas, la evaluación SQL sigue funcionando; solo fallan o quedan genéricas las partes de IA.
Si necesitas revisar qué está pasando mientras el sistema corre, puedes ver los logs de cada servicio con Docker Compose:
docker compose -f infra/docker-compose.yml logs -f api
docker compose -f infra/docker-compose.yml logs -f worker
docker compose -f infra/docker-compose.yml logs -f postgresSi quieres entender el diseño con más profundidad, revisa esta carpeta:
1-documentation/README.md: arquitectura general y decisiones principales.1-documentation/AI-COMPONENT.md: IA (Azure OpenAI), flujos, puertos/adaptadores y variables.1-documentation/api-testing-guide.md: guía para probar la API con Swagger.1-documentation/runner-sql.md: detalle técnico del runner SQL y del worker.1-documentation/api/: documentación de endpoints por módulo (p. ej.08-ai-recommendations.md).1-documentation/architecture/: diagramas de arquitectura.
- Si Docker dice que no encuentra
infra/.env, créalo a partir deinfra/.env.example. - Si el puerto
80,3000,5432o6379ya está ocupado, libera ese puerto o detén el servicio que lo usa. - Si el worker no puede ejecutar evaluaciones, asegúrate de que Docker Desktop esté activo, porque el proyecto depende del socket de Docker para ejecutar consultas en contenedores temporales.