nestcraftx 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUDIT_ROADMAP.md +798 -0
- package/CHANGELOG.fr.md +22 -0
- package/CHANGELOG.md +22 -0
- package/CLI_USAGE.fr.md +331 -331
- package/CLI_USAGE.md +364 -364
- package/LICENSE +21 -21
- package/PROGRESS.md +258 -0
- package/bin/nestcraft.js +84 -64
- package/commands/demo.js +337 -330
- package/commands/generate.js +94 -0
- package/commands/generateConf.js +91 -0
- package/commands/help.js +29 -2
- package/commands/info.js +48 -48
- package/commands/new.js +340 -335
- package/commands/start.js +19 -19
- package/commands/test.js +7 -7
- package/package.json +1 -1
- package/utils/app-module.updater.js +96 -0
- package/utils/cliParser.js +88 -76
- package/utils/colors.js +62 -62
- package/utils/configs/configureDocker.js +120 -120
- package/utils/configs/setupCleanArchitecture.js +17 -15
- package/utils/configs/setupLightArchitecture.js +15 -9
- package/utils/file-system.js +75 -0
- package/utils/file-utils/saveProjectConfig.js +36 -0
- package/utils/fullModeInput.js +607 -607
- package/utils/generators/application/dtoGenerator.js +251 -0
- package/utils/generators/application/dtoUpdater.js +54 -0
- package/utils/generators/cleanModuleGenerator.js +475 -0
- package/utils/generators/database/setupDatabase.js +49 -0
- package/utils/generators/domain/entityGenerator.js +126 -0
- package/utils/generators/domain/entityUpdater.js +78 -0
- package/utils/generators/infrastructure/mapperGenerator.js +114 -0
- package/utils/generators/infrastructure/mapperUpdater.js +65 -0
- package/utils/generators/infrastructure/middlewareGenerator.js +645 -0
- package/utils/generators/infrastructure/mongooseSchemaGenerator.js +196 -0
- package/utils/generators/infrastructure/repositoryGenerator.js +334 -0
- package/utils/generators/lightModuleGenerator.js +131 -0
- package/utils/generators/presentation/controllerGenerator.js +142 -0
- package/utils/generators/relation/relation.engine.js +64 -0
- package/utils/helpers.js +109 -0
- package/utils/interactive/askEntityInputs.js +165 -0
- package/utils/loggers/logError.js +7 -7
- package/utils/loggers/logInfo.js +7 -7
- package/utils/loggers/logSuccess.js +7 -7
- package/utils/loggers/logWarning.js +7 -7
- package/utils/setups/orms/typeOrmSetup.js +630 -630
- package/utils/setups/setupAuth.js +33 -20
- package/utils/setups/setupDatabase.js +76 -75
- package/utils/setups/setupMongoose.js +22 -5
- package/utils/setups/setupPrisma.js +748 -630
- package/utils/shell.js +112 -32
- package/utils/spinner.js +57 -57
- package/utils/systemCheck.js +124 -124
- package/utils/userInput.js +357 -421
- package/utils/utils.js +29 -2164
package/AUDIT_ROADMAP.md
ADDED
|
@@ -0,0 +1,798 @@
|
|
|
1
|
+
# 🔍 Audit Approfondi NestCraftX v0.2.6
|
|
2
|
+
## Rapport complet & Roadmap vers la v1.0 Stable
|
|
3
|
+
|
|
4
|
+
> **Dernière mise à jour :** 5 juin 2026 — Retours production intégrés
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📊 Vue d'ensemble
|
|
9
|
+
|
|
10
|
+
| Métrique | État |
|
|
11
|
+
|---|---|
|
|
12
|
+
| Version auditée | 0.2.6 |
|
|
13
|
+
| Fichiers analysés | 40+ fichiers JS |
|
|
14
|
+
| Bugs critiques | 12 (audit) + 5 (prod) = **17** |
|
|
15
|
+
| Mauvaises pratiques majeures | 18 |
|
|
16
|
+
| Manquements d'architecture | 9 |
|
|
17
|
+
| Retours production | 5 confirmés |
|
|
18
|
+
| Priorité globale | 🔴 Haute — Refactorisation avant v1.0 |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🔴 SECTION 1 — Bugs Critiques (Bloquants en production)
|
|
23
|
+
|
|
24
|
+
### BUG-01 : Module System incohérent — `utils.js` utilise ESM, le reste CommonJS
|
|
25
|
+
**Fichiers concernés :** [utils.js](file:///e:/packages/NestCraftX/utils/utils.js), [userInput.js](file:///e:/packages/NestCraftX/utils/userInput.js)
|
|
26
|
+
|
|
27
|
+
```diff
|
|
28
|
+
- import { logInfo } from "./loggers/logInfo.js"; // ESM (utils.js L1)
|
|
29
|
+
- export async function generateEntityFileContent() // ESM (utils.js L7)
|
|
30
|
+
+ const { logInfo } = require("./loggers/logInfo"); // CJS (partout ailleurs)
|
|
31
|
+
+ module.exports = { generateEntityFileContent }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
> [!CAUTION]
|
|
35
|
+
> `utils.js` et `userInput.js` utilisent `import/export` ESM alors que **TOUT** le reste du projet (shell.js, setupAuth.js, etc.) utilise `require/module.exports` CommonJS. C'est la cause de **crashes au runtime** selon les versions de Node. Le `package.json` n'a pas de `"type": "module"` donc Node traite tout en CJS par défaut → les fichiers ESM plantent à l'import.
|
|
36
|
+
|
|
37
|
+
**Fix requis :** Migrer `utils.js` et `userInput.js` en CommonJS OU migrer tout le projet en ESM avec `"type": "module"` + `.mjs` extensions.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### BUG-02 : `handleAuthGeneration` — Fonction vide avec commentaire TODO
|
|
42
|
+
**Fichier :** [generate.js](file:///e:/packages/NestCraftX/commands/generate.js#L86-L91)
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
async function handleAuthGeneration(config) {
|
|
46
|
+
// On réutilisera ton script setupAuth corrigé
|
|
47
|
+
// await require('../utils/setups/setupAuth')(config); ← COMMENTÉ
|
|
48
|
+
logInfo("🚀 Generating module auth...");
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
> [!CAUTION]
|
|
53
|
+
> La commande `nestcraftx g auth` **ne fait rien**. Elle affiche juste un log. Toute la logique est en commentaire. C'est une feature annoncée mais complètement non-fonctionnelle.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### BUG-03 : `hasAllLightModeFlags` / `hasAllFullModeFlags` — Logique inversée
|
|
58
|
+
**Fichier :** [new.js](file:///e:/packages/NestCraftX/commands/new.js#L98-L104)
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
function hasAllLightModeFlags(flags) {
|
|
62
|
+
if (!flags.interactive || flags.interactive === false) {
|
|
63
|
+
return false; // ← RETOURNE false si PAS interactif = jamais de mode non-interactif
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
> [!CAUTION]
|
|
70
|
+
> La condition est **logiquement inversée**. Le flag `--interactive` n'existe pas dans le CLI — cette fonction retourne TOUJOURS `false`, ce qui signifie que `buildLightModeFromFlags()` et `buildFullModeFromFlags()` ne sont **jamais appelées**. Le mode non-interactif est donc **totalement cassé**. Même problème pour `hasAllFullModeFlags`.
|
|
71
|
+
|
|
72
|
+
**Ce que ça devrait faire :** vérifier si tous les flags requis sont présents (`--orm`, etc.) pour éviter le mode interactif.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### BUG-04 : `createFile` ne protège pas les fichiers existants
|
|
77
|
+
**Fichier :** [userInput.js](file:///e:/packages/NestCraftX/utils/userInput.js#L341-L352)
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
export async function createFile(fileData) {
|
|
81
|
+
try {
|
|
82
|
+
if (!fs.existsSync(fileData.path)) {
|
|
83
|
+
fs.writeFileSync(`${fileData.path}`, `${fileData.contente}`);
|
|
84
|
+
} else {
|
|
85
|
+
console.log(`Existing file : ${fileData.path}`);
|
|
86
|
+
fs.writeFileSync(`${fileData.path}`, `${fileData.contente}`); // ← ÉCRASE QUAND MÊME
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
> [!CAUTION]
|
|
92
|
+
> Le log dit "Existing file" mais **écrase quand même** le fichier. Lors d'un `nestcraftx g module`, les fichiers manuellement modifiés par l'utilisateur sont **silencieusement écrasés**.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### BUG-05 : `setupPrisma` — Double écriture du `.env` qui efface le contenu
|
|
97
|
+
**Fichiers :** [setupPrisma.js](file:///e:/packages/NestCraftX/utils/setups/setupPrisma.js#L44-L57), [envGenerator.js](file:///e:/packages/NestCraftX/utils/envGenerator.js)
|
|
98
|
+
|
|
99
|
+
Le flow est :
|
|
100
|
+
1. `setupPrisma` crée un `.env` minimal avec juste `DATABASE_URL`
|
|
101
|
+
2. Puis `generateEnvFile` + `writeEnvFile` **recrée** le `.env` complet
|
|
102
|
+
|
|
103
|
+
→ L'ordre est bon dans `new.js` (`setupDatabase` avant `generateEnvFile`) MAIS dans `setupPrisma`, un `.env` minimal est créé à la ligne 49 qui sera de toute façon **écrasé** plus tard, créant de la confusion et des edge cases selon les ORMs.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### BUG-06 : `setupAuth` — Hardcode `npm install` ignorer `packageManager`
|
|
108
|
+
**Fichier :** [setupAuth.js](file:///e:/packages/NestCraftX/utils/setups/setupAuth.js#L16-L23)
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
await runCommand(
|
|
112
|
+
`npm install @nestjs/jwt @nestjs/passport passport passport-jwt bcrypt uuid`,
|
|
113
|
+
"Erreur install deps auth",
|
|
114
|
+
);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
> [!CAUTION]
|
|
118
|
+
> **Hardcodé en `npm`**. Si l'utilisateur a choisi `yarn` ou `pnpm`, les dépendances auth sont installées avec npm quand même → conflit lockfile, double installation.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### BUG-07 : `setupMongoose` — Surcharge du `.env` incompatible avec `envGenerator`
|
|
123
|
+
**Fichier :** [setupMongoose.js](file:///e:/packages/NestCraftX/utils/setups/setupMongoose.js#L71-L75)
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
const envContent = `
|
|
127
|
+
MONGO_URI=${inputs.dbConfig.MONGO_URI}
|
|
128
|
+
MONGO_DB=${inputs.dbConfig.MONGO_DB}
|
|
129
|
+
`.trim();
|
|
130
|
+
await createFile({ path: ".env", contente: envContent }); // ← Écrase TOUT le .env
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
> [!CAUTION]
|
|
134
|
+
> `setupMongoose` écrase le `.env` complet avec seulement 2 variables, PUIS `envGenerator.writeEnvFile` va réécrire. Si l'ordre change, les variables JWT/PORT/NODE_ENV sont perdues.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### BUG-08 : `safeUpdateAppModule` — Regex fragile qui casse avec des modules complexes
|
|
139
|
+
**Fichier :** [userInput.js](file:///e:/packages/NestCraftX/utils/userInput.js#L391-L410)
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
const importsBlockRegex = /imports:\s*\[((.|\\n)*?)\]/m;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
> [!WARNING]
|
|
146
|
+
> Cette regex `(.|\\n)*?` avec le flag `m` est **non-greedy** et **arrête au premier `]`** trouvé. Si un module a `TypeOrmModule.forFeature([...])` dans son bloc `imports`, la regex s'arrête au `]` de `forFeature` et retourne un match partiel. Résultat : **imports corrompus** dans `app.module.ts`.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
### BUG-09 : `setupCleanArchitecture` — `useCases.forEach` avec `async` non-attendu
|
|
151
|
+
**Fichier :** [setupCleanArchitecture.js](file:///e:/packages/NestCraftX/utils/configs/setupCleanArchitecture.js#L131-L305)
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
useCases.forEach(async (useCase) => { // ← forEach N'ATTEND PAS les promises
|
|
155
|
+
// ... await createFile(...)
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
> [!CAUTION]
|
|
160
|
+
> `Array.forEach` **n'attend pas les Promises**. Les use cases sont écrits en parallèle de façon non contrôlée. Sur des systèmes lents ou avec beaucoup d'entités, certains fichiers peuvent ne pas être créés avant la suite du setup. **Doit être `for...of` avec await**.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
### BUG-10 : `setupPrisma` — Regex non-échappée dans les remplacements
|
|
165
|
+
**Fichier :** [setupPrisma.js](file:///e:/packages/NestCraftX/utils/setups/setupPrisma.js#L165-L187)
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
schemaContent.replace(
|
|
169
|
+
new RegExp(`model ${from} \\{([\\s\\S]*?)\\n\\}`, "m"),
|
|
170
|
+
...
|
|
171
|
+
)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Le nom du modèle `from` est injecté directement dans la RegEx **sans échappement**. Si un modèle s'appelait `Order+Item`, cela causerait une RegEx invalide. Par ailleurs, les modèles Prisma sont **case-sensitive** (doivent commencer par une majuscule) mais `from` peut être minuscule.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### BUG-11 : `role.guard.ts` généré — `console.log` de debug laissés en production
|
|
179
|
+
**Fichier :** [setupAuth.js](file:///e:/packages/NestCraftX/utils/setups/setupAuth.js#L776-L778)
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// Dans le fichier role.guard.ts généré :
|
|
183
|
+
console.log('🔍 Required Roles:', requiredRoles);
|
|
184
|
+
console.log('👤 User Role:', user?.role);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
> [!WARNING]
|
|
188
|
+
> Des `console.log` de debug sont générés dans le `RolesGuard` qui sera déployé en production. Fuite d'informations sensibles sur les rôles à chaque requête protégée.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### BUG-12 : `getMapper` généré avec commentaire erroné `PostMapper`
|
|
193
|
+
**Fichier :** [utils.js](file:///e:/packages/NestCraftX/utils/utils.js#L165-L170)
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// Code généré dans le mapper de TOUTE entité :
|
|
197
|
+
/**
|
|
198
|
+
* PostMapper transforms data between ← "Post" hardcodé pour TOUTES les entités
|
|
199
|
+
* different layers...
|
|
200
|
+
*/
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Le commentaire JSDoc est hardcodé avec "PostMapper" pour toutes les entités générées.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 🟠 SECTION 2 — Mauvaises Pratiques Majeures
|
|
208
|
+
|
|
209
|
+
### MP-01 : `utils.js` — Fichier monolithique de 2198 lignes
|
|
210
|
+
**Fichier :** [utils.js](file:///e:/packages/NestCraftX/utils/utils.js) (66 617 bytes)
|
|
211
|
+
|
|
212
|
+
> [!WARNING]
|
|
213
|
+
> Un seul fichier contient la logique de génération pour les entités, DTOs, controllers, services, mappers, middlewares, repositories, et les fonctions utilitaires. C'est **insoutenable** pour la maintenance. Doit être découpé en modules dédiés.
|
|
214
|
+
|
|
215
|
+
**Découpage proposé :**
|
|
216
|
+
- `generators/entity.generator.js`
|
|
217
|
+
- `generators/dto.generator.js`
|
|
218
|
+
- `generators/controller.generator.js`
|
|
219
|
+
- `generators/mapper.generator.js`
|
|
220
|
+
- `generators/repository.generator.js`
|
|
221
|
+
- `generators/service.generator.js`
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### MP-02 : Duplication massive de code entre `fullModeInput.js` et `lightModeInput.js`
|
|
226
|
+
Les fonctions `addCustomEntities` et `addRelations` sont **dupliquées quasi-identiquement** dans les deux fichiers. La logique de validation des noms, des types de champs, et des relations est répétée.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
### MP-03 : `generateDtox` vs `generateDto` — Deux versions de la même fonction
|
|
231
|
+
**Fichier :** [utils.js](file:///e:/packages/NestCraftX/utils/utils.js#L214-L479)
|
|
232
|
+
|
|
233
|
+
Il existe deux fonctions quasi-identiques (`generateDtox` L214 et `generateDto` L481) avec des différences mineures. La première semble être une version abandonnée mais non-supprimée. Confusion lors de la maintenance.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
### MP-04 : `shell.js` — `process.exit(1)` dans une fonction utilitaire
|
|
238
|
+
**Fichier :** [shell.js](file:///e:/packages/NestCraftX/utils/shell.js#L20)
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
} catch (error) {
|
|
242
|
+
logError(errorMessage);
|
|
243
|
+
fs.appendFileSync("setup.log", ...);
|
|
244
|
+
process.exit(1); // ← Force la sortie du processus
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Un utilitaire ne devrait **jamais** appeler `process.exit()`. Il doit lancer une exception que l'appelant peut gérer (rollback, cleanup, etc.). Actuellement, toute erreur de commande shell tue le processus sans cleanup.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### MP-05 : Absence totale de tests
|
|
253
|
+
**Fichier :** [test.js](file:///e:/packages/NestCraftX/commands/test.js) (153 bytes — juste un stub)
|
|
254
|
+
|
|
255
|
+
Le `package.json` a `"test": "nestcraftx test"` qui appelle la commande `test` du CLI qui... vérifie juste les outils système (Node, npm). Il n'y a **aucun test unitaire, aucun test d'intégration** sur le générateur lui-même.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
### MP-06 : `setupAuth` — `inputs` non validé en entrée
|
|
260
|
+
**Fichier :** [setupAuth.js](file:///e:/packages/NestCraftX/utils/setups/setupAuth.js#L7)
|
|
261
|
+
|
|
262
|
+
La fonction assume que `inputs.dbConfig`, `inputs.useSwagger`, `inputs.mode` existent sans vérification. Un appel depuis `generate.js` avec un config incomplet provoque des erreurs cryptiques.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
### MP-07 : Code commenté laissé dans le repo
|
|
267
|
+
Présent dans plusieurs fichiers :
|
|
268
|
+
- [cliParser.js](file:///e:/packages/NestCraftX/utils/cliParser.js#L1-L45) : ancienne version de `parseCliArgs` commentée (45 lignes)
|
|
269
|
+
- [setupPrisma.js](file:///e:/packages/NestCraftX/utils/setups/setupPrisma.js#L756-L800) : ancienne version de `updatePrismaSchema` commentée (44 lignes)
|
|
270
|
+
- [setupCleanArchitecture.js](file:///e:/packages/NestCraftX/utils/configs/setupCleanArchitecture.js#L36) : `// "domain/enums"` commenté
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
### MP-08 : `setupLogger.js` — Nom trompeur, ne configure pas un logger
|
|
275
|
+
**Fichier :** [setupLogger.js](file:///e:/packages/NestCraftX/utils/setups/setupLogger.js)
|
|
276
|
+
|
|
277
|
+
La fonction s'appelle `setupBootstrapLogger` mais elle modifie `main.ts` pour ajouter un bloc try/catch global, `ValidationPipe`, `ConfigService`, et le logger. C'est en réalité un `setupMainTs`. Et elle est appelée **seulement si `useSwagger` est faux** dans [new.js](file:///e:/packages/NestCraftX/commands/new.js#L256-L260), ce qui signifie que si Swagger est activé, le bootstrap logger **n'est pas configuré** — la logique de setup de `main.ts` est dans `setupSwagger.js` à la place.
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
### MP-09 : `generateConf.js` — Détection ORM incorrecte (ordre priorité)
|
|
282
|
+
**Fichier :** [generateConf.js](file:///e:/packages/NestCraftX/commands/generateConf.js#L31-L38)
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
let orm = "prisma"; // par défaut
|
|
286
|
+
if (deps["@nestjs/mongoose"] || deps["mongoose"]) {
|
|
287
|
+
orm = "mongoose";
|
|
288
|
+
} else if (deps["@nestjs/typeorm"] || deps["typeorm"]) {
|
|
289
|
+
orm = "typeorm";
|
|
290
|
+
} else if (fs.existsSync(path.join(root, "prisma"))) {
|
|
291
|
+
orm = "prisma";
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Si un projet a à la fois `mongoose` ET `typeorm` installés (cas réel lors de migrations), la détection retourne `mongoose` même si le projet principal est TypeORM.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
### MP-10 : `new.js` — Gestion incohérente sans `projectName`
|
|
300
|
+
**Fichier :** [new.js](file:///e:/packages/NestCraftX/commands/new.js#L24-L54)
|
|
301
|
+
|
|
302
|
+
Quand `projectName` est absent, la fonction appelle `getFullModeInputs` directement, ignorant `flags.light`. On ne peut jamais créer un projet LIGHT sans nom en argument.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
### MP-11 : `configureDocker` appelé sans vérification du CWD
|
|
307
|
+
**Fichier :** [configureDocker.js](file:///e:/packages/NestCraftX/utils/configs/configureDocker.js)
|
|
308
|
+
|
|
309
|
+
Docker est configuré APRÈS `process.chdir(projectName)` dans `createProject`, mais si `createProject` échoue à mi-chemin (ex: npm install timeout), le CWD reste dans le dossier projet partiellement créé → les étapes suivantes écrivent dans un projet cassé.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
### MP-12 : `help.js` — Version hardcodée `v0.2.5` au lieu de lire `package.json`
|
|
314
|
+
**Fichier :** [help.js](file:///e:/packages/NestCraftX/commands/help.js#L5)
|
|
315
|
+
|
|
316
|
+
```javascript
|
|
317
|
+
║ 🌟 NestCraftX CLI v0.2.5 🌟 ║ // ← v0.2.5 alors que package.json = v0.2.6
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
La version dans `help.js` est différente de `package.json`. À chaque release, il faudra mettre à jour manuellement.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
### MP-13 : `envGenerator.js` — JWT secrets générés même si `useAuth = false`
|
|
325
|
+
**Fichier :** [envGenerator.js](file:///e:/packages/NestCraftX/utils/envGenerator.js#L9-L36)
|
|
326
|
+
|
|
327
|
+
Les secrets JWT sont toujours générés dans le `.env` même si `inputs.useAuth = false`. Ça ne casse rien mais pollue la config.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
### MP-14 : `fullModeInput.js` — `getPackageManager` importé de `utils.js` ESM
|
|
332
|
+
**Fichier :** [fullModeInput.js](file:///e:/packages/NestCraftX/utils/fullModeInput.js#L6)
|
|
333
|
+
|
|
334
|
+
```javascript
|
|
335
|
+
const { getPackageManager } = require("./utils"); // ← utils.js est en ESM !
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Cela devrait crasher à l'exécution sur Node sans flag `--experimental-require-module`.
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
### MP-15 : Adapter généré est un template générique inutile
|
|
343
|
+
**Fichiers :** [setupCleanArchitecture.js](file:///e:/packages/NestCraftX/utils/configs/setupCleanArchitecture.js#L387-L415)
|
|
344
|
+
|
|
345
|
+
L'adapter généré pour chaque entité est un template vide avec des propriétés génériques `name`, `description` qui n'ont aucun rapport avec l'entité réelle. C'est du boilerplate trompeur.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
### MP-16 : `setupAuth` — OTP stocké en mémoire (`Map`)
|
|
350
|
+
**Fichier :** [setupAuth.js](file:///e:/packages/NestCraftX/utils/setups/setupAuth.js#L263)
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
// Généré dans auth.service.ts :
|
|
354
|
+
private otps = new Map<string, string>();
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Les OTPs sont stockés **en mémoire process**. En production avec plusieurs instances ou après un redémarrage, tous les OTPs sont perdus. C'est un antipattern pour de la production.
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
### MP-17 : `setupAuth` — Oubli du `resetPassword` — Token ignoré
|
|
362
|
+
**Fichier :** [setupAuth.js](file:///e:/packages/NestCraftX/utils/setups/setupAuth.js#L372-L381)
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
async resetPassword(dto: ResetPasswordDto) {
|
|
366
|
+
const existingUser = await this.userRepository.findByEmail(dto.email);
|
|
367
|
+
if (!existingUser) throw new UnauthorizedException('Invalid reset token');
|
|
368
|
+
// ← Le token de reset n'est JAMAIS validé, n'importe qui connaissant l'email peut reset
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Le token de réinitialisation généré dans `forgotPassword` (un UUID en console) n'est **jamais stocké ni validé** dans `resetPassword`. N'importe qui avec l'email peut changer le mot de passe.
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
### MP-18 : `cleanModuleGenerator` — Condition de relation toujours vraie
|
|
376
|
+
**Fichier :** [cleanModuleGenerator.js](file:///e:/packages/NestCraftX/utils/generators/cleanModuleGenerator.js#L87-L90)
|
|
377
|
+
|
|
378
|
+
```javascript
|
|
379
|
+
if (
|
|
380
|
+
entityData.relation &&
|
|
381
|
+
(entityData.relation.type != "1-n" || entityData.relation.type != "n-n")
|
|
382
|
+
) {
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
La condition `(type != "1-n" || type != "n-n")` est **logiquement TOUJOURS vraie** (De Morgan). Pour `type = "1-n"` : `false || true = true`. Pour `type = "n-n"` : `true || false = true`. Donc tous les types de relations déclenchent le patch.
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 🟡 SECTION 3 — Manquements d'Architecture
|
|
390
|
+
|
|
391
|
+
### MA-01 : Absence de système de rollback
|
|
392
|
+
Si une étape échoue à mi-génération (ex: `setupAuth` après `setupCleanArchitecture`), le projet reste dans un état **partiellement généré et cassé**. Aucun rollback ni cleanup.
|
|
393
|
+
|
|
394
|
+
### MA-02 : `process.chdir` dans `createProject` — Effet de bord global dangereux
|
|
395
|
+
`process.chdir(inputs.projectName)` est un effet de bord permanent qui affecte **tout le process Node**. Si une fonction est appelée avant le `chdir` (race condition), elle opère dans le mauvais répertoire.
|
|
396
|
+
|
|
397
|
+
### MA-03 : Pas de validation de l'état final du projet généré
|
|
398
|
+
Après génération, aucune vérification que le projet compile (`tsc --noEmit`), que les imports sont valides, ou que les modules NestJS sont correctement câblés.
|
|
399
|
+
|
|
400
|
+
### MA-04 : Mixage CJS/ESM sans `package.json` `"type"` défini
|
|
401
|
+
Sans `"type": "module"`, Node traite tout en CJS. Les fichiers `.js` avec `import/export` plantent. Il faut décider et unifier.
|
|
402
|
+
|
|
403
|
+
### MA-05 : `demo.js` duplique tout le code de `new.js`
|
|
404
|
+
La commande `demo` répète le même flow que `new` (`createProject → setup → auth → swagger → docker → env`). Si ce flow change, il faut le maintenir dans 2 endroits.
|
|
405
|
+
|
|
406
|
+
### MA-06 : Absence de gestion des versions dépendances générées
|
|
407
|
+
Les dépendances installées dans les projets générés (NestJS, Prisma, TypeORM...) ne sont pas pinnées à des versions compatibles. Un projet généré aujourd'hui vs dans 6 mois peut avoir des incompatibilités majeures.
|
|
408
|
+
|
|
409
|
+
### MA-07 : `userInput.js` mélange UI, logique, et I/O fichier
|
|
410
|
+
`userInput.js` contient des fonctions d'entrée utilisateur (UI), de création de fichiers (I/O), des fonctions utilitaires (`capitalize`, `decapitalize`) et même des fonctions d'anciens flows (`getUserInputs2`). Violation du Principe de Responsabilité Unique.
|
|
411
|
+
|
|
412
|
+
### MA-08 : Absence de mode `--dry-run`
|
|
413
|
+
Impossible de voir ce que le CLI va générer sans réellement générer. Un `--dry-run` est essentiel pour tester et documenter.
|
|
414
|
+
|
|
415
|
+
### MA-09 : Pas de gestion du timeout sur `execSync`
|
|
416
|
+
`runCommand` utilise `execSync` sans timeout. Si `npm install` hang indefiniment (réseau lent, proxy), le CLI attend indéfiniment sans feedback.
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## 🔥 SECTION 3.5 — Retours Production Confirmés (v0.2.6)
|
|
421
|
+
|
|
422
|
+
> Ces 5 problèmes ont été rencontrés en utilisation réelle. Ils viennent renforcer et préciser certains bugs déjà listés, ou ajoutent des cas non couverts par l'audit statique.
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
### PROD-01 🔴 — Champs Prisma des relations mal générés + crash `prisma format` bloquant
|
|
427
|
+
**Criticité : CRITIQUE — Phase 0**
|
|
428
|
+
|
|
429
|
+
**Ce qui se passe :**
|
|
430
|
+
- Les noms de modèles dans le schéma Prisma sont parfois en minuscules (ex: `model user`) alors que Prisma exige une **majuscule initiale** (`model User`). Les relations générées avec `from`/`to` en minuscule produisent un schema invalide.
|
|
431
|
+
- Le champ FK (`userId String`) est parfois dupliqué dans le modèle target car la logique de déduplication de `addedFields` n'est appliquée qu'au premier pass, pas lors de l'injection des relations.
|
|
432
|
+
- La relation inverse en n-n ajoute `${from}s` mais si le pluriel est déjà existant (user → sessions), on obtient `sessions sessions[]` au lieu de `Session[]`.
|
|
433
|
+
|
|
434
|
+
**Ce qui crashe tout :**
|
|
435
|
+
```javascript
|
|
436
|
+
// setupPrisma.js L292
|
|
437
|
+
await runCommand(`npx prisma format`, "❌ Failed to format prisma schema");
|
|
438
|
+
// shell.js L20
|
|
439
|
+
process.exit(1); // ← Tout crash ici, rien ne continue
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
`prisma format` échoue si le schema est invalide → `runCommand` appelle `process.exit(1)` → **le projet reste à moitié généré**, sans message clair pour l'utilisateur.
|
|
443
|
+
|
|
444
|
+
**Fix à apporter :**
|
|
445
|
+
1. Forcer la capitalisation des noms de modèles dans le schema (`capitalize(from)`, `capitalize(to)`)
|
|
446
|
+
2. Corriger la déduplication des FKs lors du 2e pass (injection relations)
|
|
447
|
+
3. Remplacer le crash `process.exit` par une **dégradation gracieuse** : continuer la génération, écrire le schema tel quel, et afficher un avertissement `⚠️ Le schema Prisma contient des erreurs — lancez 'npx prisma format' manuellement`
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
### PROD-02 🟠 — Descriptions Swagger des DTOs trop génériques
|
|
452
|
+
**Criticité : MAJEURE — Phase 2**
|
|
453
|
+
|
|
454
|
+
**Ce qui se passe :**
|
|
455
|
+
```typescript
|
|
456
|
+
// Actuellement généré pour TOUS les champs non-reconnus :
|
|
457
|
+
@ApiProperty({ example: 'title_val', description: 'The title of the post' })
|
|
458
|
+
title!: string;
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
La fonction `getFieldDescription` dans `utils.js` (L237-L246) utilise des heuristiques basiques (`includes('email')`, `includes('password')`) et retourne `The ${f.name} of the ${entityName}` pour tout le reste — ce qui est redondant et inutile pour un consumer d'API.
|
|
462
|
+
|
|
463
|
+
**Ce qui manque avant la v1 :**
|
|
464
|
+
- Décrire le **format attendu** (longueur min/max, pattern, unité)
|
|
465
|
+
- Indiquer si le champ est **requis ou optionnel** dans la description
|
|
466
|
+
- Adapter la description selon le **contexte** (champ d'update vs création)
|
|
467
|
+
- Permettre la **saisie manuelle** de la description pendant `getFullModeInputs` (option avancée)
|
|
468
|
+
|
|
469
|
+
**Approche recommandée :**
|
|
470
|
+
Système de **templates de description par catégorie sémantique** (détection plus fine) + prompt optionnel `"Description for field '${name}' [leave empty for auto]:"` dans le flow interactif.
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
### PROD-03 🔴 — Une erreur dans un module crashe toute la génération
|
|
475
|
+
**Criticité : CRITIQUE — Phase 0**
|
|
476
|
+
|
|
477
|
+
**Ce qui se passe :**
|
|
478
|
+
Si par exemple la génération du repository de l'entité `Product` échoue (fichier corrompu, permission, ORM mal configuré), `process.exit(1)` dans `shell.js` tue tout le processus — les entités `User`, `Post` déjà générées restent en état partiel, et l'entité `Comment` n'est jamais générée.
|
|
479
|
+
|
|
480
|
+
**Le problème fondamental :** `runCommand` dans `shell.js` est un point de défaillance unique pour TOUT le setup :
|
|
481
|
+
```javascript
|
|
482
|
+
// shell.js — appelé partout
|
|
483
|
+
async function runCommand(command, errorMessage) {
|
|
484
|
+
try {
|
|
485
|
+
execSync(command, ...);
|
|
486
|
+
} catch (error) {
|
|
487
|
+
logError(errorMessage);
|
|
488
|
+
process.exit(1); // ← NUCLEAR OPTION
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Fix requis :**
|
|
494
|
+
- Distinguer les erreurs **fatales** (npm install qui échoue) des erreurs **récupérables** (prisma format, migration)
|
|
495
|
+
- Pour les erreurs récupérables : logger le warning, continuer, ajouter à un rapport final `setup.log`
|
|
496
|
+
- Afficher en fin de génération un **résumé des warnings** : `⚠️ 2 étapes ont échoué — voir setup.log`
|
|
497
|
+
- Ajouter un paramètre `{ critical: boolean }` à `runCommand`
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
### PROD-04 🟠 — Saisie des champs dans les inputs — Pas assez sécurisée ni flexible
|
|
502
|
+
**Criticité : MAJEURE — Phase 1**
|
|
503
|
+
|
|
504
|
+
**Ce qui se passe actuellement :**
|
|
505
|
+
```javascript
|
|
506
|
+
// fullModeInput.js L348
|
|
507
|
+
let fname = readline.question(" Field name (leave empty to finish) : ");
|
|
508
|
+
if (!fname) break; // ← Quitter immédiatement
|
|
509
|
+
// Si nom invalide → continue (recommence la boucle) mais perd le contexte
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
**Problèmes observés en prod :**
|
|
513
|
+
1. **Validation trop stricte sans feedback clair** : L'utilisateur tape `user-name` (avec tiret) → erreur → recommence, mais ne voit pas clairement pourquoi
|
|
514
|
+
2. **Pas de `unique` flag** : Impossible de marquer un champ comme `@unique` (ex: email) lors de la saisie — hardcodé uniquement pour `email` dans l'entité User
|
|
515
|
+
3. **Pas de `nullable` flag** : Impossible de rendre un champ optionnel lors de la saisie
|
|
516
|
+
4. **Pas de `default` value** : Impossible de définir une valeur par défaut (ex: `isActive` → `true`)
|
|
517
|
+
5. **Saisie linéaire irréversible** : Une fois un champ ajouté, impossible de revenir en arrière pour le modifier ou le supprimer
|
|
518
|
+
|
|
519
|
+
**Approche recommandée (Phase 1) :** Afficher un **résumé interactif des champs** après chaque ajout avec option de modification/suppression via Inquirer, et étendre les options de champ.
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
### PROD-05 🟠 — Impossible de modifier/supprimer/corriger un champ après confirmation
|
|
524
|
+
**Criticité : MAJEURE — Phase 1**
|
|
525
|
+
|
|
526
|
+
**Ce qui se passe :**
|
|
527
|
+
Une fois qu'un champ est ajouté (ou qu'une entité est confirmée), il n'y a **aucun moyen de revenir en arrière** :
|
|
528
|
+
- Mauvais nom de champ tapé → il faut relancer tout le CLI
|
|
529
|
+
- Mauvais type sélectionné → idem
|
|
530
|
+
- Champ ajouté en double par erreur → idem
|
|
531
|
+
- Entité mal nommée → idem
|
|
532
|
+
|
|
533
|
+
En production, cela signifie relancer le générateur entier à cause d'une faute de frappe.
|
|
534
|
+
|
|
535
|
+
**Ce qui est attendu pour v1 :**
|
|
536
|
+
Après chaque entité finalisée, afficher un **écran de révision interactif** :
|
|
537
|
+
```
|
|
538
|
+
✅ Entity "Product" — 4 fields:
|
|
539
|
+
1. name : string
|
|
540
|
+
2. price : number
|
|
541
|
+
3. isActive : boolean
|
|
542
|
+
4. userId : string
|
|
543
|
+
|
|
544
|
+
? What do you want to do?
|
|
545
|
+
❯ ✅ Confirm and continue
|
|
546
|
+
✏️ Edit a field
|
|
547
|
+
➕ Add another field
|
|
548
|
+
🗑️ Delete a field
|
|
549
|
+
✏️ Rename the entity
|
|
550
|
+
❌ Cancel this entity
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
Cela nécessite une refonte complète du flow d'input vers un **modèle basé sur un state** (pas de boucles while linéaires).
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
## 🟢 SECTION 4 — Points Positifs
|
|
558
|
+
|
|
559
|
+
- ✅ **Architecture générale bien pensée** : séparation commands/utils/generators/setups
|
|
560
|
+
- ✅ **Support multi-ORM** (Prisma, TypeORM, Mongoose) avec logique spécifique par ORM
|
|
561
|
+
- ✅ **Génération JWT complète** (access + refresh token + session management)
|
|
562
|
+
- ✅ **envGenerator** avec secrets crypto-générés automatiquement
|
|
563
|
+
- ✅ **Mode Light vs Full** bien distincts
|
|
564
|
+
- ✅ **Détection des fichiers existants** dans `generateConf`
|
|
565
|
+
- ✅ **Relations entre entités** (1-1, 1-n, n-1, n-n) gérées dans le schéma Prisma
|
|
566
|
+
- ✅ **Swagger auto-documenté** avec exemples dynamiques par type de champ
|
|
567
|
+
- ✅ **Session-based auth** avec guard + stratégie JWT bien structurés
|
|
568
|
+
- ✅ **Demo command** fonctionnelle pour onboarding rapide
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
## 🗺️ ROADMAP vers la v1.0 Stable
|
|
573
|
+
|
|
574
|
+
### Phase 0 : Stabilisation d'urgence (v0.3.0) — 2-3 semaines
|
|
575
|
+
> Corriger TOUS les bugs bloquants avant tout autre développement. Aucune nouvelle feature.
|
|
576
|
+
|
|
577
|
+
#### 0A — Crash & Stabilité (les plus urgents)
|
|
578
|
+
- [ ] **[PROD-03] Refactoriser `runCommand`** : Ajouter paramètre `{ critical: boolean }` — les erreurs non-critiques (prisma format, migrate) ne doivent plus appeler `process.exit(1)`. Logger dans `setup.log` et continuer.
|
|
579
|
+
- [ ] **[PROD-01] Dégradation gracieuse Prisma** : Si `prisma format` ou `prisma generate` échouent → afficher `⚠️ Schema Prisma invalide — continuons la génération. Corrigez manuellement avec 'npx prisma format'` au lieu de crasher
|
|
580
|
+
- [ ] **[PROD-01] Capitalisation modèles Prisma** : Forcer `capitalize(from)` et `capitalize(to)` dans toutes les regex de relations du schema pour respecter la convention Prisma
|
|
581
|
+
- [ ] **[PROD-01] Déduplication FK** : Corriger le double pass de génération de champs FK pour éviter les doublons dans le schema (`userId` dupliqué)
|
|
582
|
+
- [ ] **[BUG-09] `forEach` async → `for...of`** dans `setupCleanArchitecture` (use cases non attendus)
|
|
583
|
+
- [ ] **[BUG-01] Unifier le module system** : Convertir `utils.js` + `userInput.js` en CommonJS (ou tout en ESM avec `"type": "module"`)
|
|
584
|
+
|
|
585
|
+
#### 0B — Comportement incorrect
|
|
586
|
+
- [ ] **[BUG-03] Fixer `hasAllLightModeFlags`/`hasAllFullModeFlags`** : Logique correcte — `return flags.orm !== undefined` (vérifier la présence des flags réels)
|
|
587
|
+
- [ ] **[BUG-06] Fixer `setupAuth`** : Utiliser `inputs.packageManager` au lieu de `npm` hardcodé
|
|
588
|
+
- [ ] **[BUG-07] Fixer `setupMongoose`** : Ne plus écraser le `.env` complet — utiliser `updateFile` pour ajouter seulement les variables manquantes
|
|
589
|
+
- [ ] **[BUG-04] Fixer `createFile`** : L'option `overwrite: false` ne doit **vraiment pas** écraser — loguer et skipper proprement
|
|
590
|
+
- [ ] **[BUG-08] Corriger la regex AppModule** dans `safeUpdateAppModule` (utiliser un parser AST ou une regex non-greedy correcte sur les imports)
|
|
591
|
+
|
|
592
|
+
#### 0C — Nettoyage immédiat
|
|
593
|
+
- [ ] **[BUG-12] Fixer `help.js`** : Lire la version depuis `package.json` dynamiquement
|
|
594
|
+
- [ ] **[MP-07] Supprimer le code mort** : Code commenté dans `cliParser.js` (45 lignes) et `setupPrisma.js` (44 lignes)
|
|
595
|
+
- [ ] **[BUG-02] `handleAuthGeneration`** : Soit implémenter, soit retourner un message clair `"nestcraftx g auth n'est pas encore disponible en v0.3 — prévu en v0.7"`
|
|
596
|
+
- [ ] **[BUG-11] Retirer `console.log` debug** du `RolesGuard` généré
|
|
597
|
+
- [ ] **[BUG-12b] Corriger le commentaire `PostMapper`** hardcodé dans le mapper généré
|
|
598
|
+
|
|
599
|
+
---
|
|
600
|
+
|
|
601
|
+
### Phase 1 : Refactorisation Architecture (v0.4.0) — 3-4 semaines
|
|
602
|
+
> Rendre le code maintenable et testable. Fondations pour tout ce qui suit.
|
|
603
|
+
|
|
604
|
+
#### 1A — Découpage des gros fichiers
|
|
605
|
+
- [ ] **[MP-01] Éclater `utils.js`** (2198 lignes) en modules dédiés :
|
|
606
|
+
- `generators/entity.generator.js`
|
|
607
|
+
- `generators/dto.generator.js`
|
|
608
|
+
- `generators/controller.generator.js`
|
|
609
|
+
- `generators/mapper.generator.js`
|
|
610
|
+
- `generators/service.generator.js`
|
|
611
|
+
- `generators/module.generator.js`
|
|
612
|
+
- `utils/helpers.js` (capitalize, decapitalize, pluralize)
|
|
613
|
+
- [ ] **[MP-07] Éclater `userInput.js`** :
|
|
614
|
+
- `utils/file-system.js` (createFile, createDirectory, updateFile)
|
|
615
|
+
- `utils/app-module.updater.js` (safeUpdateAppModule)
|
|
616
|
+
- `utils/string-utils.js` (capitalize, decapitalize)
|
|
617
|
+
- [ ] **[MP-03] Supprimer `generateDtox`** (doublon de `generateDto`) et n'avoir qu'une seule fonction
|
|
618
|
+
|
|
619
|
+
#### 1B — Refonte du flow d'input entités (PROD-04 + PROD-05)
|
|
620
|
+
- [ ] **[PROD-04] Étendre le modèle de champ** : Ajouter `unique`, `nullable`, `default` aux options lors de la saisie interactive d'un champ
|
|
621
|
+
```
|
|
622
|
+
? Is this field unique? (y/N)
|
|
623
|
+
? Is this field nullable/optional? (y/N)
|
|
624
|
+
? Default value? (leave empty for none)
|
|
625
|
+
```
|
|
626
|
+
- [ ] **[PROD-05] Écran de révision d'entité** : Après saisie de tous les champs, afficher un menu de révision avec Inquirer :
|
|
627
|
+
- Modifier un champ existant (nom, type, options)
|
|
628
|
+
- Supprimer un champ
|
|
629
|
+
- Ajouter un champ supplémentaire
|
|
630
|
+
- Renommer l'entité
|
|
631
|
+
- Annuler cette entité
|
|
632
|
+
- [ ] **[PROD-04/05] Refonte en modèle state-based** : Remplacer les boucles `while(true)` linéaires par un objet `EntityBuilder` avec état mutable et navigable
|
|
633
|
+
- [ ] **[MP-02] Déduplication** : Extraire `addCustomEntities` et `addRelations` en fonctions communes partagées entre `fullModeInput.js` et `lightModeInput.js`
|
|
634
|
+
|
|
635
|
+
#### 1C — Architecture générale
|
|
636
|
+
- [ ] **[MA-05] Extraire le flow commun** de `demo.js` vers `new.js` (DRY — même pipeline `createProject → setup → auth → ...`)
|
|
637
|
+
- [ ] **[MP-04] Remplacer `execSync` par `execa`** (ou `child_process.spawn`) avec timeout configurable et streaming output
|
|
638
|
+
- [ ] **[MA-01] Créer un mécanisme de rapport final** : Au lieu de crasher, accumuler les warnings et les afficher en bloc en fin de génération
|
|
639
|
+
- [ ] **[MA-02] Isoler `process.chdir`** : Ne l'appeler qu'une fois, vérifier le CWD avant chaque opération I/O
|
|
640
|
+
- [ ] **Ajouter `--dry-run`** flag pour simuler sans écrire
|
|
641
|
+
|
|
642
|
+
---
|
|
643
|
+
|
|
644
|
+
### Phase 2 : Qualité & Sécurité (v0.5.0) — 2-3 semaines
|
|
645
|
+
> Corriger les mauvaises pratiques, sécuriser le code généré, améliorer l'expérience
|
|
646
|
+
|
|
647
|
+
#### 2A — Sécurité du code généré
|
|
648
|
+
- [ ] **[MP-17] Corriger `resetPassword`** : Stocker et valider le token de reset (table `PasswordReset` ou cache Redis)
|
|
649
|
+
- [ ] **[MP-16] Corriger les OTPs** : Utiliser la table DB ou Redis au lieu du `Map` en mémoire
|
|
650
|
+
- [ ] **[MA-06] Pinning des versions** : Spécifier des ranges semver stricts pour les dépendances générées (NestJS, Prisma, etc.)
|
|
651
|
+
|
|
652
|
+
#### 2B — Descriptions Swagger (PROD-02)
|
|
653
|
+
- [ ] **[PROD-02] Système de descriptions sémantiques** : Remplacer les heuristiques basiques par un système de templates par catégorie :
|
|
654
|
+
- Champs de date → `"ISO 8601 date string (e.g. 2024-01-15T10:30:00Z)"`
|
|
655
|
+
- Champs de prix/montant → `"Decimal value in USD (e.g. 99.99)"`
|
|
656
|
+
- Champs `*Id` → `"UUID of the referenced ${entityName} (e.g. 550e8400...)"`
|
|
657
|
+
- Champs boolean → `"true/false flag — default: false"`
|
|
658
|
+
- [ ] **[PROD-02] Description manuelle optionnelle** : Dans `getFullModeInputs`, ajouter un prompt optionnel par champ : `"Description [auto]: "` — si laissé vide, utiliser l'auto-description
|
|
659
|
+
- [ ] **[PROD-02] Description contextuelle Create vs Update** : Le DTO de mise à jour doit indiquer que tous les champs sont optionnels dans la description de classe Swagger
|
|
660
|
+
|
|
661
|
+
#### 2C — Autres corrections qualité
|
|
662
|
+
- [ ] **[BUG-18] Corriger la condition De Morgan** dans `cleanModuleGenerator` (relation type check)
|
|
663
|
+
- [ ] **[MP-09] Corriger détection ORM** dans `generateConf` (ordre de priorité + cas multi-ORM)
|
|
664
|
+
- [ ] **[MP-13] `envGenerator`** : JWT vars conditionnelles à `useAuth`
|
|
665
|
+
- [ ] **[MP-10] Corriger `new.js`** : Supporter le mode LIGHT sans nom de projet en argument
|
|
666
|
+
- [ ] **Timeout `runCommand`** : Ajouter un timeout de 5 min sur `npm install` avec message d'erreur clair
|
|
667
|
+
|
|
668
|
+
---
|
|
669
|
+
|
|
670
|
+
### Phase 3 : Tests & CI/CD (v0.6.0) — 3-4 semaines
|
|
671
|
+
> Zéro regression possible — valider que chaque correction reste correcte
|
|
672
|
+
|
|
673
|
+
#### 3A — Tests unitaires (Jest)
|
|
674
|
+
- [ ] **Generators** :
|
|
675
|
+
- `generateDto()` — vérifier output TypeScript valide pour chaque ORM
|
|
676
|
+
- `generateEntityFileContent()` — vérifier structure domaine
|
|
677
|
+
- `generateController()` — vérifier routes, guards, decorators
|
|
678
|
+
- `mapTypeToPrisma()` / `mapTypeToMongoose()` — tous les types (string, Date, enum, array, json)
|
|
679
|
+
- [ ] **Schema Prisma** :
|
|
680
|
+
- Relations 1-n → vérifier FK, inverse, capitalisation des modèles
|
|
681
|
+
- Relations n-n → vérifier table pivot ou champs array
|
|
682
|
+
- Relations 1-1 → vérifier `@unique` sur FK
|
|
683
|
+
- Déduplication des champs
|
|
684
|
+
- [ ] **CLI Parser** : tous les cas de flags (`--orm`, `--mode`, `--auth`, `-v`, etc.)
|
|
685
|
+
- [ ] **`safeUpdateAppModule`** : différents états d'`app.module.ts` (modules imbriqués, tableau multi-lignes)
|
|
686
|
+
|
|
687
|
+
#### 3B — Tests d'intégration (E2E Generator)
|
|
688
|
+
- [ ] Générer `test-full-prisma` → vérifier `tsc --noEmit` passe
|
|
689
|
+
- [ ] Générer `test-full-typeorm` → vérifier `tsc --noEmit` passe
|
|
690
|
+
- [ ] Générer `test-full-mongoose` → vérifier `tsc --noEmit` passe
|
|
691
|
+
- [ ] Générer `test-light-prisma` → vérifier `tsc --noEmit` passe
|
|
692
|
+
- [ ] Générer avec auth → vérifier que `auth.module.ts` est correctement câblé
|
|
693
|
+
- [ ] Générer avec relations 1-n → vérifier le schema Prisma résultant
|
|
694
|
+
- [ ] **[PROD-03] Test de résilience** : Simuler une erreur de migration → vérifier que le reste est généré
|
|
695
|
+
|
|
696
|
+
#### 3C — CI/CD GitHub Actions
|
|
697
|
+
- [ ] Lint (ESLint) sur chaque PR
|
|
698
|
+
- [ ] Tests sur Node 18, 20, 22 LTS
|
|
699
|
+
- [ ] Test de génération sur Ubuntu + Windows (matrix)
|
|
700
|
+
- [ ] Semantic Release automatique (version + CHANGELOG)
|
|
701
|
+
- [ ] Publish automatique sur npm à chaque release
|
|
702
|
+
|
|
703
|
+
---
|
|
704
|
+
|
|
705
|
+
### Phase 4 : Features Manquantes (v0.7.0 → v0.9.0) — 4-6 semaines
|
|
706
|
+
> Compléter les features pour être v1.0-ready
|
|
707
|
+
|
|
708
|
+
#### 4A — Features CLI
|
|
709
|
+
- [ ] **`nestcraftx g auth`** — Implémenter complètement (ajouter auth post-création dans un projet existant)
|
|
710
|
+
- [ ] **Mode non-interactif complet** — Tous les flags documentés et fonctionnels (`--orm`, `--auth`, `--swagger`, `--docker`, `--db-user`, `--db-pass`, etc.)
|
|
711
|
+
- [ ] **`nestcraftx update`** — Mettre à jour la CLI elle-même (`npm install -g nestcraftx@latest`)
|
|
712
|
+
- [ ] **`nestcraftx list`** — Lister les entités/modules du projet courant (depuis `.nestcraftxrc`)
|
|
713
|
+
- [ ] **`pnpm` support** — En plus de npm/yarn (déjà dans les menus demo mais pas implémenté)
|
|
714
|
+
|
|
715
|
+
#### 4B — Qualité du code généré
|
|
716
|
+
- [ ] **Pagination** dans les controllers et repositories générés (GET all avec `?page=1&limit=10`)
|
|
717
|
+
- [ ] **Filtering & Sorting** params query sur les endpoints GET all
|
|
718
|
+
- [ ] **Rate limiting** global (`@nestjs/throttler`) dans le projet généré
|
|
719
|
+
- [ ] **Health check endpoint** (`/health`) avec `@nestjs/terminus`
|
|
720
|
+
- [ ] **Exception filter global** typé (remplacer les erreurs 500 brutes)
|
|
721
|
+
- [ ] **Guards RBAC** conditionnels sur les endpoints selon les roles détectés
|
|
722
|
+
- [ ] **Support MySQL/SQLite** en plus de PostgreSQL pour Prisma/TypeORM
|
|
723
|
+
|
|
724
|
+
#### 4C — Expérience développeur
|
|
725
|
+
- [ ] **Téléchargement de templates** depuis GitHub pour permettre la personnalisation (`nestcraftx template use <url>`)
|
|
726
|
+
- [ ] **`nestcraftx g relation`** — Ajouter une relation entre deux modules existants sans re-générer
|
|
727
|
+
- [ ] **Rapport de génération** en fin de commande : tableau récapitulatif des fichiers créés, skippés, en erreur
|
|
728
|
+
|
|
729
|
+
---
|
|
730
|
+
|
|
731
|
+
### Phase 5 : Documentation & Site Web (v0.9.x → v1.0.0) — 3-4 semaines
|
|
732
|
+
> Site de documentation officiel
|
|
733
|
+
|
|
734
|
+
#### Site Documentation (Docusaurus ou VitePress recommandé)
|
|
735
|
+
- [ ] **Création du site** `nestcraftx.dev` avec :
|
|
736
|
+
- **Getting Started** — Installation, premier projet en 5 minutes
|
|
737
|
+
- **CLI Reference** — Toutes les commandes avec tous les flags documentés
|
|
738
|
+
- **Architecture Guide** — Explication de la Clean Architecture générée
|
|
739
|
+
- **ORM Guide** — Différences Prisma vs TypeORM vs Mongoose
|
|
740
|
+
- **Auth Deep Dive** — JWT, sessions, guards, roles
|
|
741
|
+
- **Modes (Light vs Full)** — Quand utiliser quoi
|
|
742
|
+
- **`nestcraftx g module`** — Guide complet de génération post-projet
|
|
743
|
+
- **Troubleshooting** — Problèmes courants et solutions
|
|
744
|
+
- **Migration Guide** — De 0.2.x vers 1.0
|
|
745
|
+
- **Contributing** — Comment contribuer au projet
|
|
746
|
+
- [ ] **Versioning de la doc** (Docusaurus supporte les versions)
|
|
747
|
+
- [ ] **Playground interactif** — Simuler la génération dans le navigateur
|
|
748
|
+
- [ ] **Dark/Light mode**
|
|
749
|
+
|
|
750
|
+
---
|
|
751
|
+
|
|
752
|
+
### Phase 6 : Préparation v1.0 stable (v1.0.0-rc.1) — 1-2 semaines
|
|
753
|
+
> Release candidate
|
|
754
|
+
|
|
755
|
+
- [ ] **Audit de sécurité** final (secrets, dépendances vulnérables)
|
|
756
|
+
- [ ] **Test complet sur Windows + macOS + Linux**
|
|
757
|
+
- [ ] **Revue de toutes les sorties CLI** (messages, formatage)
|
|
758
|
+
- [ ] **README mis à jour** avec badges CI, version, etc.
|
|
759
|
+
- [ ] **CHANGELOG complet** depuis v0.2.6
|
|
760
|
+
- [ ] **Publication npm** avec tag `@stable`
|
|
761
|
+
- [ ] **Annonce GitHub Release** avec notes détaillées
|
|
762
|
+
|
|
763
|
+
---
|
|
764
|
+
|
|
765
|
+
## 📋 Résumé Priorités (Mis à jour avec retours prod)
|
|
766
|
+
|
|
767
|
+
| Priorité | Phase | Items clés | Durée estimée |
|
|
768
|
+
|---|---|---|---|
|
|
769
|
+
| 🔴 URGENT | Phase 0 — Stabilisation | Crash-proofing, ESM/CJS, relations Prisma, `forEach` async | 2-3 semaines |
|
|
770
|
+
| 🟠 HAUTE | Phase 1 — Refactorisation | `utils.js` split, flow input state-based, révision entités | 3-4 semaines |
|
|
771
|
+
| 🟠 HAUTE | Phase 2 — Qualité & Sécurité | Swagger sémantique, resetPassword, OTP, envGenerator | 2-3 semaines |
|
|
772
|
+
| 🟡 MOYENNE | Phase 3 — Tests & CI/CD | Tests unitaires, E2E, GitHub Actions | 3-4 semaines |
|
|
773
|
+
| 🟡 MOYENNE | Phase 4 — Features | `g auth`, pagination, non-interactif complet | 4-6 semaines |
|
|
774
|
+
| 🟢 NORMALE | Phase 5 — Documentation | Site Docusaurus, CLI reference, guides ORM | 3-4 semaines |
|
|
775
|
+
| 🟢 NORMALE | Phase 6 — Release v1.0 | Audit sécurité, test cross-platform, npm publish | 1-2 semaines |
|
|
776
|
+
| **Total** | | | **~18-26 semaines** |
|
|
777
|
+
|
|
778
|
+
---
|
|
779
|
+
|
|
780
|
+
## 🔗 Mapping Retours Prod → Phases
|
|
781
|
+
|
|
782
|
+
| Retour Prod | Criticité | Phase | Ticket |
|
|
783
|
+
|---|---|---|---|
|
|
784
|
+
| Champs Prisma relations mal générés | 🔴 Critique | Phase 0 | PROD-01 |
|
|
785
|
+
| Crash `prisma format` bloque tout | 🔴 Critique | Phase 0 | PROD-01 |
|
|
786
|
+
| Erreur d'un module crashe tout | 🔴 Critique | Phase 0 | PROD-03 |
|
|
787
|
+
| Descriptions Swagger trop génériques | 🟠 Majeur | Phase 2 | PROD-02 |
|
|
788
|
+
| Saisie champs pas assez flexible/sécurisée | 🟠 Majeur | Phase 1 | PROD-04 |
|
|
789
|
+
| Impossible de modifier/supprimer un champ | 🟠 Majeur | Phase 1 | PROD-05 |
|
|
790
|
+
|
|
791
|
+
---
|
|
792
|
+
|
|
793
|
+
> [!NOTE]
|
|
794
|
+
> Ce roadmap est évolutif. Chaque retour prod supplémentaire sera intégré avec sa criticité et placé dans la phase appropriée. L'objectif est de ne jamais bloquer une release pour une feature, mais de toujours corriger d'abord ce qui casse l'expérience utilisateur.
|
|
795
|
+
|
|
796
|
+
---
|
|
797
|
+
|
|
798
|
+
*Audit initial : 5 juin 2026 — Retours prod intégrés : 5 juin 2026 — NestCraftX v0.2.6*
|