Analyser le besoin — Identifier le type d'application (dashboard, portail entreprise, PWA) et définir l'architecture : standalone components vs NgModules, stratégie de lazy loading, et choix de la gestion d'état (NgRx, signals, ou services simples).
Structurer le projet — Organiser en feature modules avec Angular CLI : core/ pour les services singleton, shared/ pour les composants et pipes réutilisables, et un dossier par feature contenant composants, services, models et guards associés.
Créer les composants — Développer les composants avec le décorateur @Component, utiliser les signals Angular pour l'état réactif (signal(), computed(), effect()), configurer changeDetection: OnPush pour les performances, et gérer les inputs/outputs typés.
Implémenter les services et l'injection de dépendances — Créer les services avec @Injectable({ providedIn: 'root' }), utiliser le système d'injection hiérarchique d'Angular, et implémenter les interceptors HTTP pour l'authentification et la gestion des erreurs.
Gérer les flux asynchrones avec RxJS — Utiliser les opérateurs RxJS essentiels (switchMap, mergeMap, combineLatest, debounceTime), gérer les souscriptions avec le pattern async pipe dans les templates, et éviter les memory leaks avec takeUntilDestroyed().
Configurer le routing — Définir les routes avec lazy loading (loadComponent, loadChildren), implémenter les guards fonctionnels (canActivate, canMatch), les resolvers pour le pre-fetching, et les stratégies de preloading.
Implémenter les formulaires — Utiliser les Reactive Forms avec FormBuilder, FormGroup et FormArray, créer des validateurs custom synchrones et asynchrones, et gérer l'affichage des erreurs de validation de manière centralisée.
Tester et déployer — Écrire des tests unitaires avec Jasmine/Karma ou Jest, des tests d'intégration avec TestBed, configurer les environnements de build, et optimiser le bundle avec le tree-shaking et le build AOT.
Règles
Privilégie les standalone components et les signals Angular plutôt que les NgModules classiques pour les nouveaux projets.
Utilise toujours le pipe async ou toSignal() dans les templates plutôt que des souscriptions manuelles dans les composants.
Active systématiquement changeDetection: OnPush sur chaque composant pour éviter les cycles de détection inutiles.
Ne place jamais de logique métier dans les composants — délègue aux services injectables pour la testabilité et la réutilisabilité.
Gère toujours les erreurs HTTP dans les interceptors et les services, jamais directement dans les composants.