📅 Réforme des horaires de la Vitrine démocratique 1.0

Système de mise à jour 6 fois/jour - Architecture complète (Heure de Montréal)

📅 17 février 2026
🎯 6 blocs par jour
⏱️ ~53 min de traitement

🎯 Contexte et Objectifs

Objectif Principal

La Vitrine Démocratique se met à jour 6 fois par jour (toutes les 4 heures) avec les dernières données des médias et analyses.

Modèle de fraîcheur: Les données collectées sur une fenêtre de 4h sont traitées et disponibles environ 53 minutes après le début du bloc.

Exemple: Bloc débute à 11:00 → Traitement ~53min → Données prêtes vers 11:53 (heure de Montréal)

⏱️ Horaire Complet (6 blocs/jour):
🌙
NUIT
Données: 23h-3h
Glue Job: 03:00
Pipeline: 03:00-03:53
✅ Données: ~03:53
🎯 Vitrine: 04h
🌅
MATINÉE
Données: 3h-7h
Glue Job: 07:00
Pipeline: 07:00-07:53
✅ Données: ~07:53
🎯 Vitrine: 08h
☀️
MATIN
Données: 7h-11h
Glue Job: 11:00
Pipeline: 11:00-11:53
✅ Données: ~11:53
🎯 Vitrine: 12h
☀️
MIDI
Données: 11h-15h
Glue Job: 15:00
Pipeline: 15:00-15:53
✅ Données: ~15:53
🎯 Vitrine: 16h
🌤️
APRÈS-MIDI
Données: 15h-19h
Glue Job: 19:00
Pipeline: 19:00-19:53
✅ Données: ~19:53
🎯 Vitrine: 20h
🌆
SOIRÉE
Données: 19h-23h
Glue Job: 23:00
Pipeline: 23:00-23:53
✅ Données: ~23:53
🎯 Vitrine: 00h

🔧 Architecture des Glue Jobs (ETL)

Le pipeline utilise deux types de Glue Jobs AWS pour gérer l'extraction, la transformation et le chargement des données:

1️⃣ Glue Job GÉNÉRALE (toutes les 4h)
  • Récupère tous les CSV des extracteurs des 4 dernières heures
  • Agrège et consolide les données brutes
  • Point de départ du pipeline de transformation
  • Durée: ~3 minutes
2️⃣ Glue Jobs SPÉCIFIQUES (après chaque raffineur)
  • Chaque raffineur a son propre Glue Job dédié
  • Écrit les résultats transformés vers Athena (tables SQL)
  • Permet la persistance et l'interrogation des données
  • Durée: ~3 minutes chacun
  • Total: 9 Glue Jobs spécifiques × 3 min = 27 min additionnelles

💡 Impact: Ces Glue Jobs ajoutent ~30 minutes au temps total du pipeline (~60 min au lieu de ~30 min de transformation pure).

🔬 Architecture Scientifique avec Modèles Locaux

TOUS les raffineurs utilisent maintenant salient_index comme source de vérité unique pour les scores de saillance.

Pipeline scientifique en 4 étapes:

  1. ARTICLES_SEGMENTED (WTPSPLIT API):
    • Segmentation des phrases via API dédiée
    • Durée: 3 min
  2. SALIENT_OBJECTS (GLiNER v1 + gemma3:27b):
    • Phase 1 - GLiNER v1: Extraction NER avec 18 labels (persons, locations, organizations, concepts, topics, events, products, brands, etc.)
    • Phase 2 - gemma3:27b (Ollama): Normalisation + traduction bilingue EN↔FR dans un seul prompt
    • Cache 20-40% sur normalisation
    • Traitement en 2 phases évite loading/unloading des modèles
    • Durée: 25 min (modèles locaux plus lents mais reproductibles)
  3. PARTY_SCORE (Classification):
    • Lit salient_index (ne recalcule PAS les scores)
    • Modèles: Canadian political parties + sentiment analysis
    • Auto-parallélisation côté serveur
    • Durée: 1 min
  4. ISSUES_SCORE (Enjeux du CAPP):
    • Lit salient_index (ne recalcule PAS les scores)
    • Modèle: Multi-label classification (20+ thèmes CAP)
    • Auto-parallélisation côté serveur
    • Durée: 1 min

⚖️ Trade-off: Plus lent que GPT-4 (~25 min vs ~2 min), mais scientifiquement rigoureux, reproductible, et traçable.
💡 Objectif d'optimisation continue: Réduire le délai de traitement en améliorant les performances des modèles locaux et l'architecture du pipeline.

📊 Architecture Complète des Pipelines (6x/jour)

Vue d'ensemble du flux complet, de la collecte des données jusqu'à la publication de la Vitrine:

🔧 PHASE 1: Préparation des Données (Séquentiel - ~41 min)

