Aller au contenu
Akram Moussaoui
CV PDF

ad2video

Un service qui génère des vidéos publicitaires à partir des photos, de la description et des équipements des annonces de voitures, en partenariat avec OLX.

Employeur
Groupe La Centrale
Rôle
Contributeur au démarrage, puis lead
Période
Stack
  • TypeScript strict
  • Node 24
  • AWS Lambda
  • SNS
  • SQS
  • DynamoDB
  • DynamoDB Streams
  • API Gateway
  • CloudFront
  • WAF
  • KMS
  • CDK v2

Contexte et problème

Les professionnels de l'automobile publient leurs annonces sur La Centrale avec des photos, une description et la liste des équipements. Avec OLX, nous transformons ces annonces en vidéos publicitaires, générées par l'API vidéo d'OLX.

Le service suit les contrats et les annonces de 8 000 professionnels. Il doit générer chaque vidéo au bon moment, sans jamais dépasser le plafond de 5 000 générations par jour imposé par l'API d'OLX.

Mon rôle

J'ai rejoint le projet comme contributeur au démarrage, puis j'en suis devenu le lead, dans une équipe de 3 développeurs. Un collègue a posé le socle : synchronisation des contrats et des annonces, API de consultation. J'ai conçu et livré toute la chaîne de génération : éligibilité des annonces, appel à l'API vidéo, réception des statuts, puis le batch quotidien et le renouvellement automatique des vidéos. J'ai aussi écrit le prompt de génération avec l'équipe.

Je suis l'interlocuteur technique direct des équipes d'OLX, pendant la conception comme pendant la réalisation. Depuis la mise en production, je suis le monitoring du service et ses améliorations.

Architecture

Architecture d'ad2video Synchronisation : les événements de comptes pros passent par SNS puis SQS, une Lambda synchronise contrats et annonces dans DynamoDB. Génération : DynamoDB Streams déclenche la Lambda d'orchestration, qui applique le throttling, récupère les photos et appelle l'API vidéo d'OLX. Accès : le back-office pro passe par CloudFront et WAF, puis par une API Gateway privée et une Lambda qui lit DynamoDB. Le tout est déployé en AWS CDK v2. SYNCHRONISATION DES CONTRATS ET ANNONCES GÉNÉRATION DES VIDÉOS ACTIVATION ET CONSULTATION Comptes pros événements internes SNS topic des comptes SQS lots, rejeu partiel Lambda synchronisation DynamoDB single-table · KMS DynamoDB Streams changements Orchestration Lambda · throttling Photos service interne API vidéo OLX partenaire externe Back-office pro activer, consulter CloudFront + WAF seule entrée API Gateway privée Lambda API prompt + demande de vidéo, avec retries INFRASTRUCTURE AWS CDK v2 · stacks stateless et stateful séparées · TypeScript strict sur Node 24
Schéma redessiné pour le site. En bleu, les briques des décisions détaillées plus bas ; en pointillés, le partenaire externe. Les services internes ne sont pas nommés.

L'architecture est événementielle, sur AWS :

  • Les événements de comptes des professionnels arrivent par SNS dans une file SQS, traitée par lots.
  • Une Lambda synchronise contrats et annonces dans une table DynamoDB unique, chiffrée avec KMS.
  • DynamoDB Streams déclenche la Lambda d'orchestration. Elle applique le throttling, récupère les photos auprès d'un service interne, construit le prompt et appelle l'API vidéo d'OLX, avec des retries.
  • Le back-office des professionnels active et consulte les vidéos par une API Gateway privée, joignable seulement derrière CloudFront et WAF.

L'infrastructure est décrite en AWS CDK v2, avec des stacks stateless et stateful séparées. Le code est en TypeScript strict sur Node 24.

Décisions clés

Différer une annonce déjà générée récemment

Contexte

OLX impose un plafond de 5 000 générations par jour. Une même annonce peut changer plusieurs fois dans la journée, et chaque changement peut demander une nouvelle vidéo.

Choix

Une première génération part tout de suite. Une annonce déjà générée dans les 12 dernières heures est différée.

Alternative écartée

L'option par défaut : générer une vidéo à chaque changement d'annonce, sans rien différer.

Conséquence

Le service tient le plafond d'OLX en produisant 3 000 vidéos par jour.

Passer à un batch quotidien borné

Contexte

Générer à chaque changement d'annonce rendait le volume d'appels à l'API vidéo difficile à prévoir, alors que chaque génération est facturée.

Choix

Les demandes de génération sont stockées dans DynamoDB, dans un index qui ne contient que les demandes en attente. Un batch quotidien planifié par EventBridge en traite au plus 3 000 demandes par exécution, dans l'ordre d'arrivée. L'heure et la taille du batch sont des paramètres CDK.

Alternative écartée

Garder la génération immédiate et compter seulement sur le délai de 12 dernières heures pour lisser le volume.

Conséquence

Le volume quotidien se règle sans toucher au code. Les vidéos sont aussi renouvelées automatiquement après 105 jours, avec au plus 5 générations par annonce.

Rejouer seulement les messages en échec

Contexte

Les événements de comptes arrivent par lots dans SQS. Un message en erreur ne doit pas bloquer les autres.

Choix

Un traitement par lot avec échecs partiels, via batchItemFailures : seuls les messages en erreur reviennent dans la file.

Alternative écartée

L'option par défaut : un lot qui contient une erreur est rejoué en entier.

Conséquence
Un message en erreur est rejoué seul, sans retraiter le reste du lot.

Une seule porte d'entrée : CloudFront et WAF

Contexte

L'API d'activation et de consultation des vidéos est exposée au back-office des professionnels.

Choix

L'endpoint par défaut d'API Gateway est désactivé : l'API n'est joignable que derrière CloudFront et WAF.

Alternative écartée

L'option par défaut : laisser l'endpoint public d'API Gateway actif à côté de CloudFront.

Conséquence
Aucun appel ne contourne les règles du WAF.

Résultats

3 000 vidéos par jour

Le service est en production. Il produit 3 000 vidéos par jour pour 8 000 professionnels, sans dépasser le plafond de 5 000 générations par jour fixé par OLX.

L'IA dans le produit

J'ai conçu le prompt de génération avec l'équipe. Il est construit à partir des données de l'annonce : sa description et ses équipements. La vidéo elle-même est générée par l'API d'OLX.

Limites et ce que je ferais autrement

  • Le plafond vient de l'extérieur. Le throttling étale les générations dans le temps, il ne crée pas de capacité : une annonce modifiée plusieurs fois attend sa nouvelle vidéo.
  • La génération dépend d'une API partenaire. Les retries absorbent une erreur passagère, mais la vidéo arrive alors plus tard.