Ssteven_copy
case_study · 05 / 06·Énergie · grand compte·delivered · production

Refonte Angular 21.

Refonte from scratch d'une application Angular 16 vers Angular 21 (Signals, Standalone Components). Migration de plus de 150 endpoints GET → POST pour sécurité, mise en place d'une documentation Swagger, choix d'un nouveau repo propre plutôt qu'une migration in-place.

16→21
Versions Angular sautées
150+
Endpoints migrés GET → POST
1an
Durée de la mission
0
Reprise de bad practices legacy
Angular 21RxJSTypeScriptSignalsStandalone ComponentsJava 21Spring BootSwagger / OpenAPIGitLab CI/CDJenkinsGrafanaCheckmarxSonarQube

// 01 · le-contexte

Le contexte

Une application critique d'administration interne d'un grand groupe énergétique français, utilisée quotidiennement par des administrateurs systèmes pour gérer leur infrastructure.

Côté tech : une codebase Angular 16 vieillissante, héritée de migrations partielles, avec des bad practices accumulées (composants monolithiques, services overloadés, typage faible, gestion d'état incohérente). Côté backend, du Java avec des problèmes de performance identifiés sur certains traitements (requêtes mal optimisées, boucles imbriquées).

L'enjeu de la mission : moderniser l'IHM pour bénéficier des dernières features Angular (Signals, Standalone Components, nouveaux control flows), renforcer la sécurité des endpoints, et poser des fondations propres pour les évolutions futures du produit.

// 02 · la-solution

La solution

Le projet majeur sur lequel j'ai travaillé en autonomie : la refonte from scratch de l'IHM Angular.

Le choix structurant : nouveau repo plutôt que migration in-place

Le cas classique pour migrer Angular 16 → 21, c'est de monter version par version dans le repo existant. C'est long, ça traîne les bad practices héritées, et ça monopolise une grosse partie du temps de dev pour un gain limité.

J'ai fait un autre choix : créer un nouveau repo Angular 21 from scratch, repartir sur des bases saines, et y porter progressivement les fonctionnalités. La logique : le temps qu'aurait pris la migration in-place ne valait pas le résultat. Mieux valait investir le même budget dans une codebase moderne, scalable, et maintenable sur le long terme.

Concrètement, sur le nouveau repo :

  • Standalone Components partout (suppression des NgModules)
  • Signals pour la gestion d'état réactive
  • Nouveaux control flows (@if, @for, @switch)
  • TypeScript strict (suppression de tous les any)
  • Architecture composants modulaire et réutilisable
// code
// Pattern type sur le nouveau repo
@Component({
  selector: "app-import-list",
  standalone: true,
  imports: [ImportRowComponent],
  template: `
    @for (imp of imports(); track imp.id) {
      <app-import-row [import]="imp" />
    } @empty {
      <app-empty-state />
    }
  `,
})
export class ImportListComponent {
  private service = inject(ImportService);
  imports = toSignal(this.service.getImports(), { initialValue: [] });
}

Refonte sécuritaire de 150+ endpoints (GET → POST)

L'application avait plus de 150 endpoints GET qui passaient des données sensibles en query string — visibles dans les logs serveur, dans les historiques navigateur, et exposées aux outils de monitoring tiers.

J'ai mené la migration complète de ces endpoints vers POST, avec les payloads en body. Au passage, j'ai aussi :

  • Amélioré certaines requêtes côté serveur (filtrage des données utiles uniquement, pagination)
  • Mis en place Swagger / OpenAPI pour que la documentation API soit synchronisée avec le code et à jour automatiquement

C'était plus qu'un simple rename de verbe HTTP : c'était l'occasion d'auditer la sécurité de chaque endpoint, de corriger les vulnérabilités détectées par Checkmarx et SonarQube, et de rationaliser les contrats d'API.

Apport sur l'optimisation backend

J'ai également contribué (sans en être le porteur principal) à l'identification de bottlenecks backend : requêtes mal optimisées, boucles imbriquées, traitements Java qui pouvaient être réécrits proprement. Les optimisations ont été menées en collaboration avec l'équipe back.

// 03 · les-dfis-techniques

Les défis techniques

Convaincre de l'approche "nouveau repo". Ce n'est jamais la décision par défaut sur une mission ESN — la culture est plutôt à la migration in-place. J'ai porté l'argumentaire : temps de dev équivalent, codebase finale 10x plus saine, possibilité de poser de vraies fondations scalables, moins de dette technique reportée.

Garantir la cohérence pendant la cohabitation. Pendant la transition, l'ancienne app continuait à tourner en parallèle. Les nouvelles fonctionnalités devaient s'intégrer aux mêmes APIs backend, avec les mêmes contrats. J'ai documenté précisément les correspondances pour qu'il n'y ait pas de dérive entre les deux mondes.

150+ endpoints à migrer sans casser la prod. Chaque endpoint GET → POST = un changement potentiel de comportement côté client et serveur. Tests automatisés systématiques, livraison progressive, monitoring Grafana en temps réel pour détecter les anomalies dès les premières minutes.

// 04 · rsultats

Résultats

  • Codebase Angular 21 from scratch : Standalone Components, Signals, control flows, TypeScript strict
  • Plus de 150 endpoints migrés de GET vers POST avec sécurisation des payloads
  • Documentation Swagger mise en place et synchronisée avec le code
  • Fondations posées pour la scalabilité future du produit
  • Vulnérabilités identifiées par Checkmarx et SonarQube corrigées au passage

// 05 · stack-technique

Stack technique

LayerTechnos
FrontendAngular 21, RxJS, TypeScript strict, Standalone Components, Signals
BackendJava 21, Spring Boot (collaboration avec l'équipe back)
Doc APISwagger / OpenAPI
Sécurité & qualitéCheckmarx, SonarQube, revues de code systématiques
CI/CDGitLab CI, Jenkins
MonitoringGrafana (dashboards dédiés)

// 06 · ce-que-je-retiens

Ce que je retiens

Cette mission m'a appris à arbitrer entre la solution facile et la solution juste. Migrer Angular 16 → 21 in-place aurait été le réflexe par défaut. Partir d'un nouveau repo était plus structurant, plus risqué côté communication interne — mais le résultat est une codebase qui tiendra 5 ans sans avoir besoin d'être réécrite.

C'est aussi cette expérience qui m'a donné le goût des refontes propres comme axe de mission freelance aujourd'hui : quand on hérite d'un code qui ralentit l'équipe, parfois la meilleure réponse n'est pas "on optimise", c'est "on repart sur des bases saines, en transférant ce qui mérite de l'être".