GLUE JOB GÉNÉRALE [DÉBUT] (3 min)
→ Traite le bloc du Matin (7:00-11:00)
→ Démarre à 03:00, 07:00, 11:00, 15:00, 19:00, 23:00 (heure de Montréal)
→ ✅ TERMINE à XX:03
RADAR_ARTICLES_SEGMENTED [NOUVEAU] (3 min)
→ API WTPSPLIT: segmentation des phrases
→ Input: glue_job_general (9 colonnes)
→ Output: articles_segmented (16 colonnes)
→ ✅ TERMINE à XX:09
Glue Job spécifique (3 min)
→ Écriture vers Athena
→ ✅ TERMINE à XX:12
RADAR_SALIENT_OBJECTS [MODIFIÉ] (25 min)
→ Modèle: GLiNER v1 (NER - 18 labels)
→ Modèle: gemma3:27b (Normalisation + traduction bilingue)
→ Input: articles_segmented (16 colonnes)
→ Output: salient_headlines_objects (20 colonnes)
→ Cache: 20-40% hits | Traitement en 2 phases évite loading/unloading des modèles
→ ✅ TERMINE à XX:37
Glue Job spécifique (3 min)
→ Écriture vers Athena
→ ✅ TERMINE à XX:40
SALIENT_INDEX ⭐ SOURCE DE VÉRITÉ (1 min)
→ CALCULE les scores de saillance UNE SEULE FOIS (jamais recalculé)
→ Input: salient_headlines_objects (20 colonnes)
→ Output: salient_index (20 colonnes AVEC scores)
→ ✅ TERMINE à XX:41
Glue Job spécifique (3 min)
→ Écriture vers Athena
→ ✅ TERMINE à XX:44 - Point de départ pour TOUT l'enrichissement

⚡ PHASE 2: Enrichissement (Parallèle après XX:44 - max 8 min)

Tous ces pipelines démarrent en même temps après SALIENT_INDEX et lisent salient_index. Chaque pipeline a son Glue Job spécifique (+3 min):

HEADLINE_OF_HEADLINES (5 min + 3 min GJ)
→ Lit salient_index
→ Génère les titres de headlines
→ + Glue Job spécifique (3 min)
ISSUES_SCORE (1 min + 3 min GJ)
→ Lit salient_index (20 colonnes)
→ Modèle: Enjeux du CAPP (multi-label, 20+ thèmes)
→ Output: issues_score (30 colonnes)
→ + Glue Job spécifique (3 min)
PARTY_SCORES (1 min + 3 min GJ)
→ Lit salient_index (20 colonnes)
→ Modèles: Canadian parties + sentiment
→ Output: party_score (24 colonnes)
→ + Glue Job spécifique (3 min)
HEADLINES_ISSUES (5 min + 3 min GJ)
→ Lit issues_score
→ Attend ISSUES_SCORE
→ + Glue Job spécifique (3 min)
REFLET (5 min + 3 min GJ)
→ Lit salient_index, issues_score, party_score
→ Attend ISSUES_SCORE + PARTY_SCORES
→ + Glue Job spécifique (3 min)
⚡ Innovation majeure: Un seul calcul de saillance dans SALIENT_INDEX, réutilisé par tous. Auto-parallélisation côté serveur pour les modèles de classification.

🚀 PHASE 3: Données Prêtes (~XX:53)

Tous les enrichissements terminés
→ Tous les pipelines d'enrichissement terminés (~XX:53)
→ Toutes les tables Athena disponibles avec leurs Glue Jobs
ACTUELLEMENT: VITRINE_GRAPH_DATA [TEMPORAIRE] (3 min)
→ Agrège toutes les tables enrichies
→ Génère les données JSON pour la visualisation
→ ✅ VITRINE PRÊTE environ 1h après le début du bloc
FUTURE API: Accès Direct [PROCHAINEMENT]
Élimination de VITRINE_GRAPH_DATA
→ Le backend appellera l'API directement
→ L'API chargera les fichiers Parquet depuis Athena
→ Plus besoin de transformation JSON
→ Sécurité, contrôle d'accès, et monétisation possibles
→ ✅ VITRINE PRÊTE dès ~XX:53 (gain de 7 min)
🎯 Modèle de fraîcheur: Les données collectées sur chaque fenêtre de 4h sont traitées et disponibles environ 53 minutes après le début du bloc.
Exemple: bloc débute à 11:00 → traitement ~53min → données prêtes vers 11:53 (heure de Montréal)
🔮 Avec l'API: données prêtes vers 11:53 directement (élimination de VITRINE_GRAPH_DATA)
⏱️ Durée totale du bloc: ~53 minutes incluant tous les Glue Jobs spécifiques (Préparation ~41min incluant 3 GJ + Enrichissement parallèle max 8min incluant 5 GJ)
🔮 Avec l'API future: VITRINE_GRAPH_DATA sera éliminé, le backend accédera directement aux Parquet via l'API
💡 Optimisation continue: Ces temps reflètent notre architecture actuelle avec modèles locaux. L'objectif reste de réduire ce délai en optimisant les modèles et les performances.

