workspace/projects/gamilit/docs/database/functions/VALIDATE-RUEDA-INFERENCIAS.md
rckrdmrd 289c5a4ee5
Some checks are pending
CI Pipeline / changes (push) Waiting to run
CI Pipeline / core (push) Blocked by required conditions
CI Pipeline / trading-backend (push) Blocked by required conditions
CI Pipeline / trading-data-service (push) Blocked by required conditions
CI Pipeline / trading-frontend (push) Blocked by required conditions
CI Pipeline / erp-core (push) Blocked by required conditions
CI Pipeline / erp-mecanicas (push) Blocked by required conditions
CI Pipeline / gamilit-backend (push) Blocked by required conditions
CI Pipeline / gamilit-frontend (push) Blocked by required conditions
Gamilit: Backend fixes, frontend API updates, deployment guides and validations
Backend:
- Fix email verification and password recovery services
- Fix exercise submission and student progress services

Frontend:
- Update missions, password, and profile API services
- Fix ExerciseContentRenderer component

Docs & Scripts:
- Add SSL/Certbot deployment guide
- Add quick deployment guide
- Database scripts for testing and validations
- Migration and homologation reports
- Functions inventory documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 23:42:48 -06:00

6.1 KiB

Funcion: validate_rueda_inferencias

Version: 1.0.0 Fecha: 2025-12-18 Schema: educational_content Ubicacion: apps/database/ddl/schemas/educational_content/functions/14-validate_rueda_inferencias.sql


PROPOSITO

Validar respuestas abiertas para ejercicios de tipo "Rueda de Inferencias", soportando multiples estructuras de datos y proporcionando retroalimentacion granular.


FIRMA

CREATE OR REPLACE FUNCTION educational_content.validate_rueda_inferencias(
    p_student_response JSONB,
    p_correct_answer JSONB,
    p_exercise_config JSONB DEFAULT '{}'::JSONB
) RETURNS RECORD AS $$

PARAMETROS

Parametro Tipo Descripcion
p_student_response JSONB Respuesta del estudiante
p_correct_answer JSONB Respuesta correcta esperada
p_exercise_config JSONB Configuracion adicional (opcional)

RETORNO

RECORD (
    is_correct BOOLEAN,    -- Si la respuesta es correcta
    score INTEGER,         -- Puntaje obtenido (0-100)
    feedback TEXT,         -- Retroalimentacion para el estudiante
    details JSONB          -- Detalles de evaluacion por categoria
)

ESTRUCTURAS SOPORTADAS

Estructura Nueva: categoryExpectations

{
  "categoryExpectations": {
    "category_id_1": {
      "keywords": ["palabra1", "palabra2"],
      "minLength": 10,
      "maxLength": 500
    },
    "category_id_2": {
      "keywords": ["palabra3", "palabra4"],
      "minLength": 20
    }
  },
  "fragmentStates": {
    "fragment_id_1": {
      "categoryId": "category_id_1"
    }
  }
}

Estructura Legacy: flat

{
  "keywords": ["palabra1", "palabra2", "palabra3"],
  "minLength": 10,
  "maxLength": 500,
  "minKeywords": 2
}

LOGICA DE VALIDACION

1. Deteccion de Estructura

IF p_correct_answer ? 'categoryExpectations' THEN
    -- Usar estructura nueva
ELSE
    -- Usar estructura legacy (flat)
END IF;

2. Normalizacion de Texto

v_normalized_text := lower(
    translate(
        p_student_response->>'text',
        'áéíóúÁÉÍÓÚñÑ',
        'aeiouAEIOUnN'
    )
);

3. Validacion de Longitud

v_text_length := length(p_student_response->>'text');

IF v_text_length < v_min_length THEN
    v_feedback := 'Respuesta muy corta. Minimo ' || v_min_length || ' caracteres.';
    v_is_correct := false;
END IF;

