12 KiB
Consultation fournisseurs sites: proposition de publication JSON
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.
L'objectif est de savoir si une publication sous forme de fichiers JSON versionnés peut bien répondre à vos besoins techniques et opérationnels.
Ce document ne présente pas une décision finale. Il sert à recueillir vos commentaires avant de figer le format.
Idée générale
Aujourd'hui, les données sont disponibles via Directus ou via des mécanismes de synchronisation propres à chaque site.
La proposition est de publier des fichiers JSON prêts à consommer, organisés par plateforme, par version et par publication.
Exemple:
/tfo/v1/manifest.json
/tfo/v1/runs/20260730-0900/today.json
/tfo/v1/runs/20260730-0900/latest.json
/tfo/v1/runs/20260730-0900/schedule/2026-07-30.json
/tfo/v1/runs/20260730-0900/schedule/2026-08-08.json
/tfo/v1/runs/20260730-0900/products/GP123456.json
/tfo/v1/runs/20260730-0900/collections/0123456/full.json
/tfo/v1/runs/20260730-0900/search/index.json
Les sites ne devraient pas coder un chemin de run en dur. Ils liraient d'abord:
/tfo/v1/manifest.json
Puis utiliseraient le base_path retourné par le manifest pour charger les fichiers du run actif.
Exemple de manifest
{
"schema_version": "1.0",
"platform": "tfo",
"published_at": "2026-07-30T09:50:00-04:00",
"run_id": "20260730-0900",
"base_path": "/tfo/v1/runs/20260730-0900"
}
Le manifest.json permet de changer de publication de façon atomique. Si une nouvelle génération échoue, le manifest continue de pointer vers le dernier run valide.
Runs complets et changements incrémentaux
Chaque run publié doit être considéré comme une version complète des données disponibles pour une plateforme.
Par contre, entre deux runs, tous les fichiers ne changent pas nécessairement.
Exemple:
Run 1:
8 000 produits
Run 2:
10 nouveaux produits
5 produits retirés
7 produits modifiés
Dans ce cas, le run 2 reste un run complet pour le site, mais seuls les fichiers réellement impactés devraient changer.
Conséquence pour les sites:
- il faut toujours lire le
manifest.jsonpour connaître le run actif; - il ne faut pas supposer que tous les fichiers changent à chaque run;
- un fichier produit inchangé peut être identique entre deux runs;
- un produit retiré ne devrait plus apparaître dans les indexes du nouveau run;
latest.jsonpeut aider à savoir ce qui a été ajouté, modifié ou retiré.
Cette approche permet de publier plus vite et de réduire le risque de remplacer des données valides par des données incomplètes.
Types de fichiers proposés
today.json
Contient les contenus ou programmations pertinents pour la journée courante.
Le tableau programs contient des objets de programmation légers. Il ne contient pas tout le détail du produit ou de la collection. Pour le détail complet, le site utilise les liens vers les fichiers products/{product_key}.json ou collections/{biznumber}/full.json.
{
"schema_version": "1.0",
"platform": "tfo",
"run_id": "20260730-0900",
"date": "2026-07-30",
"programs": [
{
"program_key": "190858829",
"product_key": "102828840",
"collection_biznumber": "0123456",
"serie_key": "S123",
"title": "Larguer les amarres",
"begin": "2026-07-30T06:00:00-04:00",
"end": "2026-07-30T06:24:00-04:00",
"duration_seconds": 1440,
"type": "Film",
"target": "G",
"territories": ["CA"],
"media_status": "ready",
"links": {
"product": "/tfo/v1/runs/20260730-0900/products/102828840.json",
"collection_full": "/tfo/v1/runs/20260730-0900/collections/0123456/full.json"
}
}
]
}
latest.json
Contient les contenus ajoutés, modifiés ou retirés depuis la dernière publication.
{
"schema_version": "1.0",
"platform": "tfo",
"run_id": "20260730-0900",
"added": [
{
"entity_type": "product",
"product_key": "102828840",
"collection_biznumber": "0123456",
"title": "Larguer les amarres",
"first_programmation": "2026-07-30T06:00:00-04:00",
"links": {
"product": "/tfo/v1/runs/20260730-0900/products/102828840.json"
}
}
],
"updated": [
{
"entity_type": "program",
"program_key": "190858829",
"product_key": "102828840",
"title": "Larguer les amarres",
"changed_fields": ["begin", "end"],
"links": {
"product": "/tfo/v1/runs/20260730-0900/products/102828840.json"
}
}
],
"removed": [
{
"entity_type": "product",
"product_key": "102000001",
"collection_biznumber": "0999999",
"title": "Ancien titre",
"reason": "not_in_current_snapshot"
}
]
}
schedule/YYYY-MM-DD.json
Contient la programmation pour une date précise.
{
"schema_version": "1.0",
"platform": "tfo",
"run_id": "20260730-0900",
"date": "2026-08-08",
"programs": [
{
"program_key": "123",
"product_key": "GP123456",
"collection_biznumber": "0123456",
"serie_key": "S123",
"begin": "2026-08-08T06:00:00-04:00",
"end": "2026-08-08T06:24:00-04:00",
"title": "Titre de l'épisode",
"duration_seconds": 1440,
"type": "Film",
"target": "G",
"territories": ["CA"],
"media_status": "ready",
"links": {
"product": "/tfo/v1/runs/20260730-0900/products/GP123456.json",
"collection_full": "/tfo/v1/runs/20260730-0900/collections/0123456/full.json"
}
}
]
}
La première version viserait une fenêtre future jusqu'à J+10.
products/{product_key}.json
Contient le détail d'un produit ou épisode.
{
"schema_version": "1.0",
"platform": "tfo",
"run_id": "20260730-0900",
"product": {
"product_key": "GP123456",
"biznumber": "0123456",
"title": "Titre de l'épisode",
"description": "..."
},
"programmations": {
"current": [],
"upcoming": [],
"next": {
"date": "2026-08-08",
"begin": "2026-08-08T06:00:00-04:00"
}
},
"media": {},
"images": []
}
collections/{biznumber}/full.json
Contient une vue complète d'une collection, dans le sens attendu par les sites:
collection -> saisons -> épisodes
Exemple:
{
"schema_version": "1.0",
"platform": "tfo",
"run_id": "20260730-0900",
"collection": {
"biznumber": "0123456",
"title": "Titre de la collection",
"description": "...",
"programmation": {
"start": "2026-08-08T06:00:00-04:00",
"end": "2026-08-08T06:24:00-04:00"
},
"next_programmation": {
"date": "2026-08-08",
"begin": "2026-08-08T06:00:00-04:00"
}
},
"seasons": [
{
"serie": {
"serie_key": "S123",
"title": "Saison 1"
},
"episodes": [
{
"product": {
"product_key": "GP123456",
"title": "Épisode 1"
},
"programmations": [],
"media": {},
"images": []
}
]
}
]
}
search/index.json
Fichier optionnel pouvant servir à alimenter un moteur de recherche comme Algolia, Meilisearch, Typesense ou un index interne.
[
{
"objectID": "GP123456",
"type": "product",
"title": "Titre de l'épisode",
"slug": "titre-de-lepisode",
"image": "https://...",
"collection_biznumber": "0123456"
}
]
Cache proposé
Le manifest aurait un cache court:
/tfo/v1/manifest.json
Cache-Control: public, max-age=60, stale-while-revalidate=120
Les fichiers d'un run seraient immuables et pourraient être cachés longtemps:
/tfo/v1/runs/20260730-0900/*
Cache-Control: public, max-age=31536000, immutable
Logique:
- le site consulte régulièrement
manifest.json; - si
run_idchange, le site charge les fichiers du nouveau run; - les fichiers des runs ne changent jamais;
- 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.jsonpointe 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
- Les JSON seraient versionnés dans le chemin:
/v1/, puis éventuellement/v2/. - Les changements cassants seraient publiés dans une nouvelle version.
- Les dates seraient fournies avec timezone explicite.
- Les fichiers seraient séparés pour éviter de télécharger un énorme JSON unique.
- Les sites pourraient consommer seulement les fichiers utiles à leurs pages.
- Les fournisseurs pourraient avoir accès uniquement à leur plateforme ou préfixe.
Questions pour vous
Merci de nous dire si cette approche fonctionnerait pour votre site, et de commenter les points suivants.
Consommation
- Est-ce que votre site peut consommer des fichiers JSON statiques via HTTP/CDN?
- Est-ce que votre site peut lire un
manifest.jsonavant de charger les données? - Avez-vous besoin d'une API dynamique, ou des fichiers JSON suffisent?
- Avez-vous des contraintes sur le nombre de fichiers chargés?
Structure des données
- Le modèle
collection -> seasons -> episodesconvient-il à vos pages? - Le fichier
products/{product_key}.jsoncontient-il le bon niveau de détail? - Le fichier
collections/{biznumber}/full.jsonest-il trop gros, trop petit ou correct? - Avez-vous besoin d'autres regroupements?
- Quels champs sont obligatoires pour vos pages?
Programmation
- La fenêtre future J+10 est-elle suffisante?
- Avez-vous besoin de programmation passée?
- Avez-vous besoin d'un fichier par date, par semaine ou par mois?
- Comment affichez-vous "prochain épisode" aujourd'hui?
Media et images
- Quels champs media sont requis pour votre lecteur vidéo?
- Avez-vous besoin de plusieurs formats d'image?
- Avez-vous besoin de sous-titres, transcriptions, audio ou autres assets dans le JSON?
Recherche
- Utilisez-vous Algolia, Meilisearch, Typesense ou un autre moteur?
- Un fichier
search/index.jsonvous serait-il utile? - Quels champs devraient être inclus dans l'index?
Cache et mise à jour
- Un cache court sur
manifest.jsonvous convient-il? - Quelle fréquence de vérification du manifest serait acceptable?
- Avez-vous besoin d'un webhook ou signal pour savoir qu'un nouveau run est disponible?
- Comment votre site ferait-il un rollback si nécessaire?
Migration
- Pouvez-vous tester cette approche en parallèle de votre intégration actuelle?
- Quel serait le meilleur pilote pour vous: une page, une plateforme, une collection, une section?
- Quels risques voyez-vous dans une migration vers ce modèle?
Commentaires attendus
Pour nous aider à valider l'approche, merci de répondre avec:
- les fichiers que vous utiliseriez;
- les champs manquants;
- les champs inutiles;
- les contraintes de performance ou cache;
- les impacts sur votre architecture;
- les risques de migration;
- une estimation du travail côté site.
Décision recherchée
Nous voulons confirmer si cette approche JSON peut devenir un contrat stable entre notre système de publication et les sites.
La décision attendue n'est pas encore "on migre tout". La décision attendue est plutôt:
Est-ce que ce modèle JSON est techniquement viable pour les sites?
Si oui, quels ajustements sont nécessaires avant un pilote?