📅 Pipelines Hebdomadaires & Mensuels

Versions weekly/monthly des analyses, exécutées une fois par jour (15h30-15h45 EST) — À valider :

  • Weekly (à valider): Issues, Headlines Issues, Party Scores, Reflet
  • Monthly (à valider): Issues, Headlines Issues, Party Scores, Reflet

📊 Pipelines Spéciaux

  • HOT_20: Vendredis à 11h30 EST
  • SONAR: Quotidien à 07h00 EST
  • SONAR_HEATMAPS: Mercredis à 07h30 EST

📋 Durées Mesurées (AWS Monitoring)

Temps d'exécution réels observés en production (exemple: bloc Glue Job à 11:00):

Raffineur / Glue Job Durée Réelle Heure (ex: 11:00) Notes
GLUE JOB GÉNÉRALE 3 min 11:00 Traite le bloc du Matin (7:00-11:00)
ARTICLES_SEGMENTED 3 min 11:03 API WTPSPLIT
+ Glue Job spécifique 3 min 11:06 Écriture Athena
SALIENT_OBJECTS 25 min 11:09 GLiNER v1 + gemma3:27b
+ Glue Job spécifique 3 min 11:34 Écriture Athena
SALIENT_INDEX 1 min 11:37 Calcul scores saillance
+ Glue Job spécifique 3 min 11:38 Écriture Athena
⚡ Enrichissement (parallèle)
HEADLINE_OF_HEADLINES 5 min 11:41 Génération titres
+ Glue Job spécifique 3 min 11:46 Écriture Athena
ISSUES_SCORE 1 min 11:41 Classification Enjeux du CAPP
+ Glue Job spécifique 3 min 11:42 Écriture Athena
PARTY_SCORES 1 min 11:41 Partis + sentiment
+ Glue Job spécifique 3 min 11:42 Écriture Athena
HEADLINES_ISSUES 5 min 11:42 Attend ISSUES_SCORE
+ Glue Job spécifique 3 min 11:47 Écriture Athena
REFLET 5 min 11:42 Attend ISSUES + PARTY
+ Glue Job spécifique 3 min 11:47 Écriture Athena
🚀 Données Prêtes (~11:53)
VITRINE_GRAPH_DATA 3 min --:-- Sera éliminé avec l'API (accès direct Parquet)
✅ Avec l'API: Données disponibles directement via Athena Parquet à ~11:53
📅 Pipelines Hebdomadaires & Mensuels (1x/jour à 15h30 EST)
ISSUES_SCORE_WEEKLY ~1 min 15:30 Agrégation hebdomadaire — À valider
ISSUES_SCORE_MONTHLY ~1 min 15:31 Agrégation mensuelle — À valider
PARTY_SCORES_WEEKLY ~1 min 15:32 Scores partis hebdo — À valider
PARTY_SCORES_MONTHLY ~1 min 15:33 Scores partis mensuel — À valider
HEADLINES_ISSUES_WEEKLY ~5 min 15:34 Headlines hebdo — À valider
HEADLINES_ISSUES_MONTHLY ~5 min 15:39 Headlines mensuel — À valider
REFLET_WEEKLY ~5 min 15:44 Reflet hebdomadaire — À valider
REFLET_MONTHLY ~5 min 15:49 Reflet mensuel — À valider
🎯 Pipelines Spéciaux
HOT_20 ~5 min 11:30 Vendredis 11h30 EST
SONAR ~3 min 07:00 Quotidien 07h00 EST
SONAR_HEATMAPS ~5 min 07:03 Mercredis 07h30 EST
💡 Note: Chaque raffineur a son propre Glue Job spécifique qui écrit les résultats vers Athena. Ces 3 minutes s'ajoutent à chaque étape du pipeline.

🔄 Comparaison des Horaires

❌ ANCIEN HORAIRE (Montréal)
GLUE JOB: 00:03 04:03 08:03 12:03 16:03 20:03
SALIENT_OBJECTS: 00:16 04:16 08:16 12:16 16:16 20:16
SALIENT_INDEX: 00:20 04:20 08:20 12:20 16:20 20:20
HEADLINE_OF_HEADLINES: 00:28 04:28 08:28 12:28 16:28 20:28
VITRINE_GRAPH_DATA: --:-- 04:39 08:39 12:39 16:39 20:39

