Documentation de l’API
# Serveur de métadonnées podcasts
## Installation sur l'autre serveur
Copier tout le dossier metadata-server. Node.js 20 ou supérieur est requis.
Aucune dépendance npm et aucune base MongoDB ne sont nécessaires.
cd metadata-server
npm start
Port par défaut : 3002. Documentation accessible à la racine / et sur /docs.
Le serveur audio et DIGAS continuent de fonctionner séparément.
Variables d'environnement facultatives (à définir dans le service ou le shell) :
- PORT : port HTTP, 3002 par défaut.
- HOST : adresse d'écoute, 0.0.0.0 par défaut.
- METADATA_DATA_DIR : dossier persistant des JSON, data/ par défaut.
- METADATA_API_TOKEN : jeton Bearer protégeant les POST et GET de données.
Si vide, ces routes sont accessibles sans authentification.
Exemple de lancement avec authentification :
METADATA_API_TOKEN='votre-jeton' PORT=3002 npm start
Les variables sont lues au démarrage. Le serveur ne charge pas de fichier .env.
Pour un accès Internet, utiliser HTTPS via le proxy du serveur et définir un jeton.
La documentation reste accessible sans jeton et ne contient pas les données reçues.
## Brancher le backend audio
Dans Configuration → Envoi HTTP des métadonnées :
- URL : http://ADRESSE_DU_SERVEUR:3002/api/metadata
- Jeton Bearer : même valeur que METADATA_API_TOKEN, si configuré.
- Activer puis enregistrer.
Le backend envoie le nom du fichier audio normalisé, extension comprise,
et la date de diffusion du podcast. Les anciens JSON sans ces deux champs
ne sont pas importables sans les compléter.
## POST /api/metadata
Content-Type: application/json
Authorization: Bearer votre-jeton (uniquement si un jeton est configuré)
Corps requis :
{
"fileName": "JOURVAT_20260915_normalized.mp3",
"broadcastDate": "2026-09-15",
"title": "Titre du podcast",
"chapo": "Présentation courte.",
"transcription": "Transcription complète du podcast."
}
Les trois textes peuvent être vides, mais doivent être présents comme chaînes.
La taille totale du JSON est limitée à 10 Mio. Les champs supplémentaires sont ignorés.
fileName est un nom sans chemin. Sa casse et son extension sont significatives.
La date correspond à la diffusion, pas à la réception du POST.
curl --fail-with-body 'http://localhost:3002/api/metadata' \
-H 'Authorization: Bearer votre-jeton' \
-H 'Content-Type: application/json' \
--data-binary '@podcast.json'
Réponse : HTTP 201 pour une création, HTTP 200 pour une mise à jour.
{
"success": true,
"created": true,
"metadata": {
"fileName": "JOURVAT_20260915_normalized.mp3",
"broadcastDate": "2026-09-15",
"title": "Titre du podcast",
"chapo": "Présentation courte.",
"transcription": "Transcription complète du podcast.",
"createdAt": "2026-09-15T10:00:00.000Z",
"updatedAt": "2026-09-15T10:00:00.000Z"
}
}
Le nom du fichier est la clé unique. Un nouvel envoi du même nom remplace
les métadonnées, conserve createdAt et actualise updatedAt. Une correction de
broadcastDate déplace aussi le résultat vers la nouvelle date de recherche.
## GET /api/metadata?date=AAAA-MM-JJ
Récupérer tous les podcasts d'une date de diffusion :
curl --get 'http://localhost:3002/api/metadata' \
-H 'Authorization: Bearer votre-jeton' \
--data-urlencode 'date=2026-09-15'
## GET /api/metadata?fileName=nom.mp3
Recherche exacte du nom du fichier envoyé dans le POST :
curl --get 'http://localhost:3002/api/metadata' \
-H 'Authorization: Bearer votre-jeton' \
--data-urlencode 'fileName=JOURVAT_20260915_normalized.mp3'
Les deux filtres peuvent être combinés : le résultat doit satisfaire les deux.
Au moins un filtre est obligatoire. Les réponses GET ont toujours cette forme :
{ "count": 1, "items": [ { "fileName": "...", "broadcastDate": "...",
"title": "...", "chapo": "...", "transcription": "...",
"createdAt": "...", "updatedAt": "..." } ] }
Aucun résultat : HTTP 200 avec { "count": 0, "items": [] }.
Les résultats sont triés par nom de fichier et incluent la transcription complète.
## Erreurs
- 400 : JSON, champs ou filtres invalides (notamment une date impossible).
- 401 : jeton absent ou incorrect.
- 404 : route inconnue.
- 405 : méthode autre que GET ou POST.
- 413 : corps dépassant 10 Mio.
- 415 : Content-Type différent de application/json.
- 500 : erreur interne de stockage.
Format : { "error": "Explication", "docs": "/docs" }.
## Stockage et exploitation
Les JSON sont conservés sur disque avec écriture atomique. Sauvegarder le dossier
data/ (ou METADATA_DATA_DIR) et le conserver lors des mises à jour/déploiements.
Utiliser une seule instance d'écriture par dossier de stockage. Le serveur ne purge
pas les données. Une recherche par date lit les fichiers conservés : cette version
convient à une collection de taille modérée et ne propose pas de pagination.
Tests locaux : npm test