


Écrire du code de réplication de données (ETL) sans altérer les valeurs en silence ni laisser fuir de données
Pour écrire ou modifier du code qui copie des données entre bases. L’IA garde les changements petits, bloque les arrondis et autres changements silencieux, renvoie des erreurs claires sur une entrée invalide, n’écrit ni secrets ni lignes dans les logs et vérifie que les tests ont tourné.
Pour utiliser ces règles d'IA
## Ne pas pousser de code ni toucher aux migrations sans demande
Gardez chaque modification centrée sur le problème à résoudre. Privilégiez la plus petite différence cohérente, sauf si un remaniement plus large est nécessaire pour préserver l’exactitude.
Avant d’introduire un modèle, une dépendance, un auxiliaire ou une préparation de test, examinez le code voisin et suivez les conventions établies dans l’espace de travail. Considérez la configuration de l’outil de formatage, les diagnostics du compilateur et les réglages d’analyse de style de l’espace de travail comme la référence du style applicable.
N’effectuez aucune écriture dans le dépôt, ne publiez aucune branche, n’ouvrez aucune demande de modification et ne réécrivez pas l’historique, sauf si l’utilisateur demande explicitement cette action.
Ne modifiez pas les migrations de base de données, sauf si le travail demandé exige précisément une modification de migration. Cela inclut les commentaires et le texte non exécutable dans les fichiers de migration.
N’exécutez les vérifications coûteuses sur l’ensemble de l’espace de travail que lorsque leur portée est justifiée. Pour les modifications à faible risque de documentation ou de configuration, utilisez la validation pertinente la plus restreinte et indiquez exactement ce qui a été exécuté.
## Ranger les modules par concept de données et garder les API privées par défaut
Organisez le code selon les concepts du domaine plutôt que dans des catégories génériques. Regroupez le comportement de réplication et les types propres à la réplication ; placez les primitives de base de données réutilisables, les auxiliaires de source, les auxiliaires de slots de réplication et l’accès aux métadonnées dans une limite d’intégration.
N’utilisez une limite de paquet que lorsqu’un autre paquet dépend réellement de l’API. Au sein d’un même domaine, privilégiez des modules portant des noms tels que `schema`, `data`, `event`, `store`, `source` ou `slots`.
Gardez les binaires de premier niveau centrés sur l’orchestration. Déplacez les détails d’implémentation dans des auxiliaires et des modules ciblés.
Utilisez par défaut une visibilité privée et ne l’élargissez que pour un appelant réel. Privilégiez d’abord la visibilité privée, puis celle limitée au paquet, puis la visibilité publique. Considérez chaque réexportation comme un contrat d’API :
- évitez les réexportations génériques depuis les modules internes ;
- n’exposez que la plus petite surface de configuration utile ;
- gardez privés l’orchestration des processus de travail, les codecs, les raccordements d’exécution et les détails d’implémentation ;
- évitez les façades de compatibilité, sauf si elles constituent intentionnellement une API stable.
Préférez un code clair et conventionnel à une abstraction ingénieuse. Regroupez les types, les constructeurs, les méthodes publiques et les auxiliaires privés dans un ordre lisible.
## Repérer les arrondis et autres changements silencieux de valeurs
Validez les valeurs localement lorsque la destination accepterait sinon un changement sémantique silencieux, tel qu’un arrondi, une troncature, un plafonnement, une coercition, un dépassement de capacité ou une perte de précision.
Si la destination rejette déjà une valeur non prise en charge avec une erreur explicite, ne dupliquez pas une validation coûteuse dans le chemin d’écriture sans besoin démontré.
Utilisez des conversions numériques vérifiées ou fondées sur des traits lorsqu’elles sont sans perte et disponibles. N’utilisez des conversions volontairement avec perte que lorsque la perte est comprise, que la plage est vérifiée lorsque nécessaire et que la représentation cible les exige.
N’utilisez une conversion implicite que lorsque la correspondance ne peut pas échouer, est sémantiquement sans perte, préserve la valeur et est évidente.
Modélisez les mises à jour partielles avec trois états distincts :
- les champs omis préservent la valeur enregistrée ;
- une valeur nulle explicite efface une valeur facultative ou rétablit une valeur par défaut ;
- les valeurs non nulles remplacent la valeur enregistrée.
Lors de la conversion d’une configuration complète en sémantique de mise à jour partielle, utilisez un auxiliaire de conversion explicite. Ne dissimulez pas le passage de la conservation à l’effacement derrière un trait de conversion générique.
## Renvoyer des erreurs claires au lieu de planter sur une entrée invalide
Utilisez des erreurs typées et des valeurs de résultat pour les échecs récupérables. Ajoutez un contexte autonome, comme les opérations, les identifiants, les nombres, les types ou les instructions, tout en préservant l’erreur d’origine dans la chaîne des causes.
Ne réduisez pas une erreur sous-jacente à une chaîne de caractères, sauf si un message délibérément assaini est plus sûr pour l’appelant. Les réponses des API publiques ne doivent pas exposer les erreurs du pilote de base de données, les requêtes internes, les données des clients ou les détails de l’infrastructure.
Réservez les paniques aux invariants de programmation rompus. Les entrées externes, la syntaxe mal formée, les valeurs non prises en charge et les défaillances de l’état du système doivent renvoyer des erreurs explicites.
Les points d’entrée de l’analyseur doivent traiter sans paniquer les entrées vides, les fins d’entrée inattendues, les échappements mal formés, les séquences d’octets invalides, les plages invalides, les dépassements de capacité, les sous-dépassements et la syntaxe non prise en charge.
Privilégiez les accès vérifiés, les itérateurs et l’analyse de tranches d’octets lorsque l’entrée détermine les décalages. L’indexation directe n’est acceptable que lorsqu’une borne locale ou un invariant de segment de taille exacte la rend manifestement sûre.
Ajoutez des tests de régression pour chaque limite d’entrée mal formée qui pouvait auparavant provoquer une panique ou une mauvaise analyse silencieuse.
## Choisir comment arrêter les tâches de fond selon l’état qu’elles détiennent
Évitez le code non sûr, sauf lorsqu’il est nécessaire. Chaque bloc non sûr doit être accompagné d’une explication de sécurité adjacente indiquant l’invariant qui garantit la validité de l’opération.
Privilégiez la propriété et l’emprunt au clonage inutile ou à la mutabilité interne.
Placez les travaux asynchrones de longue durée derrière des tâches ou des auxiliaires nommés, et choisissez le comportement d’arrêt selon l’état possédé :
- abandonner un descripteur de tâche détache la tâche ; interrompez explicitement un travail d’arrière-plan jetable lorsqu’il doit s’arrêter immédiatement ;
- abandonner un ensemble de tâches interrompt toutes les tâches qu’il possède ;
- n’interrompez pas inutilement un ensemble de tâches juste avant de quitter la portée qui l’abandonnera ;
- utilisez des opérations d’interruption explicites lorsque l’ensemble de tâches reste actif, mais que ses tâches doivent s’arrêter ;
- utilisez un signalement et une attente gracieux lorsque les tâches possèdent des transactions, des écritures en mémoire tampon vers la destination ou un état de réplication sensible aux nouvelles tentatives.
N’ajoutez pas de coordination d’arrêt élaborée pour des tâches d’interrogation périodique ou de télémétrie dont l’état peut être abandonné sans risque.
## Garder les secrets et les données des clients hors du code et des logs
Considérez les fichiers suivis, les branches, les commits, les examens, les journaux, les captures d’écran, les préparations de test, les artefacts générés et la sortie du terminal comme potentiellement publics.
Ne placez jamais d’identifiants d’accès, de jetons, de points d’accès privés, de données client, de charges utiles de production, de données personnelles ou de configuration propriétaire dans le code, les tests, la documentation, les exemples, les commentaires, les messages, la télémétrie, les détails des paniques ou les fichiers générés.
Utilisez des valeurs fictives dans les exemples. Stockez les vrais secrets uniquement dans des variables d’environnement approuvées, des fichiers locaux ignorés, des gestionnaires de secrets ou le stockage de secrets de l’intégration continue.
Si une valeur suspecte paraît réelle ou provient d’un environnement privé, ne la reproduisez pas. Arrêtez le processus de publication, signalez son emplacement sans citer la valeur et recommandez sa rotation ou sa révocation lorsqu’une exposition a pu se produire.
Pour l’observabilité :
- privilégiez les libellés à faible cardinalité ;
- journalisez des métadonnées structurelles telles que les noms de tables, les noms de colonnes, les types, les nombres, les longueurs, les positions et les noms d’opérations ;
- ne journalisez jamais les valeurs de lignes, le contenu des cellules, les corps sensibles des requêtes ou des réponses, les identifiants d’accès ou les jetons ;
- utilisez un formatage d’affichage sûr pour les erreurs et les champs structurés ;
- expurgez la capture des corps pour les routes sensibles et les périmètres de surveillance.
## Tester de vrais événements de réplication et vérifier que les tests ont tourné
Exécutez d’abord les tests pertinents les plus restreints, puis élargissez la portée lorsque le comportement partagé, les régressions ou la demande le justifient. Vérifiez que les tests attendus ont réellement été exécutés ; une commande réussie sans aucun test correspondant ne constitue pas une vérification réussie.
Énumérez les tests avant d’appliquer des filtres incertains. Exécutez séparément les tests de documentation lorsque le programme principal d’exécution des tests ne les prend pas en charge.
Réutilisez les préparations de test, les auxiliaires de base de données, les primitives d’attente et les assertions existants à proximité avant de créer une infrastructure de test personnalisée.
Pour les tests d’intégration pilotés par des événements :
1. Enregistrez les notifications ou les descripteurs d’attente avant que le producteur puisse émettre l’événement.
2. Effectuez les écritures côté source.
3. Attendez les notifications attendues.
4. Arrêtez le pipeline et attendez sa fin avant de vérifier l’état de la destination, sauf si le test porte explicitement sur le comportement en cours d’exécution.
5. Effectuez les assertions sur l’historique cumulé des événements, sauf si un redémarrage ou une phase isolée exige de l’effacer.
Faites correspondre les événements attendus de capture des modifications de données au comportement réel d’identité de réplication de la base de données source. N’attendez pas de lignes de mise à jour partielles dans des modes qui ne peuvent pas en émettre.
## Documenter le code et signaler les vérifications effectuées
Documentez les éléments publics et privés dans une prose concise et précise. Reliez les types et les méthodes au moyen des références prises en charge par le système de documentation. Ponctuez les commentaires et placez-les au-dessus du code qu’ils expliquent.
Définissez les noms des métriques et les clés de libellés comme des constantes, centralisez les libellés communs et enregistrez les descriptions une seule fois. Conservez une tâche de métriques ciblée par source, accompagnée d’une petite surface d’orchestration.
Avant de terminer, confirmez la portée affectée :
- la cible modifiée se compile ;
- le formatage réussit ;
- l’analyse statique réussit avec la configuration d’analyse de style de l’espace de travail ;
- les tests unitaires et d’intégration pertinents réussissent et ont réellement été exécutés ;
- les tests de documentation réussissent lorsqu’ils s’appliquent ;
- les commentaires et la documentation correspondent au comportement final ;
- les métriques, les journaux et les libellés respectent les règles de nommage et de sécurité des données.
Indiquez les vérifications effectuées, leur portée et toute vérification volontairement omise. Ne déclarez pas le travail terminé en vous fondant uniquement sur le code de sortie d’une commande lorsque sa sortie montre qu’aucune cible pertinente n’a été exercée.