ISSUES_SCORE: --:-- --:-- 08:09 12:09 16:09 --:--
PARTY_SCORES: --:-- --:-- 08:18 12:18 16:18 --:--
HEADLINES_ISSUES: --:-- --:-- 08:10 12:10 16:10 --:--
REFLET: --:-- --:-- 08:24 12:24 16:24 --:--
ARTICLES_SEGMENTED n'existait pas
Seulement 5 blocs (pas de minuit)
Issues/Party/Reflet seulement 3x/jour
Pas de synchronisation claire
✅ NOUVEL HORAIRE (Montréal - EST/EDT)
GLUE JOB: 03:00 07:00 11:00 15:00 19:00 23:00
ARTICLES_SEGMENTED: 03:03 07:03 11:03 15:03 19:03 23:03
SALIENT_OBJECTS: 03:09 07:09 11:09 15:09 19:09 23:09
SALIENT_INDEX: 03:37 07:37 11:37 15:37 19:37 23:37
HEADLINE_OF_HEADLINES: 03:41 07:41 11:41 15:41 19:41 23:41

ISSUES_SCORE: 03:41 07:41 11:41 15:41 19:41 23:41
PARTY_SCORES: 03:41 07:41 11:41 15:41 19:41 23:41
HEADLINES_ISSUES: 03:42 07:42 11:42 15:42 19:42 23:42
REFLET: 03:42 07:42 11:42 15:42 19:42 23:42

6 blocs complets par jour (toutes les 4h)
~53 min réels incluant tous les Glue Jobs (8 spécifiques × 3 min)
Pipelines parallèles après SALIENT_INDEX
TOUS les raffineurs 6x/jour (Issues, Party, Reflet, Headlines Issues)
API Future: Élimination de VITRINE_GRAPH_DATA, accès direct aux Parquet

📈 Visualisation d'un Bloc (exemple: Bloc MATIN 7h-11h)

⏱️ Timeline: 7h00 → 11h53 (heure de Montréal)
  • Données : 7h-11h
  • Glue Job : 11:00
  • Pipeline : 11:00-11:53
  • ✅ Données : ~11:53
  • 🎯 Vitrine : 12h
11:00
11:10
11:20
11:30
11:40
11:50
12:00
GJ 3min
GLUE JOB
3min
ARTICLES_SEG
+GJ 3m
SALIENT_OBJECTS 25min
SALIENT_OBJ
+GJ 3m
1m
SALIENT_IDX
+GJ 3m
⚡ Parallèle
HOH 5m
HEADLINE_HOH
+GJ 3m
1m
ISSUES
+GJ 3m
1m
PARTY
+GJ 3m
H_ISS 5m
HEAD_ISSUES
+GJ 3m
REFLET 5m
REFLET
+GJ 3m
PRÊT
✅ DONNÉES
✅ 11:53

🔮 Impact de la Future API

⚠️ Note importante: L'architecture va évoluer avec l'arrivée de l'API

Actuellement (Glue Jobs + Lambda)

  • Glue Jobs récupèrent les CSV générés par les pipelines
  • Chaque raffineur Lambda analyse les données et publie dans Athena
  • Une seule Glue Job générale agrège toutes les tables

Avec la Future API

  • Élimination du raffineur VITRINE_GRAPH_DATA: Le backend va directement appeler l'API pour charger les fichiers Parquet depuis Athena
  • Accès direct aux données Parquet: Plus besoin de transformer les données en JSON, l'API lit directement depuis l'infrastructure Athena
  • Simplification de l'architecture: L'API facilite l'appel et centralise l'accès aux données
  • Sécurité et contrôle d'accès: Possibilité d'ajouter des codes d'accès, des durées d'accès limitées, et de contrôler qui accède aux données
  • Monétisation future: Infrastructure prête pour un modèle d'accès payant si souhaité
  • Performance améliorée: Réduction des délais entre les étapes grâce à l'accès direct
  • Flexibilité: Déclenchement de mises à jour à la demande possible

🚀 Prochaines Étapes

✅ Validation de l'horaire (EN COURS)

Approbation de l'équipe et confirmation des durées réelles en production

🔧 Déploiement de ARTICLES_SEGMENTED

PR #107 du repo aws-refiners - Création de l'infrastructure Lambda + ECR - Tests en environnement DEV

📊 Mise à jour de tous les raffineurs

Application du nouvel horaire - Ajout du 6ème bloc (minuit) - Mise à jour des payloads

🧪 Phase de Test (2 semaines)

Monitoring intensif des temps d'exécution - Ajustements si nécessaire - Validation de la synchronisation

📈 Optimisation Continue

Réduction progressive des marges de sécurité - Préparation à l'arrivée de l'API - Documentation des métriques

Version: 1.0 | Dernière mise à jour: 17 février 2026

🌙
04:00
Bloc NUIT (23:00-3:00)