Correction du décalage quotidien des snapshots
Billet #375 : Correction de la programmation UTC de l'import quotidien
Type : Diagnostic / Exploitation / Fiabilité des données
Composants concernés : scripts/pipeline.crontab, tests/test_pipeline_schedule.py, documentation opérationnelle
Besoin
Le 31 octobre 2026, la version sécurisée affichait un snapshot du 29 octobre, alors que la dernière séance terminée était celle du vendredi 30 octobre. Le décalage était signalé depuis plusieurs semaines.
Investigation et cause confirmée
La vérification en lecture seule du VPS a établi que son fuseau était Etc/UTC et que l'import était planifié à 02 h UTC du lundi au samedi. À cette heure, Montréal est encore à la date de la veille : 22 h en heure d'été, 21 h en heure d'hiver.
Le pipeline utilise correctement la veille ouvrée de la date montréalaise. Ainsi, l'exécution du samedi 31 octobre à 02 h UTC intervient le vendredi 30 octobre à 22 h à Montréal et demande les données du 29 octobre. La dernière date en base était effectivement le 29 octobre : il ne s'agissait pas d'une simple erreur d'affichage.
La date exacte de début du décalage n'a pas été établie. Le rapport d'incident d'août mentionne déjà 02 h UTC, ce qui indique que cette programmation n'est pas récente. Un contrôle des vendredis de septembre et octobre a établi que les quatre vendredis de septembre sont présents, mais que les 2, 9, 16, 23 et 30 octobre sont absents. Le défaut ne touche donc pas seulement la fraîcheur du dernier snapshot : des séances manquent dans l'historique. Ces données établissent un manque dès le 2 octobre, sans prouver quand l'horaire a été modifié ni comment les vendredis de septembre ont été importés.
Correctif préparé
- Horaire de référence versionné dans
scripts/pipeline.crontab: 06 h UTC, du lundi au samedi, soit 02 h EDT / 01 h EST à Montréal, sur la même date locale. - Conservation de la logique Python de veille ouvrée, des garde-fous du dimanche et du rattrapage du lundi.
- Remplacement de la seule entrée du pipeline après validation, sans écraser les autres tâches planifiées.
- Aucun changement de prix ou de date artificiel pour masquer le retard.
Preuves de validation locale
- Sept scénarios ont échoué avec l'horaire de production à 02 h UTC avant correction.
- Six scénarios de calendrier passent avec 06 h UTC, couvrant les deux changements d'heure et la récupération du vendredi.
- Un test d'intégration vérifie la date demandée à l'API, la date et le cours enregistrés dans SQLite, puis le snapshot affiché par le dashboard sécurisé.
- 90 tests ciblés réussis, dont 74 pour le calendrier, le pipeline et le dashboard et 16 pour la configuration documentaire et le wiki. Deux avertissements attendus concernent le CSV corrompu.
- Couverture de code ciblée de
pipeline.py: 70,93 %, au-dessus du seuil de 67 % utilisé pour cette validation. Ce chiffre n'est pas une mesure globale du dépôt. - Portefeuille local isolé : deux imports réels du pipeline avec réponses API simulées, snapshots du 29 et du 30 octobre, sans accès à la base de production.
Validation et application en production
L'utilisateur a explicitement validé le portefeuille local et autorisé d'abord l'application de l'horaire et la récupération du 30 octobre, puis le rattrapage des quatre vendredis précédents.
- Le cron installé a été sauvegardé avant modification; seule l'entrée du pipeline et son commentaire de fuseau ont changé. L'installation à 06 h UTC a été relue et le service
cronest actif. - 132 cours sur 138 ont été récupérés pour le 30 octobre et comparés aux valeurs réellement enregistrées, en tenant compte de la précision des colonnes de production.
- Six cours restent indisponibles chez le fournisseur; aucun prix CSV n'a été utilisé pour leur donner artificiellement une date récente. Une alerte opérateur a été envoyée.
- Le dernier snapshot en base est désormais le 30 octobre 2026, sans doublon. Le rendu du dashboard et de l'historique d'une fiche titre a été vérifié avec les données de production dans un processus de diagnostic distinct, sans changer l'authentification du service en ligne.
Deux contrôles stricts ont demandé une investigation complémentaire : l'import a ajouté un titre suivi du CSV, sans position courante ni transaction, et une comparaison exacte des quantités a rencontré la précision historique à deux décimales, contre quatre dans le registre. Le nouveau titre a été confirmé à zéro action dans le snapshot; les quantités enregistrées correspondent au registre à la précision réelle de la colonne. Le code d'import ne modifie ni les positions courantes ni les transactions. Aucun changement de schéma n'a été effectué.
Rattrapage des vendredis précédents
Après autorisation, les 2, 9, 16 et 23 octobre ont été récupérés avec des cours Marketstack correspondant exactement à chaque séance, sans repli CSV.
L'accès aux taux historiques APILayer a retourné HTTP 401. L'utilisateur a autorisé, pour ce rattrapage uniquement, les taux moyens quotidiens USD→CAD de la Banque du Canada. Le fournisseur de l'import quotidien, son cache et sa configuration n'ont pas été modifiés.
| Séance | Cours enregistrés / titres suivis | Cours indisponibles | Taux USD→CAD daté |
|---|---|---|---|
| 2 octobre 2026 | 133 / 138 | 5 | 1,4246 |
| 9 octobre 2026 | 133 / 138 | 5 | 1,4271 |
| 16 octobre 2026 | 133 / 138 | 5 | 1,4154 |
| 23 octobre 2026 | 132 / 138 | 6 | 1,3993 |
Les 531 cours persistés et leurs conversions ont été comparés aux données fournisseur à la précision réelle des colonnes; les quantités correspondent au registre à chaque date. Aucun doublon n'a été créé. Les transactions, positions courantes existantes et snapshots hors de ces quatre dates sont préservés. L'import a également actualisé les métadonnées des titres et ajouté un titre suivi disposant de cours historiques, sans position courante ni transaction.
Le contrôle initial portant sur toutes les colonnes des titres a été affiné pour distinguer cette actualisation normale des métadonnées des données financières à préserver. Le 2 octobre, déjà écrit lors de ce contrôle, a été revérifié sans réécriture avant de terminer les trois autres séances.
Les indisponibilités ont déclenché une alerte opérateur pour chaque date; aucun cours ni taux actuel n'a été substitué. Le dashboard conserve le dernier snapshot du 30 octobre et une fiche titre affiche les quatre dates récupérées dans son tableau d'historique. Ces rendus ont été vérifiés en lecture seule avec les données de production, sans modification du service en ligne.
Bilan d'utilisation de jetons
Le suivi de consommation porte sur l'investigation du billet #375, la correction de l'horaire, le rattrapage des snapshots, les vérifications et la documentation.
| Élément suivi | État du bilan |
|---|---|
| Durée de la session de travail (estimation) | Environ 1 heure |
| Crédits Copilot AI consommés | 134,7 |
| Coût total | Environ 1.35$ |