vault backup: 2026-07-31 05:32:51
This commit is contained in:
@@ -0,0 +1,850 @@
|
||||
|
||||
## Objectif
|
||||
|
||||
Ce document resume une proposition de refonte de la synchronisation Mogador afin de rendre le systeme plus fiable, plus simple a maintenir et plus rapide a publier vers les sites TFO, IDELLO, ONFR et Linear.
|
||||
|
||||
Le but n'est pas de jeter toute la connaissance metier existante. Le code actuel contient plusieurs regles importantes qui doivent etre conservees. Par contre, l'architecture actuelle est devenue lourde parce que la synchronisation, Directus, les permissions, la publication web, les rapports et les corrections d'urgence sont trop melanges.
|
||||
|
||||
## Contexte actuel
|
||||
|
||||
Louise est la vraie source de verite.
|
||||
|
||||
Toutes les 3 heures, Louise produit un fichier SQL complet, `export_mogador.sql`. Ce fichier n'est jamais incremental. Il commence par des `TRUNCATE`, puis reinsere toutes les donnees.
|
||||
|
||||
Le flux actuel ressemble a ceci:
|
||||
|
||||
```text
|
||||
Louise
|
||||
-> export_mogador.sql complet
|
||||
-> rsync vers serveur Linux
|
||||
-> import dans une base MySQL structuree avec mogador.sql
|
||||
-> API Mogador officielle qui parle a cette base
|
||||
-> application Laravel interne
|
||||
-> synchronisation vers Directus
|
||||
-> sites web / fournisseurs consomment Directus ou redistribuent dans leurs propres bases
|
||||
```
|
||||
|
||||
Aujourd'hui, il y a trois serveurs avec une copie du meme code:
|
||||
|
||||
```text
|
||||
P1: TFO + Linear
|
||||
P2: IDELLO
|
||||
P3: ONFR
|
||||
```
|
||||
|
||||
Cette separation existe surtout parce qu'un seul serveur prendrait trop de temps a synchroniser toutes les plateformes. L'export, le transfert, l'import SQL et la synchronisation prennent environ 1 heure par cycle.
|
||||
|
||||
## Contraintes importantes
|
||||
|
||||
- La source officielle reste le fichier SQL exporte par Louise.
|
||||
- L'equipe dev peut regarder la base Mogador, mais la consommation officielle des donnees doit passer par l'API Mogador.
|
||||
- L'API Mogador doit rester dans le flux pour rester conforme aux attentes contractuelles et eviter de contourner une logique API qui pourrait changer.
|
||||
- L'app Laravel ne doit pas etre exposee a Internet selon les contraintes Infra actuelles.
|
||||
- Les fournisseurs ont besoin d'un acces read-only aux donnees publiees.
|
||||
- L'equipe interne doit pouvoir faire des corrections d'urgence sans attendre le prochain export Louise.
|
||||
- Les sites veulent des donnees organisees dans le sens utilisateur: collection -> saisons -> episodes -> programmations.
|
||||
- Louise expose souvent les donnees dans le sens inverse: episode -> programmation -> serie -> collection.
|
||||
- Directus est utile pour les permissions et l'edition, mais devient problematique comme moteur relationnel/publication.
|
||||
|
||||
## Problemes actuels
|
||||
|
||||
### 1. Architecture lourde
|
||||
|
||||
Le meme code est deploye sur plusieurs serveurs, chaque serveur etant responsable d'une plateforme. Cela rend les mises a jour, les migrations, les alertes et le debugging plus compliques.
|
||||
|
||||
### 2. Directus est force dans un role trop large
|
||||
|
||||
Directus sert aujourd'hui a:
|
||||
|
||||
- donner un acces read-only aux fournisseurs;
|
||||
- permettre des corrections d'urgence par l'equipe interne;
|
||||
- exposer les donnees aux sites;
|
||||
- representer des relations complexes entre produits, programmations, series et collections.
|
||||
|
||||
Le probleme est surtout le dernier point. Les relations entre `products`, `programmations`, `series` et `collections` sont difficiles a maintenir dans Directus. Certaines relations ne peuvent pas etre creees proprement a cause de contraintes FK ou du modele de donnees.
|
||||
|
||||
### 3. Le modele attendu par les sites est different du modele Louise
|
||||
|
||||
Terminologie metier:
|
||||
|
||||
```text
|
||||
Collection = serie pour le public
|
||||
Serie = saison
|
||||
Episode = episode
|
||||
```
|
||||
|
||||
Les sites veulent souvent:
|
||||
|
||||
```json
|
||||
{
|
||||
"collection": {},
|
||||
"seasons": [
|
||||
{
|
||||
"serie": {},
|
||||
"episodes": [
|
||||
{
|
||||
"product": {},
|
||||
"programmations": [],
|
||||
"media": {},
|
||||
"images": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Mais les donnees Louise/Mogador sont souvent disponibles depuis l'episode, puis il faut remonter vers la serie/saison et la collection.
|
||||
|
||||
Exemple de difficulte: `is_original` est disponible sur les episodes, mais pas directement sur la collection. Si le site veut afficher cette information au niveau collection, il faut definir une regle de remontee.
|
||||
|
||||
### 4. Peu d'observabilite proactive
|
||||
|
||||
Aujourd'hui, l'equipe est souvent reactive. Les problemes sont decouverts quand la production ou les sites signalent une erreur.
|
||||
|
||||
Exemples de problemes deja rencontres:
|
||||
|
||||
- supervisor down;
|
||||
- worker queue down;
|
||||
- migration Laravel oubliee lors d'un changement de serveur;
|
||||
- programmation attendue absente du site;
|
||||
- synchro incomplete;
|
||||
- donnees manquantes dans Directus.
|
||||
|
||||
### 5. Besoin de programmation future
|
||||
|
||||
Une demande recurrente est de pouvoir afficher des informations comme:
|
||||
|
||||
```text
|
||||
Prochain episode le 8 aout
|
||||
```
|
||||
|
||||
Aujourd'hui, se limiter a la programmation du jour evite de ralentir la sync, mais limite les usages des sites.
|
||||
|
||||
## Decision recommandee
|
||||
|
||||
La recommandation principale est de ne plus utiliser Directus comme moteur principal de publication web.
|
||||
|
||||
L'application Laravel devrait rester interne et produire des JSON statiques prets a consommer par les sites.
|
||||
|
||||
Architecture cible:
|
||||
|
||||
```text
|
||||
Louise SQL full export
|
||||
-> import MySQL Mogador
|
||||
-> API Mogador officielle
|
||||
-> Laravel interne: Sync Engine v2
|
||||
-> donnees internes / snapshots / rapports
|
||||
-> generation de JSON statiques
|
||||
-> publication vers buckets S3/CDN par plateforme
|
||||
-> sites web consomment les JSON
|
||||
```
|
||||
|
||||
Laravel ne serait pas expose a Internet. Les sites ne parlent pas a Laravel. Ils lisent des fichiers JSON statiques publies dans un bucket ou CDN.
|
||||
|
||||
## Role futur de Directus
|
||||
|
||||
Deux options sont possibles.
|
||||
|
||||
### Option 1: retirer Directus progressivement
|
||||
|
||||
Si les sites consomment les JSON statiques et si les permissions fournisseurs sont gerees par bucket ou prefixe, Directus n'est plus necessaire dans la chaine de publication.
|
||||
|
||||
Les permissions peuvent etre gerees par:
|
||||
|
||||
```text
|
||||
bucket-tfo
|
||||
bucket-idello
|
||||
bucket-onfr
|
||||
```
|
||||
|
||||
Ou par un seul bucket avec prefixes:
|
||||
|
||||
```text
|
||||
publication/tfo/
|
||||
publication/idello/
|
||||
publication/onfr/
|
||||
```
|
||||
|
||||
Chaque fournisseur ou site a acces seulement a son bucket ou son prefixe.
|
||||
|
||||
### Option 2: garder Directus uniquement temporairement
|
||||
|
||||
Directus peut rester pendant une periode de transition pour:
|
||||
|
||||
- consultation interne;
|
||||
- edition d'urgence;
|
||||
- acces read-only fournisseur existant.
|
||||
|
||||
Mais il ne devrait plus etre responsable de composer le JSON relationnel final utilise par les sites.
|
||||
|
||||
## Edition d'urgence
|
||||
|
||||
Si Directus est retire, il faut remplacer son role d'edition d'urgence.
|
||||
|
||||
La proposition est de creer un mini CMS interne dans Laravel, non expose a Internet.
|
||||
|
||||
Ce mini CMS doit etre protege par authentification. Les edimestres qui ont aujourd'hui acces a Directus devront avoir acces a cet outil interne selon leurs roles.
|
||||
|
||||
Acces proposes:
|
||||
|
||||
```text
|
||||
Admin sync:
|
||||
- peut configurer et publier
|
||||
- peut gerer les utilisateurs
|
||||
- peut faire rollback
|
||||
|
||||
Edimestre:
|
||||
- peut rechercher et consulter
|
||||
- peut creer une correction d'urgence
|
||||
- peut voir les overrides actifs
|
||||
- ne peut pas changer la configuration systeme
|
||||
|
||||
Read-only interne:
|
||||
- peut consulter les donnees, rapports et JSON publies
|
||||
- ne peut pas modifier
|
||||
```
|
||||
|
||||
Le mini CMS doit rester disponible uniquement sur le reseau interne ou via VPN/SSO interne. Il ne doit pas devenir une API publique.
|
||||
|
||||
Fonctions minimales:
|
||||
|
||||
- rechercher un produit, programme, collection ou serie;
|
||||
- voir les donnees venant de Mogador;
|
||||
- voir le JSON actuellement publie;
|
||||
- ajouter une correction temporaire;
|
||||
- mettre une raison;
|
||||
- mettre une date d'expiration;
|
||||
- republier les JSON concernes;
|
||||
- garder un historique complet.
|
||||
|
||||
Exemple de table:
|
||||
|
||||
```text
|
||||
manual_overrides
|
||||
- id
|
||||
- platform
|
||||
- entity_type: product | program | collection | serie
|
||||
- entity_key: product_key | program_key | biznumber
|
||||
- field_path
|
||||
- value_json
|
||||
- reason
|
||||
- active_from
|
||||
- active_until
|
||||
- created_by
|
||||
- approved_by
|
||||
- created_at
|
||||
- updated_at
|
||||
```
|
||||
|
||||
Exemple d'override:
|
||||
|
||||
```json
|
||||
{
|
||||
"platform": "tfo",
|
||||
"entity_type": "collection",
|
||||
"entity_key": "0123456",
|
||||
"field_path": "is_original",
|
||||
"value_json": true,
|
||||
"reason": "Correction urgente demandee par programmation",
|
||||
"active_until": "2026-08-02T23:59:59"
|
||||
}
|
||||
```
|
||||
|
||||
Important: il ne faut pas modifier les JSON publies directement a la main. Les overrides doivent etre appliques dans le pipeline de generation, sinon ils seront perdus ou impossibles a auditer.
|
||||
|
||||
Chaque override devrait inclure:
|
||||
|
||||
- l'utilisateur;
|
||||
- le role;
|
||||
- la raison;
|
||||
- la date d'expiration;
|
||||
- l'entite touchee;
|
||||
- l'ancien contenu;
|
||||
- le nouveau contenu;
|
||||
- le run dans lequel la correction a ete publiee.
|
||||
|
||||
## Fabrication d'un incremental a partir d'un full export
|
||||
|
||||
Louise ne fournit pas d'incremental. Chaque export est complet.
|
||||
|
||||
La solution est de sauvegarder des snapshots internes et de comparer les snapshots entre eux.
|
||||
|
||||
Exemple:
|
||||
|
||||
```text
|
||||
09h00: export Louise complet
|
||||
-> import MySQL
|
||||
-> extraction via API Mogador
|
||||
-> snapshot_09h00
|
||||
|
||||
12h00: export Louise complet
|
||||
-> import MySQL
|
||||
-> extraction via API Mogador
|
||||
-> snapshot_12h00
|
||||
|
||||
Diff snapshot_09h00 -> snapshot_12h00:
|
||||
-> programmes ajoutes
|
||||
-> programmes retires
|
||||
-> produits modifies
|
||||
-> images modifiees
|
||||
-> dates de programmation modifiees
|
||||
-> erreurs ou anomalies
|
||||
```
|
||||
|
||||
On ne demande donc pas a Louise de changer son fonctionnement. On fabrique notre propre diff a partir des donnees extraites apres chaque full export.
|
||||
|
||||
Cela permet:
|
||||
|
||||
- de savoir ce qui a change;
|
||||
- de generer un `latest.json`;
|
||||
- de limiter certaines publications;
|
||||
- de produire un rapport clair;
|
||||
- de conserver un historique.
|
||||
|
||||
## Donnees internes proposees
|
||||
|
||||
Le terme "canonical" veut simplement dire: donnees internes propres, normalisees et controlees par nous.
|
||||
|
||||
Il n'est pas obligatoire d'utiliser le mot `canonical` dans le code. L'idee est d'avoir une couche interne avant la publication.
|
||||
|
||||
Exemples de tables:
|
||||
|
||||
```text
|
||||
sync_runs
|
||||
sync_run_items
|
||||
sync_anomalies
|
||||
products
|
||||
programs
|
||||
collections
|
||||
series
|
||||
episodes
|
||||
media
|
||||
publication_snapshots
|
||||
manual_overrides
|
||||
deleted_programs
|
||||
```
|
||||
|
||||
Avec une colonne `platform`:
|
||||
|
||||
```text
|
||||
tfo
|
||||
idello
|
||||
onfr
|
||||
linear
|
||||
```
|
||||
|
||||
Cela evite de dupliquer toute la logique dans des tables separees comme `tfo_products`, `idello_products`, `onfr_products`, etc., sauf si une contrainte technique oblige a garder cette separation.
|
||||
|
||||
## JSON statiques proposes
|
||||
|
||||
Au lieu d'un seul gros JSON, il faut publier plusieurs fichiers specialises.
|
||||
|
||||
Exemple pour TFO:
|
||||
|
||||
```text
|
||||
/tfo/v1/manifest.json
|
||||
/tfo/v1/runs/20260730-0900/today.json
|
||||
/tfo/v1/runs/20260730-0900/latest.json
|
||||
/tfo/v1/runs/20260730-0900/schedule/index.json
|
||||
/tfo/v1/runs/20260730-0900/schedule/2026-07-30.json
|
||||
/tfo/v1/runs/20260730-0900/schedule/2026-07-31.json
|
||||
/tfo/v1/runs/20260730-0900/collections/index.json
|
||||
/tfo/v1/runs/20260730-0900/collections/0123456/full.json
|
||||
/tfo/v1/runs/20260730-0900/products/GP123456.json
|
||||
/tfo/v1/runs/20260730-0900/search/index.json
|
||||
```
|
||||
|
||||
Pour 8 000 produits TFO et 22 000 produits IDELLO, ce volume de fichiers JSON n'est pas un probleme pour un bucket S3/CDN. C'est meme preferable a un gros fichier unique.
|
||||
|
||||
Le site ne devrait pas coder un chemin de run en dur. Il lit toujours le manifest:
|
||||
|
||||
```text
|
||||
/tfo/v1/manifest.json
|
||||
```
|
||||
|
||||
Puis il utilise le `base_path` retourne:
|
||||
|
||||
```text
|
||||
/tfo/v1/runs/20260730-0900
|
||||
```
|
||||
|
||||
### manifest.json
|
||||
|
||||
Le manifest indique quelle version est publiee.
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"platform": "tfo",
|
||||
"published_at": "2026-07-30T09:50:00",
|
||||
"run_id": "20260730-0900",
|
||||
"base_path": "/tfo/v1/runs/20260730-0900"
|
||||
}
|
||||
```
|
||||
|
||||
Le manifest est le seul fichier qui doit avoir un cache court.
|
||||
|
||||
Cache recommande:
|
||||
|
||||
```text
|
||||
/tfo/v1/manifest.json
|
||||
Cache-Control: public, max-age=60, stale-while-revalidate=120
|
||||
|
||||
/tfo/v1/runs/20260730-0900/*
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
```
|
||||
|
||||
Meme si Louise exporte seulement toutes les 3 heures, le manifest ne devrait pas etre cache 3 heures. Il doit pouvoir changer rapidement pour:
|
||||
|
||||
- correction d'urgence via mini CMS;
|
||||
- rollback;
|
||||
- republication apres erreur;
|
||||
- correction d'un mapping;
|
||||
- correction d'une video/image;
|
||||
- publication manuelle.
|
||||
|
||||
Compromis acceptable si Infra veut reduire les appels:
|
||||
|
||||
```text
|
||||
manifest.json: max-age=300
|
||||
```
|
||||
|
||||
Donc 5 minutes. Mais 3 heures est trop long pour les corrections d'urgence.
|
||||
|
||||
### today.json
|
||||
|
||||
Contient ce qui doit etre en ligne aujourd'hui.
|
||||
|
||||
```json
|
||||
{
|
||||
"date": "2026-07-30",
|
||||
"programs": []
|
||||
}
|
||||
```
|
||||
|
||||
### latest.json
|
||||
|
||||
Contient les nouveautes et changements depuis la derniere publication.
|
||||
|
||||
```json
|
||||
{
|
||||
"run_id": "20260730-0900",
|
||||
"added": [],
|
||||
"updated": [],
|
||||
"removed": []
|
||||
}
|
||||
```
|
||||
|
||||
### schedule/YYYY-MM-DD.json
|
||||
|
||||
Contient la programmation d'une date precise.
|
||||
|
||||
```json
|
||||
{
|
||||
"date": "2026-08-08",
|
||||
"programs": [
|
||||
{
|
||||
"program_key": 123,
|
||||
"product_key": 456,
|
||||
"begin": "2026-08-08T06:00:00",
|
||||
"end": "2026-08-08T06:24:00",
|
||||
"title": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### products/{id}.json
|
||||
|
||||
Contient le detail d'un produit.
|
||||
|
||||
```json
|
||||
{
|
||||
"product": {},
|
||||
"programmations": {
|
||||
"current": [],
|
||||
"upcoming": [],
|
||||
"next": {
|
||||
"date": "2026-08-08",
|
||||
"begin": "2026-08-08T06:00:00"
|
||||
}
|
||||
},
|
||||
"media": {},
|
||||
"images": []
|
||||
}
|
||||
```
|
||||
|
||||
### collections/{biznumber}/full.json
|
||||
|
||||
Contient le modele attendu par les sites.
|
||||
|
||||
```json
|
||||
{
|
||||
"collection": {
|
||||
"biznumber": "0123456",
|
||||
"title": "...",
|
||||
"is_original": true,
|
||||
"next_programmation": {
|
||||
"date": "2026-08-08",
|
||||
"begin": "2026-08-08T06:00:00"
|
||||
}
|
||||
},
|
||||
"seasons": [
|
||||
{
|
||||
"serie": {},
|
||||
"episodes": [
|
||||
{
|
||||
"product": {},
|
||||
"programmations": [],
|
||||
"media": {},
|
||||
"images": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Programmations futures
|
||||
|
||||
Pour afficher des messages comme "prochain episode le 8 aout", il faut extraire une fenetre future de programmation.
|
||||
|
||||
Proposition configurable:
|
||||
|
||||
```env
|
||||
TFO_SCHEDULE_DAYS_AHEAD=10
|
||||
IDELLO_SCHEDULE_DAYS_AHEAD=10
|
||||
ONFR_SCHEDULE_DAYS_AHEAD=10
|
||||
LINEAR_SCHEDULE_DAYS_BEHIND=7
|
||||
LINEAR_SCHEDULE_DAYS_AHEAD=10
|
||||
```
|
||||
|
||||
Les programmations futures sont publiees dans:
|
||||
|
||||
```text
|
||||
/tfo/schedule/2026-08-08.json
|
||||
```
|
||||
|
||||
Et resumees dans les JSON produit/collection:
|
||||
|
||||
```json
|
||||
{
|
||||
"next_programmation": {
|
||||
"date": "2026-08-08",
|
||||
"begin": "2026-08-08T06:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Cela evite aux sites de parcourir toute la grille future pour afficher une information simple.
|
||||
|
||||
Le maximum propose pour la v1 est J+10. Cette limite garde les JSON raisonnables et evite que la generation future ralentisse inutilement la synchronisation.
|
||||
|
||||
Le site peut ensuite appliquer sa logique d'affichage selon l'heure. Par exemple, si un programme est prevu a 6h, le JSON contient deja `begin: 06:00`, et le site decide quand l'afficher ou le mettre en evidence.
|
||||
|
||||
## Search et Algolia
|
||||
|
||||
Un fichier comme:
|
||||
|
||||
```text
|
||||
/tfo/search/index.json
|
||||
```
|
||||
|
||||
peut servir a alimenter Algolia, Meilisearch, Typesense ou un autre moteur de recherche.
|
||||
|
||||
Il peut contenir seulement les champs utiles a la recherche:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"objectID": "GP123456",
|
||||
"type": "product",
|
||||
"title": "...",
|
||||
"slug": "...",
|
||||
"image": "...",
|
||||
"collection_biznumber": "0123456"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Si les sites ont besoin d'une vraie recherche rapide sur 8 000 a 22 000 items, un moteur dedie comme Algolia reste preferable a un gros fichier recherche charge cote client.
|
||||
|
||||
## Publication atomique
|
||||
|
||||
Il faut eviter qu'un site lise une publication incomplete.
|
||||
|
||||
Principe:
|
||||
|
||||
```text
|
||||
/tfo/v1/runs/20260730-0900/...
|
||||
/tfo/v1/runs/20260730-1200/...
|
||||
/tfo/v1/manifest.json
|
||||
```
|
||||
|
||||
Le site lit d'abord:
|
||||
|
||||
```text
|
||||
/tfo/manifest.json
|
||||
```
|
||||
|
||||
Puis utilise le `base_path` indique.
|
||||
|
||||
Si la generation du run `20260730-1200` echoue, `manifest.json` continue de pointer vers `20260730-0900`.
|
||||
|
||||
Ainsi, une sync ratee ne casse pas le site.
|
||||
|
||||
Exemple simplifie:
|
||||
|
||||
```text
|
||||
/tfo/v1/runs/1/collections/...
|
||||
/tfo/v1/runs/1/products/...
|
||||
|
||||
/tfo/v1/runs/2/collections/...
|
||||
/tfo/v1/runs/2/products/...
|
||||
|
||||
/tfo/v1/manifest.json -> pointe vers /tfo/v1/runs/2
|
||||
```
|
||||
|
||||
### Retention des runs
|
||||
|
||||
Il faut supprimer les anciens runs pour eviter une croissance infinie du bucket.
|
||||
|
||||
Politique proposee:
|
||||
|
||||
```text
|
||||
JSON publies:
|
||||
- garder les runs des 10 derniers jours
|
||||
- garder au minimum les 3 derniers runs valides
|
||||
- supprimer les runs incomplets jamais publies
|
||||
|
||||
Rapports:
|
||||
- garder 90 jours
|
||||
|
||||
Anomalies importantes / audit:
|
||||
- garder 1 an ou selon politique interne
|
||||
```
|
||||
|
||||
Pourquoi garder au moins 3 runs valides:
|
||||
|
||||
- rollback rapide;
|
||||
- comparaison entre publications;
|
||||
- diagnostic si un site signale un probleme.
|
||||
|
||||
### Versioning du contrat JSON
|
||||
|
||||
Les JSON deviennent un contrat avec les sites. Il faut donc versionner le format.
|
||||
|
||||
Version dans le chemin:
|
||||
|
||||
```text
|
||||
/tfo/v1/manifest.json
|
||||
/tfo/v1/runs/20260730-0900/products/GP123456.json
|
||||
/tfo/v1/runs/20260730-0900/collections/0123456/full.json
|
||||
```
|
||||
|
||||
Version dans chaque fichier:
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": "1.0",
|
||||
"platform": "tfo",
|
||||
"run_id": "20260730-0900"
|
||||
}
|
||||
```
|
||||
|
||||
Si un changement cassant est necessaire:
|
||||
|
||||
```text
|
||||
/tfo/v2/manifest.json
|
||||
```
|
||||
|
||||
La v1 et la v2 peuvent coexister pendant une periode de transition.
|
||||
|
||||
### Documentation et validation
|
||||
|
||||
Swagger/OpenAPI est surtout utile pour des API dynamiques. Pour des JSON statiques, la documentation devrait plutot etre:
|
||||
|
||||
```text
|
||||
docs/
|
||||
publication-contract.md
|
||||
files.md
|
||||
cache-strategy.md
|
||||
versioning.md
|
||||
examples/
|
||||
manifest.json
|
||||
product.json
|
||||
collection-full.json
|
||||
schedule-day.json
|
||||
schemas/
|
||||
manifest.schema.json
|
||||
product.schema.json
|
||||
collection-full.schema.json
|
||||
schedule-day.schema.json
|
||||
```
|
||||
|
||||
Les JSON Schema sont importants parce qu'ils permettent de valider automatiquement les fichiers avant publication.
|
||||
|
||||
Avant de publier un run:
|
||||
|
||||
```text
|
||||
1. generer tous les JSON
|
||||
2. valider chaque type de fichier contre son JSON Schema
|
||||
3. produire le rapport
|
||||
4. publier seulement si les erreurs critiques sont absentes
|
||||
5. mettre a jour manifest.json
|
||||
```
|
||||
|
||||
## Rapport et alertes
|
||||
|
||||
Le rapport est une piece centrale de la v2.
|
||||
|
||||
Il doit comparer:
|
||||
|
||||
```text
|
||||
ce que le fichier Louise/Mogador contient
|
||||
vs
|
||||
ce que Laravel a traite
|
||||
vs
|
||||
ce qui a ete publie en JSON
|
||||
vs
|
||||
eventuellement ce qui reste dans Directus pendant la transition
|
||||
```
|
||||
|
||||
Exemple de rapport:
|
||||
|
||||
```text
|
||||
Plateforme: TFO
|
||||
Run: 20260730-0900
|
||||
|
||||
Export SQL recu: oui
|
||||
Import MySQL: succes
|
||||
API Mogador: OK
|
||||
|
||||
Programmes attendus aujourd'hui: 1230
|
||||
Programmes publies: 1229
|
||||
Produits attendus: 8142
|
||||
Produits publies: 8139
|
||||
|
||||
Ecarts:
|
||||
- 1 programme absent du JSON final
|
||||
- 2 produits sans video JWP
|
||||
- 5 images manquantes
|
||||
- 1 produit ignore car type extrait
|
||||
|
||||
Publication:
|
||||
- statut: publie avec avertissements
|
||||
- manifest pointe vers: /tfo/runs/20260730-0900
|
||||
```
|
||||
|
||||
Alertes a mettre en place:
|
||||
|
||||
- export SQL non recu;
|
||||
- fichier SQL trop petit ou checksum identique de facon suspecte;
|
||||
- import MySQL echoue;
|
||||
- API Mogador ne repond pas;
|
||||
- workers down;
|
||||
- queue bloquee;
|
||||
- sync trop longue;
|
||||
- ecart entre attendu et publie;
|
||||
- programme prevu a 6h absent de la publication avant 6h;
|
||||
- video JWP manquante;
|
||||
- image ou transcription manquante;
|
||||
- override actif proche expiration.
|
||||
|
||||
## Fichier SQL hors Laravel
|
||||
|
||||
Le fait que `export_mogador.sql` soit hors du repertoire Laravel n'est pas un probleme.
|
||||
|
||||
Le script d'import peut ecrire un fichier de statut dans un chemin connu:
|
||||
|
||||
```json
|
||||
{
|
||||
"export_received_at": "2026-07-30T09:01:00",
|
||||
"import_started_at": "2026-07-30T09:35:00",
|
||||
"import_finished_at": "2026-07-30T09:48:00",
|
||||
"sql_file_size": 306184192,
|
||||
"checksum": "abc123",
|
||||
"status": "success"
|
||||
}
|
||||
```
|
||||
|
||||
Laravel lit ce statut pour produire son rapport.
|
||||
|
||||
Chemins configurables:
|
||||
|
||||
```env
|
||||
MOGADOR_EXPORT_PATH=/data/mogador/export_mogador.sql
|
||||
MOGADOR_IMPORT_STATUS_PATH=/data/mogador/import-status.json
|
||||
MOGADOR_IMPORT_LOG_PATH=/var/log/mogador-import.log
|
||||
```
|
||||
|
||||
## Plan de migration propose
|
||||
|
||||
### Phase 1: Observabilite
|
||||
|
||||
Objectif: savoir ce qui se passe avant de tout changer.
|
||||
|
||||
- Ajouter `sync_runs`.
|
||||
- Ajouter `sync_run_items`.
|
||||
- Ajouter `sync_anomalies`.
|
||||
- Generer un rapport par plateforme.
|
||||
- Alerter sur les ecarts critiques.
|
||||
- Garder Directus tel quel.
|
||||
|
||||
### Phase 2: Publication JSON en parallele
|
||||
|
||||
Objectif: produire les JSON sans encore remplacer Directus.
|
||||
|
||||
- Generer `/manifest.json`.
|
||||
- Generer `/today.json`.
|
||||
- Generer `/schedule/YYYY-MM-DD.json`.
|
||||
- Generer quelques `/products/{id}.json`.
|
||||
- Generer quelques `/collections/{id}/full.json`.
|
||||
- Comparer JSON vs Directus.
|
||||
|
||||
### Phase 3: Premier site pilote
|
||||
|
||||
Objectif: faire consommer les JSON par un site ou une section limitee.
|
||||
|
||||
- Choisir une plateforme simple, probablement ONFR ou une portion TFO.
|
||||
- Publier dans un bucket/prefix dedie.
|
||||
- Valider performance, structure JSON, cache et rollback.
|
||||
|
||||
### Phase 4: Mini CMS interne
|
||||
|
||||
Objectif: remplacer l'edition d'urgence Directus.
|
||||
|
||||
- Ajouter `manual_overrides`.
|
||||
- Ajouter interface interne Laravel.
|
||||
- Ajouter audit trail.
|
||||
- Ajouter expiration automatique.
|
||||
- Ajouter rapport des overrides actifs.
|
||||
|
||||
### Phase 5: Reduction ou retrait de Directus
|
||||
|
||||
Objectif: retirer Directus de la publication si les JSON remplissent le besoin.
|
||||
|
||||
- Garder Directus seulement pendant transition.
|
||||
- Migrer les usages fournisseurs vers buckets/CDN.
|
||||
- Retirer progressivement les dependances Directus.
|
||||
|
||||
## Position finale
|
||||
|
||||
La proposition recommandee est:
|
||||
|
||||
```text
|
||||
Laravel interne + snapshots + diff maison + JSON statiques + buckets/CDN + rapports + mini CMS d'urgence
|
||||
```
|
||||
|
||||
Directus peut etre garde temporairement, mais ne devrait plus etre le moteur principal de publication web.
|
||||
|
||||
Cette approche respecte les contraintes:
|
||||
|
||||
- Louise reste source de verite.
|
||||
- L'API Mogador officielle reste utilisee.
|
||||
- Laravel n'est pas expose a Internet.
|
||||
- Les sites recoivent des donnees simples et rapides.
|
||||
- Les fournisseurs peuvent etre isoles par bucket ou prefixe.
|
||||
- L'equipe interne garde la capacite de corriger en urgence.
|
||||
- Les erreurs deviennent visibles avant que la production les signale.
|
||||
Reference in New Issue
Block a user