From 4afccb89ef9994e10646d52dcd49e76c4a27540c Mon Sep 17 00:00:00 2001 From: Nurfog Date: Thu, 2 Apr 2026 14:15:16 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20Implementar=20reglas=20de=20negocio=20e?= =?UTF-8?q?spec=C3=ADficas=20de=20la=20empresa=20para=20la=20composici?= =?UTF-8?q?=C3=B3n=20de=20plantillas=20de=20prueba?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/cms-service/src/external_handlers.rs | 20 ++++++++--- .../src/handlers_test_templates.rs | 34 ++++++++++++------- .../TestTemplates/TestTemplateForm.tsx | 13 ------- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/services/cms-service/src/external_handlers.rs b/services/cms-service/src/external_handlers.rs index e1ed0ac..32e5085 100644 --- a/services/cms-service/src/external_handlers.rs +++ b/services/cms-service/src/external_handlers.rs @@ -9,6 +9,14 @@ use serde_json::json; use sqlx::PgPool; 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 { let api_key = headers .get("X-API-Key") @@ -218,12 +226,14 @@ async fn create_course_lesson_and_apply_template( .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - if template.2 == "CA" && template_questions.len() < 4 { - return Err(StatusCode::BAD_REQUEST); - } + if uses_company_specific_template_rules(org_id) { + if template.2 == "CA" && template_questions.len() < 4 { + return Err(StatusCode::BAD_REQUEST); + } - if template.2 != "CA" && template_questions.len() != 1 { - return Err(StatusCode::BAD_REQUEST); + if template.2 != "CA" && template_questions.len() != 1 { + return Err(StatusCode::BAD_REQUEST); + } } let questions_json: Vec = template_questions diff --git a/services/cms-service/src/handlers_test_templates.rs b/services/cms-service/src/handlers_test_templates.rs index 8550e63..f5faee7 100644 --- a/services/cms-service/src/handlers_test_templates.rs +++ b/services/cms-service/src/handlers_test_templates.rs @@ -13,6 +13,14 @@ use sqlx::PgPool; use std::time::Duration; 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 ==================== #[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())); } - // Business rules for template composition. - if matches!(template.test_type, TestType::CA) && template_questions.len() < 4 { - return Err(( - StatusCode::BAD_REQUEST, - "Las plantillas CA deben tener minimo 4 preguntas".to_string(), - )); - } + // Company-specific business rules for template composition. + if uses_company_specific_template_rules(org_ctx.id) { + if matches!(template.test_type, TestType::CA) && template_questions.len() < 4 { + return Err(( + StatusCode::BAD_REQUEST, + "Las plantillas CA deben tener minimo 4 preguntas".to_string(), + )); + } - if !matches!(template.test_type, TestType::CA) && template_questions.len() != 1 { - return Err(( - StatusCode::BAD_REQUEST, - "Las plantillas MWT, MOT, FOT y FWT deben tener exactamente 1 pregunta".to_string(), - )); + if !matches!(template.test_type, TestType::CA) && template_questions.len() != 1 { + return Err(( + StatusCode::BAD_REQUEST, + "Las plantillas MWT, MOT, FOT y FWT deben tener exactamente 1 pregunta".to_string(), + )); + } } // Build quiz_data JSON from template questions diff --git a/web/studio/src/components/TestTemplates/TestTemplateForm.tsx b/web/studio/src/components/TestTemplates/TestTemplateForm.tsx index 13fd524..c96235a 100644 --- a/web/studio/src/components/TestTemplates/TestTemplateForm.tsx +++ b/web/studio/src/components/TestTemplates/TestTemplateForm.tsx @@ -205,19 +205,6 @@ export default function TestTemplateForm({ templateId, onSuccess, onCancel }: Te 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 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');