@girardelli/architect 5.0.0 → 8.1.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.
Files changed (335) hide show
  1. package/dist/{cli.d.ts → src/adapters/cli.d.ts} +1 -2
  2. package/dist/{cli.js → src/adapters/cli.js} +191 -213
  3. package/dist/src/adapters/cli.js.map +1 -0
  4. package/dist/src/adapters/github-action.d.ts +9 -0
  5. package/dist/src/adapters/github-action.js +94 -0
  6. package/dist/src/adapters/github-action.js.map +1 -0
  7. package/dist/src/adapters/html-reporter/scripts.d.ts +5 -0
  8. package/dist/src/adapters/html-reporter/scripts.js +400 -0
  9. package/dist/src/adapters/html-reporter/scripts.js.map +1 -0
  10. package/dist/src/adapters/html-reporter/sections/agents.d.ts +2 -0
  11. package/dist/src/adapters/html-reporter/sections/agents.js +260 -0
  12. package/dist/src/adapters/html-reporter/sections/agents.js.map +1 -0
  13. package/dist/src/adapters/html-reporter/sections/anti-patterns.d.ts +13 -0
  14. package/dist/src/adapters/html-reporter/sections/anti-patterns.js +64 -0
  15. package/dist/src/adapters/html-reporter/sections/anti-patterns.js.map +1 -0
  16. package/dist/src/adapters/html-reporter/sections/header.d.ts +3 -0
  17. package/dist/src/adapters/html-reporter/sections/header.js +30 -0
  18. package/dist/src/adapters/html-reporter/sections/header.js.map +1 -0
  19. package/dist/src/adapters/html-reporter/sections/layers.d.ts +9 -0
  20. package/dist/src/adapters/html-reporter/sections/layers.js +143 -0
  21. package/dist/src/adapters/html-reporter/sections/layers.js.map +1 -0
  22. package/dist/src/adapters/html-reporter/sections/overview.d.ts +2 -0
  23. package/dist/src/adapters/html-reporter/sections/overview.js +58 -0
  24. package/dist/src/adapters/html-reporter/sections/overview.js.map +1 -0
  25. package/dist/src/adapters/html-reporter/sections/refactoring-plan.d.ts +3 -0
  26. package/dist/src/adapters/html-reporter/sections/refactoring-plan.js +151 -0
  27. package/dist/src/adapters/html-reporter/sections/refactoring-plan.js.map +1 -0
  28. package/dist/src/adapters/html-reporter/sections/score.d.ts +7 -0
  29. package/dist/src/adapters/html-reporter/sections/score.js +70 -0
  30. package/dist/src/adapters/html-reporter/sections/score.js.map +1 -0
  31. package/dist/src/adapters/html-reporter/sections/suggestions.d.ts +7 -0
  32. package/dist/src/adapters/html-reporter/sections/suggestions.js +34 -0
  33. package/dist/src/adapters/html-reporter/sections/suggestions.js.map +1 -0
  34. package/dist/src/adapters/html-reporter/styles.d.ts +1 -0
  35. package/dist/src/adapters/html-reporter/styles.js +526 -0
  36. package/dist/src/adapters/html-reporter/styles.js.map +1 -0
  37. package/dist/src/adapters/html-reporter/utils_adapters.d.ts +20 -0
  38. package/dist/src/adapters/html-reporter/utils_adapters.js +32 -0
  39. package/dist/src/adapters/html-reporter/utils_adapters.js.map +1 -0
  40. package/dist/src/adapters/html-reporter/utils_sections.d.ts +7 -0
  41. package/dist/src/adapters/html-reporter/utils_sections.js +58 -0
  42. package/dist/src/adapters/html-reporter/utils_sections.js.map +1 -0
  43. package/dist/src/adapters/html-reporter.d.ts +10 -0
  44. package/dist/src/adapters/html-reporter.js +97 -0
  45. package/dist/src/adapters/html-reporter.js.map +1 -0
  46. package/dist/src/adapters/progress-logger.d.ts +55 -0
  47. package/dist/src/adapters/progress-logger.js +200 -0
  48. package/dist/src/adapters/progress-logger.js.map +1 -0
  49. package/dist/{refactor-reporter.d.ts → src/adapters/refactor-reporter.d.ts} +1 -2
  50. package/dist/{refactor-reporter.js → src/adapters/refactor-reporter.js} +1 -1
  51. package/dist/src/adapters/refactor-reporter.js.map +1 -0
  52. package/dist/{reporter.d.ts → src/adapters/reporter.d.ts} +1 -2
  53. package/dist/src/adapters/reporter.js.map +1 -0
  54. package/dist/src/core/GenesisTerminal.d.ts +8 -0
  55. package/dist/src/core/GenesisTerminal.js +105 -0
  56. package/dist/src/core/GenesisTerminal.js.map +1 -0
  57. package/dist/{index.d.ts → src/core/architect.d.ts} +4 -18
  58. package/dist/{index.js → src/core/architect.js} +22 -21
  59. package/dist/src/core/architect.js.map +1 -0
  60. package/dist/tests/architect-adapter-enrichment.test.d.ts +1 -0
  61. package/dist/tests/architect-adapter-enrichment.test.js +11 -0
  62. package/dist/tests/architect-adapter-enrichment.test.js.map +1 -0
  63. package/dist/tests/github-action.test.d.ts +1 -0
  64. package/dist/tests/github-action.test.js +92 -0
  65. package/dist/tests/github-action.test.js.map +1 -0
  66. package/package.json +15 -65
  67. package/src/adapters/cli.ts +492 -0
  68. package/src/adapters/github-action.ts +109 -0
  69. package/src/adapters/html-reporter/scripts.ts +402 -0
  70. package/src/adapters/html-reporter/sections/agents.ts +267 -0
  71. package/src/adapters/html-reporter/sections/anti-patterns.ts +81 -0
  72. package/src/adapters/html-reporter/sections/header.ts +35 -0
  73. package/src/adapters/html-reporter/sections/layers.ts +165 -0
  74. package/src/adapters/html-reporter/sections/overview.ts +64 -0
  75. package/src/adapters/html-reporter/sections/refactoring-plan.ts +166 -0
  76. package/src/adapters/html-reporter/sections/score.ts +80 -0
  77. package/src/adapters/html-reporter/sections/suggestions.ts +39 -0
  78. package/src/adapters/html-reporter/styles.ts +525 -0
  79. package/src/adapters/html-reporter/utils_adapters.ts +39 -0
  80. package/src/adapters/html-reporter/utils_sections.ts +55 -0
  81. package/src/adapters/html-reporter.ts +102 -0
  82. package/src/adapters/progress-logger.ts +236 -0
  83. package/src/{refactor-reporter.ts → adapters/refactor-reporter.ts} +2 -2
  84. package/src/{reporter.ts → adapters/reporter.ts} +1 -1
  85. package/src/core/GenesisTerminal.ts +127 -0
  86. package/src/{index.ts → core/architect.ts} +27 -45
  87. package/tests/github-action.test.ts +109 -0
  88. package/tsconfig.json +12 -19
  89. package/CONTRIBUTING.md +0 -140
  90. package/LICENSE +0 -21
  91. package/PROJECT_STRUCTURE.txt +0 -168
  92. package/README.md +0 -257
  93. package/architect-run.sh +0 -431
  94. package/assets/banner-v3.html +0 -561
  95. package/dist/agent-generator/context-enricher.d.ts +0 -58
  96. package/dist/agent-generator/context-enricher.d.ts.map +0 -1
  97. package/dist/agent-generator/context-enricher.js +0 -613
  98. package/dist/agent-generator/context-enricher.js.map +0 -1
  99. package/dist/agent-generator/domain-inferrer.d.ts +0 -52
  100. package/dist/agent-generator/domain-inferrer.d.ts.map +0 -1
  101. package/dist/agent-generator/domain-inferrer.js +0 -585
  102. package/dist/agent-generator/domain-inferrer.js.map +0 -1
  103. package/dist/agent-generator/framework-detector.d.ts +0 -40
  104. package/dist/agent-generator/framework-detector.d.ts.map +0 -1
  105. package/dist/agent-generator/framework-detector.js +0 -611
  106. package/dist/agent-generator/framework-detector.js.map +0 -1
  107. package/dist/agent-generator/index.d.ts +0 -47
  108. package/dist/agent-generator/index.d.ts.map +0 -1
  109. package/dist/agent-generator/index.js +0 -545
  110. package/dist/agent-generator/index.js.map +0 -1
  111. package/dist/agent-generator/stack-detector.d.ts +0 -14
  112. package/dist/agent-generator/stack-detector.d.ts.map +0 -1
  113. package/dist/agent-generator/stack-detector.js +0 -124
  114. package/dist/agent-generator/stack-detector.js.map +0 -1
  115. package/dist/agent-generator/templates/core/agents.d.ts +0 -17
  116. package/dist/agent-generator/templates/core/agents.d.ts.map +0 -1
  117. package/dist/agent-generator/templates/core/agents.js +0 -1256
  118. package/dist/agent-generator/templates/core/agents.js.map +0 -1
  119. package/dist/agent-generator/templates/core/architecture-rules.d.ts +0 -7
  120. package/dist/agent-generator/templates/core/architecture-rules.d.ts.map +0 -1
  121. package/dist/agent-generator/templates/core/architecture-rules.js +0 -274
  122. package/dist/agent-generator/templates/core/architecture-rules.js.map +0 -1
  123. package/dist/agent-generator/templates/core/general-rules.d.ts +0 -8
  124. package/dist/agent-generator/templates/core/general-rules.d.ts.map +0 -1
  125. package/dist/agent-generator/templates/core/general-rules.js +0 -301
  126. package/dist/agent-generator/templates/core/general-rules.js.map +0 -1
  127. package/dist/agent-generator/templates/core/hooks-generator.d.ts +0 -21
  128. package/dist/agent-generator/templates/core/hooks-generator.d.ts.map +0 -1
  129. package/dist/agent-generator/templates/core/hooks-generator.js +0 -233
  130. package/dist/agent-generator/templates/core/hooks-generator.js.map +0 -1
  131. package/dist/agent-generator/templates/core/index-md.d.ts +0 -7
  132. package/dist/agent-generator/templates/core/index-md.d.ts.map +0 -1
  133. package/dist/agent-generator/templates/core/index-md.js +0 -246
  134. package/dist/agent-generator/templates/core/index-md.js.map +0 -1
  135. package/dist/agent-generator/templates/core/orchestrator.d.ts +0 -8
  136. package/dist/agent-generator/templates/core/orchestrator.d.ts.map +0 -1
  137. package/dist/agent-generator/templates/core/orchestrator.js +0 -422
  138. package/dist/agent-generator/templates/core/orchestrator.js.map +0 -1
  139. package/dist/agent-generator/templates/core/preflight.d.ts +0 -8
  140. package/dist/agent-generator/templates/core/preflight.d.ts.map +0 -1
  141. package/dist/agent-generator/templates/core/preflight.js +0 -213
  142. package/dist/agent-generator/templates/core/preflight.js.map +0 -1
  143. package/dist/agent-generator/templates/core/quality-gates.d.ts +0 -11
  144. package/dist/agent-generator/templates/core/quality-gates.d.ts.map +0 -1
  145. package/dist/agent-generator/templates/core/quality-gates.js +0 -254
  146. package/dist/agent-generator/templates/core/quality-gates.js.map +0 -1
  147. package/dist/agent-generator/templates/core/security-rules.d.ts +0 -7
  148. package/dist/agent-generator/templates/core/security-rules.d.ts.map +0 -1
  149. package/dist/agent-generator/templates/core/security-rules.js +0 -528
  150. package/dist/agent-generator/templates/core/security-rules.js.map +0 -1
  151. package/dist/agent-generator/templates/core/skills-generator.d.ts +0 -19
  152. package/dist/agent-generator/templates/core/skills-generator.d.ts.map +0 -1
  153. package/dist/agent-generator/templates/core/skills-generator.js +0 -546
  154. package/dist/agent-generator/templates/core/skills-generator.js.map +0 -1
  155. package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts +0 -7
  156. package/dist/agent-generator/templates/core/workflow-fix-bug.d.ts.map +0 -1
  157. package/dist/agent-generator/templates/core/workflow-fix-bug.js +0 -237
  158. package/dist/agent-generator/templates/core/workflow-fix-bug.js.map +0 -1
  159. package/dist/agent-generator/templates/core/workflow-new-feature.d.ts +0 -8
  160. package/dist/agent-generator/templates/core/workflow-new-feature.d.ts.map +0 -1
  161. package/dist/agent-generator/templates/core/workflow-new-feature.js +0 -321
  162. package/dist/agent-generator/templates/core/workflow-new-feature.js.map +0 -1
  163. package/dist/agent-generator/templates/core/workflow-review.d.ts +0 -7
  164. package/dist/agent-generator/templates/core/workflow-review.d.ts.map +0 -1
  165. package/dist/agent-generator/templates/core/workflow-review.js +0 -104
  166. package/dist/agent-generator/templates/core/workflow-review.js.map +0 -1
  167. package/dist/agent-generator/templates/domain/index.d.ts +0 -22
  168. package/dist/agent-generator/templates/domain/index.d.ts.map +0 -1
  169. package/dist/agent-generator/templates/domain/index.js +0 -1176
  170. package/dist/agent-generator/templates/domain/index.js.map +0 -1
  171. package/dist/agent-generator/templates/stack/index.d.ts +0 -8
  172. package/dist/agent-generator/templates/stack/index.d.ts.map +0 -1
  173. package/dist/agent-generator/templates/stack/index.js +0 -695
  174. package/dist/agent-generator/templates/stack/index.js.map +0 -1
  175. package/dist/agent-generator/templates/template-helpers.d.ts +0 -75
  176. package/dist/agent-generator/templates/template-helpers.d.ts.map +0 -1
  177. package/dist/agent-generator/templates/template-helpers.js +0 -726
  178. package/dist/agent-generator/templates/template-helpers.js.map +0 -1
  179. package/dist/agent-generator/types.d.ts +0 -196
  180. package/dist/agent-generator/types.d.ts.map +0 -1
  181. package/dist/agent-generator/types.js +0 -27
  182. package/dist/agent-generator/types.js.map +0 -1
  183. package/dist/analyzer.d.ts +0 -38
  184. package/dist/analyzer.d.ts.map +0 -1
  185. package/dist/analyzer.js +0 -383
  186. package/dist/analyzer.js.map +0 -1
  187. package/dist/analyzers/forecast.d.ts +0 -85
  188. package/dist/analyzers/forecast.d.ts.map +0 -1
  189. package/dist/analyzers/forecast.js +0 -337
  190. package/dist/analyzers/forecast.js.map +0 -1
  191. package/dist/analyzers/git-cache.d.ts +0 -7
  192. package/dist/analyzers/git-cache.d.ts.map +0 -1
  193. package/dist/analyzers/git-cache.js +0 -41
  194. package/dist/analyzers/git-cache.js.map +0 -1
  195. package/dist/analyzers/git-history.d.ts +0 -113
  196. package/dist/analyzers/git-history.d.ts.map +0 -1
  197. package/dist/analyzers/git-history.js +0 -333
  198. package/dist/analyzers/git-history.js.map +0 -1
  199. package/dist/analyzers/index.d.ts +0 -10
  200. package/dist/analyzers/index.d.ts.map +0 -1
  201. package/dist/analyzers/index.js +0 -7
  202. package/dist/analyzers/index.js.map +0 -1
  203. package/dist/analyzers/temporal-scorer.d.ts +0 -72
  204. package/dist/analyzers/temporal-scorer.d.ts.map +0 -1
  205. package/dist/analyzers/temporal-scorer.js +0 -140
  206. package/dist/analyzers/temporal-scorer.js.map +0 -1
  207. package/dist/anti-patterns.d.ts +0 -24
  208. package/dist/anti-patterns.d.ts.map +0 -1
  209. package/dist/anti-patterns.js +0 -230
  210. package/dist/anti-patterns.js.map +0 -1
  211. package/dist/cli.d.ts.map +0 -1
  212. package/dist/cli.js.map +0 -1
  213. package/dist/config.d.ts +0 -12
  214. package/dist/config.d.ts.map +0 -1
  215. package/dist/config.js +0 -110
  216. package/dist/config.js.map +0 -1
  217. package/dist/diagram.d.ts +0 -9
  218. package/dist/diagram.d.ts.map +0 -1
  219. package/dist/diagram.js +0 -116
  220. package/dist/diagram.js.map +0 -1
  221. package/dist/html-reporter.d.ts +0 -47
  222. package/dist/html-reporter.d.ts.map +0 -1
  223. package/dist/html-reporter.js +0 -1747
  224. package/dist/html-reporter.js.map +0 -1
  225. package/dist/index.d.ts.map +0 -1
  226. package/dist/index.js.map +0 -1
  227. package/dist/project-summarizer.d.ts +0 -38
  228. package/dist/project-summarizer.d.ts.map +0 -1
  229. package/dist/project-summarizer.js +0 -463
  230. package/dist/project-summarizer.js.map +0 -1
  231. package/dist/refactor-engine.d.ts +0 -18
  232. package/dist/refactor-engine.d.ts.map +0 -1
  233. package/dist/refactor-engine.js +0 -86
  234. package/dist/refactor-engine.js.map +0 -1
  235. package/dist/refactor-reporter.d.ts.map +0 -1
  236. package/dist/refactor-reporter.js.map +0 -1
  237. package/dist/reporter.d.ts.map +0 -1
  238. package/dist/reporter.js.map +0 -1
  239. package/dist/rules/barrel-optimizer.d.ts +0 -13
  240. package/dist/rules/barrel-optimizer.d.ts.map +0 -1
  241. package/dist/rules/barrel-optimizer.js +0 -77
  242. package/dist/rules/barrel-optimizer.js.map +0 -1
  243. package/dist/rules/dead-code-detector.d.ts +0 -21
  244. package/dist/rules/dead-code-detector.d.ts.map +0 -1
  245. package/dist/rules/dead-code-detector.js +0 -117
  246. package/dist/rules/dead-code-detector.js.map +0 -1
  247. package/dist/rules/hub-splitter.d.ts +0 -13
  248. package/dist/rules/hub-splitter.d.ts.map +0 -1
  249. package/dist/rules/hub-splitter.js +0 -110
  250. package/dist/rules/hub-splitter.js.map +0 -1
  251. package/dist/rules/import-organizer.d.ts +0 -13
  252. package/dist/rules/import-organizer.d.ts.map +0 -1
  253. package/dist/rules/import-organizer.js +0 -85
  254. package/dist/rules/import-organizer.js.map +0 -1
  255. package/dist/rules/module-grouper.d.ts +0 -13
  256. package/dist/rules/module-grouper.d.ts.map +0 -1
  257. package/dist/rules/module-grouper.js +0 -110
  258. package/dist/rules/module-grouper.js.map +0 -1
  259. package/dist/scanner.d.ts +0 -31
  260. package/dist/scanner.d.ts.map +0 -1
  261. package/dist/scanner.js +0 -328
  262. package/dist/scanner.js.map +0 -1
  263. package/dist/scorer.d.ts +0 -27
  264. package/dist/scorer.d.ts.map +0 -1
  265. package/dist/scorer.js +0 -229
  266. package/dist/scorer.js.map +0 -1
  267. package/dist/types.d.ts +0 -186
  268. package/dist/types.d.ts.map +0 -1
  269. package/dist/types.js +0 -2
  270. package/dist/types.js.map +0 -1
  271. package/examples/sample-report.md +0 -207
  272. package/jest.config.js +0 -18
  273. package/src/agent-generator/context-enricher.ts +0 -672
  274. package/src/agent-generator/domain-inferrer.ts +0 -635
  275. package/src/agent-generator/framework-detector.ts +0 -669
  276. package/src/agent-generator/index.ts +0 -634
  277. package/src/agent-generator/stack-detector.ts +0 -115
  278. package/src/agent-generator/templates/core/agents.ts +0 -1296
  279. package/src/agent-generator/templates/core/architecture-rules.ts +0 -287
  280. package/src/agent-generator/templates/core/general-rules.ts +0 -306
  281. package/src/agent-generator/templates/core/hooks-generator.ts +0 -242
  282. package/src/agent-generator/templates/core/index-md.ts +0 -260
  283. package/src/agent-generator/templates/core/orchestrator.ts +0 -459
  284. package/src/agent-generator/templates/core/preflight.ts +0 -215
  285. package/src/agent-generator/templates/core/quality-gates.ts +0 -256
  286. package/src/agent-generator/templates/core/security-rules.ts +0 -543
  287. package/src/agent-generator/templates/core/skills-generator.ts +0 -585
  288. package/src/agent-generator/templates/core/workflow-fix-bug.ts +0 -239
  289. package/src/agent-generator/templates/core/workflow-new-feature.ts +0 -323
  290. package/src/agent-generator/templates/core/workflow-review.ts +0 -106
  291. package/src/agent-generator/templates/domain/index.ts +0 -1201
  292. package/src/agent-generator/templates/stack/index.ts +0 -705
  293. package/src/agent-generator/templates/template-helpers.ts +0 -776
  294. package/src/agent-generator/types.ts +0 -232
  295. package/src/analyzer.ts +0 -447
  296. package/src/analyzers/forecast.ts +0 -496
  297. package/src/analyzers/git-cache.ts +0 -52
  298. package/src/analyzers/git-history.ts +0 -488
  299. package/src/analyzers/index.ts +0 -33
  300. package/src/analyzers/temporal-scorer.ts +0 -227
  301. package/src/anti-patterns.ts +0 -287
  302. package/src/cli.ts +0 -517
  303. package/src/config.ts +0 -123
  304. package/src/diagram.ts +0 -144
  305. package/src/html-reporter.ts +0 -1830
  306. package/src/project-summarizer.ts +0 -521
  307. package/src/refactor-engine.ts +0 -117
  308. package/src/rules/barrel-optimizer.ts +0 -97
  309. package/src/rules/dead-code-detector.ts +0 -132
  310. package/src/rules/hub-splitter.ts +0 -123
  311. package/src/rules/import-organizer.ts +0 -98
  312. package/src/rules/module-grouper.ts +0 -124
  313. package/src/scanner.ts +0 -344
  314. package/src/scorer.ts +0 -254
  315. package/src/types.ts +0 -193
  316. package/tests/agent-generator.test.ts +0 -427
  317. package/tests/analyzers-integration.test.ts +0 -174
  318. package/tests/anti-patterns.test.ts +0 -94
  319. package/tests/context-enricher.test.ts +0 -971
  320. package/tests/fixtures/monorepo/package.json +0 -6
  321. package/tests/fixtures/monorepo/packages/app/package.json +0 -12
  322. package/tests/fixtures/monorepo/packages/app/src/index.ts +0 -6
  323. package/tests/fixtures/monorepo/packages/core/package.json +0 -7
  324. package/tests/fixtures/monorepo/packages/core/src/index.ts +0 -7
  325. package/tests/forecast.test.ts +0 -509
  326. package/tests/framework-detector.test.ts +0 -1172
  327. package/tests/git-history.test.ts +0 -254
  328. package/tests/monorepo-scan.test.ts +0 -170
  329. package/tests/scanner.test.ts +0 -54
  330. package/tests/scorer.test.ts +0 -674
  331. package/tests/stack-detector.test.ts +0 -241
  332. package/tests/template-generation.test.ts +0 -706
  333. package/tests/template-helpers.test.ts +0 -1152
  334. package/tests/temporal-scorer.test.ts +0 -307
  335. /package/dist/{reporter.js → src/adapters/reporter.js} +0 -0
