feat: Implementar reglas de negocio específicas de la empresa para la composición de plantillas de prueba
This commit is contained in:
@@ -9,6 +9,14 @@ use serde_json::json;
|
|||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
const COMPANY_SPECIFIC_RULES_ORG_ID: &str = "00000000-0000-0000-0000-000000000001";
|
||||||
|
|
||||||
|
fn uses_company_specific_template_rules(org_id: Uuid) -> bool {
|
||||||
|
Uuid::parse_str(COMPANY_SPECIFIC_RULES_ORG_ID)
|
||||||
|
.map(|id| id == org_id)
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
async fn validate_api_key(headers: &HeaderMap, pool: &PgPool) -> Result<Uuid, StatusCode> {
|
async fn validate_api_key(headers: &HeaderMap, pool: &PgPool) -> Result<Uuid, StatusCode> {
|
||||||
let api_key = headers
|
let api_key = headers
|
||||||
.get("X-API-Key")
|
.get("X-API-Key")
|
||||||
@@ -218,12 +226,14 @@ async fn create_course_lesson_and_apply_template(
|
|||||||
.await
|
.await
|
||||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||||
|
|
||||||
if template.2 == "CA" && template_questions.len() < 4 {
|
if uses_company_specific_template_rules(org_id) {
|
||||||
return Err(StatusCode::BAD_REQUEST);
|
if template.2 == "CA" && template_questions.len() < 4 {
|
||||||
}
|
return Err(StatusCode::BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
if template.2 != "CA" && template_questions.len() != 1 {
|
if template.2 != "CA" && template_questions.len() != 1 {
|
||||||
return Err(StatusCode::BAD_REQUEST);
|
return Err(StatusCode::BAD_REQUEST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let questions_json: Vec<serde_json::Value> = template_questions
|
let questions_json: Vec<serde_json::Value> = template_questions
|
||||||
|
|||||||
@@ -13,6 +13,14 @@ use sqlx::PgPool;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
const COMPANY_SPECIFIC_RULES_ORG_ID: &str = "00000000-0000-0000-0000-000000000001";
|
||||||
|
|
||||||
|
fn uses_company_specific_template_rules(org_id: Uuid) -> bool {
|
||||||
|
Uuid::parse_str(COMPANY_SPECIFIC_RULES_ORG_ID)
|
||||||
|
.map(|id| id == org_id)
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
// ==================== Query Parameters ====================
|
// ==================== Query Parameters ====================
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
@@ -555,19 +563,21 @@ pub async fn apply_template_to_lesson(
|
|||||||
return Err((StatusCode::BAD_REQUEST, "Template has no questions".to_string()));
|
return Err((StatusCode::BAD_REQUEST, "Template has no questions".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Business rules for template composition.
|
// Company-specific business rules for template composition.
|
||||||
if matches!(template.test_type, TestType::CA) && template_questions.len() < 4 {
|
if uses_company_specific_template_rules(org_ctx.id) {
|
||||||
return Err((
|
if matches!(template.test_type, TestType::CA) && template_questions.len() < 4 {
|
||||||
StatusCode::BAD_REQUEST,
|
return Err((
|
||||||
"Las plantillas CA deben tener minimo 4 preguntas".to_string(),
|
StatusCode::BAD_REQUEST,
|
||||||
));
|
"Las plantillas CA deben tener minimo 4 preguntas".to_string(),
|
||||||
}
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if !matches!(template.test_type, TestType::CA) && template_questions.len() != 1 {
|
if !matches!(template.test_type, TestType::CA) && template_questions.len() != 1 {
|
||||||
return Err((
|
return Err((
|
||||||
StatusCode::BAD_REQUEST,
|
StatusCode::BAD_REQUEST,
|
||||||
"Las plantillas MWT, MOT, FOT y FWT deben tener exactamente 1 pregunta".to_string(),
|
"Las plantillas MWT, MOT, FOT y FWT deben tener exactamente 1 pregunta".to_string(),
|
||||||
));
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build quiz_data JSON from template questions
|
// Build quiz_data JSON from template questions
|
||||||
|
|||||||
@@ -205,19 +205,6 @@ export default function TestTemplateForm({ templateId, onSuccess, onCancel }: Te
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Business rules by test type:
|
|
||||||
// - CA must have at least 4 questions.
|
|
||||||
// - MWT/MOT/FOT/FWT must have exactly 1 question.
|
|
||||||
if (formData.test_type === 'CA' && questions.length < 4) {
|
|
||||||
alert('Las plantillas CA deben tener minimo 4 preguntas.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formData.test_type !== 'CA' && questions.length !== 1) {
|
|
||||||
alert('Las plantillas MWT, MOT, FOT y FWT deben tener exactamente 1 pregunta.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate: either mysql_course_id OR level+course_type must be provided
|
// Validate: either mysql_course_id OR level+course_type must be provided
|
||||||
if (!formData.mysql_course_id && (!formData.level || !formData.course_type)) {
|
if (!formData.mysql_course_id && (!formData.level || !formData.course_type)) {
|
||||||
alert('Debes seleccionar un curso de MySQL o especificar nivel y tipo de curso manualmente');
|
alert('Debes seleccionar un curso de MySQL o especificar nivel y tipo de curso manualmente');
|
||||||
|
|||||||
Reference in New Issue
Block a user