vault backup: 2026-08-01 16:32:03
This commit is contained in:
+30
@@ -1,3 +1,5 @@
|
|||||||
|
# Consultation fournisseurs sites: proposition de publication JSON
|
||||||
|
|
||||||
## Objectif
|
## Objectif
|
||||||
|
|
||||||
Nous évaluons une nouvelle façon de fournir les données de programmation et de contenus aux sites web TFO, IDELLO, ONFR et linéaire.
|
Nous évaluons une nouvelle façon de fournir les données de programmation et de contenus aux sites web TFO, IDELLO, ONFR et linéaire.
|
||||||
@@ -312,6 +314,34 @@ Logique:
|
|||||||
- les fichiers des runs ne changent jamais;
|
- les fichiers des runs ne changent jamais;
|
||||||
- un rollback peut être fait en repointant le manifest vers un run précédent.
|
- un rollback peut être fait en repointant le manifest vers un run précédent.
|
||||||
|
|
||||||
|
## Garanties attendues
|
||||||
|
|
||||||
|
Le modèle proposé vise à garantir les comportements suivants:
|
||||||
|
|
||||||
|
- un run publié est complet pour la plateforme concernée;
|
||||||
|
- `manifest.json` pointe seulement vers un run valide;
|
||||||
|
- si une génération échoue, le manifest reste sur le dernier run valide;
|
||||||
|
- les fichiers d'un run ne changent pas après publication;
|
||||||
|
- les changements sont visibles via `latest.json`;
|
||||||
|
- les produits retirés ne sont plus présents dans les indexes du nouveau run;
|
||||||
|
- les anciens runs peuvent servir au rollback pendant la période de rétention.
|
||||||
|
|
||||||
|
Ce modèle permet aussi de publier rapidement des corrections ciblées. Par exemple, si une correction interne touche une collection ou un produit, seuls les fichiers impactés devraient changer dans le prochain run.
|
||||||
|
|
||||||
|
Limite importante: cette publication ne rend pas la source officielle instantanée. Si une donnée n'a pas encore été reçue par notre système, elle ne peut pas apparaître dans les JSON.
|
||||||
|
|
||||||
|
## Ce que ce feed n'est pas
|
||||||
|
|
||||||
|
Ce feed JSON n'est pas destiné à devenir:
|
||||||
|
|
||||||
|
- une API dynamique publique;
|
||||||
|
- un CMS éditorial;
|
||||||
|
- un moteur de recherche complet;
|
||||||
|
- un outil d'édition fournisseur;
|
||||||
|
- une refonte de votre site.
|
||||||
|
|
||||||
|
L'objectif est de fournir un contrat de données stable, versionné et facile à consommer.
|
||||||
|
|
||||||
## Points importants pour les sites
|
## Points importants pour les sites
|
||||||
|
|
||||||
- Les JSON seraient versionnés dans le chemin: `/v1/`, puis éventuellement `/v2/`.
|
- Les JSON seraient versionnés dans le chemin: `/v1/`, puis éventuellement `/v2/`.
|
||||||
|
|||||||
@@ -0,0 +1,319 @@
|
|||||||
|
|
||||||
|
|
||||||
|
## Objectif
|
||||||
|
|
||||||
|
Ce document liste les tests à prévoir pour un pilote du `Content Publication Engine`.
|
||||||
|
|
||||||
|
Le but n'est pas seulement de vérifier que les JSON sont générés. Le but est de valider que l'architecture est fiable dans les cas réels:
|
||||||
|
|
||||||
|
- export Louise/Mogador incomplet;
|
||||||
|
- bug fournisseur;
|
||||||
|
- produit retiré;
|
||||||
|
- correction d'urgence;
|
||||||
|
- vidéo JWP manquante;
|
||||||
|
- cache CDN;
|
||||||
|
- rollback;
|
||||||
|
- run partiellement généré;
|
||||||
|
- consommation par un site fournisseur.
|
||||||
|
|
||||||
|
## Principe du pilote
|
||||||
|
|
||||||
|
Le pilote devrait être limité à une plateforme ou à un sous-ensemble.
|
||||||
|
|
||||||
|
Options recommandées:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Option 1: ONFR
|
||||||
|
- plus petit volume;
|
||||||
|
- plus facile à valider;
|
||||||
|
- bon premier test technique.
|
||||||
|
|
||||||
|
Option 2: sous-ensemble TFO
|
||||||
|
- plus proche des enjeux réels;
|
||||||
|
- permet de tester collections/saisons/épisodes;
|
||||||
|
- plus représentatif pour la production.
|
||||||
|
```
|
||||||
|
|
||||||
|
Le pilote ne devrait pas remplacer Directus ou la synchro actuelle immédiatement. Il devrait tourner en parallèle.
|
||||||
|
|
||||||
|
## Critères de réussite
|
||||||
|
|
||||||
|
- Le CPE génère un run JSON complet et valide.
|
||||||
|
- `manifest.json` pointe seulement vers un run validé.
|
||||||
|
- Les sites peuvent consommer le feed via manifest + fichiers JSON.
|
||||||
|
- Une correction d'urgence peut être publiée rapidement.
|
||||||
|
- Un rollback peut être exécuté rapidement.
|
||||||
|
- Un produit inchangé n'est pas écrasé par une donnée source suspecte.
|
||||||
|
- Les anomalies sont visibles avant les plaintes de production.
|
||||||
|
- Les performances sont suffisantes pour la plateforme pilote.
|
||||||
|
- Le format JSON est validé par au moins un fournisseur/site consommateur.
|
||||||
|
|
||||||
|
## Tests d'ingestion source
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Export SQL reçu correctement|Le CPE détecte le nouvel export ou son statut d'import|
|
||||||
|
|Export SQL absent|Alerte, aucun nouveau run publié|
|
||||||
|
|Export SQL trop petit|Alerte, aucun run publié sans validation manuelle|
|
||||||
|
|Export SQL identique au précédent|Run ignoré ou marqué sans changement|
|
||||||
|
|Import MySQL réussi|Snapshot peut commencer|
|
||||||
|
|Import MySQL échoué|Alerte, manifest inchangé|
|
||||||
|
|Mogador Toolkit indisponible|Alerte, manifest inchangé|
|
||||||
|
|Réponses API lentes|Retry/backoff, rapport de lenteur|
|
||||||
|
|Réponses API partielles|Anomalie, pas d'écrasement massif|
|
||||||
|
|
||||||
|
## Tests de snapshot et diff
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Nouveau produit|Produit présent dans `latest.added` et fichier produit généré|
|
||||||
|
|Produit modifié|Produit présent dans `latest.updated` et fichier produit régénéré|
|
||||||
|
|Produit supprimé|Produit absent des indexes, présent dans `latest.removed`|
|
||||||
|
|Programmation ajoutée|`today.json` ou `schedule/YYYY-MM-DD.json` mis à jour|
|
||||||
|
|Programmation modifiée|`changed_fields` indique le changement|
|
||||||
|
|Programmation supprimée|Programme absent du schedule concerné|
|
||||||
|
|Image modifiée|Produit ou collection impactée régénérée|
|
||||||
|
|Média modifié|Produit/collection impactée régénérée|
|
||||||
|
|Aucun changement|Nouveau run optionnel, ou aucun run publié|
|
||||||
|
|
||||||
|
## Tests de publication incrémentale protégée
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Run 1 contient 8 000 produits, run 2 ajoute 10 produits|Le CPE traite les 10 nouveaux et conserve les fichiers inchangés|
|
||||||
|
|Run 2 retire 5 produits|Les 5 produits disparaissent des indexes du run 2|
|
||||||
|
|Produit inchangé dans le snapshot|Le dernier JSON valide est conservé|
|
||||||
|
|Produit inchangé devient soudainement incomplet|Anomalie, ancien JSON valide conservé|
|
||||||
|
|Bug source sur plusieurs anciens produits|Alerte globale, pas d'écrasement massif|
|
||||||
|
|Trop d'anomalies dans un run|Run bloqué ou publié avec seuil contrôlé|
|
||||||
|
|Diff incohérent|Manifest inchangé, rapport d'erreur|
|
||||||
|
|
||||||
|
Point à ne pas oublier: il faut définir des seuils.
|
||||||
|
|
||||||
|
Exemples:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Si plus de 5% des produits deviennent incomplets sans raison connue:
|
||||||
|
-> bloquer le run
|
||||||
|
|
||||||
|
Si 1 produit nouveau est incomplet:
|
||||||
|
-> publier avec avertissement ou exclure selon règle métier
|
||||||
|
|
||||||
|
Si un produit prévu aujourd'hui à 6h est incomplet:
|
||||||
|
-> alerte critique
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tests de génération JSON
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|`manifest.json` généré|Contient `schema_version`, `platform`, `run_id`, `base_path`, `published_at`|
|
||||||
|
|`today.json` généré|Contient les programmes légers du jour|
|
||||||
|
|`schedule/YYYY-MM-DD.json` généré|Contient les programmes de la date|
|
||||||
|
|Schedule J+10 généré|Les 10 prochains jours sont disponibles|
|
||||||
|
|`products/{product_key}.json` généré|Contient produit, programmations, média, images|
|
||||||
|
|`collections/{biznumber}/full.json` généré|Contient collection -> saisons -> épisodes|
|
||||||
|
|Produit multi-plateforme|Chaque plateforme a sa version contextualisée|
|
||||||
|
|Champs obligatoires manquants|Validation échoue ou anomalie créée|
|
||||||
|
|JSON invalide|Run non publié|
|
||||||
|
|JSON Schema échoue|Run non publié|
|
||||||
|
|
||||||
|
## Tests de fichiers et chemins
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Chemins sans caractères problématiques|Aucun espace ou caractère ambigu dans les paths|
|
||||||
|
|`product_key` numérique ou string|Convention documentée et stable|
|
||||||
|
|`biznumber` avec zéros en début|Zéros conservés|
|
||||||
|
|Produit absent|Retour HTTP attendu défini, ex. 404|
|
||||||
|
|Ancien run consulté|Disponible pendant la rétention|
|
||||||
|
|Run supprimé par rétention|Plus accessible après purge contrôlée|
|
||||||
|
|Chemins de liens dans `today.json`|Pointent vers le bon `base_path`|
|
||||||
|
|
||||||
|
## Tests de publication atomique
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Run complet généré avec succès|Fichiers uploadés, validation OK, manifest mis à jour|
|
||||||
|
|Run échoue pendant génération|Manifest reste sur ancien run|
|
||||||
|
|Run échoue pendant upload|Manifest reste sur ancien run|
|
||||||
|
|Run échoue après upload partiel|Manifest reste sur ancien run, fichiers incomplets nettoyés ou ignorés|
|
||||||
|
|Manifest upload échoue|Ancien manifest reste actif|
|
||||||
|
|Manifest pointe vers run inexistant|Détecté par validation pré-publication|
|
||||||
|
|Deux runs simultanés|Lock empêche collision ou ordre déterministe|
|
||||||
|
|
||||||
|
## Tests de cache CDN
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|`manifest.json` cache court|Nouveau run visible après TTL attendu|
|
||||||
|
|Fichiers de run cache long|Fichiers immuables servis efficacement|
|
||||||
|
|Rollback manifest|Site revient au run précédent après TTL/purge|
|
||||||
|
|Purge manifest CDN|Nouveau manifest visible rapidement|
|
||||||
|
|Fichier immutable modifié par erreur|Test doit échouer, les runs sont immuables|
|
||||||
|
|Site garde un ancien manifest|Comportement acceptable documenté|
|
||||||
|
|
||||||
|
Point facile à oublier: les sites doivent gérer le cas où le manifest change pendant une navigation.
|
||||||
|
|
||||||
|
Recommandation:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Une page devrait utiliser un seul run_id pendant son rendu.
|
||||||
|
Elle ne devrait pas mélanger des fichiers de deux runs différents dans la même réponse.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tests de rollback
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Rollback vers run précédent|Manifest repointe vers le run précédent|
|
||||||
|
|Rollback après bug source|Anciens JSON valides disponibles|
|
||||||
|
|Rollback après mauvais override|Override désactivé, run précédent ou nouveau run correct publié|
|
||||||
|
|Rollback audité|Qui, quand, pourquoi enregistré|
|
||||||
|
|Rollback communiqué au site|Site détecte nouveau `run_id`|
|
||||||
|
|
||||||
|
## Tests de Publication Console
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Login édimestre|Accès autorisé seulement en interne|
|
||||||
|
|Rôle read-only|Consultation seulement|
|
||||||
|
|Rôle édimestre|Peut créer override autorisé|
|
||||||
|
|Rôle admin|Peut approuver, rollback, republier|
|
||||||
|
|Override avec expiration|Désactivation automatique après expiration|
|
||||||
|
|Override sans raison|Refusé|
|
||||||
|
|Override sans audit|Refusé|
|
||||||
|
|Override produit|`publication_job` ciblé créé|
|
||||||
|
|Override collection|Collection et indexes impactés régénérés|
|
||||||
|
|Override supprimé|Nouveau run revient aux données source|
|
||||||
|
|Conflit override vs nouveau snapshot|Rapport d'écart généré|
|
||||||
|
|
||||||
|
Point facile à oublier: un override doit avoir une durée de vie.
|
||||||
|
|
||||||
|
Sans expiration, la Publication Console devient un CMS parallèle et on recrée le problème de gouvernance.
|
||||||
|
|
||||||
|
## Tests Media Pipeline / JWP
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Vidéo prête|`media_assets.status = ready`, produit republié|
|
||||||
|
|Vidéo manquante|`media_assets.status = missing`, alerte si critique|
|
||||||
|
|Vidéo en encodage|`processing`, JSON indique un état contrôlé|
|
||||||
|
|Vidéo échouée|`failed`, rapport visible|
|
||||||
|
|Poster manquant|Anomalie non bloquante ou bloquante selon règle|
|
||||||
|
|Sous-titres manquants|Anomalie selon règle d'accessibilité|
|
||||||
|
|Media Pipeline down|CPE continue avec dernier `media_assets` connu|
|
||||||
|
|JWP indisponible|Pas d'écrasement des anciens médias valides|
|
||||||
|
|`publication_job media_ready`|Produit/collection impactés republiés|
|
||||||
|
|
||||||
|
Point facile à oublier: le CPE ne devrait pas appeler JWP directement pour construire chaque JSON. Il doit lire l'état interne `media_assets`.
|
||||||
|
|
||||||
|
## Tests de sécurité et accès
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|App interne non exposée Internet|Accès bloqué hors réseau/VPN/SSO|
|
||||||
|
|Bucket par plateforme ou préfixe|Chaque fournisseur voit seulement son feed|
|
||||||
|
|Secrets absents des JSON|Aucun token, URL signée privée ou donnée interne sensible|
|
||||||
|
|`product_key` visible selon règle|Confirmer ce qui peut être exposé aux fournisseurs|
|
||||||
|
|Logs sans secret|Aucun credential dans logs/rapports|
|
||||||
|
|Accès écriture bucket limité|Seul le CPE peut publier|
|
||||||
|
|Suppression accidentelle bucket|Protection IAM ou versioning bucket|
|
||||||
|
|
||||||
|
Point facile à oublier: les JSON publics ne doivent pas contenir d'information réservée à l'équipe interne.
|
||||||
|
|
||||||
|
## Tests d'observabilité
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Rapport par run|Disponible après chaque tentative|
|
||||||
|
|Rapport attendu vs publié|Écarts listés clairement|
|
||||||
|
|Alerte export absent|Envoyée rapidement|
|
||||||
|
|Alerte programme 6h absent|Critique avant l'heure de diffusion|
|
||||||
|
|Alerte queue bloquée|Visible avant impact site|
|
||||||
|
|Alerte trop d'anomalies|Run bloqué ou escaladé|
|
||||||
|
|Dashboard dernier run|Plateforme, statut, durée, anomalies|
|
||||||
|
|Logs corrélés par `run_id`|Diagnostic possible rapidement|
|
||||||
|
|
||||||
|
## Tests de performance
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Génération complète pilote|Durée mesurée|
|
||||||
|
|Génération incrémentale 10 produits|Beaucoup plus rapide qu'une génération complète|
|
||||||
|
|Publication 8 000 produits|Durée upload mesurée|
|
||||||
|
|Publication 22 000 produits|Estimation IDELLO réaliste|
|
||||||
|
|Lecture manifest CDN|Latence faible|
|
||||||
|
|Lecture produit CDN|Latence faible|
|
||||||
|
|Lecture collection full|Taille et latence acceptables|
|
||||||
|
|Search index|Taille acceptable ou moteur dédié requis|
|
||||||
|
|
||||||
|
Mesures à collecter:
|
||||||
|
|
||||||
|
```text
|
||||||
|
durée extraction source
|
||||||
|
durée diff
|
||||||
|
durée génération JSON
|
||||||
|
durée validation JSON Schema
|
||||||
|
durée upload
|
||||||
|
durée publication manifest
|
||||||
|
nombre de fichiers
|
||||||
|
taille totale
|
||||||
|
nombre d'anomalies
|
||||||
|
temps de rollback
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tests avec fournisseurs sites
|
||||||
|
|
||||||
|
|Test|Résultat attendu|
|
||||||
|
|---|---|
|
||||||
|
|Fournisseur lit `manifest.json`|OK|
|
||||||
|
|Fournisseur charge `today.json`|OK|
|
||||||
|
|Fournisseur charge un produit via `links.product`|OK|
|
||||||
|
|Fournisseur charge une collection complète|OK|
|
||||||
|
|Fournisseur gère `latest.json`|OK ou besoin clarifié|
|
||||||
|
|Fournisseur gère un produit retiré|OK|
|
||||||
|
|Fournisseur gère un rollback|OK|
|
||||||
|
|Fournisseur ne mélange pas deux runs|OK|
|
||||||
|
|Champs manquants identifiés|Ajustement JSON v1 avant gel|
|
||||||
|
|
||||||
|
## Détails faciles à oublier
|
||||||
|
|
||||||
|
Voici les points qui peuvent sembler petits, mais qui ont un gros impact:
|
||||||
|
|
||||||
|
- `manifest.json` ne doit jamais pointer vers un run incomplet.
|
||||||
|
- Les fichiers dans `/runs/{run_id}/` doivent être immuables.
|
||||||
|
- Une page site doit utiliser un seul `run_id` pendant son rendu.
|
||||||
|
- Les zéros au début des `biznumber` doivent être conservés.
|
||||||
|
- Les dates doivent inclure la timezone.
|
||||||
|
- `product_key` et `program_key` doivent avoir un type stable, idéalement string dans les JSON.
|
||||||
|
- Les produits multi-plateformes doivent être contextualisés par plateforme.
|
||||||
|
- Les overrides doivent expirer.
|
||||||
|
- Les suppressions doivent être visibles dans `latest.json` et dans les rapports.
|
||||||
|
- Les produits retirés ne doivent plus apparaître dans les indexes.
|
||||||
|
- Les anciens fichiers retirés ne doivent pas rester découvrables via les indexes actifs.
|
||||||
|
- Les fichiers lourds comme `collections/{biznumber}/full.json` doivent être mesurés.
|
||||||
|
- Les champs internes ou sensibles ne doivent pas sortir dans les JSON publics.
|
||||||
|
- Le CPE doit être idempotent: relancer un job ne doit pas casser l'état.
|
||||||
|
- Les seuils d'anomalies doivent être définis avant le pilote.
|
||||||
|
- Le run doit avoir un rapport lisible par humains, pas seulement des logs techniques.
|
||||||
|
- Le rollback doit être testé avant le premier incident réel.
|
||||||
|
- La rétention doit être automatisée.
|
||||||
|
- Le bucket/CDN doit avoir une stratégie de purge du manifest.
|
||||||
|
- Les sites doivent savoir quoi faire si un fichier lié retourne 404.
|
||||||
|
- Les liens dans les JSON doivent être relatifs au `base_path` ou documentés clairement.
|
||||||
|
- Les JSON Schema doivent être validés dans le pipeline.
|
||||||
|
- Le feed JSON ne doit pas devenir une API dynamique cachée.
|
||||||
|
|
||||||
|
## Décision de fin de pilote
|
||||||
|
|
||||||
|
À la fin du pilote, il faut pouvoir répondre clairement:
|
||||||
|
|
||||||
|
- Est-ce que les sites peuvent consommer le feed JSON?
|
||||||
|
- Est-ce que la génération est assez rapide?
|
||||||
|
- Est-ce que le modèle protège contre les bugs source?
|
||||||
|
- Est-ce que les rapports permettent d'être proactifs?
|
||||||
|
- Est-ce que les corrections d'urgence sont assez rapides?
|
||||||
|
- Est-ce que le rollback est simple?
|
||||||
|
- Est-ce que le périmètre reste maîtrisé?
|
||||||
|
- Est-ce qu'on peut généraliser à TFO, IDELLO, ONFR et linéaire?
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
## TL;DR
|
## TL;DR
|
||||||
|
|
||||||
Le système actuel de synchro Louise/Mogador fonctionne, mais il est devenu trop fragile: trois serveurs avec le même code, dépendance forte à Directus, peu d'observabilité, corrections d'urgence difficiles à tracer, et trop de logique implicite dans une synchro construite rapidement.
|
Le système actuel de synchro Louise/Mogador fonctionne, mais il est devenu trop fragile: trois serveurs avec le même code, dépendance forte à Directus, peu d'observabilité, corrections d'urgence difficiles à tracer, et trop de logique implicite dans une synchro construite rapidement.
|
||||||
@@ -108,7 +107,7 @@ Le même code est déployé sur plusieurs serveurs. Cela complique:
|
|||||||
- les alertes;
|
- les alertes;
|
||||||
- le debugging;
|
- le debugging;
|
||||||
- les reprises après incident;
|
- les reprises après incident;
|
||||||
- la comprehension globale du système.
|
- la compréhension globale du système.
|
||||||
|
|
||||||
### Directus porte trop de responsabilités
|
### Directus porte trop de responsabilités
|
||||||
|
|
||||||
@@ -174,9 +173,9 @@ Exemples déjà rencontrès:
|
|||||||
- synchro incomplète;
|
- synchro incomplète;
|
||||||
- données manquantes dans Directus.
|
- données manquantes dans Directus.
|
||||||
|
|
||||||
## Decision recommandée
|
## Décision recommandée
|
||||||
|
|
||||||
La recommandation principale est de ne plus utilisér Directus comme moteur principal de publication web.
|
La recommandation principale est de ne plus utiliser Directus comme moteur principal de publication web.
|
||||||
|
|
||||||
L'application interne devrait produire des JSON statiques prêts à consommer par les sites.
|
L'application interne devrait produire des JSON statiques prêts à consommer par les sites.
|
||||||
|
|
||||||
@@ -225,7 +224,7 @@ Il peut inclure:
|
|||||||
- une meilleure compatibilité SSL;
|
- une meilleure compatibilité SSL;
|
||||||
- des limites de concurrence documentées;
|
- des limites de concurrence documentées;
|
||||||
- des exports plus faciles à consommer;
|
- des exports plus faciles à consommer;
|
||||||
- à long terme, des events/webhooks comme signal de changement pour aller vers une publication presque instantanee.
|
- à long terme, des events/webhooks comme signal de changement pour aller vers une publication presque instantanée.
|
||||||
|
|
||||||
Ce chantier a une relation directe avec la synchro interne, mais il ne doit pas bloquer le chantier A. La synchro interne doit être conçue pour fonctionner avec le Mogador Toolkit actuel, puis remplacer son lecteur source par Louise API v2 si elle arrive.
|
Ce chantier a une relation directe avec la synchro interne, mais il ne doit pas bloquer le chantier A. La synchro interne doit être conçue pour fonctionner avec le Mogador Toolkit actuel, puis remplacer son lecteur source par Louise API v2 si elle arrive.
|
||||||
|
|
||||||
@@ -253,7 +252,7 @@ flowchart TD
|
|||||||
|
|
||||||
Jobs["publication_jobsfile de republication"]
|
Jobs["publication_jobsfile de republication"]
|
||||||
Engine["Content Publication EngineLaravel ou autre"]
|
Engine["Content Publication EngineLaravel ou autre"]
|
||||||
Validator["Validation + rapportsattendu vs publie"]
|
Validator["Validation + rapportsattendu vs publié"]
|
||||||
Runs["Published Content Feedruns JSON immuables"]
|
Runs["Published Content Feedruns JSON immuables"]
|
||||||
Manifest["manifest.jsonpointe vers le run actif"]
|
Manifest["manifest.jsonpointe vers le run actif"]
|
||||||
Bucket["Bucket/CDNexposition publique contrôlee"]
|
Bucket["Bucket/CDNexposition publique contrôlee"]
|
||||||
@@ -454,6 +453,39 @@ Dans ce cas, le CPE devrait:
|
|||||||
|
|
||||||
Ce compromis rend le système plus rapide et plus fiable. On garde les bénéfices d'un run complet pour les sites, mais avec une stratégie de génération incrémentale protégée.
|
Ce compromis rend le système plus rapide et plus fiable. On garde les bénéfices d'un run complet pour les sites, mais avec une stratégie de génération incrémentale protégée.
|
||||||
|
|
||||||
|
## Garde-fous non négociables
|
||||||
|
|
||||||
|
Pour que cette architecture soit réellement fiable, certaines règles doivent être traitées comme non négociables.
|
||||||
|
|
||||||
|
Le CPE doit:
|
||||||
|
|
||||||
|
- ne jamais publier un run incomplet;
|
||||||
|
- ne jamais mettre à jour `manifest.json` avant la validation du run;
|
||||||
|
- ne jamais écraser un produit inchangé avec une version source devenue suspecte;
|
||||||
|
- garder le dernier JSON valide pour les entités inchangées;
|
||||||
|
- alerter sur les anomalies;
|
||||||
|
- produire un rapport attendu vs publié;
|
||||||
|
- permettre un rollback en repointant `manifest.json`;
|
||||||
|
- garder un audit complet des overrides;
|
||||||
|
- garder une trace des suppressions et des entités retirées;
|
||||||
|
- rendre les publications idempotentes, donc relançables sans effet secondaire imprévu.
|
||||||
|
|
||||||
|
Le point le plus important est le suivant:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Un nouveau snapshot source ne veut pas automatiquement dire que tous les JSON doivent être remplacés.
|
||||||
|
```
|
||||||
|
|
||||||
|
Le CPE doit distinguer:
|
||||||
|
|
||||||
|
- une donnée réellement modifiée;
|
||||||
|
- une donnée absente;
|
||||||
|
- une donnée incomplète;
|
||||||
|
- une donnée suspecte;
|
||||||
|
- une donnée inchangée qui doit rester publiée dans sa dernière version valide.
|
||||||
|
|
||||||
|
Cette règle est ce qui protège le système contre une régression fournisseur, une extraction incomplète ou une erreur ponctuelle dans Mogador.
|
||||||
|
|
||||||
## Données internes proposées
|
## Données internes proposées
|
||||||
|
|
||||||
Tables possibles:
|
Tables possibles:
|
||||||
@@ -521,7 +553,7 @@ Puis utilise le `base_path` retourné:
|
|||||||
|
|
||||||
### manifest.json
|
### manifest.json
|
||||||
|
|
||||||
Le manifest indique quelle version est publiee.
|
Le manifest indique quelle version est publiée.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -549,9 +581,9 @@ Compromis acceptable si Infra veut réduire les appels:
|
|||||||
manifest.json: max-age=300
|
manifest.json: max-age=300
|
||||||
```
|
```
|
||||||
|
|
||||||
Donc 5 minutes. Trois heures serait trop long pour les corrections d'urgence, les rollbacks et les republications après media JWP.
|
Donc 5 minutes. Trois heures serait trop long pour les corrections d'urgence, les rollbacks et les republications après média JWP.
|
||||||
|
|
||||||
Important: les runs sont des copies complètes et immuables. Donc oui, garder plusieurs runs multiplie le nombre de fichiers stockes.
|
Important: les runs sont des copies complètes et immuables. Donc oui, garder plusieurs runs multiplie le nombre de fichiers stockés.
|
||||||
|
|
||||||
Exemple simplifie avec TFO:
|
Exemple simplifie avec TFO:
|
||||||
|
|
||||||
@@ -561,7 +593,7 @@ Exemple simplifie avec TFO:
|
|||||||
= environ 40 000 fichiers produits
|
= environ 40 000 fichiers produits
|
||||||
```
|
```
|
||||||
|
|
||||||
Et il faut ajoutér les collections, schedules, indexes, `today.json`, `latest.json`, etc.
|
Et il faut ajouter les collections, schedules, indexes, `today.json`, `latest.json`, etc.
|
||||||
|
|
||||||
Estimation plus complète pour TFO avec 5 runs:
|
Estimation plus complète pour TFO avec 5 runs:
|
||||||
|
|
||||||
@@ -584,14 +616,14 @@ environ 41 500 à 42 000 fichiers
|
|||||||
|
|
||||||
Le `manifest.json` n'est pas multiplie de la même façon: il pointe seulement vers le run actif.
|
Le `manifest.json` n'est pas multiplie de la même façon: il pointe seulement vers le run actif.
|
||||||
|
|
||||||
Ce volume reste raisonnable pour un bucket/CDN, mais il doit être assume dans la stratégie de retention. C'est pour cela qu'on garde:
|
Ce volume reste raisonnable pour un bucket/CDN, mais il doit être assumé dans la stratégie de rétention. C'est pour cela qu'on garde:
|
||||||
|
|
||||||
- les runs recents utiles au rollback;
|
- les runs récents utiles au rollback;
|
||||||
- un minimum de 3 runs valides;
|
- un minimum de 3 runs valides;
|
||||||
- une limite de retention, par exemple 10 jours;
|
- une limite de rétention, par exemple 10 jours;
|
||||||
- des policies de nettoyage automatique.
|
- des policies de nettoyage automatique.
|
||||||
|
|
||||||
Le compromis est volontaire: on accepte plus de fichiers stockes pour obtenir une publication atomique, un rollback simple, un cache agressif sur les runs, et aucun risque qu'un site lise une publication à moitie génèree.
|
Le compromis est volontaire: on accepte plus de fichiers stockés pour obtenir une publication atomique, un rollback simple, un cache agressif sur les runs, et aucun risque qu'un site lise une publication à moitié générée.
|
||||||
|
|
||||||
### today.json
|
### today.json
|
||||||
|
|
||||||
@@ -769,7 +801,7 @@ LINEAR_SCHEDULE_DAYS_BEHIND=7
|
|||||||
LINEAR_SCHEDULE_DAYS_AHEAD=10
|
LINEAR_SCHEDULE_DAYS_AHEAD=10
|
||||||
```
|
```
|
||||||
|
|
||||||
Les programmations futures sont publiees dans:
|
Les programmations futures sont publiées dans:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/tfo/v1/runs/{run_id}/schedule/2026-08-08.json
|
/tfo/v1/runs/{run_id}/schedule/2026-08-08.json
|
||||||
@@ -815,7 +847,7 @@ Il peut contenir seulement les champs utiles:
|
|||||||
|
|
||||||
Si les sites ont besoin d'une vraie recherche rapide sur 8 000 à 22 000 items, un moteur dédié reste préférable à un gros fichier recherche chargé côté client.
|
Si les sites ont besoin d'une vraie recherche rapide sur 8 000 à 22 000 items, un moteur dédié reste préférable à un gros fichier recherche chargé côté client.
|
||||||
|
|
||||||
## Publication atomique et retention
|
## Publication atomique et rétention
|
||||||
|
|
||||||
Principe:
|
Principe:
|
||||||
|
|
||||||
@@ -827,6 +859,8 @@ Principe:
|
|||||||
|
|
||||||
Si la génération du run `20260730-1200` échoue, `manifest.json` continue de pointer vers `20260730-0900`. Une sync ratée ne casse pas le site.
|
Si la génération du run `20260730-1200` échoue, `manifest.json` continue de pointer vers `20260730-0900`. Une sync ratée ne casse pas le site.
|
||||||
|
|
||||||
|
Cette règle s'applique aussi aux corrections rapides: si une correction d'urgence ou une republication media échoue, le manifest reste sur le dernier run valide.
|
||||||
|
|
||||||
Retention proposée:
|
Retention proposée:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@@ -900,7 +934,7 @@ Swagger/OpenAPI est utile pour les endpoints internes de la Publication Console.
|
|||||||
|
|
||||||
Deux options sont possibles.
|
Deux options sont possibles.
|
||||||
|
|
||||||
### Option 1: retirér Directus progressivement
|
### Option 1: retirer Directus progressivement
|
||||||
|
|
||||||
Si les sites consomment les JSON statiques et si les permissions fournisseurs sont gérées par bucket ou préfixe, Directus n'est plus nécessaire dans la chaîne de publication.
|
Si les sites consomment les JSON statiques et si les permissions fournisseurs sont gérées par bucket ou préfixe, Directus n'est plus nécessaire dans la chaîne de publication.
|
||||||
|
|
||||||
@@ -933,7 +967,7 @@ Mais il ne devrait plus composer le JSON relationnel final utilisé par les site
|
|||||||
|
|
||||||
## Publication Console: édition d'urgence
|
## Publication Console: édition d'urgence
|
||||||
|
|
||||||
Si Directus est retiré ou reduit, il faut remplacer son rôle d'édition d'urgence.
|
Si Directus est retiré ou réduit, il faut remplacer son rôle d'édition d'urgence.
|
||||||
|
|
||||||
La proposition est de créer une `Publication Console` interne, non exposée à Internet.
|
La proposition est de créer une `Publication Console` interne, non exposée à Internet.
|
||||||
|
|
||||||
@@ -960,11 +994,11 @@ Fonctions minimales:
|
|||||||
|
|
||||||
- rechercher un produit, programme, collection ou serie;
|
- rechercher un produit, programme, collection ou serie;
|
||||||
- voir les données venant de Louise/Mogador;
|
- voir les données venant de Louise/Mogador;
|
||||||
- voir le JSON actuellement publie;
|
- voir le JSON actuellement publié;
|
||||||
- ajoutér une correction temporaire;
|
- ajouter une correction temporaire;
|
||||||
- mettre une raison;
|
- mettre une raison;
|
||||||
- mettre une date d'expiration;
|
- mettre une date d'expiration;
|
||||||
- republier les JSON concernes;
|
- republier les JSON concernés;
|
||||||
- garder un historique complet.
|
- garder un historique complet.
|
||||||
|
|
||||||
Exemple de table:
|
Exemple de table:
|
||||||
@@ -988,13 +1022,26 @@ manual_overrides
|
|||||||
|
|
||||||
Important: il ne faut pas modifier les JSON publiés directement à la main. Les overrides doivent être appliqués dans le pipeline de génération, sinon ils seront perdus ou impossibles à auditer.
|
Important: il ne faut pas modifier les JSON publiés directement à la main. Les overrides doivent être appliqués dans le pipeline de génération, sinon ils seront perdus ou impossibles à auditer.
|
||||||
|
|
||||||
|
Pour les corrections internes, la Publication Console doit être rapide parce qu'elle ne devrait pas relancer toute la plateforme. Une correction doit créer un `publication_job` ciblé et republier seulement les entités touchées:
|
||||||
|
|
||||||
|
```text
|
||||||
|
correction collection
|
||||||
|
-> publication_job collection
|
||||||
|
-> régénération de collections/{biznumber}/full.json
|
||||||
|
-> mise à jour des indexes ou schedules impactés si nécessaire
|
||||||
|
-> nouveau run valide
|
||||||
|
-> manifest mis à jour
|
||||||
|
```
|
||||||
|
|
||||||
|
Cela permet de corriger rapidement une donnée déjà reçue ou une donnée éditoriale interne. Par contre, cela ne rend pas Louise instantané: si un changement n'est pas encore arrivé dans l'export Louise/Mogador, le CPE ne peut pas l'inventer.
|
||||||
|
|
||||||
Chaque override devrait inclure:
|
Chaque override devrait inclure:
|
||||||
|
|
||||||
- l'utilisateur;
|
- l'utilisateur;
|
||||||
- le rôle;
|
- le rôle;
|
||||||
- la raison;
|
- la raison;
|
||||||
- la date d'expiration;
|
- la date d'expiration;
|
||||||
- l'entité touchee;
|
- l'entité touchée;
|
||||||
- l'ancien contenu;
|
- l'ancien contenu;
|
||||||
- le nouveau contenu;
|
- le nouveau contenu;
|
||||||
- le run dans lequel la correction a été publiée.
|
- le run dans lequel la correction a été publiée.
|
||||||
@@ -1003,18 +1050,18 @@ Chaque override devrait inclure:
|
|||||||
|
|
||||||
L'app AdonisJS qui synchronise les vidéos vers JWP ne devrait pas devenir le moteur de publication JSON complet. Son rôle naturel est:
|
L'app AdonisJS qui synchronise les vidéos vers JWP ne devrait pas devenir le moteur de publication JSON complet. Son rôle naturel est:
|
||||||
|
|
||||||
> vérifier les vidéos, envoyer ou mettre à jour les medias dans JWP, suivre leur statut, et declarer qu'un produit doit être republie quand le media est prêt.
|
> vérifier les vidéos, envoyer ou mettre à jour les médias dans JWP, suivre leur statut, et déclarer qu'un produit doit être republié quand le média est prêt.
|
||||||
|
|
||||||
Le point important n'est pas la technologie de cette app, mais le contrat entre le Media Pipeline et le Content Publication Engine.
|
Le point important n'est pas la technologie de cette app, mais le contrat entre le Media Pipeline et le Content Publication Engine.
|
||||||
|
|
||||||
Elle devrait faire:
|
Elle devrait faire:
|
||||||
|
|
||||||
- lire les infos video source depuis Louise/Mogador ou depuis le snapshot interne;
|
- lire les infos vidéo source depuis Louise/Mogador ou depuis le snapshot interne;
|
||||||
- vérifier la presence du fichier video source;
|
- vérifier la présence du fichier vidéo source;
|
||||||
- créer ou mettre à jour le media dans JWP;
|
- créer ou mettre à jour le media dans JWP;
|
||||||
- gérer poster, sous-titres, métadonnées et statut d'encodage;
|
- gérer poster, sous-titres, métadonnées et statut d'encodage;
|
||||||
- maintenir une table interne `media_assets`;
|
- maintenir une table interne `media_assets`;
|
||||||
- créer un job de republication quand un media change.
|
- créer un job de republication quand un média change.
|
||||||
|
|
||||||
Elle ne devrait pas faire:
|
Elle ne devrait pas faire:
|
||||||
|
|
||||||
@@ -1023,6 +1070,35 @@ Elle ne devrait pas faire:
|
|||||||
- écrire directement dans les fichiers publics;
|
- écrire directement dans les fichiers publics;
|
||||||
- remplacer le Content Publication Engine.
|
- remplacer le Content Publication Engine.
|
||||||
|
|
||||||
|
## Limites volontaires du CPE
|
||||||
|
|
||||||
|
Le CPE doit rester un moteur de publication. C'est la condition principale pour éviter de recréer une usine à gaz.
|
||||||
|
|
||||||
|
Il ne doit pas devenir:
|
||||||
|
|
||||||
|
- un nouveau Directus complet;
|
||||||
|
- un DAM vidéo;
|
||||||
|
- un CMS généraliste;
|
||||||
|
- une API publique dynamique;
|
||||||
|
- un moteur de recherche;
|
||||||
|
- un outil de gestion PCI;
|
||||||
|
- une refonte des sites.
|
||||||
|
|
||||||
|
Sa responsabilité doit rester claire:
|
||||||
|
|
||||||
|
```text
|
||||||
|
lire la source officielle
|
||||||
|
comparer
|
||||||
|
valider
|
||||||
|
appliquer les overrides
|
||||||
|
enrichir avec media_assets
|
||||||
|
générer les JSON
|
||||||
|
publier le manifest
|
||||||
|
rapporter et alerter
|
||||||
|
```
|
||||||
|
|
||||||
|
Tout ce qui dépasse ce périmètre doit être questionné avant d'être ajouté au projet.
|
||||||
|
|
||||||
## Contrat entre Media Pipeline et Content Publication Engine
|
## Contrat entre Media Pipeline et Content Publication Engine
|
||||||
|
|
||||||
### Table `media_assets`
|
### Table `media_assets`
|
||||||
@@ -1082,7 +1158,7 @@ Exemple:
|
|||||||
|
|
||||||
### Table `publication_jobs`
|
### Table `publication_jobs`
|
||||||
|
|
||||||
Cette table sert à dire au Content Publication Engine: "quelque chose a change, republie ce qui est touché".
|
Cette table sert à dire au Content Publication Engine: "quelque chose a changé, republie ce qui est touché".
|
||||||
|
|
||||||
Champs proposés:
|
Champs proposés:
|
||||||
|
|
||||||
@@ -1147,7 +1223,7 @@ Pourquoi cette table est le meilleur compromis:
|
|||||||
- plus simple à auditer;
|
- plus simple à auditer;
|
||||||
- ne force pas le Media Pipeline et le Content Publication Engine a être déployés ensemble.
|
- ne force pas le Media Pipeline et le Content Publication Engine a être déployés ensemble.
|
||||||
|
|
||||||
On peut garder un scan periodique comme filet de securite, par exemple toutes les 15 ou 30 minutes, pour détectér un media modifie qui n'aurait pas crée de job.
|
On peut garder un scan periodique comme filet de sécurité, par exemple toutes les 15 ou 30 minutes, pour détectér un media modifie qui n'aurait pas crée de job.
|
||||||
|
|
||||||
## Rapport et alertes
|
## Rapport et alertes
|
||||||
|
|
||||||
@@ -1187,7 +1263,7 @@ Ecarts:
|
|||||||
- 1 produit ignoré car type extrait
|
- 1 produit ignoré car type extrait
|
||||||
|
|
||||||
Publication:
|
Publication:
|
||||||
- statut: publie avec avertissements
|
- statut: publié avec avertissements
|
||||||
- manifest pointe vers: /tfo/v1/runs/20260730-0900
|
- manifest pointe vers: /tfo/v1/runs/20260730-0900
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1200,7 +1276,7 @@ Alertes à mettre en place:
|
|||||||
- workers down;
|
- workers down;
|
||||||
- queue bloquee;
|
- queue bloquee;
|
||||||
- sync trop longue;
|
- sync trop longue;
|
||||||
- ecart entre attendu et publie;
|
- écart entre attendu et publié;
|
||||||
- programme prévu à 6h absent de la publication avant 6h;
|
- programme prévu à 6h absent de la publication avant 6h;
|
||||||
- video JWP manquante;
|
- video JWP manquante;
|
||||||
- image ou transcription manquante;
|
- image ou transcription manquante;
|
||||||
@@ -1267,7 +1343,7 @@ Objectif: savoir ce qui se passe avant de tout remplacer.
|
|||||||
- Ajouter `sync_run_items`.
|
- Ajouter `sync_run_items`.
|
||||||
- Ajouter `sync_anomalies`.
|
- Ajouter `sync_anomalies`.
|
||||||
- Generer un rapport par plateforme.
|
- Generer un rapport par plateforme.
|
||||||
- Alerter sur les ecarts critiques.
|
- Alerter sur les écarts critiques.
|
||||||
- Garder Directus tel quel.
|
- Garder Directus tel quel.
|
||||||
|
|
||||||
### Phase 2: Media Pipeline minimal
|
### Phase 2: Media Pipeline minimal
|
||||||
@@ -1276,7 +1352,7 @@ Durée estimée: 1 à 2 semaines.
|
|||||||
|
|
||||||
- L'app AdonisJS écrit dans `media_assets`.
|
- L'app AdonisJS écrit dans `media_assets`.
|
||||||
- Elle crée des jobs `publication_jobs`.
|
- Elle crée des jobs `publication_jobs`.
|
||||||
- Elle détecté les medias `missing`, `processing`, `ready`, `failed`.
|
- Elle détecte les médias `missing`, `processing`, `ready`, `failed`.
|
||||||
- Elle produit un rapport simple sur les vidéos manquantes ou en erreur.
|
- Elle produit un rapport simple sur les vidéos manquantes ou en erreur.
|
||||||
|
|
||||||
### Phase 3: publication JSON en parallèle
|
### Phase 3: publication JSON en parallèle
|
||||||
@@ -1298,7 +1374,7 @@ Durée estimée: 2 semaines.
|
|||||||
|
|
||||||
- Choisir ONFR ou une portion TFO.
|
- Choisir ONFR ou une portion TFO.
|
||||||
- Publier dans un bucket/prefix dédié.
|
- Publier dans un bucket/prefix dédié.
|
||||||
- Valider performance, structure JSON, cache, rollback et medias JWP.
|
- Valider performance, structure JSON, cache, rollback et médias JWP.
|
||||||
- Ajouter alertes Slack/Better Stack.
|
- Ajouter alertes Slack/Better Stack.
|
||||||
|
|
||||||
### Phase 5: Publication Console
|
### Phase 5: Publication Console
|
||||||
@@ -1341,16 +1417,16 @@ Points à documenter pour PCI:
|
|||||||
|
|
||||||
Exemples de besoins:
|
Exemples de besoins:
|
||||||
|
|
||||||
- reçuperer tous les produits/programmes d'une plateforme pour une fenêtre de dates;
|
- récupérer tous les produits/programmes d'une plateforme pour une fenêtre de dates;
|
||||||
- reçuperer une collection complète;
|
- récupérer une collection complète;
|
||||||
- reçuperer un produit complet;
|
- récupérer un produit complet;
|
||||||
- reçuperer les horaires J+10;
|
- récupérer les horaires J+10;
|
||||||
- reçuperer les droits et pays autorises;
|
- récupérer les droits et pays autorises;
|
||||||
- reçuperer les informations video source, mais pas les champs JWP.
|
- récupérer les informations vidéo source, mais pas les champs JWP.
|
||||||
|
|
||||||
### Etape B3: demander un mode événementiel
|
### Etape B3: demander un mode événementiel
|
||||||
|
|
||||||
PCI pourrait envoyer un event quand une modification est sauvegardée dans Louise. Cet event ne publie rien directement. Il sert seulement a déclencher une relecture officielle par notre système interne.
|
PCI pourrait envoyer un event quand une modification est sauvegardée dans Louise. Cet event ne ne publie rien directement. Il sert seulement à déclencher une relecture officielle par notre système interne.
|
||||||
|
|
||||||
Exemple:
|
Exemple:
|
||||||
|
|
||||||
@@ -1365,37 +1441,37 @@ Exemple:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Notre système recoit l'event, relit le détail via API officielle, applique les validations, enrichit avec JWP/overrides, puis republie les JSON touches.
|
Notre système reçoit l'event, relit le détail via API officielle, applique les validations, enrichit avec JWP/overrides, puis republie les JSON touchés.
|
||||||
|
|
||||||
## Vision long terme: publication presque instantanee
|
## Vision long terme: publication presque instantanée
|
||||||
|
|
||||||
Aujourd'hui, Louise exporte un full SQL toutes les 3 heures. Tant que c'est le seul signal officiel, on ne peut pas garantir une publication instantanee d'une modification faite dans Louise.
|
Aujourd'hui, Louise exporte un full SQL toutes les 3 heures. Tant que c'est le seul signal officiel, on ne peut pas garantir une publication instantanée d'une modification faite dans Louise.
|
||||||
|
|
||||||
Par contre, on peut preparer l'architecture pour le futur.
|
Par contre, on peut préparer l'architecture pour le futur.
|
||||||
|
|
||||||
A court terme:
|
À court terme:
|
||||||
|
|
||||||
- snapshot toutes les 3 heures;
|
- snapshot toutes les 3 heures;
|
||||||
- diff interne;
|
- diff interne;
|
||||||
- publication atomique;
|
- publication atomique;
|
||||||
- overrides internes rapides;
|
- overrides internes rapides;
|
||||||
- republication rapide quand un media JWP devient pret.
|
- republication rapide quand un média JWP devient prêt.
|
||||||
|
|
||||||
A moyen terme:
|
À moyen terme:
|
||||||
|
|
||||||
- demander à PCI une API Louise/Mogador v2 bulk fiable;
|
- demander à PCI une API Louise/Mogador v2 bulk fiable;
|
||||||
- réduire le temps de lecture;
|
- réduire le temps de lecture;
|
||||||
- éviter les milliers d'appels API individuels;
|
- éviter les milliers d'appels API individuels;
|
||||||
- garder le snapshot complet comme filet de securite.
|
- garder le snapshot complet comme filet de sécurité.
|
||||||
|
|
||||||
A long terme:
|
À long terme:
|
||||||
|
|
||||||
- demander à PCI des événements/webhooks comme signal;
|
- demander à PCI des événements/webhooks comme signal;
|
||||||
- chaque changement dans Louise envoie un événement;
|
- chaque changement dans Louise envoie un événement;
|
||||||
- notre système relit le détail officiel via API;
|
- notre système relit le détail officiel via API;
|
||||||
- le snapshot complet continue de tourner pour reconciler les ecarts.
|
- le snapshot complet continue de tourner pour réconcilier les écarts.
|
||||||
|
|
||||||
Important: le webhook ne devrait pas publier directement vers les sites. Il devrait seulement dire: "quelque chose a change". Notre système interne reste responsable de valider, enrichir, publier, alerter et rollback.
|
Important: le webhook ne devrait pas publier directement vers les sites. Il devrait seulement dire: "quelque chose a changé". Notre système interne reste responsable de valider, enrichir, publier, alerter et rollback.
|
||||||
|
|
||||||
## Choix technique recommande pour la nouvelle app v2
|
## Choix technique recommande pour la nouvelle app v2
|
||||||
|
|
||||||
@@ -1403,10 +1479,10 @@ La nouvelle app v2 devrait être faite en Laravel.
|
|||||||
|
|
||||||
Raisons principales:
|
Raisons principales:
|
||||||
|
|
||||||
- le projet est surtout un système métier back-office, pas une API publique temps reel;
|
- le projet est surtout un système métier back-office, pas une API publique temps réel;
|
||||||
- Laravel gère très bien les jobs, le scheduler, les commandes, les retries et les traitements planifies;
|
- Laravel gère très bien les jobs, le scheduler, les commandes, les retries et les traitements planifiés;
|
||||||
- Horizon donne une bonne visibilité sur les queues si Redis est utilisé correctement;
|
- Horizon donne une bonne visibilité sur les queues si Redis est utilisé correctement;
|
||||||
- l'ecosystème Laravel est très solide pour construire une `Publication Console` interne avec auth, rôles, policies et audit;
|
- l'écosystème Laravel est très solide pour construire une `Publication Console` interne avec auth, rôles, policies et audit;
|
||||||
- les migrations, seeders, commands et jobs sont bien adaptés à ce type de pipeline;
|
- les migrations, seeders, commands et jobs sont bien adaptés à ce type de pipeline;
|
||||||
- l'équipe connait déjà le contexte Laravel de la synchro actuelle;
|
- l'équipe connait déjà le contexte Laravel de la synchro actuelle;
|
||||||
- la logique de publication doit être fiable et observable plus que fashionable;
|
- la logique de publication doit être fiable et observable plus que fashionable;
|
||||||
@@ -1425,24 +1501,24 @@ Content Publication Engine
|
|||||||
-> génère les JSON publics
|
-> génère les JSON publics
|
||||||
```
|
```
|
||||||
|
|
||||||
Avec cette séparation, le Media Pipeline peut évoluer independamment. La nouvelle app v2, elle, devrait être le système de publication fiable, auditable et opérationnel; Laravel est le meilleur choix pour ce rôle.
|
Avec cette séparation, le Media Pipeline peut évoluer indépendamment. La nouvelle app v2, elle, devrait être le système de publication fiable, auditable et opérationnel; Laravel est le meilleur choix pour ce rôle.
|
||||||
|
|
||||||
## Risques principaux
|
## Risques principaux
|
||||||
|
|
||||||
|Risque|Probabilite|Impact|Reponse|
|
|Risque|Probabilité|Impact|Réponse|
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
|Le projet devient trop large et tente de remplacer Directus, Mogador, JWP et les sites en même temps|Élevée|Eleve|Decouper en pilote, garder PCI comme chantier séparé, livrer par increments|
|
|Le projet devient trop large et tente de remplacer Directus, Mogador, JWP et les sites en même temps|Élevée|Élevé|Découper en pilote, garder PCI comme chantier séparé, livrer par incréments|
|
||||||
|Les règles métier actuelles sont implicites dans le vieux code|Élevée|Eleve|Extraire les règles, valider avec production, ajoutér rapports de comparaison|
|
|Les règles métier actuelles sont implicites dans le vieux code|Élevée|Élevé|Extraire les règles, valider avec production, ajouter rapports de comparaison|
|
||||||
|Les corrections d'urgence entrent en conflit avec Louise au prochain export|Élevée|Eleve|Definir precedence, expiration d'override, audit et rapport d'ecart|
|
|Les corrections d'urgence entrent en conflit avec Louise au prochain export|Élevée|Élevé|Définir précédence, expiration d'override, audit et rapport d'écart|
|
||||||
|Le manifest est cache trop longtemps|Moyenne|Eleve|TTL court sur manifest, runs immuables cachés longtemps, procedure purge CDN|
|
|Le manifest est caché trop longtemps|Moyenne|Élevé|TTL court sur manifest, runs immuables cachés longtemps, procédure purge CDN|
|
||||||
|Media Pipeline et Publication Engine se couplent trop fortement|Moyenne|Eleve|Passer uniquement par `media_assets` et `publication_jobs`|
|
|Media Pipeline et Publication Engine se couplent trop fortement|Moyenne|Élevé|Passer uniquement par `media_assets` et `publication_jobs`|
|
||||||
|Le système publie un JSON incomplet mais valide techniquement|Moyenne|Eleve|Ajouter validations métier, rapports attendu vs publie et seuils bloquants|
|
|Le système publie un JSON incomplet mais valide techniquement|Moyenne|Élevé|Ajouter validations métier, rapports attendu vs publié et seuils bloquants|
|
||||||
|L'absence d'API PCI v2 maintient certaines lenteurs|Élevée|Moyen|Concevoir le `Source Reader` remplacable et optimiser avec snapshots/diffs internes|
|
|L'absence d'API PCI v2 maintient certaines lenteurs|Élevée|Moyen|Concevoir le `Source Reader` remplaçable et optimiser avec snapshots/diffs internes|
|
||||||
|PCI ne livre pas d'events/webhooks à court terme|Élevée|Moyen|Ne pas en faire une dépendance du MVP; garder polling 3h et overrides internes|
|
|PCI ne livre pas d'events/webhooks à court terme|Élevée|Moyen|Ne pas en faire une dépendance du MVP; garder polling 3h et overrides internes|
|
||||||
|Infra refuse l'exposition de l'app interne|Moyenne|Moyen|Exposer seulement les JSON via bucket/CDN; garder la console sur réseau interne|
|
|Infra refuse l'exposition de l'app interne|Moyenne|Moyen|Exposer seulement les JSON via bucket/CDN; garder la console sur réseau interne|
|
||||||
|Migration depuis Directus cause une interruption|Moyenne|Eleve|Double-run, comparaison, pilote, rollback, aucun big bang|
|
|Migration depuis Directus cause une interruption|Moyenne|Élevé|Double-run, comparaison, pilote, rollback, aucun big bang|
|
||||||
|
|
||||||
## Noms recommandes
|
## Noms recommandés
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Louise
|
Louise
|
||||||
|
|||||||
Reference in New Issue
Block a user