better-i18n Doctor: Monitoreo Automatizado de Calidad de Traducción
Escanea tu código en busca de traducciones faltantes, orphan keys y discrepancias en placeholders. Obtén una puntuación de salud del 0 al 100 con cada commit.
better-i18n Doctor: Monitoreo Automatizado de Calidad de Traducción
Tu aplicación se distribuye en doce idiomas. Pero, ¿cómo sabes que cada pantalla, cada mensaje de error, cada tooltip ha sido traducido? ¿Cómo sabes que un placeholder como {count} en inglés no fue escrito accidentalmente como {nombre} en francés? ¿Cómo sabes que las keys que eliminaste del código hace tres sprints no siguen en tus archivos de traducción, añadiendo desorden y confusión?
La mayoría de los equipos se entera de los problemas de traducción a través de los usuarios. Un cliente en Tokio ve una key sin procesar como dashboard.welcome_message en lugar de un saludo. Un usuario alemán reporta que un precio muestra {amount} en vez del número real. Un ingeniero de QA compara manualmente archivos JSON y descubre que la traducción al español le faltan 47 keys que se añadieron el mes pasado.
better-i18n Doctor es una verificación automatizada de salud i18n que escanea tu código y archivos de traducción, identifica cada categoría de problema de traducción y produce una puntuación de salud del 0 al 100. Se ejecuta localmente mediante la CLI, se integra en tu pipeline de CI/CD y reporta los resultados a la plataforma better-i18n para su seguimiento a lo largo del tiempo.
Cómo Funciona la Puntuación de Salud
Doctor produce un único número: una puntuación de salud del 0 al 100. Esta puntuación es un agregado ponderado de cuatro categorías, cada una evaluando una dimensión diferente de tu calidad i18n.
Las Cuatro Categorías
Coverage mide si cada key utilizada en tu código existe en cada archivo de idioma objetivo. Una key presente en inglés pero ausente en japonés es una brecha de cobertura. La cobertura es la fuente más común de problemas de traducción: las nuevas funcionalidades se publican con keys que nunca se enviaron para traducción, o un desarrollador añade una key a un namespace y se olvida de añadirla a los demás.
Quality verifica el contenido de las traducciones en busca de corrección estructural. Las discrepancias en placeholders son la principal preocupación: si la cadena en inglés tiene {count} y {name}, la traducción al alemán debe contener exactamente los mismos placeholders. Quality también comprueba traducciones vacías (keys que existen pero tienen valores en blanco), traducciones excesivamente largas que pueden romper los layouts de la UI, y cadenas idénticas al idioma fuente (lo que puede indicar contenido sin traducir copiado del inglés).
Structure evalúa la organización de tus archivos de traducción. Comprueba las orphan keys, es decir, keys que existen en los archivos de traducción pero nunca se referencian en el código fuente. Las orphan keys son inofensivas pero generan carga de mantenimiento: los traductores dedican tiempo a actualizar cadenas que ningún usuario verá jamás, y los desarrolladores pierden tiempo revisando traducciones de funcionalidades en desuso. Structure también verifica la coherencia en el nombrado de keys, keys duplicadas y la organización de namespaces.
Code utiliza análisis a nivel de AST para escanear tu código fuente en busca de cadenas hardcodeadas que deberían estar internacionalizadas. Detecta cadenas orientadas al usuario en componentes JSX, template literals pasados a funciones de UI, y constantes de cadenas usadas en mensajes de error o notificaciones. Esta categoría detecta la fuente más común de deuda i18n: un desarrollador escribe <p>Loading...</p> en vez de <p>{t('common.loading')}</p> porque es más rápido, con la intención de arreglarlo después. Doctor encuentra estas cadenas antes de que se publiquen.
Cálculo de la Puntuación
Cada categoría produce una sub-puntuación del 0 al 100 basada en la proporción de verificaciones superadas respecto al total. La puntuación de salud general es un promedio ponderado:
| Categoría | Peso | Qué Mide |
|---|---|---|
| Coverage | 40% | Keys de traducción faltantes en todos los idiomas |
| Quality | 30% | Discrepancias en placeholders, valores vacíos, contenido sospechoso |
| Structure | 20% | Orphan keys, coherencia en el nombrado, duplicados |
| Code | 10% | Cadenas hardcodeadas en el código fuente |
La cobertura tiene el mayor peso porque las traducciones faltantes tienen el impacto más directo en el usuario: resultan en que se muestren keys sin procesar o el idioma de fallback. El análisis de código tiene el menor peso porque las cadenas hardcodeadas son deuda técnica que no rompe inmediatamente la experiencia del usuario, aunque deben corregirse con el tiempo.
Umbral de Aprobación/Fallo
Un escaneo se marca como aprobado cuando la puntuación general es 80 o superior y no hay ningún error (a diferencia de las advertencias). Los errores son problemas que afectan directamente a los usuarios: traducciones faltantes para funcionalidades completas, discrepancias en placeholders que causarán errores en tiempo de ejecución, o keys que referencian namespaces inexistentes. Las advertencias son problemas que deben corregirse pero no rompen la experiencia del usuario: orphan keys, nombrado inconsistente o cadenas hardcodeadas.
Puedes configurar el umbral de aprobación para adaptarlo a los estándares de tu equipo:
bi18n doctor --threshold 90
Ejecutar Doctor Localmente
Escaneo Básico
Ejecuta una verificación de salud completa desde la raíz de tu proyecto:
bi18n doctor
Doctor descubre automáticamente tus archivos de traducción según tu configuración better-i18n.yml o detectando estructuras de directorio comunes (locales/, messages/, i18n/, lib/l10n/). Escanea tus archivos de origen en busca de uso de keys y hace referencias cruzadas con todo para producir el informe de salud.
La salida es un informe estructurado que muestra la puntuación general, los desglose por categoría y los resultados de las reglas individuales:
i18n Doctor Report
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Overall Score: 87/100 ✓ PASSED
Coverage 92/100 ██████████████████░░ 3 missing keys
Quality 85/100 █████████████████░░░ 2 placeholder mismatches
Structure 78/100 ███████████████░░░░░ 12 orphan keys
Code 90/100 ██████████████████░░ 4 hardcoded strings
Errors: 0 Warnings: 21
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Escaneos Específicos
Omite categorías que no sean relevantes o que sean demasiado lentas para tus necesidades inmediatas:
# Omitir análisis de código (escaneo más rápido)
bi18n doctor --skip-code
# Omitir verificaciones de salud/calidad (solo cobertura y estructura)
bi18n doctor --skip-health
# Omitir verificaciones de estado de sincronización
bi18n doctor --skip-sync
# Salida detallada: mostrar cada resultado de regla, no solo los fallos
bi18n doctor --verbose
Comandos de Verificación Individual
Doctor incluye varias verificaciones que también pueden ejecutarse de forma independiente:
# Verificar keys de traducción faltantes en todos los idiomas
bi18n check:missing
# Verificar orphan keys no referenciadas en el código fuente
bi18n check:unused
# Ejecutar todas las verificaciones (equivalente a doctor sin análisis de código)
bi18n check
# Escanear el código fuente en busca de cadenas hardcodeadas
bi18n scan
# Estado de sincronización: comparar archivos locales con el estado de la plataforma
bi18n sync --dry-run
Cada comando produce una salida enfocada en su preocupación específica, lo que resulta útil cuando estás trabajando en corregir una categoría particular de problemas.
Integración con CI/CD
GitHub Actions
Doctor está diseñado para ejecutarse como una verificación de CI en cada pull request. La flag --ci genera resultados en un formato que GitHub Actions entiende, produciendo anotaciones inline en los archivos con problemas:
# .github/workflows/i18n-doctor.yml
name: i18n Health Check
on:
pull_request:
paths:
- "locales/**"
- "src/**"
- "messages/**"
jobs:
doctor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install
- name: Run i18n Doctor
run: bunx @better-i18n/cli doctor --ci --threshold 80
env:
BETTER_I18N_API_KEY: ${{ secrets.BETTER_I18N_API_KEY }}
Cuando la flag --ci está activada, Doctor:
- Sale con código 1 si el escaneo falla (puntuación por debajo del umbral o errores presentes), haciendo que la verificación de GitHub Actions falle
- Genera anotaciones en formato GitHub Actions, de modo que los problemas aparecen como comentarios inline en el diff del PR
- Produce un resumen que aparece en la salida de la verificación de GitHub Actions
Flujo de Trabajo de GitHub Actions Generado Automáticamente
Si no deseas escribir el archivo de flujo de trabajo manualmente, better-i18n puede crearlo por ti. En el panel de la plataforma, navega a Integrations y luego a GitHub Actions y haz clic en Create Doctor Workflow. Esto crea un pull request en tu repositorio con un archivo de flujo de trabajo preconfigurado y adaptado a la configuración de tu proyecto.
El flujo de trabajo generado automáticamente incluye:
- Filtros de ruta que coinciden con las ubicaciones de tus archivos de traducción
- Tu umbral configurado
- Instrucciones de configuración de la API key
- Notificación opcional de Slack en caso de fallo
Reporte a la Plataforma
Cuando Doctor se ejecuta con la flag --report y una API key, envía el informe completo a la plataforma better-i18n:
bi18n doctor --report --api-key $BETTER_I18N_API_KEY
El informe incluye:
- Puntuación y estado de aprobación/fallo
- Conteo de errores y advertencias por categoría
- Resultados de reglas individuales con keys y archivos afectados
- Metadatos: commit SHA, nombre de rama, número de archivos escaneados, número de keys verificadas, timestamp
Los informes enviados a la plataforma se almacenan y muestran en el panel del proyecto. Puedes ver las tendencias de puntuación a lo largo del tiempo, comparar informes entre ramas y hacer seguimiento de qué categorías están mejorando o degradándose.
Envío de Informes en CI
En entornos de CI, combina --ci y --report para validar el PR y enviar el informe:
- name: Run i18n Doctor
run: bunx @better-i18n/cli doctor --ci --report --threshold 85
env:
BETTER_I18N_API_KEY: ${{ secrets.BETTER_I18N_API_KEY }}
Esto te proporciona dos bucles de retroalimentación:
- Inmediato: La verificación del PR pasa o falla, y los desarrolladores ven las anotaciones inline
- Histórico: El informe se almacena en la plataforma para análisis de tendencias y visibilidad del equipo
Detalles de las Reglas
Doctor evalúa un conjunto de reglas dentro de cada categoría. Aquí están las reglas más impactantes y lo que detectan.
Reglas de Coverage
missing-keys: Para cada key utilizada en tu código fuente, verifica si existe una traducción en cada archivo de idioma objetivo. Las keys faltantes son el problema i18n más común y el más visible para el usuario: resultan en que se muestren nombres de key sin procesar o el idioma de fallback.
namespace-coverage: Verifica que cada namespace referenciado en tu código tenga los archivos de traducción correspondientes para todos los idiomas objetivo. Un desarrollador podría añadir t('checkout.confirm_order') pero el archivo del namespace checkout no existe para coreano.
Reglas de Quality
placeholder-mismatch: Compara placeholders entre traducciones fuente y objetivo. Si existe en: "Hello {name}, you have {count} items", verifica que la traducción de cada otro idioma contenga exactamente {name} y {count}. Los placeholders adicionales o faltantes causan errores en tiempo de ejecución o muestran la sintaxis del placeholder sin procesar.
empty-translation: Marca keys que existen en un idioma objetivo pero tienen valores de cadena vacíos. Las traducciones vacías suelen ser el resultado de añadir keys de forma programática sin proporcionar contenido traducido real.
source-identical: Marca traducciones que son carácter a carácter idénticas al idioma fuente. Aunque algunas cadenas (nombres de marca, URLs, términos técnicos) son legítimamente idénticas en todos los idiomas, un alto número de cadenas source-identical generalmente indica contenido sin traducir.
Reglas de Structure
orphan-keys: Identifica keys en archivos de traducción que no están referenciadas en ningún lugar del código fuente. Las orphan keys se acumulan cuando se eliminan funcionalidades pero no se limpian los archivos de traducción. Desperdician el esfuerzo de los traductores y generan confusión sobre lo que está activamente en uso.
duplicate-keys: Detecta la misma key definida múltiples veces dentro de un único archivo o namespace. Los duplicados causan comportamiento impredecible: el motor de traducción usa uno de ellos, pero cuál depende de los detalles de implementación.
naming-consistency: Verifica que los nombres de las keys sigan patrones coherentes. Si la mayoría de las keys usan snake_case, una key que use camelCase es marcada. El nombrado inconsistente hace que las keys sean más difíciles de encontrar y mantener.
Reglas de Code
hardcoded-jsx: Usa análisis AST para detectar cadenas literales dentro de elementos JSX. <h1>Welcome</h1> es marcado; <h1>{t('welcome')}</h1> no lo es. Esta regla entiende JSX e ignora cadenas no orientadas al usuario como nombres de clases CSS y atributos de datos.
hardcoded-template: Detecta cadenas literales pasadas a funciones que típicamente producen salida orientada al usuario: notificaciones toast, diálogos de alerta, mensajes de error. showToast("Operation successful") es marcado.
hardcoded-constant: Identifica constantes de cadena asignadas a variables con nombres orientados al usuario (como errorMessage, label, title, placeholder) que no están envueltas en funciones de traducción.
Panel de la Plataforma
Los informes enviados mediante --report se visualizan en el panel de la plataforma better-i18n.
Tendencias de Puntuación
Un gráfico de series temporales muestra tu puntuación de salud a lo largo del tiempo. Cada punto representa un informe de Doctor, representado por fecha. Puedes filtrar por rama para ver la trayectoria de salud de main versus ramas de funcionalidades. La línea de tendencia facilita ver si tu calidad i18n está mejorando, estable o degradándose.
Desglose por Categoría
Profundiza en cada categoría para ver qué reglas están pasando y cuáles están fallando. Para cada regla fallida, puedes ver las keys y archivos específicos involucrados. Haz clic en una key para abrirla en el editor de traducciones; haz clic en un archivo para verlo en el contexto de tu repositorio.
Comparación Entre Proyectos
Para organizaciones con múltiples proyectos, el panel muestra las puntuaciones de salud en todos los proyectos. Esto es útil para identificar qué proyectos necesitan atención i18n y para establecer estándares de calidad a nivel organizacional.
Alertas
Configura alertas para ser notificado cuando tu puntuación de salud caiga por debajo de un umbral:
- Email: Resumen semanal de cambios en la puntuación de salud
- Slack: Notificación instantánea cuando un informe falla
- Webhook: Integración personalizada para tu stack de monitoreo
Ejemplos Prácticos
Ejemplo 1: Detectar Traducciones Faltantes Antes del Lanzamiento
Tu equipo añadió un nuevo flujo de checkout con 30 nuevas keys de traducción. El desarrollador añadió todas las keys al archivo en inglés. Se solicitaron traducciones al francés y alemán pero aún no se han completado. Sin Doctor, esto se publica con keys sin procesar visibles para los usuarios franceses y alemanes.
Con Doctor en CI:
Coverage 60/100 ████████████░░░░░░░░ 30 missing keys (fr, de)
Error: 30 keys missing in target languages
checkout.confirm_order — missing in: fr, de
checkout.payment_method — missing in: fr, de
checkout.shipping_address — missing in: fr, de
... (27 more)
Result: FAILED (score 60, threshold 80)
El PR está bloqueado. El desarrollador ve las anotaciones inline, solicita las traducciones y el PR se fusiona solo después de que las traducciones estén completas.
Ejemplo 2: Detectar Discrepancias en Placeholders
Un traductor actualiza la traducción al alemán de una cadena de notificación. El fuente en inglés tiene You have {count} new messages from {sender}. La traducción alemana usa accidentalmente {anzahl} en vez de {count}.
Doctor lo detecta:
Quality 75/100 ███████████████░░░░░ 1 placeholder mismatch
Error: Placeholder mismatch in notifications.new_messages (de)
Source placeholders: {count}, {sender}
Target placeholders: {anzahl}, {sender}
Missing: {count}
Extra: {anzahl}
Ejemplo 3: Limpieza Después de Eliminar una Funcionalidad
Tu equipo eliminó el dashboard heredado hace seis meses. El código se fue, pero los archivos de traducción aún contienen 85 keys bajo el namespace legacy_dashboard. Los traductores ocasionalmente actualizan estas cadenas al hacer pases de traducción masivos, desperdiciando esfuerzo en contenido que nadie ve.
Doctor encuentra las orphan keys:
Structure 65/100 █████████████░░░░░░░ 85 orphan keys
Warning: 85 keys in namespace "legacy_dashboard" are not referenced in source code
legacy_dashboard.welcome — not referenced
legacy_dashboard.stats_header — not referenced
legacy_dashboard.chart_title — not referenced
... (82 more)
Ejemplo 4: Encontrar Cadenas Hardcodeadas
Un nuevo desarrollador se une al equipo y escribe una funcionalidad sin usar el sistema de traducción. Hardcodea todas las cadenas directamente en JSX:
// Antes de Doctor
<div>
<h2>Account Settings</h2>
<p>Manage your account preferences below.</p>
<button>Save Changes</button>
</div>
Doctor marca cada cadena hardcodeada:
Code 40/100 ████████░░░░░░░░░░░░ 3 hardcoded strings
Warning: Hardcoded string in JSX element (src/pages/Settings.tsx:15)
<h2>Account Settings</h2>
Suggestion: <h2>{t('settings.account_title')}</h2>
Warning: Hardcoded string in JSX element (src/pages/Settings.tsx:16)
<p>Manage your account preferences below.</p>
Warning: Hardcoded string in JSX element (src/pages/Settings.tsx:17)
<button>Save Changes</button>
Comparación con Alternativas
Comparación Manual de JSON: Los equipos que comparan archivos de traducción manualmente detectan problemas de cobertura pero se pierden todo lo demás: discrepancias en placeholders, orphan keys, cadenas hardcodeadas. Las verificaciones manuales también son propensas a errores y no escalan más allá de un puñado de idiomas.
Plugins i18n de ESLint: Las reglas de linting como eslint-plugin-i18next detectan cadenas hardcodeadas en JSX pero no verifican la calidad de los archivos de traducción, la cobertura entre idiomas ni los problemas estructurales. Doctor incluye el análisis de código como una de cuatro categorías y cubre el espectro completo de problemas i18n.
Phrase QPS (Quality Performance Score): Phrase proporciona una puntuación de calidad de traducción, pero se centra en la calidad lingüística (gramática, terminología) en lugar de la calidad técnica (keys faltantes, discrepancias en placeholders, orphan keys). Doctor se centra en la dimensión técnica: los problemas que causan errores en tiempo de ejecución e interfaces rotas.
Sin Verificaciones Automatizadas: Muchos equipos no tienen ninguna verificación automatizada de i18n. Los problemas son descubiertos por los usuarios o ingenieros de QA. Doctor proporciona cobertura automatizada integral que detecta problemas antes de que lleguen a cualquier entorno.
Preguntas Frecuentes
¿Cuánto tarda un escaneo de Doctor?
Un escaneo típico de un proyecto con 10,000 keys, 8 idiomas y 200 archivos de origen se completa en menos de 10 segundos. El análisis de código (análisis AST) es la categoría más lenta: usa --skip-code para escaneos más rápidos cuando solo necesitas verificaciones de cobertura y calidad.
¿Puedo ejecutar Doctor sin conectarme a la plataforma better-i18n?
Sí. Doctor se ejecuta completamente de forma local por defecto. La flag --report es opcional y solo se necesita si deseas enviar resultados a la plataforma para seguimiento de tendencias.
¿Qué frameworks admite el análisis de código? El análisis de código actualmente admite React (JSX/TSX), Vue (plantillas SFC) y componentes Svelte. El soporte para Angular está planificado. La detección del framework es automática basándose en las dependencias de tu proyecto.
¿Puedo añadir reglas personalizadas? Las reglas personalizadas están en el roadmap. Actualmente, puedes configurar la severidad de las reglas (error vs. advertencia) y deshabilitar reglas específicas que no sean relevantes para tu proyecto.
¿Funciona Doctor con monorepos? Sí. Doctor admite escaneo con conciencia de workspaces. Detecta los límites del workspace y escanea cada paquete de forma independiente, produciendo un informe por paquete y una puntuación general agregada.
¿Cómo funciona la creación del flujo de trabajo de GitHub Actions?
En el panel de better-i18n, la acción Create Doctor Workflow usa la API de GitHub para crear un pull request en tu repositorio con un archivo .github/workflows/i18n-doctor.yml preconfigurado. Revisas y fusionas el PR para activar el flujo de trabajo.
Comienza a Monitorear tu Salud i18n
Los problemas de traducción deben detectarse en CI, no por los usuarios. better-i18n Doctor le da a tu equipo una verificación de salud continua y automatizada que puntúa cada dimensión de tu calidad i18n y bloquea las traducciones rotas antes de que se publiquen.
Comienza tu prueba gratuita y ejecuta tu primer escaneo de Doctor en menos de cinco minutos.