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
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
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.