15) { jsonError('El número telefónico no es válido (debe tener entre 6 y 15 dígitos).'); } } $docVal = trim($datos['numero_documento'] ?? ''); $tipoDoc = trim($datos['tipo_documento'] ?? 'CC'); if ($docVal !== '' && in_array($tipoDoc, ['CC', 'TI', 'RC', 'CE'], true)) { $docDigits = preg_replace('/[^0-9]/', '', $docVal); if (strlen($docDigits) < 4 || strlen($docDigits) > 12) { jsonError('La cédula/TI/RC/CE debe tener entre 4 y 12 dígitos numéricos.'); } } $emailVal = trim($datos['email'] ?? ''); if ($emailVal !== '' && !filter_var($emailVal, FILTER_VALIDATE_EMAIL)) { jsonError('El correo electrónico no es válido. Ej: nombre@dominio.com.'); } // ──────────────────────────────────────────────────────────────────────── $pac = new Paciente(); $admin = adminId(); if (!empty($datos['id'])) { // Actualización $id = (int)$datos['id']; unset($datos['id']); $pac->actualizar($id, $datos, $admin); jsonOk(['id' => $id], 'Paciente actualizado correctamente'); } else { // Creación — nombre obligatorio if (empty($datos['nombre_completo'])) { jsonError('El campo nombre_completo es obligatorio'); } $id = $pac->crear($datos, $admin); jsonOk(['id' => $id], 'Paciente creado correctamente'); } } catch (Exception $e) { $msg = $e->getMessage(); // Traducir errores de clave duplicada que hayan escapado la validación previa if (stripos($msg, 'Duplicate entry') !== false || stripos($msg, '1062') !== false) { if (stripos($msg, 'numero_documento') !== false || stripos($msg, 'documento') !== false) { jsonError('Ya existe un paciente con ese número de documento'); } if (stripos($msg, 'email') !== false) { jsonError('Ya existe un paciente con ese correo electrónico'); } jsonError('Ya existe un registro con esos datos (valor duplicado)'); } jsonError($msg, 400); }