Étude de cas : comrenov
Monorepo 4 packages — pipeline saga NestJS
Comrenov
Plateforme de rénovation énergétique
Remplace JotForm + Make.com par une solution full-stack avec pipeline saga NestJS, formulaire public Lit 3, et admin Angular 21. Monorepo 4 packages avec 11 agents Claude spécialisés.
comrenov est une plateforme de rénovation énergétique qui remplace un assemblage JotForm + Make.com par une solution propriétaire full-stack, avec le plus grand nombre d'agents Claude spécialisés (11) de mon lab.
1. Contexte et objectifs
Problématique métier
Comrenov gérait son flux de demandes de rénovation avec un assemblage d'outils SaaS : JotForm pour les formulaires et Make.com pour l'automatisation. Ce setup posait des problèmes critiques :
- Pas de contrôle sur le pipeline de traitement des demandes
- Perte de données lors des synchronisations Make.com
- Aucune visibilité temps réel sur l'état des demandes
- Impossibilité de personnaliser le parcours formulaire
- Coûts récurrents élevés (JotForm + Make.com + plugins)
Pourquoi remplacer ?
Contrôle total
Maîtrise complète du pipeline, de la soumission à la synchronisation CRM.
Visibilité
Dashboard admin avec KPIs temps réel sur les demandes et les conversions.
Fiabilité
Pipeline saga avec retry et garantie de livraison. Zéro perte de données.
Économies
Suppression des abonnements JotForm + Make.com. Hébergement autonome.
2. Architecture monorepo
4 packages npm workspaces
Le projet est organisé en monorepo avec 4 packages distincts partageant des types TypeScript via @comrenov/shared :
comrenov/
├── packages/
│ ├── frontend/ # Lit 3 — formulaire public
│ ├── backend/ # NestJS 11 — saga pipeline
│ ├── admin/ # Angular 21 — dashboard
│ └── shared/ # Types partagés
├── e2e/ # Playwright E2E
└── tools/scripts/ # SSOT sync, utilities @comrenov/frontend
Formulaire public en Lit 3 (Web Components). Remplace JotForm. Validation côté client, multi-étapes, responsive.
@comrenov/backend
API NestJS 11 avec pipeline saga. Remplace Make.com. Orchestration des étapes de traitement avec retry automatique.
@comrenov/admin
Panel d'administration Angular 21 avec KPIs, tableaux de bord, gestion des demandes et des utilisateurs.
@comrenov/shared
Types TypeScript partagés entre les 3 packages. DTOs, enums, interfaces métier. Source de vérité pour les contrats.
3. Pipeline saga
Architecture du pipeline
Le coeur du système est un pipeline saga NestJS qui remplace les scénarios Make.com. Chaque étape est un handler indépendant avec retry automatique et logging structuré :
Validation
Schéma + règles métier
Déduplication
Détection de doublons
Axonaut CRM
Sync contact + affaire
Google Drive
Upload documents
Notification
Alerte admin
Pipeline saga NestJS
Chaque étape est un handler injectable indépendant. En cas d'échec, le pipeline peut reprendre à l'étape qui a échoué sans rejouer les précédentes.
// Pipeline saga — chaque étape est un handler indépendant
@Injectable()
export class RequestPipeline {
async process(request: RenovationRequest) {
await this.validate(request);
await this.deduplicate(request);
await this.syncAxonaut(request);
await this.uploadToDrive(request);
await this.notifyAdmin(request);
}
} 4. 11 agents Claude spécialisés
Comrenov utilise le plus grand nombre d'agents Claude spécialisés sur un seul projet dans mon lab. Chaque agent a son domaine de compétence et ses propres instructions :
CLAUDE.md 11 agents ## Agents Claude (11 spécialisés)
### Backend agents
- `backend-api` : Routes NestJS, controllers, DTOs
- `backend-saga` : Pipeline saga, handlers, retry
- `backend-axonaut` : Intégration CRM Axonaut
- `backend-drive` : Google Drive upload, permissions
- `backend-security` : Chiffrement AES-256-GCM, JWT
### Frontend agents
- `frontend-form` : Formulaire Lit 3, validation
- `frontend-shared` : Composants et styles partagés
### Admin agents
- `admin-dashboard` : KPIs, graphiques, tableaux
- `admin-auth` : Login, rôles, guards
### Cross-cutting agents
- `e2e-tests` : Playwright, scénarios critiques
- `ssot-sync` : Google Sheets sync bidirectionnel Pourquoi 11 agents ?
- Spécialisation : chaque agent connaît son domaine (Axonaut, Drive, Lit, Angular) sans surcharge cognitive
- Contexte réduit : chaque agent ne charge que les fichiers de son package, économisant les tokens
- Parallélisme : plusieurs agents peuvent travailler simultanément sur des packages différents
- Qualité : un agent dédié aux E2E ne fait que des tests ; un agent saga ne fait que du pipeline
5. SSOT Google Sheets
Source de vérité externe
Les données de référence (types de travaux, zones géographiques, barèmes) sont gérées dans Google Sheets par l'équipe non-technique, puis synchronisées automatiquement dans la base PostgreSQL :
Synchronisation bidirectionnelle
Google Sheets sert de SSOT pour les données de référence. Un script de synchronisation maintient la cohérence entre Sheets et PostgreSQL via Prisma.
// Synchronisation bidirectionnelle Google Sheets
@Injectable()
export class SSOTSyncService {
async syncFromSheets(): Promise<SyncResult> {
const rows = await this.sheets.getRows(SSOT_RANGE);
const parsed = this.parseReferenceData(rows);
for (const item of parsed) {
await this.prisma.referenceData.upsert({
where: { externalId: item.id },
create: item,
update: item,
});
}
return { synced: parsed.length, source: 'sheets' };
}
} Collaboration non-tech
L'équipe métier met à jour les barèmes directement dans Google Sheets, sans intervention dev.
Sync automatique
Les changements sont propagés en base via un script planifié ou déclenché manuellement.
Historique natif
Google Sheets fournit un historique de versions gratuit, utile pour l'audit des changements.
Validation
Le script de sync valide les données avant import et signale les erreurs par email.
6. Sécurité
Chiffrement et authentification
Le projet implémente un niveau de sécurité avancé pour protéger les données personnelles des demandeurs de rénovation :
Chiffrement AES-256-GCM
Toutes les clés API tierces (Axonaut, Google) sont chiffrées au repos avec AES-256-GCM. Le déchiffrement se fait uniquement en mémoire au runtime.
// Chiffrement AES-256-GCM pour les clés API
@Injectable()
export class EncryptionService {
private readonly algorithm = 'aes-256-gcm';
encrypt(plaintext: string): EncryptedPayload {
const iv = randomBytes(16);
const cipher = createCipheriv(this.algorithm, this.key, iv);
const encrypted = Buffer.concat([
cipher.update(plaintext, 'utf8'),
cipher.final(),
]);
const tag = cipher.getAuthTag();
return { encrypted, iv, tag };
}
} JWT avec rôles
Trois niveaux d'accès : SUPER_ADMIN (configuration complète), ADMIN (gestion des demandes), VIEWER (consultation seule). Tokens signés avec rotation automatique.
Données personnelles
Les informations des demandeurs (nom, adresse, revenus) sont chiffrées en base. Conformité RGPD avec droit à l'oubli implémenté.
7. Métriques et résultats
Activité du projet
Ratio sessions/commits : 2.36
Interprétation : Un ratio de 2.36 sessions par commit indique une utilisation intensive de Claude Code pour l'exploration, la revue de code et le refactoring, en plus de la production de code. Ce ratio est cohérent avec un projet monorepo de cette complexité.
Couverture de test
8. Problèmes rencontrés et solutions
Coordination 11 agents
Problème : Avec 11 agents, le risque de conflits de merge et d'incohérences entre packages augmente considérablement.
Solution : Types partagés dans @comrenov/shared comme contrat strict. Chaque agent travaille sur son package sans toucher aux autres.
Pipeline saga complexe
Problème : La gestion des erreurs et des retries dans un pipeline à 5 étapes avec des services externes (Axonaut, Drive) est intrinsèquement complexe.
Solution : Chaque handler est idempotent. Le pipeline persiste l'état de progression et peut reprendre à l'étape échouée.
SSOT Sheets désynchronisé
Problème : Des modifications manuelles dans Google Sheets pouvaient casser les contraintes de la base PostgreSQL.
Solution : Validation stricte avant import avec rapport d'erreurs envoyé par email. Les lignes invalides sont ignorées mais signalées.
Lit 3 et SSR
Problème : Les Web Components Lit 3 posent des défis pour le SEO et le rendu initial côté serveur.
Solution : Declarative Shadow DOM pour le SSR. Pre-rendering des formulaires critiques avec Lit SSR.
9. Enseignements clés
Monorepo npm workspaces simplifie le partage de types
Un seul @comrenov/shared garantit la cohérence des DTOs entre frontend, backend et admin. Pas de dérive de contrats.
Pipeline saga > intégration monolithique
La résilience du pipeline saga permet de tolérer les pannes de services externes sans perdre de données. Chaque étape est indépendante et retryable.
11 agents spécialisés > 1 agent généraliste
Pour les gros projets monorepo, la spécialisation des agents réduit la charge cognitive et les erreurs de contexte. Chaque agent est expert de son domaine.
SSOT externe pour la collaboration non-tech
Google Sheets comme source de vérité permet à l'équipe métier de gérer les données de référence sans intervention développeur.