Mireya Cueto Garrido d7f9ae8841 Improve responsive UX/UI consistency across all frontend screens.
This polish pass unifies mobile navigation, spacing, typography hierarchy, and CTA behavior so all core exam workflows remain clear and fully usable on both mobile and desktop.
2026-06-02 12:56:30 +02:00
2026-05-13 13:58:28 +02:00

GenExamenes IA

Backend para generar exámenes con IA, procesar la salida de un LLM y exportar preguntas a Moodle XML.

Guía detallada de flujo, endpoints, ejemplos y errores: GUIA_API_Y_FLUJO.md

El proyecto está centrado en backend. La carpeta frontend se mantiene vacía a nivel de aplicación, aunque existe un servicio en Docker Compose para reservar el despliegue futuro.

Stack

  • FastAPI
  • PostgreSQL
  • SQLAlchemy
  • Cliente LLM para Sinbad2IA UJA (POST /api/chat, modelo qwen3.5:35b)
  • Docker Compose con servicios backend, frontend y db

Puesta en Marcha

Copia el ejemplo de variables dentro de la carpeta del backend:

cp backend/.env.example backend/.env

Después levanta los servicios:

docker compose up --build

La API queda disponible en:

http://sinbad2.ujaen.es:8074

Configuración

El archivo de entorno debe estar en backend/.env.

Variables principales:

  • JWT_SECRET_KEY: secreto para firmar tokens JWT (mínimo 32 caracteres).
  • JWT_EXPIRE_MINUTES: duración del token de acceso.
  • GOOGLE_CLIENT_ID: Client ID de OAuth 2.0 en Google Cloud Console (para /auth/google).
  • DATABASE_URL: conexión PostgreSQL usada por el backend.
  • LLM_BASE_URL: URL base del servidor (por defecto ``; el cliente usa /api/chat).
  • LLM_MODEL: modelo (por defecto qwen3.5:35b).
  • LLM_TIMEOUT_SECONDS: tiempo máximo de espera (por defecto 180 s).
  • LLM_API_KEY: opcional, solo si el servidor exige autenticación.
  • ALLOWED_ORIGINS: orígenes permitidos por CORS.
  • MAX_STORAGE_BYTES_PER_TEMPLATE: cupo total de almacenamiento por examen (materiales + imágenes).

Todas las rutas bajo /exam requieren autenticación de usuario con:

Authorization: Bearer <access_token>

Si ya tenías una base de datos creada antes de añadir usuarios, recrea el volumen:

docker compose down -v
docker compose up --build

Flujo de Usuario

  1. Registrarse o iniciar sesión.
  2. Crear una plantilla de examen (queda asociada al usuario).
  3. Subir materiales de referencia (PDF, DOCX, TXT, PNG, JPG…) a la plantilla.
  4. Generar un prompt guiado para el LLM (incluye el texto extraído de los ficheros).
  5. Generar preguntas automáticamente con el LLM o parsear una salida externa en JSON/TXT.
  6. Guardar las preguntas validadas en PostgreSQL.
  7. Consultar el historial de exámenes creados.
  8. Exportar el examen a Moodle XML, TXT o JSON.

Endpoints

GET /health

Comprueba que la API está levantada.

POST /auth/register

Registra un usuario con email y contraseña.

POST /auth/login

Devuelve un token JWT para usar en las rutas protegidas.

POST /auth/google

Recibe el id_token de Google (Sign in with Google en el frontend), verifica la cuenta y devuelve el mismo JWT de la API.

GET /auth/me

Devuelve los datos del usuario autenticado.

GET /exam/history

Lista el historial de exámenes del usuario (plantillas, preguntas y exportaciones).

POST /exam/templates/{template_id}/materials

Sube un fichero (multipart/form-data, campo file). Formatos: PDF, DOCX, TXT, MD, PNG, JPG, WEBP. Extrae texto y lo guarda como contexto.

GET /exam/templates/{template_id}/materials

Lista los materiales subidos a una plantilla.

DELETE /exam/templates/{template_id}/materials/{material_id}

Elimina un material.

POST /exam/templates/{template_id}/images

Sube una imagen para preguntas visuales (file, opcional caption). No se usa OCR: la imagen se muestra en el examen y se embebe en el XML de Moodle.

GET /exam/templates/{template_id}/images

Lista las imágenes de la plantilla.

GET /exam/images/{image_id}/content

Devuelve la imagen (requiere JWT). Para previsualizar en el frontend o en Moodle tras importar.

DELETE /exam/templates/{template_id}/images/{image_id}

Elimina una imagen.

PATCH /exam/questions/{question_id}/image

Vincula o desvincula una imagen a una pregunta existente ({"image_id": "uuid"} o null).

POST /exam/templates

Crea una plantilla con materia, nivel educativo, tipos de pregunta, puntuación, penalización y dificultad.

GET /exam/templates

Lista las plantillas del usuario autenticado.

GET /exam/templates/{template_id}

Obtiene una plantilla concreta.

GET /exam/templates/{template_id}/storage

Muestra cuánto espacio usa el examen (materiales + imágenes) y el límite configurado.

POST /exam/prompts/{template_id}

Genera un prompt estructurado para IA.

POST /exam/generate

Llama al LLM configurado, parsea la respuesta y guarda las preguntas.

POST /exam/parse

Procesa una salida externa de IA en formato json o txt.

GET /exam/export/xml/{template_id}

Exporta las preguntas en Moodle XML.

GET /exam/export/txt/{template_id}

Exporta las preguntas en texto plano.

GET /exam/export/json/{template_id}

Exporta las preguntas en JSON.

Seguridad

  • Registro e inicio de sesión con contraseña hasheada (bcrypt).
  • Autenticación JWT por usuario.
  • Cada examen pertenece a un único usuario; no se puede acceder al de otro.
  • Rate limiting por cliente.
  • Límite de tamaño de petición.
  • Validación de entrada con Pydantic.
  • Manejo uniforme de errores HTTP.
  • Sanitización básica de prompts y respuestas antes de persistir/exportar.
S
Description
Generador avanzado de exámenes con IA, capaz de crear cuestionarios personalizados, configurar tipos de preguntas y exportar automáticamente el resultado en formato Moodle XML listo para importar.
Readme 181 KiB
Languages
JavaScript 45.3%
Python 45.3%
CSS 8.6%
Dockerfile 0.6%
HTML 0.2%