Une app incassable
Pourquoi chaque correction de bug en crée deux · Comment une architecture vraie empêche ça · Comment un agent IA la respecte sans te poser de questions · Et si tu veux, on la construit pour toi.
Avant une architecture. Après une architecture.
❌ Avant
- • Tu fixes un bug → 2 autres cassent
- • L'agent corrige là où c'est le plus court
- • Tout est connecté à tout
- • Ajouter une feature prend 3x plus de temps
- • Un test qui passe ≠ le code qui marche
- • Peur de chaque merge
✅ Après
- • Tu fixes un bug → rien d'autre ne casse
- • L'agent respecte les couches
- • Chaque couche connaît son job
- • Ajouter une feature suit un chemin prévisible
- • Un test qui passe = confiance
- • Merge sans stress
Le problème du vibe coding. Et pourquoi l'architecture le résout.
Quand tu dis à une IA « ajoute cette feature », elle voit ton code comme un gros bloc indifférencié. Elle modifie là où c'est le plus court entre les deux points. Zéro intention de structure. Zéro respect des couches.
Résultat : un bug dans la base de données se propage à l'UI. Un changement dans l'UI casse la logique métier. Tout tient debout sur un chaînage fragile, et chaque correction risque de tout écrouler.
Une architecture incassable le rend impossible. Pas une bonne intention — un mécanisme.
Tu sépares ton code en trois couches : présentation, métier, données. Le compilateur refuserait un import qui traverse les couches. Une règle de lint le bloque. Et l'agent IA, en respectant ces garde-fous, touche à ce qu'il peut vraiment modifier sans effet de bord.
Les cinq règles. Chacune avec son garde-fou.
Règle 1. Les couches.
Trois couches, une direction de dépendances : présentation parle au métier, métier parle aux données. Jamais l'inverse.
Mécanisme : Pas d'imports cross-layer. Lint + compilateur refusent une violation.
Règle 2. Les entités sont pures.
Une entité du métier ne sait rien de Firestore, d'une API, ou de l'UI. Elle décrit le métier pur. Pas d'horloge système : la date se passe en paramètre.
Mécanisme : Une entité ne peut importer que des classes du domaine. Le compilateur le vérifie.
Règle 3. Les erreurs sont typées.
Pas de `Exception` générique. Une `FirestoreException` devient un `NetworkFailure` typé. L'UI sait exactement quoi afficher.
Mécanisme : Un type fermé par catégorie d'erreur (classe scellée, union de types, enum selon ta techno), traité de façon exhaustive : oublier un cas = erreur de compilation ou de lint.
Règle 4. Tu testes le métier, pas l'UI.
Les bugs se cachent dans la logique métier. Teste où ils vivent : les UseCases purs, sans mock.
Mécanisme : 80% de tests unitaires sur le domaine. 15% d'intégration. 5% d'E2E sur les chemins critiques.
Règle 5. Un nom = une techno.
Pas de `UserRepositoryImpl`. Une classe concrète s'appelle `FirestoreUserRepository` ou `RestUserRepository`. Le nom te dit où elle vit.
Mécanisme : Une convention de nommage qu'on respecte. Relue au code review.
Douze pièges. Et ce qu'ils m'ont coûté.
1. Logique métier dans la Présentation
Un calcul de prix, une validation dans le widget. Ça marche une fois. À la correction, tu oublies.
Coût : Une correction qui crée 3 bugs.
2. Ignorer les exceptions à la frontière data
Une `FirebaseException` remonte jusqu'à l'UI. Le widget ne sait pas la traiter.
Coût : Des crashes sporadiques, une semaine pour tracer.
3. DTOs sans @Default() sur les nullables
Firestore retourne `null`. Le JSON decode rate. Une `UnimplementedError` remonte.
Coût : 45 minutes à tracer un bug qui n'existe que pour 0,3% des documents.
4. Tester des mocks au lieu du vrai métier
Un test dit "tout fonctionne". Le test testait un mock parfait, pas les vraies données.
Coût : Un bug utilisateur. Un mois pour confirmer l'edge case.
5. Un UseCase qui fait deux choses
`TransfertMontantEtEnvoyerNotification`. Tu corriges le transfert. L'agent touche aussi la notification.
Coût : Une notification en double, ou bloquée.
6. Nommer les implémentations sans la techno
`class UserRepositoryImpl`. Trois ans plus tard, tu ne sais pas si c'est Firestore ou REST.
Coût : Une migration avortée. Deux semaines de refactoring.
7. DataSource qui retourne une Entité
Firestore retourne l'entité domaine directement. Pas de DTO. Un jour tu ajoutes un champ.
Coût : Refactoring en chaîne. Trois jours de merge conflicts.
8. UseCase qui retourne une Entité brute
L'UI change directement les propriétés. Elle modifie l'entité sans passer par le métier.
Coût : Une donnée corrompue. Un utilisateur avec un solde négatif.
9. Pas d'injection de dépendances
Les dépendances se créent à la main partout. Tu as 40 endroits qui créent un `Dio()`.
Coût : Un bug où le timeout marche à un endroit, pas l'autre.
10. Des fichiers de plus de 200 lignes
Une classe énorme. L'agent va la modifier. Elle a trois responsabilités.
Coût : Un merge qui prend une journée.
11. Des imports relatifs au lieu d'imports de paquets
`import '../../../domain/auth'`. Tu déplaces un fichier. Les relatifs cassent.
Coût : Le build casse. Une refonte d'une heure prend une journée.
12. Oublier qu'un test qui passe ≠ confiance
90% de couverture. Un test qui passe. Ça casse en prod. Le test testait un cas qui n'arrive jamais.
Coût : Un bug utilisateur. Une journée d'astreinte.
Checklist de livraison. À cocher une par une.
Ce que ce guide ne te donne pas. Et quand c'est une raison de m'appeler.
1. Passer à l'échelle
Ce guide tient pour une app solo-dev. Quand tu passes à trois devs, le coût du coordination monte. Une architecture c'est une convention, et les conventions se négocient mal sans quelqu'un pour les defendre.
2. Les pannes 3h du matin
Ton app plantait. Tu lis le test qui échoue, tu le fix, tu dors. Mais les pannes n'arrivent jamais seules. Je suis là quand le compilateur refuse ton code n'est pas une réponse suffisante.
3. Le goût (transformer « ça sonne faux » en contrainte)
Un utilisateur dit « l'app se sent lente ». Un test dit que tout passe. L'architecture est propre. Mais il y a un chemin qui déclenche trois requêtes au lieu d'une. Des allers-retours pour le trouver.
On la construit pour toi, et on la fait vivre.
Trente minutes à parler de ta pile, ta taille, ce qui te tue chaque semaine. Puis on te la pose. Du jour 1 : la couche est découpée, le linter refuse les faux pas, et ton agent code sans te poser cent questions.
Après ça, on la tient : bugs à 3h du matin, refonte qui change les plans, équipe qui triple. Tu dis « ça sonne pas juste », on trouve. On s'arrête quand l'app respire.
Parler de mon app →Les skills à déposer dans ton projet.
Des fichiers .md lisibles par Claude Code, Cursor, Codex ou tout agent IA. Le zip est prêt à décompresser à la racine de ton repo (AGENTS.md et .claude/skills/).
Télécharger tous les skills (.zip)- AGENTS.md les règles d'architecture que ton agent lit avant de coder
- architecture-guard situer chaque modif dans la bonne couche, refuser un import interdit
- bugfix-sans-regression un test qui échoue, la correction, toute la suite au vert
- nouvelle-fonctionnalite métier, données, écran : toujours dans cet ordre
- revue-avant-merge l'IA relit son propre diff et dit ce qu'elle n'a pas vérifié
+ REPARTIR AVEC
Reçois les skills et les 5 règles par email.
Un email avec les liens de téléchargement. Rien d'autre.
C'est parti.
L'email arrive. Vérifie les indésirables s'il traîne.