Aller au contenu
Akram Moussaoui
CV PDF

Pilot

La nouvelle interface du compte professionnel de La Centrale, en Next.js, déployée sur AWS Lambda derrière CloudFront.

Employeur
Groupe La Centrale
Rôle
Contributeur, fonctionnalités de bout en bout et plateforme
Période
Stack
  • Next.js
  • React
  • TypeScript
  • design system interne
  • react-hook-form
  • zod
  • chart.js
  • AWS Lambda
  • CloudFront
  • Secrets Manager
  • Cognito
  • CDK
  • Sentry
  • Jest
  • Testing Library

Contexte et problème

Les professionnels de l'automobile qui publient sur La Centrale gèrent leur activité depuis un espace pro. Pilot remplace l'ancienne interface : ils y filtrent un stock d'annonces parfois important, suivent leurs contacts (appels, emails, SMS), achètent et suivent des options de visibilité, et gèrent les accès de leurs collaborateurs.

L'application est en Next.js (App Router, Server Components, server actions), déployée sur AWS Lambda derrière CloudFront avec CDK.

Mon rôle

Je travaille sur Pilot depuis ses premiers mois, dans une équipe de une dizaine de développeurs. J'y livre des fonctionnalités de bout en bout : l'interface React, les server actions, l'appel aux services backend et les tests Jest. Parmi elles : la page Contacts, les filtres de la liste d'annonces, la sélection multiple et la suppression d'annonces, la page Boost (co-construite avec l'équipe), les annonces archivées, la refonte de la page Collaborateurs et la carte de vidéo IA.

J'ai aussi pris en charge des sujets de plateforme : la lecture des secrets à l'exécution, la protection des source maps et la correction des droits tronqués dans les tokens d'authentification.

Architecture

Architecture de Pilot Le navigateur passe par CloudFront ; une CloudFront Function filtre l'accès aux source maps. Une Lambda exécute Next.js (rendu serveur, Server Components, server actions). Elle lit les clés d'API dans Secrets Manager, vérifie la session avec Cognito et appelle les services backend du groupe, dont le service de vidéos générées par IA, streamé avec Suspense. Le tout est déployé en AWS CDK, les erreurs suivies dans Sentry. Navigateur pros CloudFront + Function source maps Lambda Next.js SSR · server actions Services backend annonces, contacts, droits Vidéo IA streamée (Suspense) Secrets Manager lu à l'exécution Cognito session, droits INFRASTRUCTURE AWS CDK · contrôle de taille de l'environnement au synth · Sentry
Schéma redessiné pour le site. En bleu, les briques des décisions détaillées plus bas. Les services internes ne sont pas nommés.

L'application tourne en serverless, sur AWS :

  • CloudFront sert l'application et ses fichiers statiques. Une CloudFront Function filtre l'accès aux source maps.
  • Une Lambda exécute Next.js : rendu serveur des pages, Server Components et server actions.
  • Les pages appellent les services backend du groupe : annonces, contacts, options, droits des utilisateurs et vidéos générées par IA.
  • L'authentification passe par Cognito. Les clés d'API sont lues à l'exécution dans Secrets Manager.

L'infrastructure est décrite en AWS CDK. Sentry suit les erreurs en production.

Décisions clés

Streamer la carte vidéo IA au lieu de l'attendre

Contexte

Le détail d'une annonce affiche la vidéo générée par IA. Le service vidéo peut être lent, avec des retries et un timeout, alors que la carte n'est pas critique pour la page.

Choix

L'appel part sans être attendu par le composant serveur. La carte est streamée avec Suspense et Await, et une ErrorBoundary silencieuse la masque en cas d'échec. Un test dont le mock ne se résout jamais prouve que la page s'affiche quand même.

Alternative écartée

L'option par défaut : attendre la réponse du service vidéo dans le composant serveur avant de rendre la page.

Conséquence

Le rendu serveur du détail d'annonce ne dépend plus du temps de réponse du service vidéo.

Lire les secrets à l'exécution

Contexte

L'environnement d'une Lambda est limité à 4 Ko, et les clés d'API injectées au déploiement l'approchaient.

Choix

Les clés sont lues à l'exécution dans AWS Secrets Manager, avec un cache. Un contrôle au synth CDK fait échouer le build avant que la taille de l'environnement n'atteigne la limite.

Alternative écartée

Continuer à injecter chaque clé comme variable d'environnement de la Lambda.

Conséquence

L'environnement garde de la marge, et la rotation d'une clé ne demande plus de redéploiement. Un secret mal formé lève une erreur qui ne cite jamais sa valeur.

Protéger les source maps sans les supprimer

Contexte

Sentry a besoin des source maps pour lire les erreurs de production, mais elles ne doivent pas exposer le code source au public.

Choix

Un comportement CloudFront dédié aux fichiers de source maps, filtré par une CloudFront Function : seul l'outil de suivi d'erreurs ou une adresse autorisée y accède.

Alternative écartée
Supprimer les source maps du déploiement, ou les laisser publiques.
Conséquence

Les erreurs restent lisibles dans Sentry, et une requête publique sur une source map est refusée.

Un seul parseur pour les droits tronqués

Contexte

Pour tenir dans la taille d'un attribut du token, la liste des comptes d'un utilisateur est tronquée, avec un marqueur. Plusieurs endroits du code interprétaient ce marqueur différemment, et les utilisateurs rattachés à beaucoup de comptes se voyaient refuser l'accès.

Choix

Un utilitaire unique, testé, lit les droits. Quand il détecte la troncature, il récupère la liste complète auprès du service des droits.

Alternative écartée
Corriger chaque endroit qui lisait le token, un par un.
Conséquence

Les utilisateurs rattachés à beaucoup de comptes retrouvent leurs accès, et la règle de lecture n'existe plus qu'à un seul endroit.

Résultats

5 000 connexions par jour

Pilot est ouvert à tous les professionnels et compte 5 000 connexions par jour. Les fonctionnalités listées plus haut sont en production.

L'IA dans le produit

La carte de vidéo IA du détail d'annonce affiche les vidéos produites par ad2video, l'autre projet que je mène. Une autre fonctionnalité de Pilot utilise un LLM : elle a été réalisée par d'autres membres de l'équipe.

Limites et ce que je ferais autrement

  • Pilot dépend de nombreux services backend. Une page reste aussi rapide que le plus lent des services qu'elle attend, d'où le streaming des blocs non critiques.
  • Le format des droits est imposé par la taille des attributs du token. La troncature reste un compromis : elle coûte un appel de plus pour les utilisateurs rattachés à beaucoup de comptes.