IF v_max_length IS NOT NULL AND v_text_length > v_max_length THEN
    v_feedback := 'Respuesta muy larga. Maximo ' || v_max_length || ' caracteres.';
    v_is_correct := false;
END IF;

4. Conteo de Keywords

v_keyword_count := 0;

FOR v_keyword IN SELECT jsonb_array_elements_text(v_keywords) LOOP
    IF v_normalized_text LIKE '%' || lower(v_keyword) || '%' THEN
        v_keyword_count := v_keyword_count + 1;
    END IF;
END LOOP;

5. Calculo de Score

-- Puntuacion parcial basada en keywords encontradas
v_keyword_ratio := v_keyword_count::FLOAT / v_total_keywords::FLOAT;
v_score := LEAST(100, ROUND(v_keyword_ratio * 100));

-- Bonus por longitud adecuada
IF v_text_length >= v_ideal_length THEN
    v_score := v_score + 10;
END IF;

EJEMPLOS DE USO

Estructura categoryExpectations

SELECT educational_content.validate_rueda_inferencias(
    '{"text": "El texto habla sobre la importancia de la lectura critica"}'::JSONB,
    '{
        "categoryExpectations": {
            "cat-inferencias": {
                "keywords": ["lectura", "critica", "importancia", "texto"],
                "minLength": 20
            }
        }
    }'::JSONB
);
-- Retorna: (true, 75, 'Respuesta aceptable', {"keywords_found": 3, "keywords_total": 4})

Estructura Legacy

SELECT educational_content.validate_rueda_inferencias(
    '{"text": "Pienso que el autor quiere transmitir un mensaje sobre la sociedad"}'::JSONB,
    '{
        "keywords": ["autor", "mensaje", "sociedad", "transmitir"],
        "minLength": 30,
        "minKeywords": 2
    }'::JSONB
);
-- Retorna: (true, 100, 'Excelente respuesta', {"keywords_found": 4, "keywords_total": 4})

MANEJO DE ERRORES

Categoria No Encontrada

Si un fragmentId no tiene categoryId mapeado, se usa fallback:

v_category_id := COALESCE(
    p_correct_answer->'fragmentStates'->v_fragment_id->>'categoryId',
    'cat-literal'  -- Fallback
);

Respuesta Vacia

IF p_student_response IS NULL OR p_student_response->>'text' = '' THEN
    RETURN (false, 0, 'No se proporciono respuesta', '{}'::JSONB);
END IF;

RETROALIMENTACION

Mensajes Predefinidos

Condicion Mensaje
Score >= 90 "Excelente respuesta"
Score >= 70 "Buena respuesta"
Score >= 50 "Respuesta aceptable, considera agregar mas detalles"
Score < 50 "Respuesta insuficiente, revisa los conceptos clave"
Muy corta "Respuesta muy corta. Minimo X caracteres"
Muy larga "Respuesta muy larga. Maximo X caracteres"

DETALLES DE RETORNO

Estructura de details

{
  "keywords_found": 3,
  "keywords_total": 5,
  "text_length": 85,
  "min_length": 20,
  "max_length": 500,
  "categories_evaluated": [
    {
      "category_id": "cat-inferencias",
      "keywords_found": 2,
      "keywords_total": 3,
      "passed": true
    }
  ]
}

INTEGRACION

Trigger de Validacion

CREATE TRIGGER trg_validate_rueda_response
BEFORE INSERT ON educational_content.exercise_attempts
FOR EACH ROW
WHEN (NEW.exercise_type = 'rueda_inferencias')
EXECUTE FUNCTION educational_content.validate_rueda_response_trigger();

Uso desde Backend

const result = await db.query(`
  SELECT * FROM educational_content.validate_rueda_inferencias($1, $2)
`, [studentResponse, correctAnswer]);

const { is_correct, score, feedback, details } = result.rows[0];

HISTORIAL DE CAMBIOS

Fecha Version Cambio
2025-12-15 1.0.0 Version inicial con soporte dual

REFERENCIAS


Ultima actualizacion: 2025-12-18