Buscar/Crear código de replicación de datos (ETL) que no cambie valores en silencio ni filtre datos

Crear código de replicación de datos (ETL) que no cambie valores en silencio ni filtre datos

Úsalo al crear o cambiar código que copia datos entre bases de datos. Mantiene los cambios pequeños, evita redondeos y otros cambios silenciosos, devuelve errores claros ante entradas malas, no registra secretos ni filas en los logs y comprueba que las pruebas se ejecutaron.

Para usar estas reglas de IA
## No hacer push ni tocar migraciones si no se pide Mantén cada cambio centrado en el problema que se está resolviendo. Prefiere la diferencia coherente más pequeña, salvo que sea necesaria una refactorización más amplia para preservar la corrección. Antes de introducir un patrón, una dependencia, un auxiliar o un fixture de pruebas, inspecciona el código cercano y sigue las convenciones establecidas del espacio de trabajo. Trata la configuración del formateador, los diagnósticos del compilador y los ajustes de análisis estático del espacio de trabajo como la fuente de verdad del estilo exigible. No escribas en el repositorio, publiques ramas, abras solicitudes de cambio ni reescribas el historial, a menos que el usuario solicite expresamente esa acción. No alteres las migraciones de la base de datos, salvo que el trabajo solicitado requiera específicamente cambiar una migración. Esto incluye los comentarios y el texto no ejecutable dentro de los archivos de migración. Ejecuta comprobaciones costosas de todo el espacio de trabajo solo cuando su alcance esté justificado. Para cambios de documentación o configuración de bajo riesgo, usa la validación pertinente más pequeña e informa exactamente de lo que se ejecutó. ## Agrupar los módulos por concepto de datos y dejar las API privadas por defecto Organiza el sistema por conceptos de dominio, no por categorías genéricas. Mantén juntos el comportamiento de replicación y los tipos específicos de replicación; coloca los elementos básicos reutilizables de la base de datos, los auxiliares del origen, los auxiliares de ranuras y el acceso a metadatos en un límite de integración. Usa límites de paquete solo cuando otro paquete dependa realmente de la API. Dentro de un dominio, prefiere módulos con nombres como `schema`, `data`, `event`, `store`, `source` o `slots`. Mantén los binarios de nivel superior centrados en la orquestación. Traslada los detalles de implementación a auxiliares y módulos con una finalidad concreta. Usa visibilidad privada de forma predeterminada y amplíala solo para un llamador real. Prefiere primero la visibilidad privada, después la del paquete y por último la pública. Trata cada reexportación como un contrato de API: - evita las reexportaciones con comodines desde módulos internos; - expón únicamente la superficie de configuración útil más pequeña; - mantén privados la orquestación de trabajadores, los códecs, la infraestructura de ejecución y los detalles de implementación; - evita las fachadas de compatibilidad salvo que sean una API estable intencionada. Prefiere código claro y convencional a abstracciones ingeniosas. Agrupa los tipos, constructores, métodos públicos y auxiliares privados en un orden legible. ## Detectar redondeos y otros cambios silenciosos de valores Valida los valores localmente cuando, de otro modo, el destino aceptaría silenciosamente un cambio semántico, como redondeo, truncamiento, limitación a un intervalo, coerción, desbordamiento o pérdida de precisión. Si el destino ya rechaza un valor no compatible con un error explícito, no dupliques una validación costosa en la ruta de escritura sin una necesidad demostrada. Usa conversiones numéricas comprobadas o basadas en traits cuando sean sin pérdidas y estén disponibles. Usa conversiones de tipo deliberadamente con pérdida solo cuando esta se entienda, se haya comprobado el intervalo cuando corresponda y la representación de destino las requiera. Usa una conversión implícita solo cuando la correspondencia sea infalible, semánticamente sin pérdidas, conserve el valor y sea evidente. Modela las actualizaciones de parches con tres estados distintos: - los campos omitidos conservan el valor almacenado; - un null explícito borra un valor opcional o restablece un valor predeterminado; - los valores distintos de null sustituyen el valor almacenado. Al convertir una configuración completa a la semántica de un parche, usa un auxiliar de conversión explícito. No ocultes un cambio de conservar a borrar detrás de un trait de conversión genérico. ## Devolver errores claros en vez de fallar ante entradas malas Usa errores tipados y valores de resultado para los fallos recuperables. Añade contexto propio, como operaciones, identificadores, recuentos, tipos o sentencias, mientras conservas el error original como cadena de causas. No aplanes un error subyacente en una cadena, salvo que un mensaje saneado deliberadamente sea más seguro para el llamador. Las respuestas de la API pública no deben exponer errores del controlador de la base de datos, consultas internas, datos de clientes ni detalles de infraestructura. Reserva los pánicos para invariantes de programación rotos. Las entradas externas, la sintaxis mal formada, los valores no compatibles y los fallos del estado del sistema deben devolver errores explícitos. Los puntos de entrada del analizador deben manejar entradas vacías, finales inesperados de la entrada, secuencias de escape mal formadas, secuencias de bytes no válidas, intervalos no válidos, desbordamiento, subdesbordamiento y sintaxis no compatible sin provocar pánicos. Prefiere el acceso comprobado, los iteradores y el análisis de segmentos de bytes cuando la entrada controle los desplazamientos. La indexación directa solo es aceptable cuando un límite local o una invariante de segmento exacto lo haga evidente. Añade pruebas de regresión para cada límite de entrada mal formada que antes pudiera provocar un pánico o un análisis silenciosamente erróneo. ## Elegir cómo se detienen las tareas en segundo plano según el estado que guardan Evita el código unsafe salvo que sea necesario. Cada bloque unsafe debe tener al lado una explicación de seguridad que indique la invariante que hace válida y segura la operación. Prefiere la propiedad y el préstamo a la clonación innecesaria o la mutabilidad interior. Coloca el trabajo asíncrono de larga duración detrás de tareas o auxiliares con nombre y elige el comportamiento de apagado según el estado que posean: - descartar un manejador de tarea desacopla la tarea; cancela explícitamente el trabajo de fondo desechable cuando deba detenerse de inmediato; - descartar un conjunto de tareas cancela todas las tareas que posee; - no canceles de forma redundante un conjunto de tareas justo antes de salir del alcance que lo descartará; - usa operaciones explícitas de cancelación cuando el conjunto de tareas siga activo, pero sus tareas deban detenerse; - usa señalización ordenada y espera a que las tareas terminen cuando posean transacciones, escrituras de destino almacenadas en búfer o un estado de replicación sensible a los reintentos. No añadas una coordinación de apagado compleja para tareas de sondeo o telemetría cuyo estado pueda descartarse de forma segura. ## Mantener los secretos y los datos de clientes fuera del código y los logs Considera que los archivos bajo seguimiento, las ramas, los commits, las revisiones, los registros, las capturas de pantalla, los fixtures de prueba, los artefactos generados y la salida del terminal pueden llegar a ser públicos. Nunca incluyas credenciales, tokens, puntos de conexión privados, datos de clientes, cargas útiles de producción, datos personales ni configuración propietaria en el código, las pruebas, la documentación, los ejemplos, los comentarios, los mensajes, la telemetría, los detalles de pánico o los archivos generados. Usa marcadores ficticios en los ejemplos. Guarda los secretos reales únicamente en variables de entorno aprobadas, archivos locales ignorados, gestores de secretos o el almacenamiento de secretos de CI. Si un valor sospechoso parece real o procede de un entorno privado, no lo reproduzcas. Detén la ruta de publicación, informa de la ubicación sin citar el valor y recomienda su rotación o revocación cuando pueda haberse producido una exposición. Para la observabilidad: - prefiere etiquetas de baja cardinalidad; - registra metadatos estructurales como nombres de tablas, nombres de columnas, tipos, recuentos, longitudes, posiciones y nombres de operaciones; - nunca registres valores de filas, contenido de celdas, cuerpos sensibles de solicitudes o respuestas, credenciales ni tokens; - usa un formato de visualización seguro para los errores y los campos estructurados; - elimina los datos sensibles de la captura de cuerpos en las rutas sensibles y los ámbitos de supervisión. ## Probar eventos reales de replicación y confirmar que las pruebas se ejecutaron Ejecuta primero las pruebas pertinentes de alcance más reducido y amplíalo después cuando lo justifiquen el comportamiento compartido, las regresiones o la solicitud. Verifica que las pruebas esperadas se hayan ejecutado realmente; un comando que finalice correctamente sin pruebas coincidentes no constituye una verificación aprobada. Enumera las pruebas antes de aplicar filtros inciertos. Ejecuta por separado las pruebas de documentación cuando el ejecutor principal no las admita. Reutiliza los fixtures de prueba, los auxiliares de base de datos, las primitivas de espera y las aserciones cercanos antes de crear una infraestructura de pruebas personalizada. Para las pruebas de integración basadas en eventos: 1. Registra las notificaciones o los manejadores de espera antes de que el productor pueda emitir el evento. 2. Realiza las escrituras en el origen. 3. Espera las notificaciones previstas. 4. Detén la canalización y espera a que termine antes de comprobar el estado del destino, salvo que la prueba cubra explícitamente el comportamiento en curso. 5. Comprueba el historial acumulado de eventos, salvo que un reinicio o una fase aislada requiera borrarlo. Ajusta los eventos previstos de captura de cambios de datos al comportamiento real de identidad de réplica de la base de datos de origen. No esperes filas de actualización parcial en modos que no pueden emitirlas. ## Documentar el código e informar de las comprobaciones ejecutadas Documenta los elementos públicos y privados con una prosa concisa y precisa. Enlaza tipos y métodos mediante las referencias compatibles con el sistema de documentación. Puntúa los comentarios y colócalos encima del código que explican. Define los nombres de métricas y las claves de etiquetas como constantes, centraliza las etiquetas compartidas y registra las descripciones una sola vez. Mantén una tarea de métricas específica por origen y una pequeña superficie de orquestación. Antes de terminar, confirma el alcance afectado: - el objetivo modificado compila; - el formato es correcto; - el análisis estático se completa correctamente con la configuración de análisis del espacio de trabajo; - las pruebas unitarias y de integración pertinentes se completan correctamente y se ejecutaron de verdad; - las pruebas de documentación se completan correctamente cuando corresponda; - los comentarios y la documentación coinciden con el comportamiento final; - las métricas, los registros y las etiquetas cumplen las reglas de nomenclatura y seguridad de los datos. Informa de las comprobaciones realizadas, su alcance y las que se omitieron deliberadamente. No declares la finalización basándote solo en el estado de salida de un comando cuando su salida muestre que no se ejercitó ningún objetivo significativo.