@@ -1,971 +0,0 @@
1
- import { ContextEnricher } from '../src/agent-generator/context-enricher.js';
2
- import { AnalysisReport, RefactoringPlan } from '../src/types.js';
3
- import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from 'fs';
4
- import { join } from 'path';
5
-
6
- // ── Test Data Factories ──
7
-
8
- function makeReport(overrides: Partial<AnalysisReport> = {}): AnalysisReport {
9
- return {
10
- timestamp: new Date().toISOString(),
11
- projectInfo: {
12
- path: '/test',
13
- name: 'test-project',
14
- frameworks: ['NestJS'],
15
- totalFiles: 50,
16
- totalLines: 5000,
17
- primaryLanguages: ['TypeScript'],
18
- },
19
- score: {
20
- overall: 72,
21
- components: [],
22
- breakdown: { modularity: 80, coupling: 65, cohesion: 70, layering: 75 },
23
- },
24
- antiPatterns: [
25
- {
26
- name: 'God Class',
27
- severity: 'CRITICAL',
28
- location: 'src/AppService.ts',
29
- description: 'Class with 800 lines',
30
- suggestion: 'Split into smaller services',
31
- affectedFiles: ['src/AppService.ts'],
32
- },
33
- ],
34
- layers: [
35
- { name: 'API', files: ['src/controller.ts'], description: 'API layer' },
36
- { name: 'Service', files: ['src/service.ts'], description: 'Service layer' },
37
- ],
38
- dependencyGraph: {
39
- nodes: ['src/app.module.ts', 'src/app.controller.ts', 'src/app.service.ts', 'src/entity/user.entity.ts'],
40
- edges: [
41
- { from: 'src/app.controller.ts', to: 'src/app.service.ts', type: 'import', weight: 1 },
42
- { from: 'src/app.service.ts', to: 'src/entity/user.entity.ts', type: 'import', weight: 1 },
43
- ],
44
- },
45
- suggestions: [],
46
- diagram: { mermaid: '', type: 'layer' },
47
- ...overrides,
48
- };
49
- }
50
-
51
- function makePlan(overrides: Partial<RefactoringPlan> = {}): RefactoringPlan {
52
- return {
53
- timestamp: new Date().toISOString(),
54
- projectPath: '/test',
55
- currentScore: {
56
- overall: 72,
57
- components: [],
58
- breakdown: { modularity: 80, coupling: 65, cohesion: 70, layering: 75 },
59
- },
60
- estimatedScoreAfter: { overall: 82, breakdown: { modularity: 85, coupling: 75, cohesion: 80, layering: 80 } },
61
- steps: [
62
- {
63
- id: 1,
64
- tier: 1,
65
- rule: 'hub-splitter',
66
- priority: 'HIGH',
67
- title: 'Split AppService',
68
- description: 'Split monolith service',
69
- rationale: 'Reduce coupling',
70
- operations: [],
71
- scoreImpact: [{ metric: 'modularity', before: 80, after: 85 }],
72
- },
73
- ],
74
- totalOperations: 1,
75
- tier1Steps: 1,
76
- tier2Steps: 0,
77
- ...overrides,
78
- };
79
- }
80
-
81
- // ── Test Suite ──
82
-
83
- describe('ContextEnricher', () => {
84
- const enricher = new ContextEnricher();
85
- let tempDir: string;
86
-
87
- beforeEach(() => {
88
- tempDir = mkdtempSync(join(process.cwd(), '__test_context_'));
89
- });
90
-
91
- afterEach(() => {
92
- if (tempDir) {
93
- rmSync(tempDir, { recursive: true, force: true });
94
- }
95
- });
96
-
97
- describe('enrich()', () => {
98
- it('should return a valid EnrichedTemplateContext', () => {
99
- const report = makeReport();
100
- const plan = makePlan();
101
-
102
- const result = enricher.enrich(report, plan, {
103
- primary: 'TypeScript',
104
- languages: ['TypeScript'],
105
- frameworks: ['NestJS'],
106
- hasBackend: true,
107
- hasFrontend: false,
108
- hasMobile: false,
109
- hasDatabase: true,
110
- testFramework: 'Jest',
111
- packageManager: 'npm',
112
- }, tempDir);
113
-
114
- expect(result).toBeDefined();
115
- expect(result.report).toBe(report);
116
- expect(result.plan).toBe(plan);
117
- expect(result.projectName).toBe('test-project');
118
- expect(result.modules).toBeDefined();
119
- expect(result.endpoints).toBeDefined();
120
- expect(result.untestedModules).toBeDefined();
121
- expect(result.criticalPaths).toBeDefined();
122
- expect(result.projectDepth).toBeDefined();
123
- });
124
-
125
- it('should detect modules from dependency graph nodes', () => {
126
- const report = makeReport({
127
- dependencyGraph: {
128
- nodes: [
129
- 'src/modules/users/users.controller.ts',
130
- 'src/modules/users/users.service.ts',
131
- 'src/modules/users/user.entity.ts',
132
- 'src/modules/auth/auth.controller.ts',
133
- 'src/modules/auth/auth.service.ts',
134
- ],
135
- edges: [],
136
- },
137
- });
138
- const plan = makePlan();
139
-
140
- const result = enricher.enrich(report, plan, {
141
- primary: 'TypeScript',
142
- languages: ['TypeScript'],
143
- frameworks: ['NestJS'],
144
- hasBackend: true,
145
- hasFrontend: false,
146
- hasMobile: false,
147
- hasDatabase: true,
148
- testFramework: 'Jest',
149
- packageManager: 'npm',
150
- }, tempDir);
151
-
152
- expect(result.modules.length).toBeGreaterThan(0);
153
- const moduleNames = result.modules.map(m => m.name);
154
- expect(moduleNames).toContain('users');
155
- expect(moduleNames).toContain('auth');
156
- });
157
-
158
- it('should extract modules sorted by file count descending', () => {
159
- const report = makeReport({
160
- dependencyGraph: {
161
- nodes: [
162
- 'src/modules/users/users.controller.ts',
163
- 'src/modules/users/users.service.ts',
164
- 'src/modules/users/user.entity.ts',
165
- 'src/modules/auth/auth.controller.ts',
166
- ],
167
- edges: [],
168
- },
169
- });
170
- const plan = makePlan();
171
-
172
- const result = enricher.enrich(report, plan, {
173
- primary: 'TypeScript',
174
- languages: ['TypeScript'],
175
- frameworks: ['NestJS'],
176
- hasBackend: true,
177
- hasFrontend: false,
178
- hasMobile: false,
179
- hasDatabase: true,
180
- testFramework: 'Jest',
181
- packageManager: 'npm',
182
- }, tempDir);
183
-
184
- // Users has 3 files, auth has 1 file → users should come first
185
- expect(result.modules[0].name).toBe('users');
186
- expect(result.modules[0].fileCount).toBe(3);
187
- });
188
-
189
- it('should generate smart descriptions for known patterns', () => {
190
- const report = makeReport({
191
- dependencyGraph: {
192
- nodes: [
193
- 'src/modules/extractors/pdf.extractor.ts',
194
- 'src/modules/extractors/image.extractor.ts',
195
- 'src/modules/ocr/ocr.service.ts',
196
- 'src/modules/guards/auth.guard.ts',
197
- ],
198
- edges: [],
199
- },
200
- });
201
- const plan = makePlan();
202
-
203
- const result = enricher.enrich(report, plan, {
204
- primary: 'TypeScript',
205
- languages: ['TypeScript'],
206
- frameworks: ['NestJS'],
207
- hasBackend: true,
208
- hasFrontend: false,
209
- hasMobile: false,
210
- hasDatabase: true,
211
- testFramework: 'Jest',
212
- packageManager: 'npm',
213
- }, tempDir);
214
-
215
- const extractorsModule = result.modules.find(m => m.name === 'extractors');
216
- expect(extractorsModule).toBeDefined();
217
- expect(extractorsModule!.description).toContain('Extração');
218
-
219
- const ocrModule = result.modules.find(m => m.name === 'ocr');
220
- expect(ocrModule).toBeDefined();
221
- expect(ocrModule!.description).toContain('OCR');
222
-
223
- const guardsModule = result.modules.find(m => m.name === 'guards');
224
- expect(guardsModule).toBeDefined();
225
- expect(guardsModule!.description).toContain('Validação');
226
- });
227
-
228
- it('should count lines for real files', () => {
229
- // Create a temp file with 10 lines
230
- const subdir = join(tempDir, 'src', 'modules', 'test');
231
- mkdirSync(subdir, { recursive: true });
232
- const filePath = join(subdir, 'test.ts');
233
- const content = Array(10).fill('console.log("test");').join('\n');
234
- writeFileSync(filePath, content);
235
-
236
- const report = makeReport({
237
- dependencyGraph: {
238
- nodes: ['src/modules/test/test.ts'],
239
- edges: [],
240
- },
241
- });
242
- const plan = makePlan();
243
-
244
- const result = enricher.enrich(report, plan, {
245
- primary: 'TypeScript',
246
- languages: ['TypeScript'],
247
- frameworks: ['NestJS'],
248
- hasBackend: true,
249
- hasFrontend: false,
250
- hasMobile: false,
251
- hasDatabase: true,
252
- testFramework: 'Jest',
253
- packageManager: 'npm',
254
- }, tempDir);
255
-
256
- const testModule = result.modules.find(m => m.name === 'test');
257
- expect(testModule).toBeDefined();
258
- expect(testModule!.lineCount).toBeGreaterThan(0);
259
- });
260
-
261
- it('should detect test files in modules', () => {
262
- const report = makeReport({
263
- dependencyGraph: {
264
- nodes: [
265
- 'src/modules/users/users.service.ts',
266
- 'src/modules/users/users.service.test.ts',
267
- 'src/modules/users/__tests__/users.spec.ts',
268
- ],
269
- edges: [],
270
- },
271
- });
272
- const plan = makePlan();
273
-
274
- const result = enricher.enrich(report, plan, {
275
- primary: 'TypeScript',
276
- languages: ['TypeScript'],
277
- frameworks: ['NestJS'],
278
- hasBackend: true,
279
- hasFrontend: false,
280
- hasMobile: false,
281
- hasDatabase: true,
282
- testFramework: 'Jest',
283
- packageManager: 'npm',
284
- }, tempDir);
285
-
286
- const usersModule = result.modules.find(m => m.name === 'users');
287
- expect(usersModule).toBeDefined();
288
- expect(usersModule!.hasTests).toBe(true);
289
- expect(usersModule!.testFiles.length).toBe(2);
290
- });
291
-
292
- it('should extract endpoints from route/controller files', () => {
293
- const report = makeReport({
294
- dependencyGraph: {
295
- nodes: [
296
- 'src/modules/users/users.controller.ts',
297
- 'src/modules/users/users.service.ts',
298
- 'src/auth/auth.controller.ts',
299
- 'src/health/health.controller.ts',
300
- ],
301
- edges: [
302
- { from: 'src/modules/users/users.controller.ts', to: 'src/modules/users/users.service.ts', type: 'import', weight: 1 },
303
- { from: 'src/auth/auth.controller.ts', to: 'src/dependencies/auth.guard.ts', type: 'import', weight: 1 },
304
- ],
305
- },
306
- });
307
- const plan = makePlan();
308
-
309
- const result = enricher.enrich(report, plan, {
310
- primary: 'TypeScript',
311
- languages: ['TypeScript'],
312
- frameworks: ['NestJS'],
313
- hasBackend: true,
314
- hasFrontend: false,
315
- hasMobile: false,
316
- hasDatabase: true,
317
- testFramework: 'Jest',
318
- packageManager: 'npm',
319
- }, tempDir);
320
-
321
- expect(result.endpoints.length).toBeGreaterThan(0);
322
- // Should detect users endpoints
323
- const userEndpoints = result.endpoints.filter(e => e.path.includes('users'));
324
- expect(userEndpoints.length).toBeGreaterThan(0);
325
- });
326
-
327
- it('should detect endpoints with authentication', () => {
328
- const report = makeReport({
329
- dependencyGraph: {
330
- nodes: [
331
- 'src/auth/auth.controller.ts',
332
- 'src/dependencies/auth.guard.ts',
333
- ],
334
- edges: [
335
- { from: 'src/auth/auth.controller.ts', to: 'src/dependencies/auth.guard.ts', type: 'import', weight: 1 },
336
- ],
337
- },
338
- });
339
- const plan = makePlan();
340
-
341
- const result = enricher.enrich(report, plan, {
342
- primary: 'TypeScript',
343
- languages: ['TypeScript'],
344
- frameworks: ['NestJS'],
345
- hasBackend: true,
346
- hasFrontend: false,
347
- hasMobile: false,
348
- hasDatabase: true,
349
- testFramework: 'Jest',
350
- packageManager: 'npm',
351
- }, tempDir);
352
-
353
- const authEndpoints = result.endpoints.filter(e => e.path.includes('auth'));
354
- expect(authEndpoints.length).toBeGreaterThan(0);
355
- // Auth endpoints should be marked as no auth (login/register are public)
356
- const loginEndpoint = authEndpoints.find(e => e.path === '/auth/login');
357
- expect(loginEndpoint).toBeDefined();
358
- expect(loginEndpoint!.hasAuth).toBe(false);
359
- });
360
-
361
- it('should detect untested modules', () => {
362
- const report = makeReport({
363
- dependencyGraph: {
364
- nodes: [
365
- 'src/modules/users/users.service.ts',
366
- 'src/modules/users/users.controller.ts',
367
- 'src/modules/notested/service.ts',
368
- 'src/modules/notested/handler.ts',
369
- ],
370
- edges: [],
371
- },
372
- });
373
- const plan = makePlan();
374
-
375
- const result = enricher.enrich(report, plan, {
376
- primary: 'TypeScript',
377
- languages: ['TypeScript'],
378
- frameworks: ['NestJS'],
379
- hasBackend: true,
380
- hasFrontend: false,
381
- hasMobile: false,
382
- hasDatabase: true,
383
- testFramework: 'Jest',
384
- packageManager: 'npm',
385
- }, tempDir);
386
-
387
- expect(result.untestedModules).toContain('notested');
388
- });
389
-
390
- it('should identify critical paths (files with high coupling)', () => {
391
- const report = makeReport({
392
- dependencyGraph: {
393
- nodes: [
394
- 'src/app.module.ts',
395
- 'src/app.controller.ts',
396
- 'src/app.service.ts',
397
- 'src/users/user.service.ts',
398
- 'src/auth/auth.service.ts',
399
- ],
400
- edges: [
401
- { from: 'src/app.module.ts', to: 'src/app.controller.ts', type: 'import', weight: 1 },
402
- { from: 'src/app.module.ts', to: 'src/app.service.ts', type: 'import', weight: 1 },
403
- { from: 'src/app.module.ts', to: 'src/users/user.service.ts', type: 'import', weight: 1 },
404
- { from: 'src/app.module.ts', to: 'src/auth/auth.service.ts', type: 'import', weight: 1 },
405
- { from: 'src/app.controller.ts', to: 'src/app.service.ts', type: 'import', weight: 1 },
406
- ],
407
- },
408
- });
409
- const plan = makePlan();
410
-
411
- const result = enricher.enrich(report, plan, {
412
- primary: 'TypeScript',
413
- languages: ['TypeScript'],
414
- frameworks: ['NestJS'],
415
- hasBackend: true,
416
- hasFrontend: false,
417
- hasMobile: false,
418
- hasDatabase: true,
419
- testFramework: 'Jest',
420
- packageManager: 'npm',
421
- }, tempDir);
422
-
423
- expect(result.criticalPaths.length).toBeGreaterThan(0);
424
- // app.module.ts should be in critical paths (4 edges)
425
- expect(result.criticalPaths).toContain('src/app.module.ts');
426
- });
427
-
428
- it('should classify project depth as small', () => {
429
- const report = makeReport({
430
- projectInfo: {
431
- path: '/test',
432
- name: 'small-project',
433
- frameworks: ['NestJS'],
434
- totalFiles: 10,
435
- totalLines: 1000,
436
- primaryLanguages: ['TypeScript'],
437
- },
438
- dependencyGraph: {
439
- nodes: [],
440
- edges: [],
441
- },
442
- });
443
- const plan = makePlan();
444
-
445
- const result = enricher.enrich(report, plan, {
446
- primary: 'TypeScript',
447
- languages: ['TypeScript'],
448
- frameworks: ['NestJS'],
449
- hasBackend: true,
450
- hasFrontend: false,
451
- hasMobile: false,
452
- hasDatabase: true,
453
- testFramework: 'Jest',
454
- packageManager: 'npm',
455
- }, tempDir);
456
-
457
- expect(result.projectDepth).toBe('small');
458
- });
459
-
460
- it('should classify project depth as medium', () => {
461
- const report = makeReport({
462
- projectInfo: {
463
- path: '/test',
464
- name: 'medium-project',
465
- frameworks: ['NestJS'],
466
- totalFiles: 150,
467
- totalLines: 30000,
468
- primaryLanguages: ['TypeScript'],
469
- },
470
- dependencyGraph: {
471
- nodes: [],
472
- edges: [],
473
- },
474
- });
475
- const plan = makePlan();
476
-
477
- const result = enricher.enrich(report, plan, {
478
- primary: 'TypeScript',
479
- languages: ['TypeScript'],
480
- frameworks: ['NestJS'],
481
- hasBackend: true,
482
- hasFrontend: false,
483
- hasMobile: false,
484
- hasDatabase: true,
485
- testFramework: 'Jest',
486
- packageManager: 'npm',
487
- }, tempDir);
488
-
489
- expect(result.projectDepth).toBe('medium');
490
- });
491
-
492
- it('should classify project depth as large', () => {
493
- const report = makeReport({
494
- projectInfo: {
495
- path: '/test',
496
- name: 'large-project',
497
- frameworks: ['NestJS'],
498
- totalFiles: 300,
499
- totalLines: 70000,
500
- primaryLanguages: ['TypeScript'],
501
- },
502
- dependencyGraph: {
503
- nodes: [],
504
- edges: [],
505
- },
506
- });
507
- const plan = makePlan();
508
-
509
- const result = enricher.enrich(report, plan, {
510
- primary: 'TypeScript',
511
- languages: ['TypeScript'],
512
- frameworks: ['NestJS'],
513
- hasBackend: true,
514
- hasFrontend: false,
515
- hasMobile: false,
516
- hasDatabase: true,
517
- testFramework: 'Jest',
518
- packageManager: 'npm',
519
- }, tempDir);
520
-
521
- expect(result.projectDepth).toBe('large');
522
- });
523
-
524
- it('should classify project depth as enterprise', () => {
525
- const report = makeReport({
526
- projectInfo: {
527
- path: '/test',
528
- name: 'enterprise-project',
529
- frameworks: ['NestJS'],
530
- totalFiles: 1000,
531
- totalLines: 150000,
532
- primaryLanguages: ['TypeScript'],
533
- },
534
- dependencyGraph: {
535
- nodes: [],
536
- edges: [],
537
- },
538
- });
539
- const plan = makePlan();
540
-
541
- const result = enricher.enrich(report, plan, {
542
- primary: 'TypeScript',
543
- languages: ['TypeScript'],
544
- frameworks: ['NestJS'],
545
- hasBackend: true,
546
- hasFrontend: false,
547
- hasMobile: false,
548
- hasDatabase: true,
549
- testFramework: 'Jest',
550
- packageManager: 'npm',
551
- }, tempDir);
552
-
553
- expect(result.projectDepth).toBe('enterprise');
554
- });
555
- });
556
-
557
- describe('Module inference strategies', () => {
558
- it('should infer module name from explicit module markers', () => {
559
- const report = makeReport({
560
- dependencyGraph: {
561
- nodes: [
562
- 'src/modules/users/users.service.ts',
563
- 'src/modules/auth/auth.service.ts',
564
- 'src/features/notifications/notifier.ts',
565
- ],
566
- edges: [],
567
- },
568
- });
569
- const plan = makePlan();
570
-
571
- const result = enricher.enrich(report, plan, {
572
- primary: 'TypeScript',
573
- languages: ['TypeScript'],
574
- frameworks: ['NestJS'],
575
- hasBackend: true,
576
- hasFrontend: false,
577
- hasMobile: false,
578
- hasDatabase: true,
579
- testFramework: 'Jest',
580
- packageManager: 'npm',
581
- }, tempDir);
582
-
583
- const moduleNames = result.modules.map(m => m.name);
584
- expect(moduleNames).toContain('users');
585
- expect(moduleNames).toContain('auth');
586
- expect(moduleNames).toContain('notifications');
587
- });
588
-
589
- it('should infer module name from Django app pattern', () => {
590
- const report = makeReport({
591
- dependencyGraph: {
592
- nodes: [
593
- 'apps/users/views.py',
594
- 'apps/users/models.py',
595
- 'apps/posts/views.py',
596
- ],
597
- edges: [],
598
- },
599
- });
600
- const plan = makePlan();
601
-
602
- const result = enricher.enrich(report, plan, {
603
- primary: 'Python',
604
- languages: ['Python'],
605
- frameworks: ['Django'],
606
- hasBackend: true,
607
- hasFrontend: false,
608
- hasMobile: false,
609
- hasDatabase: true,
610
- testFramework: 'pytest',
611
- packageManager: 'pip',
612
- }, tempDir);
613
-
614
- const moduleNames = result.modules.map(m => m.name);
615
- expect(moduleNames).toContain('users');
616
- expect(moduleNames).toContain('posts');
617
- });
618
-
619
- it('should infer module name from clean architecture layers', () => {
620
- const report = makeReport({
621
- dependencyGraph: {
622
- nodes: [
623
- 'src/domain/entities/user.entity.ts',
624
- 'src/application/services/user.service.ts',
625
- 'src/infrastructure/persistence/user.repository.ts',
626
- ],
627
- edges: [],
628
- },
629
- });
630
- const plan = makePlan();
631
-
632
- const result = enricher.enrich(report, plan, {
633
- primary: 'TypeScript',
634
- languages: ['TypeScript'],
635
- frameworks: ['NestJS'],
636
- hasBackend: true,
637
- hasFrontend: false,
638
- hasMobile: false,
639
- hasDatabase: true,
640
- testFramework: 'Jest',
641
- packageManager: 'npm',
642
- }, tempDir);
643
-
644
- // Should infer modules related to user entity
645
- expect(result.modules.length).toBeGreaterThan(0);
646
- });
647
-
648
- it('should handle Java package structure', () => {
649
- const report = makeReport({
650
- dependencyGraph: {
651
- nodes: [
652
- 'src/main/java/com/example/users/User.java',
653
- 'src/main/java/com/example/users/UserService.java',
654
- 'src/main/java/com/example/auth/AuthService.java',
655
- ],
656
- edges: [],
657
- },
658
- });
659
- const plan = makePlan();
660
-
661
- const result = enricher.enrich(report, plan, {
662
- primary: 'Java',
663
- languages: ['Java'],
664
- frameworks: ['Spring Boot'],
665
- hasBackend: true,
666
- hasFrontend: false,
667
- hasMobile: false,
668
- hasDatabase: true,
669
- testFramework: 'JUnit',
670
- packageManager: 'maven',
671
- }, tempDir);
672
-
673
- const moduleNames = result.modules.map(m => m.name);
674
- expect(moduleNames.length).toBeGreaterThan(0);
675
- });
676
- });
677
-
678
- describe('Entity and controller detection', () => {
679
- it('should detect entity files', () => {
680
- const report = makeReport({
681
- dependencyGraph: {
682
- nodes: [
683
- 'src/modules/users/entities/user.entity.ts',
684
- 'src/modules/users/models/user.model.ts',
685
- 'src/modules/users/user.service.ts',
686
- ],
687
- edges: [],
688
- },
689
- });
690
- const plan = makePlan();
691
-
692
- const result = enricher.enrich(report, plan, {
693
- primary: 'TypeScript',
694
- languages: ['TypeScript'],
695
- frameworks: ['NestJS'],
696
- hasBackend: true,
697
- hasFrontend: false,
698
- hasMobile: false,
699
- hasDatabase: true,
700
- testFramework: 'Jest',
701
- packageManager: 'npm',
702
- }, tempDir);
703
-
704
- const usersModule = result.modules.find(m => m.name === 'users');
705
- expect(usersModule).toBeDefined();
706
- expect(usersModule!.entities.length).toBeGreaterThan(0);
707
- expect(usersModule!.entities.some(e => e.includes('User'))).toBe(true);
708
- });
709
-
710
- it('should detect controller files', () => {
711
- const report = makeReport({
712
- dependencyGraph: {
713
- nodes: [
714
- 'src/modules/users/users.controller.ts',
715
- 'src/modules/auth/auth.controller.ts',
716
- 'src/modules/users/users.service.ts',
717
- ],
718
- edges: [],
719
- },
720
- });
721
- const plan = makePlan();
722
-
723
- const result = enricher.enrich(report, plan, {
724
- primary: 'TypeScript',
725
- languages: ['TypeScript'],
726
- frameworks: ['NestJS'],
727
- hasBackend: true,
728
- hasFrontend: false,
729
- hasMobile: false,
730
- hasDatabase: true,
731
- testFramework: 'Jest',
732
- packageManager: 'npm',
733
- }, tempDir);
734
-
735
- const usersModule = result.modules.find(m => m.name === 'users');
736
- expect(usersModule).toBeDefined();
737
- expect(usersModule!.controllers.length).toBeGreaterThan(0);
738
- });
739
-
740
- it('should detect service files', () => {
741
- const report = makeReport({
742
- dependencyGraph: {
743
- nodes: [
744
- 'src/modules/users/users.service.ts',
745
- 'src/modules/auth/auth.service.ts',
746
- 'src/modules/users/users.controller.ts',
747
- ],
748
- edges: [],
749
- },
750
- });
751
- const plan = makePlan();
752
-
753
- const result = enricher.enrich(report, plan, {
754
- primary: 'TypeScript',
755
- languages: ['TypeScript'],
756
- frameworks: ['NestJS'],
757
- hasBackend: true,
758
- hasFrontend: false,
759
- hasMobile: false,
760
- hasDatabase: true,
761
- testFramework: 'Jest',
762
- packageManager: 'npm',
763
- }, tempDir);
764
-
765
- const usersModule = result.modules.find(m => m.name === 'users');
766
- expect(usersModule).toBeDefined();
767
- expect(usersModule!.services.length).toBeGreaterThan(0);
768
- });
769
- });
770
-
771
- describe('Smart descriptions for patterns', () => {
772
- it('should generate description for routes/controllers', () => {
773
- const report = makeReport({
774
- dependencyGraph: {
775
- nodes: ['src/modules/routes/app.routes.ts'],
776
- edges: [],
777
- },
778
- });
779
- const plan = makePlan();
780
-
781
- const result = enricher.enrich(report, plan, {
782
- primary: 'TypeScript',
783
- languages: ['TypeScript'],
784
- frameworks: ['NestJS'],
785
- hasBackend: true,
786
- hasFrontend: false,
787
- hasMobile: false,
788
- hasDatabase: true,
789
- testFramework: 'Jest',
790
- packageManager: 'npm',
791
- }, tempDir);
792
-
793
- const routesModule = result.modules.find(m => m.name === 'routes');
794
- expect(routesModule).toBeDefined();
795
- expect(routesModule!.description).toContain('rotas');
796
- });
797
-
798
- it('should generate description for services', () => {
799
- const report = makeReport({
800
- dependencyGraph: {
801
- nodes: ['src/modules/services/payment.service.ts'],
802
- edges: [],
803
- },
804
- });
805
- const plan = makePlan();
806
-
807
- const result = enricher.enrich(report, plan, {
808
- primary: 'TypeScript',
809
- languages: ['TypeScript'],
810
- frameworks: ['NestJS'],
811
- hasBackend: true,
812
- hasFrontend: false,
813
- hasMobile: false,
814
- hasDatabase: true,
815
- testFramework: 'Jest',
816
- packageManager: 'npm',
817
- }, tempDir);
818
-
819
- const servicesModule = result.modules.find(m => m.name === 'services');
820
- expect(servicesModule).toBeDefined();
821
- expect(servicesModule!.description).toContain('Serviços');
822
- });
823
-
824
- it('should generate description for auth modules', () => {
825
- const report = makeReport({
826
- dependencyGraph: {
827
- nodes: ['src/modules/auth/auth.service.ts'],
828
- edges: [],
829
- },
830
- });
831
- const plan = makePlan();
832
-
833
- const result = enricher.enrich(report, plan, {
834
- primary: 'TypeScript',
835
- languages: ['TypeScript'],
836
- frameworks: ['NestJS'],
837
- hasBackend: true,
838
- hasFrontend: false,
839
- hasMobile: false,
840
- hasDatabase: true,
841
- testFramework: 'Jest',
842
- packageManager: 'npm',
843
- }, tempDir);
844
-
845
- const authModule = result.modules.find(m => m.name === 'auth');
846
- expect(authModule).toBeDefined();
847
- expect(authModule!.description.toLowerCase()).toContain('autenticação');
848
- });
849
-
850
- it('should include composition info in descriptions', () => {
851
- const report = makeReport({
852
- dependencyGraph: {
853
- nodes: [
854
- 'src/modules/users/users.controller.ts',
855
- 'src/modules/users/users.service.ts',
856
- 'src/modules/users/entities/user.entity.ts',
857
- ],
858
- edges: [],
859
- },
860
- });
861
- const plan = makePlan();
862
-
863
- const result = enricher.enrich(report, plan, {
864
- primary: 'TypeScript',
865
- languages: ['TypeScript'],
866
- frameworks: ['NestJS'],
867
- hasBackend: true,
868
- hasFrontend: false,
869
- hasMobile: false,
870
- hasDatabase: true,
871
- testFramework: 'Jest',
872
- packageManager: 'npm',
873
- }, tempDir);
874
-
875
- const usersModule = result.modules.find(m => m.name === 'users');
876
- expect(usersModule).toBeDefined();
877
- // Should include composition info (endpoints, services, entities)
878
- expect(usersModule!.description).toMatch(/endpoint|service|entit/i);
879
- });
880
- });
881
-
882
- describe('Line counting edge cases', () => {
883
- it('should handle missing files gracefully', () => {
884
- const report = makeReport({
885
- dependencyGraph: {
886
- nodes: ['src/nonexistent/file.ts'],
887
- edges: [],
888
- },
889
- });
890
- const plan = makePlan();
891
-
892
- const result = enricher.enrich(report, plan, {
893
- primary: 'TypeScript',
894
- languages: ['TypeScript'],
895
- frameworks: ['NestJS'],
896
- hasBackend: true,
897
- hasFrontend: false,
898
- hasMobile: false,
899
- hasDatabase: true,
900
- testFramework: 'Jest',
901
- packageManager: 'npm',
902
- }, tempDir);
903
-
904
- // Should not crash, modules should exist
905
- expect(result.modules).toBeDefined();
906
- });
907
-
908
- it('should handle empty files', () => {
909
- const subdir = join(tempDir, 'src', 'modules', 'empty');
910
- mkdirSync(subdir, { recursive: true });
911
- const filePath = join(subdir, 'empty.ts');
912
- writeFileSync(filePath, '');
913
-
914
- const report = makeReport({
915
- dependencyGraph: {
916
- nodes: ['src/modules/empty/empty.ts'],
917
- edges: [],
918
- },
919
- });
920
- const plan = makePlan();
921
-
922
- const result = enricher.enrich(report, plan, {
923
- primary: 'TypeScript',
924
- languages: ['TypeScript'],
925
- frameworks: ['NestJS'],
926
- hasBackend: true,
927
- hasFrontend: false,
928
- hasMobile: false,
929
- hasDatabase: true,
930
- testFramework: 'Jest',
931
- packageManager: 'npm',
932
- }, tempDir);
933
-
934
- const emptyModule = result.modules.find(m => m.name === 'empty');
935
- expect(emptyModule).toBeDefined();
936
- expect(emptyModule!.lineCount).toBe(0);
937
- });
938
-
939
- it('should count lines in files with various line endings', () => {
940
- const subdir = join(tempDir, 'src', 'modules', 'mixed');
941
- mkdirSync(subdir, { recursive: true });
942
- const filePath = join(subdir, 'mixed.ts');
943
- // 5 lines
944
- writeFileSync(filePath, 'line1\nline2\nline3\nline4\nline5');
945
-
946
- const report = makeReport({
947
- dependencyGraph: {
948
- nodes: ['src/modules/mixed/mixed.ts'],
949
- edges: [],
950
- },
951
- });
952
- const plan = makePlan();
953
-
954
- const result = enricher.enrich(report, plan, {
955
- primary: 'TypeScript',
956
- languages: ['TypeScript'],
957
- frameworks: ['NestJS'],
958
- hasBackend: true,
959
- hasFrontend: false,
960
- hasMobile: false,
961
- hasDatabase: true,
962
- testFramework: 'Jest',
963
- packageManager: 'npm',
964
- }, tempDir);
965
-
966
- const mixedModule = result.modules.find(m => m.name === 'mixed');
967
- expect(mixedModule).toBeDefined();
968
- expect(mixedModule!.lineCount).toBeGreaterThan(0);
969
- });
970
- });
971
- });