@atlashub/smartstack-cli 3.36.0 → 3.38.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 (219) hide show
  1. package/dist/index.js +16 -24
  2. package/dist/index.js.map +1 -1
  3. package/dist/mcp-entry.mjs +201 -256
  4. package/dist/mcp-entry.mjs.map +1 -1
  5. package/package.json +3 -2
  6. package/scripts/extract-api-endpoints.ts +325 -0
  7. package/scripts/extract-business-rules.ts +440 -0
  8. package/scripts/generate-doc-with-mock-ui.ts +804 -0
  9. package/scripts/health-check.sh +168 -0
  10. package/scripts/postinstall.js +18 -0
  11. package/templates/agents/ba-reader.md +9 -9
  12. package/templates/agents/ba-writer.md +12 -15
  13. package/templates/agents/code-reviewer.md +1 -1
  14. package/templates/agents/docs-context-reader.md +1 -1
  15. package/templates/agents/gitflow/merge.md +0 -4
  16. package/templates/agents/gitflow/pr.md +0 -4
  17. package/templates/agents/gitflow/start.md +30 -5
  18. package/templates/mcp-scaffolding/frontend/nav-routes.ts.hbs +20 -20
  19. package/templates/mcp-scaffolding/frontend/routes.tsx.hbs +16 -24
  20. package/templates/mcp-scaffolding/migrations/seed-roles.cs.hbs +2 -2
  21. package/templates/skills/_resources/mcp-validate-documentation-spec.md +3 -3
  22. package/templates/skills/_shared.md +15 -17
  23. package/templates/skills/ai-prompt/SKILL.md +1 -1
  24. package/templates/skills/ai-prompt/steps/step-00-init.md +47 -0
  25. package/templates/skills/apex/SKILL.md +3 -4
  26. package/templates/skills/apex/_shared.md +10 -20
  27. package/templates/skills/apex/references/analysis-methods.md +141 -0
  28. package/templates/skills/apex/references/challenge-questions.md +1 -21
  29. package/templates/skills/apex/references/core-seed-data.md +35 -57
  30. package/templates/skills/apex/references/examine-build-validation.md +87 -0
  31. package/templates/skills/apex/references/execution-frontend-gates.md +177 -0
  32. package/templates/skills/apex/references/execution-frontend-patterns.md +105 -0
  33. package/templates/skills/apex/references/execution-layer1-rules.md +96 -0
  34. package/templates/skills/apex/references/initialization-challenge-flow.md +110 -0
  35. package/templates/skills/apex/references/planning-layer-mapping.md +151 -0
  36. package/templates/skills/apex/references/post-checks.md +145 -40
  37. package/templates/skills/apex/references/smartstack-api.md +35 -51
  38. package/templates/skills/apex/references/smartstack-frontend.md +17 -17
  39. package/templates/skills/apex/references/smartstack-layers.md +38 -62
  40. package/templates/skills/apex/steps/step-00-init.md +14 -26
  41. package/templates/skills/apex/steps/step-01-analyze.md +10 -143
  42. package/templates/skills/apex/steps/step-02-plan.md +10 -92
  43. package/templates/skills/apex/steps/step-03-execute.md +47 -249
  44. package/templates/skills/apex/steps/step-04-examine.md +14 -78
  45. package/templates/skills/apex/steps/step-05-deep-review.md +2 -2
  46. package/templates/skills/apex/steps/step-08-run-tests.md +2 -0
  47. package/templates/skills/application/SKILL.md +6 -7
  48. package/templates/skills/application/references/backend-controller-hierarchy.md +16 -16
  49. package/templates/skills/application/references/backend-seeding-and-dto-output.md +83 -0
  50. package/templates/skills/application/references/backend-table-prefix-mapping.md +79 -0
  51. package/templates/skills/application/references/backend-verification.md +1 -1
  52. package/templates/skills/application/references/frontend-i18n-and-output.md +67 -0
  53. package/templates/skills/application/references/frontend-route-naming.md +117 -0
  54. package/templates/skills/application/references/frontend-route-wiring-app-tsx.md +107 -0
  55. package/templates/skills/application/references/frontend-verification.md +12 -12
  56. package/templates/skills/application/references/init-parameter-detection.md +120 -0
  57. package/templates/skills/application/references/migration-checklist-troubleshooting.md +100 -0
  58. package/templates/skills/application/references/nav-fallback-procedure.md +5 -6
  59. package/templates/skills/application/references/provider-template.md +2 -6
  60. package/templates/skills/application/references/roles-client-project-handling.md +55 -0
  61. package/templates/skills/application/references/roles-fallback-procedure.md +149 -0
  62. package/templates/skills/application/references/test-coverage-requirements.md +213 -0
  63. package/templates/skills/application/references/test-frontend.md +3 -3
  64. package/templates/skills/application/steps/step-00-init.md +11 -141
  65. package/templates/skills/application/steps/step-01-navigation.md +3 -3
  66. package/templates/skills/application/steps/step-02-permissions.md +4 -4
  67. package/templates/skills/application/steps/step-03-roles.md +18 -175
  68. package/templates/skills/application/steps/step-03b-provider.md +1 -2
  69. package/templates/skills/application/steps/step-04-backend.md +19 -110
  70. package/templates/skills/application/steps/step-05-frontend.md +17 -143
  71. package/templates/skills/application/steps/step-06-migration.md +12 -60
  72. package/templates/skills/application/steps/step-07-tests.md +9 -76
  73. package/templates/skills/application/templates-backend.md +29 -27
  74. package/templates/skills/application/templates-frontend.md +48 -48
  75. package/templates/skills/application/templates-seed.md +57 -131
  76. package/templates/skills/business-analyse/SKILL.md +27 -30
  77. package/templates/skills/business-analyse/_architecture.md +6 -6
  78. package/templates/skills/business-analyse/_shared.md +60 -88
  79. package/templates/skills/business-analyse/questionnaire/04-data.md +3 -3
  80. package/templates/skills/business-analyse/questionnaire/06-security.md +1 -1
  81. package/templates/skills/business-analyse/questionnaire/13-cross-module.md +1 -1
  82. package/templates/skills/business-analyse/react/application-viewer.md +12 -12
  83. package/templates/skills/business-analyse/react/components.md +8 -12
  84. package/templates/skills/business-analyse/react/schema.md +11 -11
  85. package/templates/skills/business-analyse/references/agent-module-prompt.md +2 -3
  86. package/templates/skills/business-analyse/references/analysis-semantic-checks.md +190 -0
  87. package/templates/skills/business-analyse/references/cache-warming-strategy.md +2 -2
  88. package/templates/skills/business-analyse/references/cadrage-challenge-patterns.md +41 -0
  89. package/templates/skills/business-analyse/references/cadrage-coverage-matrix.md +74 -0
  90. package/templates/skills/business-analyse/references/cadrage-shared-modules.md +69 -0
  91. package/templates/skills/business-analyse/references/cadrage-structure-cards.md +1 -1
  92. package/templates/skills/business-analyse/references/compilation-structure-cards.md +297 -0
  93. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +2 -2
  94. package/templates/skills/business-analyse/references/deploy-modes.md +5 -5
  95. package/templates/skills/business-analyse/references/detection-strategies.md +7 -7
  96. package/templates/skills/business-analyse/references/handoff-file-templates.md +14 -22
  97. package/templates/skills/business-analyse/references/handoff-mappings.md +4 -4
  98. package/templates/skills/business-analyse/references/handoff-seeddata-generation.md +312 -0
  99. package/templates/skills/business-analyse/references/init-schema-deployment.md +3 -3
  100. package/templates/skills/business-analyse/references/naming-conventions.md +22 -24
  101. package/templates/skills/business-analyse/references/prd-generation.md +2 -2
  102. package/templates/skills/business-analyse/references/review-data-mapping.md +2 -2
  103. package/templates/skills/business-analyse/references/robustness-checks.md +1 -1
  104. package/templates/skills/business-analyse/references/spec-auto-inference.md +3 -3
  105. package/templates/skills/business-analyse/references/team-orchestration.md +49 -6
  106. package/templates/skills/business-analyse/references/ui-dashboard-spec.md +1 -1
  107. package/templates/skills/business-analyse/references/ui-resource-cards.md +18 -18
  108. package/templates/skills/business-analyse/references/validate-incremental-html.md +2 -2
  109. package/templates/skills/business-analyse/references/validation-checklist.md +2 -2
  110. package/templates/skills/business-analyse/schemas/application-schema.json +4 -5
  111. package/templates/skills/business-analyse/schemas/project-schema.json +1 -6
  112. package/templates/skills/business-analyse/schemas/sections/metadata-schema.json +2 -3
  113. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +4 -4
  114. package/templates/skills/business-analyse/steps/step-00-init.md +8 -17
  115. package/templates/skills/business-analyse/steps/step-01-cadrage.md +35 -198
  116. package/templates/skills/business-analyse/steps/step-01b-applications.md +16 -20
  117. package/templates/skills/business-analyse/steps/step-02-decomposition.md +1 -1
  118. package/templates/skills/business-analyse/steps/step-03a1-setup.md +4 -4
  119. package/templates/skills/business-analyse/steps/step-03a2-analysis.md +1 -1
  120. package/templates/skills/business-analyse/steps/step-03b-ui.md +4 -4
  121. package/templates/skills/business-analyse/steps/step-03c-compile.md +66 -140
  122. package/templates/skills/business-analyse/steps/step-03d-validate.md +2 -2
  123. package/templates/skills/business-analyse/steps/step-04a-collect.md +2 -2
  124. package/templates/skills/business-analyse/steps/step-04b-analyze.md +42 -160
  125. package/templates/skills/business-analyse/steps/step-04c-decide.md +1 -1
  126. package/templates/skills/business-analyse/steps/step-05a-handoff.md +74 -104
  127. package/templates/skills/business-analyse/steps/step-05b-deploy.md +13 -11
  128. package/templates/skills/business-analyse/steps/step-06-review.md +3 -3
  129. package/templates/skills/business-analyse/templates/tpl-frd.md +13 -13
  130. package/templates/skills/business-analyse/templates/tpl-handoff.md +12 -12
  131. package/templates/skills/business-analyse/templates-frd.md +25 -25
  132. package/templates/skills/business-analyse/templates-react.md +15 -21
  133. package/templates/skills/controller/SKILL.md +1 -1
  134. package/templates/skills/controller/postman-templates.md +1 -1
  135. package/templates/skills/controller/references/controller-code-templates.md +2 -2
  136. package/templates/skills/controller/references/mcp-scaffold-workflow.md +209 -0
  137. package/templates/skills/controller/references/permission-sync-templates.md +13 -16
  138. package/templates/skills/controller/steps/step-00-init.md +11 -11
  139. package/templates/skills/controller/steps/step-03-generate.md +64 -103
  140. package/templates/skills/controller/templates.md +67 -71
  141. package/templates/skills/debug/SKILL.md +13 -218
  142. package/templates/skills/debug/steps/step-00-init.md +57 -0
  143. package/templates/skills/debug/steps/step-01-analyze.md +219 -0
  144. package/templates/skills/debug/steps/step-02-resolve.md +85 -0
  145. package/templates/skills/documentation/SKILL.md +49 -345
  146. package/templates/skills/documentation/data-schema.md +11 -8
  147. package/templates/skills/documentation/steps/step-00-init.md +70 -0
  148. package/templates/skills/documentation/steps/step-01-scan.md +113 -0
  149. package/templates/skills/documentation/steps/step-02-generate.md +231 -0
  150. package/templates/skills/documentation/steps/step-03-validate.md +238 -0
  151. package/templates/skills/documentation/templates.md +480 -322
  152. package/templates/skills/efcore/references/both-contexts.md +32 -0
  153. package/templates/skills/efcore/references/database-operations.md +67 -0
  154. package/templates/skills/efcore/references/destructive-operations.md +38 -0
  155. package/templates/skills/efcore/references/reset-operations.md +81 -0
  156. package/templates/skills/efcore/references/seed-methods.md +86 -0
  157. package/templates/skills/efcore/references/shared-init-functions.md +250 -0
  158. package/templates/skills/efcore/references/sql-objects-injection.md +61 -0
  159. package/templates/skills/efcore/references/troubleshooting.md +81 -0
  160. package/templates/skills/efcore/steps/db/step-deploy.md +1 -32
  161. package/templates/skills/efcore/steps/db/step-reset.md +7 -103
  162. package/templates/skills/efcore/steps/db/step-seed.md +10 -132
  163. package/templates/skills/efcore/steps/db/step-status.md +5 -44
  164. package/templates/skills/efcore/steps/migration/step-03-validate.md +8 -62
  165. package/templates/skills/efcore/steps/rebase-snapshot/step-03-create.md +1 -57
  166. package/templates/skills/efcore/steps/shared/step-00-init.md +11 -254
  167. package/templates/skills/efcore/steps/squash/step-03-create.md +1 -58
  168. package/templates/skills/feature-full/SKILL.md +1 -1
  169. package/templates/skills/feature-full/steps/step-00-init.md +57 -0
  170. package/templates/skills/feature-full/steps/step-01-implementation.md +1 -1
  171. package/templates/skills/gitflow/SKILL.md +1 -1
  172. package/templates/skills/gitflow/_shared.md +23 -0
  173. package/templates/skills/gitflow/references/commit-message-generation.md +58 -0
  174. package/templates/skills/gitflow/references/commit-migration-validation.md +49 -0
  175. package/templates/skills/gitflow/references/finish-cleanup.md +51 -0
  176. package/templates/skills/gitflow/references/finish-version-bumping.md +45 -0
  177. package/templates/skills/gitflow/references/init-environment-detection.md +41 -0
  178. package/templates/skills/gitflow/references/init-questions.md +185 -0
  179. package/templates/skills/gitflow/references/init-structure-creation.md +71 -0
  180. package/templates/skills/gitflow/references/init-version-detection.md +21 -0
  181. package/templates/skills/gitflow/references/init-workspace-detection.md +43 -0
  182. package/templates/skills/gitflow/references/merge-ci-status.md +36 -0
  183. package/templates/skills/gitflow/references/merge-execution.md +62 -0
  184. package/templates/skills/gitflow/references/merge-pr-context.md +76 -0
  185. package/templates/skills/gitflow/references/pr-build-checks.md +60 -0
  186. package/templates/skills/gitflow/references/pr-generation.md +58 -0
  187. package/templates/skills/gitflow/references/start-branch-normalization.md +28 -0
  188. package/templates/skills/gitflow/references/start-worktree-creation.md +50 -0
  189. package/templates/skills/gitflow/references/sync-push-verify.md +44 -0
  190. package/templates/skills/gitflow/references/sync-rebase-conflicts.md +38 -0
  191. package/templates/skills/gitflow/steps/step-commit.md +12 -91
  192. package/templates/skills/gitflow/steps/step-finish.md +15 -159
  193. package/templates/skills/gitflow/steps/step-init.md +24 -326
  194. package/templates/skills/gitflow/steps/step-merge.md +17 -176
  195. package/templates/skills/gitflow/steps/step-pr.md +10 -116
  196. package/templates/skills/gitflow/steps/step-start.md +16 -109
  197. package/templates/skills/gitflow/steps/step-sync.md +6 -69
  198. package/templates/skills/ralph-loop/SKILL.md +6 -0
  199. package/templates/skills/ralph-loop/references/category-completeness.md +185 -0
  200. package/templates/skills/ralph-loop/references/compact-loop.md +1 -1
  201. package/templates/skills/ralph-loop/references/init-resume-recovery.md +127 -0
  202. package/templates/skills/ralph-loop/references/module-transition.md +151 -0
  203. package/templates/skills/ralph-loop/references/multi-module-queue.md +171 -0
  204. package/templates/skills/ralph-loop/references/parallel-execution.md +246 -0
  205. package/templates/skills/ralph-loop/references/task-transform-legacy.md +6 -9
  206. package/templates/skills/ralph-loop/references/team-orchestration.md +45 -3
  207. package/templates/skills/ralph-loop/steps/step-00-init.md +36 -109
  208. package/templates/skills/ralph-loop/steps/step-01-task.md +15 -163
  209. package/templates/skills/ralph-loop/steps/step-02-execute.md +8 -154
  210. package/templates/skills/ralph-loop/steps/step-04-check.md +21 -73
  211. package/templates/skills/review-code/references/owasp-api-top10.md +5 -5
  212. package/templates/skills/review-code/references/smartstack-conventions.md +11 -11
  213. package/templates/skills/validate-feature/references/api-smoke-tests.md +140 -0
  214. package/templates/skills/validate-feature/references/db-validation-checks.md +180 -0
  215. package/templates/skills/validate-feature/steps/step-01-compile.md +5 -2
  216. package/templates/skills/validate-feature/steps/step-04-api-smoke.md +34 -145
  217. package/templates/skills/validate-feature/steps/step-05-db-validation.md +74 -260
  218. package/templates/skills/workflow/SKILL.md +1 -1
  219. package/templates/skills/workflow/steps/step-00-init.md +57 -0
@@ -0,0 +1,804 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generate Documentation with Mock UI for SmartStack Modules
4
+ *
5
+ * This script generates complete documentation pages with embedded mock UI components
6
+ * that visually represent the module's interface without requiring real screenshots.
7
+ *
8
+ * Usage:
9
+ * node generate-doc-with-mock-ui.ts \
10
+ * --module users \
11
+ * --application administration \
12
+ * --app-path "D:/01 - projets/SmartStack.app/02-Develop"
13
+ *
14
+ * Output: Complete TSX file with mock UI (e.g., UsersDocPage.tsx)
15
+ */
16
+
17
+ import * as fs from 'fs';
18
+ import * as path from 'path';
19
+ import { glob } from 'glob';
20
+ import { execSync } from 'child_process';
21
+
22
+ interface ModuleInfo {
23
+ module: string; // e.g., "users"
24
+ application: string; // e.g., "administration"
25
+ appPath: string;
26
+ }
27
+
28
+ interface EntityProperty {
29
+ name: string; // e.g., "Email", "FirstName"
30
+ type: string; // e.g., "string", "bool", "DateTime?"
31
+ isRequired: boolean;
32
+ isNullable: boolean;
33
+ }
34
+
35
+ interface MockDataField {
36
+ propertyName: string;
37
+ mockValue: string; // Generated mock value
38
+ }
39
+
40
+ interface PageStructure {
41
+ hasTable: boolean;
42
+ hasKPIs: boolean;
43
+ hasForm: boolean;
44
+ hasFilters: boolean;
45
+ columns: string[]; // Table column names
46
+ }
47
+
48
+ /**
49
+ * Parse command line arguments
50
+ */
51
+ function parseArgs(): ModuleInfo {
52
+ const args = process.argv.slice(2);
53
+
54
+ const getArg = (flag: string): string | null => {
55
+ const index = args.indexOf(flag);
56
+ return index !== -1 && index + 1 < args.length ? args[index + 1] : null;
57
+ };
58
+
59
+ const module = getArg('--module');
60
+ const application = getArg('--application');
61
+ const appPath = getArg('--app-path');
62
+
63
+ if (!module || !application || !appPath) {
64
+ console.error('Usage: node generate-doc-with-mock-ui.ts --module <name> --application <app> --app-path <path>');
65
+ process.exit(1);
66
+ }
67
+
68
+ return { module, application, appPath };
69
+ }
70
+
71
+ /**
72
+ * Find Domain entity file
73
+ * Tries both singular and plural forms (e.g., users → User.cs)
74
+ */
75
+ async function findEntityFile(appPath: string, module: string): Promise<string | null> {
76
+ const domainPath = path.join(appPath, 'src/SmartStack.Domain');
77
+
78
+ // Try singular form first (most common: users → User.cs)
79
+ const singularForm = capitalize(singularize(module));
80
+ const singularPattern = `**/${singularForm}.cs`;
81
+
82
+ try {
83
+ let files = await glob(singularPattern, { cwd: domainPath, absolute: true });
84
+ if (files.length > 0) {
85
+ return files[0];
86
+ }
87
+
88
+ // Fallback to plural form
89
+ const pluralForm = capitalize(module);
90
+ const pluralPattern = `**/${pluralForm}.cs`;
91
+ files = await glob(pluralPattern, { cwd: domainPath, absolute: true });
92
+ return files.length > 0 ? files[0] : null;
93
+ } catch (error) {
94
+ console.error('Error finding entity:', error);
95
+ return null;
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Find React page file
101
+ */
102
+ async function findPageFile(appPath: string, module: string, application: string): Promise<string | null> {
103
+ const pagesPath = path.join(appPath, `web/smartstack-web/src/pages/${application}/${module}`);
104
+ const pattern = `${capitalize(module)}Page.tsx`;
105
+
106
+ const fullPath = path.join(pagesPath, pattern);
107
+ return fs.existsSync(fullPath) ? fullPath : null;
108
+ }
109
+
110
+ /**
111
+ * Extract entity properties from Domain entity file
112
+ */
113
+ function extractEntityProperties(entityPath: string): EntityProperty[] {
114
+ const content = fs.readFileSync(entityPath, 'utf-8');
115
+ const lines = content.split('\n');
116
+ const properties: EntityProperty[] = [];
117
+
118
+ for (const line of lines) {
119
+ // Match property declarations: public string Email { get; private set; }
120
+ const propMatch = line.match(/public\s+(\w+\??)\s+(\w+)\s*\{\s*get;/);
121
+ if (propMatch) {
122
+ const type = propMatch[1];
123
+ const name = propMatch[2];
124
+
125
+ // Skip base entity properties and navigation properties
126
+ if (['Id', 'CreatedAt', 'UpdatedAt', 'CreatedBy', 'UpdatedBy'].includes(name)) {
127
+ continue;
128
+ }
129
+
130
+ // Skip collections (List, IReadOnlyCollection, etc.)
131
+ if (line.includes('List<') || line.includes('IReadOnlyCollection<') || line.includes('ICollection<')) {
132
+ continue;
133
+ }
134
+
135
+ properties.push({
136
+ name,
137
+ type,
138
+ isRequired: !type.endsWith('?'),
139
+ isNullable: type.endsWith('?'),
140
+ });
141
+ }
142
+ }
143
+
144
+ return properties;
145
+ }
146
+
147
+ /**
148
+ * Analyze React page structure
149
+ */
150
+ function analyzePageStructure(pagePath: string): PageStructure {
151
+ const content = fs.readFileSync(pagePath, 'utf-8');
152
+
153
+ const structure: PageStructure = {
154
+ hasTable: content.includes('<table') || content.includes('Table'),
155
+ hasKPIs: content.includes('KPI') || content.includes('stat') || content.includes('metric'),
156
+ hasForm: content.includes('<form') || content.includes('Form') || content.includes('input'),
157
+ hasFilters: content.includes('filter') || content.includes('Filter') || content.includes('search'),
158
+ columns: [],
159
+ };
160
+
161
+ // Try to extract table column names
162
+ const thRegex = /<th[^>]*>([^<]+)<\/th>/g;
163
+ let match;
164
+ while ((match = thRegex.exec(content)) !== null) {
165
+ structure.columns.push(match[1].trim());
166
+ }
167
+
168
+ return structure;
169
+ }
170
+
171
+ /**
172
+ * Generate mock value for a property
173
+ */
174
+ function generateMockValue(property: EntityProperty, index: number): string {
175
+ const type = property.type.replace('?', '');
176
+
177
+ switch (type.toLowerCase()) {
178
+ case 'string':
179
+ if (property.name.toLowerCase().includes('email')) {
180
+ const names = ['john.doe', 'jane.smith', 'bob.johnson', 'alice.williams', 'charlie.brown'];
181
+ return `"${names[index % names.length]}@example.com"`;
182
+ }
183
+ if (property.name.toLowerCase().includes('name')) {
184
+ if (property.name.toLowerCase().includes('first')) {
185
+ const names = ['John', 'Jane', 'Bob', 'Alice', 'Charlie'];
186
+ return `"${names[index % names.length]}"`;
187
+ }
188
+ if (property.name.toLowerCase().includes('last')) {
189
+ const names = ['Doe', 'Smith', 'Johnson', 'Williams', 'Brown'];
190
+ return `"${names[index % names.length]}"`;
191
+ }
192
+ return `"${property.name} ${index + 1}"`;
193
+ }
194
+ if (property.name.toLowerCase().includes('title')) {
195
+ return `"Sample ${property.name} ${index + 1}"`;
196
+ }
197
+ if (property.name.toLowerCase().includes('description')) {
198
+ return `"This is a sample description for item ${index + 1}"`;
199
+ }
200
+ return `"Sample ${property.name}"`;
201
+
202
+ case 'bool':
203
+ case 'boolean':
204
+ return index % 2 === 0 ? 'true' : 'false';
205
+
206
+ case 'int':
207
+ case 'int32':
208
+ case 'long':
209
+ return String((index + 1) * 10);
210
+
211
+ case 'decimal':
212
+ case 'double':
213
+ case 'float':
214
+ return String((index + 1) * 10.5);
215
+
216
+ case 'datetime':
217
+ const dates = ['2026-01-15', '2026-01-20', '2026-02-01', '2026-02-10', '2026-02-15'];
218
+ return `"${dates[index % dates.length]}"`;
219
+
220
+ case 'guid':
221
+ // Generate a fixed mock GUID based on index to keep consistent data
222
+ const mockGuids = [
223
+ '"550e8400-e29b-41d4-a716-446655440000"',
224
+ '"6ba7b810-9dad-11d1-80b4-00c04fd430c8"',
225
+ '"6ba7b811-9dad-11d1-80b4-00c04fd430c9"',
226
+ '"6ba7b812-9dad-11d1-80b4-00c04fd430ca"',
227
+ '"6ba7b813-9dad-11d1-80b4-00c04fd430cb"'
228
+ ];
229
+ return mockGuids[index % mockGuids.length];
230
+
231
+ default:
232
+ return property.isNullable ? 'null' : '""';
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Generate mock data array
238
+ */
239
+ function generateMockData(properties: EntityProperty[], module: string, count: number = 5): string {
240
+ const mockItems: string[] = [];
241
+
242
+ for (let i = 0; i < count; i++) {
243
+ const fields = properties
244
+ .filter(p => !p.name.includes('Hash') && !p.name.includes('Token')) // Skip sensitive fields
245
+ .map(p => `${p.name.charAt(0).toLowerCase() + p.name.slice(1)}: ${generateMockValue(p, i)}`)
246
+ .join(', ');
247
+
248
+ mockItems.push(` { ${fields} }`);
249
+ }
250
+
251
+ const singularName = module.endsWith('s') ? module.slice(0, -1) : module;
252
+ return `const mock${capitalize(module)} = [\n${mockItems.join(',\n')}\n];`;
253
+ }
254
+
255
+ /**
256
+ * Generate KPI stats based on entity properties
257
+ */
258
+ function generateKPIStats(properties: EntityProperty[], module: string, count: number = 5): string {
259
+ const stats: string[] = [];
260
+
261
+ // Always add total count
262
+ stats.push(` { label: 'Total', value: '${count * 10}', color: 'var(--text-primary)' }`);
263
+
264
+ // Check for IsActive/Status property
265
+ const activeProperty = properties.find(p =>
266
+ p.name.toLowerCase() === 'isactive' && (p.type.toLowerCase() === 'bool' || p.type.toLowerCase() === 'boolean')
267
+ );
268
+
269
+ if (activeProperty) {
270
+ const activeCount = Math.floor(count * 10 * 0.6); // 60% active
271
+ const inactiveCount = count * 10 - activeCount;
272
+ stats.push(` { label: 'Active', value: '${activeCount}', color: 'var(--success-text)', border: 'var(--success-border)' }`);
273
+ stats.push(` { label: 'Inactive', value: '${inactiveCount}', color: 'var(--error-text)', border: 'var(--error-border)' }`);
274
+ }
275
+
276
+ // Check for Status property (enum/string)
277
+ const statusProperty = properties.find(p =>
278
+ p.name.toLowerCase() === 'status' && p.type.toLowerCase() === 'string'
279
+ );
280
+
281
+ if (statusProperty) {
282
+ stats.push(` { label: 'Pending', value: '${Math.floor(count * 2)}', color: 'var(--warning-text)', border: 'var(--warning-border)' }`);
283
+ stats.push(` { label: 'In Progress', value: '${Math.floor(count * 3)}', color: 'var(--info-text)', border: 'var(--info-border)' }`);
284
+ stats.push(` { label: 'Completed', value: '${Math.floor(count * 5)}', color: 'var(--success-text)', border: 'var(--success-border)' }`);
285
+ }
286
+
287
+ // Check for DateTime property (e.g., CreatedAt, LastLoginAt)
288
+ const dateProperty = properties.find(p =>
289
+ p.type.toLowerCase() === 'datetime' &&
290
+ (p.name.toLowerCase().includes('created') || p.name.toLowerCase().includes('login'))
291
+ );
292
+
293
+ if (dateProperty) {
294
+ stats.push(` { label: 'Last 7 days', value: '${Math.floor(count * 1.5)}', color: 'var(--info-text)', border: 'var(--info-border)' }`);
295
+ }
296
+
297
+ return `const ${module}Stats = [\n${stats.join(',\n')}\n];`;
298
+ }
299
+
300
+ /**
301
+ * Generate form fields based on entity properties
302
+ */
303
+ function generateFormSection(properties: EntityProperty[], module: string): string {
304
+ const ModuleName = capitalize(singularize(module));
305
+
306
+ // Filter properties suitable for form input
307
+ const formProps = properties.filter(p => {
308
+ const name = p.name.toLowerCase();
309
+ // Exclude read-only, computed, and sensitive fields
310
+ return !name.includes('hash') &&
311
+ !name.includes('token') &&
312
+ !name.includes('normalized') &&
313
+ !name.endsWith('id') &&
314
+ !name.includes('createdat') &&
315
+ !name.includes('updatedat') &&
316
+ !name.includes('createdby') &&
317
+ !name.includes('updatedby') &&
318
+ !name.includes('data') &&
319
+ !name.includes('proxy') &&
320
+ p.name !== 'Id';
321
+ }).slice(0, 6); // Limit to 6 most relevant fields
322
+
323
+ const formFields = formProps.map(p => {
324
+ const fieldName = p.name.charAt(0).toLowerCase() + p.name.slice(1);
325
+ const label = p.name.replace(/([A-Z])/g, ' $1').trim();
326
+ const isRequired = p.isRequired;
327
+
328
+ if (p.type.toLowerCase() === 'bool' || p.type.toLowerCase() === 'boolean') {
329
+ return ` <div className="flex items-center gap-2">
330
+ <input type="checkbox" id="${fieldName}" className="w-4 h-4" />
331
+ <label htmlFor="${fieldName}" className="text-sm">${label}</label>
332
+ </div>`;
333
+ }
334
+
335
+ if (p.type.toLowerCase() === 'datetime') {
336
+ return ` <div>
337
+ <label className="block text-sm font-medium mb-1">${label}${isRequired ? ' *' : ''}</label>
338
+ <input type="date" className="w-full px-3 py-2 border border-[var(--border-color)] rounded-lg" />
339
+ </div>`;
340
+ }
341
+
342
+ if (p.name.toLowerCase().includes('email')) {
343
+ return ` <div>
344
+ <label className="block text-sm font-medium mb-1">${label}${isRequired ? ' *' : ''}</label>
345
+ <input type="email" placeholder="user@example.com" className="w-full px-3 py-2 border border-[var(--border-color)] rounded-lg" />
346
+ </div>`;
347
+ }
348
+
349
+ if (p.name.toLowerCase().includes('description') || p.name.toLowerCase().includes('notes')) {
350
+ return ` <div className="md:col-span-2">
351
+ <label className="block text-sm font-medium mb-1">${label}</label>
352
+ <textarea rows={3} className="w-full px-3 py-2 border border-[var(--border-color)] rounded-lg" />
353
+ </div>`;
354
+ }
355
+
356
+ // Default text input
357
+ return ` <div>
358
+ <label className="block text-sm font-medium mb-1">${label}${isRequired ? ' *' : ''}</label>
359
+ <input type="text" className="w-full px-3 py-2 border border-[var(--border-color)] rounded-lg" />
360
+ </div>`;
361
+ }).join('\n');
362
+
363
+ return ` {/* Section 4: Create Form Example */}
364
+ <section id="create-form" className="card p-6">
365
+ <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
366
+ <span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">4</span>
367
+ Create ${ModuleName} Form
368
+ </h2>
369
+ <p className="text-[var(--text-secondary)] mb-4">
370
+ Form interface for creating new ${module}.
371
+ </p>
372
+
373
+ <div className="border border-[var(--border-color)] rounded-lg p-6 bg-[var(--bg-secondary)]">
374
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
375
+ ${formFields}
376
+ </div>
377
+
378
+ <div className="flex items-center gap-3 mt-6 pt-6 border-t border-[var(--border-color)]">
379
+ <button className="px-4 py-2 bg-[var(--color-primary-600)] text-white rounded-lg flex items-center gap-2">
380
+ <Plus className="w-4 h-4" />
381
+ Create ${ModuleName}
382
+ </button>
383
+ <button className="px-4 py-2 border border-[var(--border-color)] rounded-lg">
384
+ Cancel
385
+ </button>
386
+ </div>
387
+ </div>
388
+ </section>`;
389
+ }
390
+
391
+ /**
392
+ * Generate KPI section UI
393
+ */
394
+ function generateKPISection(module: string): string {
395
+ return ` {/* Stats */}
396
+ <div className="p-4 border-b border-[var(--border-color)] bg-[var(--bg-secondary)]">
397
+ <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-2">
398
+ {${module}Stats.map((stat) => (
399
+ <div
400
+ key={stat.label}
401
+ className="p-3 bg-[var(--bg-primary)] rounded-lg text-center"
402
+ style={{ borderLeft: stat.border ? \`3px solid \${stat.border}\` : undefined }}
403
+ >
404
+ <div className="text-2xl font-bold" style={{ color: stat.color }}>{stat.value}</div>
405
+ <div className="text-xs text-[var(--text-secondary)] mt-1">{stat.label}</div>
406
+ </div>
407
+ ))}
408
+ </div>
409
+ </div>`;
410
+ }
411
+
412
+ /**
413
+ * Generate table mock UI section
414
+ */
415
+ function generateTableMockUI(properties: EntityProperty[], module: string): string {
416
+ // Smart property selection for table display
417
+ const filteredProps = properties.filter(p => {
418
+ const name = p.name.toLowerCase();
419
+ // Exclude sensitive, internal, and FK properties
420
+ return !name.includes('hash') &&
421
+ !name.includes('token') &&
422
+ !name.includes('password') &&
423
+ !name.endsWith('id') && // Skip foreign keys
424
+ !name.includes('normalized') &&
425
+ !name.includes('data') && // Skip JSON/blob fields
426
+ !name.includes('proxy') &&
427
+ !name.includes('im') &&
428
+ p.name !== 'Sponsors' &&
429
+ p.name !== 'ProxyAddresses' &&
430
+ p.name !== 'ImAddresses';
431
+ });
432
+
433
+ // Prioritize display properties: name/title > email > status > date
434
+ const priorityProps: EntityProperty[] = [];
435
+
436
+ // Add name/title properties first
437
+ priorityProps.push(...filteredProps.filter(p =>
438
+ p.name.toLowerCase().includes('name') ||
439
+ p.name.toLowerCase().includes('title')
440
+ ).slice(0, 2));
441
+
442
+ // Add email if available
443
+ const emailProp = filteredProps.find(p => p.name.toLowerCase().includes('email'));
444
+ if (emailProp && !priorityProps.includes(emailProp)) {
445
+ priorityProps.push(emailProp);
446
+ }
447
+
448
+ // Add status/active properties
449
+ const statusProp = filteredProps.find(p =>
450
+ p.name.toLowerCase().includes('active') ||
451
+ p.name.toLowerCase().includes('status')
452
+ );
453
+ if (statusProp && !priorityProps.includes(statusProp)) {
454
+ priorityProps.push(statusProp);
455
+ }
456
+
457
+ // Fill remaining slots with other properties (max 6 total)
458
+ const remainingProps = filteredProps.filter(p => !priorityProps.includes(p));
459
+ priorityProps.push(...remainingProps.slice(0, 6 - priorityProps.length));
460
+
461
+ const displayProps = priorityProps.slice(0, 6);
462
+
463
+ const headers = displayProps.map(p => `<th className="text-left p-3 font-medium">${p.name}</th>`).join('\n ');
464
+
465
+ const cells = displayProps.map(p => {
466
+ const propName = p.name.charAt(0).toLowerCase() + p.name.slice(1);
467
+
468
+ if (p.type.toLowerCase() === 'bool' || p.type.toLowerCase() === 'boolean') {
469
+ return `<td className="p-3">
470
+ <span className={\`px-2 py-1 text-xs rounded \${item.${propName} ? 'bg-green-500/10 text-green-600' : 'bg-gray-500/10 text-gray-600'}\`}>
471
+ {item.${propName} ? 'Yes' : 'No'}
472
+ </span>
473
+ </td>`;
474
+ }
475
+
476
+ if (p.type.toLowerCase() === 'datetime') {
477
+ return `<td className="p-3 text-[var(--text-secondary)]">{new Date(item.${propName}).toLocaleDateString()}</td>`;
478
+ }
479
+
480
+ return `<td className="p-3">{item.${propName}}</td>`;
481
+ }).join('\n ');
482
+
483
+ return ` {/* Table */}
484
+ <div className="overflow-x-auto">
485
+ <table className="w-full text-sm">
486
+ <thead className="bg-[var(--bg-secondary)]">
487
+ <tr>
488
+ ${headers}
489
+ <th className="text-right p-3 font-medium">Actions</th>
490
+ </tr>
491
+ </thead>
492
+ <tbody>
493
+ {mock${capitalize(module)}.map((item, idx) => (
494
+ <tr key={idx} className="border-b border-[var(--border-color)] hover:bg-[var(--bg-hover)]">
495
+ ${cells}
496
+ <td className="p-3 text-right">
497
+ <div className="flex items-center justify-end gap-1">
498
+ <button className="p-1.5 hover:bg-[var(--bg-secondary)] rounded">
499
+ <Eye className="w-4 h-4" />
500
+ </button>
501
+ <button className="p-1.5 hover:bg-[var(--bg-secondary)] rounded text-[var(--error-text)]">
502
+ <Trash2 className="w-4 h-4" />
503
+ </button>
504
+ </div>
505
+ </td>
506
+ </tr>
507
+ ))}
508
+ </tbody>
509
+ </table>
510
+ </div>`;
511
+ }
512
+
513
+ /**
514
+ * Generate complete TSX documentation file
515
+ */
516
+ function generateDocumentationTSX(
517
+ moduleInfo: ModuleInfo,
518
+ properties: EntityProperty[],
519
+ apiEndpoints: any[],
520
+ businessRules: any[],
521
+ pageStructure: PageStructure
522
+ ): string {
523
+ const { module, application } = moduleInfo;
524
+ const ModuleName = capitalize(module);
525
+
526
+ // Generate mock data
527
+ const mockDataCode = generateMockData(properties, module);
528
+
529
+ // Generate KPI stats
530
+ const kpiStatsCode = generateKPIStats(properties, module);
531
+ const kpiSectionUI = generateKPISection(module);
532
+
533
+ // Generate table UI
534
+ const tableMockUI = generateTableMockUI(properties, module);
535
+
536
+ // Generate form section
537
+ const formSectionUI = generateFormSection(properties, module);
538
+
539
+ // Generate API endpoints mock data
540
+ const apiEndpointsCode = `const apiEndpoints = ${JSON.stringify(apiEndpoints, null, 2)};`;
541
+
542
+ return `import { Link } from 'react-router-dom';
543
+ import { useTranslation } from 'react-i18next';
544
+ import {
545
+ ArrowRight,
546
+ Shield,
547
+ Eye,
548
+ Trash2,
549
+ Plus,
550
+ Info,
551
+ MessageSquare,
552
+ HelpCircle,
553
+ } from 'lucide-react';
554
+
555
+ // Mock data for ${ModuleName}
556
+ ${mockDataCode}
557
+
558
+ // KPI Stats
559
+ ${kpiStatsCode}
560
+
561
+ // API endpoints
562
+ ${apiEndpointsCode}
563
+
564
+ export function ${ModuleName}DocPage() {
565
+ const { t } = useTranslation('docs');
566
+
567
+ return (
568
+ <div className="space-y-8">
569
+ {/* Breadcrumb */}
570
+ <div className="flex items-center gap-2 text-sm text-[var(--text-secondary)]">
571
+ <Link to="/system/docs" className="hover:text-[var(--color-primary-600)]">Documentation</Link>
572
+ <span>/</span>
573
+ <Link to="/system/docs/user" className="hover:text-[var(--color-primary-600)]">User</Link>
574
+ <span>/</span>
575
+ <span>${ModuleName}</span>
576
+ </div>
577
+
578
+ {/* Header */}
579
+ <div>
580
+ <h1 className="text-3xl font-bold mb-4">
581
+ ${ModuleName} Management
582
+ </h1>
583
+ <p className="text-lg text-[var(--text-secondary)]">
584
+ Complete management interface for ${module}
585
+ </p>
586
+ </div>
587
+
588
+ {/* Section 1: Introduction */}
589
+ <section id="introduction" className="card p-6">
590
+ <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
591
+ <span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">1</span>
592
+ Introduction
593
+ </h2>
594
+ <p className="text-[var(--text-secondary)]">
595
+ The ${ModuleName} module provides comprehensive management capabilities including
596
+ viewing, creating, updating, and deleting ${module}.
597
+ </p>
598
+ </section>
599
+
600
+ {/* Section 2: Access */}
601
+ <section id="access" className="card p-6">
602
+ <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
603
+ <span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">2</span>
604
+ Access
605
+ </h2>
606
+
607
+ <div className="mb-4">
608
+ <div className="text-sm font-medium mb-2">Navigation</div>
609
+ <div className="flex items-center gap-2 text-sm bg-[var(--bg-secondary)] p-3 rounded-lg">
610
+ <span className="px-2 py-1 bg-[var(--bg-primary)] rounded">${capitalize(application)}</span>
611
+ <ArrowRight className="w-4 h-4 text-[var(--text-tertiary)]" />
612
+ <span className="px-2 py-1 bg-[var(--color-primary-600)] text-white rounded">${ModuleName}</span>
613
+ </div>
614
+ </div>
615
+
616
+ <div className="mb-4">
617
+ <div className="text-sm font-medium mb-2">URL</div>
618
+ <code className="block p-3 bg-[var(--bg-secondary)] rounded-lg text-sm font-mono">
619
+ /${application}/${module}
620
+ </code>
621
+ </div>
622
+ </section>
623
+
624
+ {/* Section 3: Overview - MOCK UI */}
625
+ <section id="overview" className="card p-6">
626
+ <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
627
+ <span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">3</span>
628
+ Interface Overview
629
+ </h2>
630
+ <p className="text-[var(--text-secondary)] mb-4">
631
+ The main ${module} interface displays all records in a table format with search and filter capabilities.
632
+ </p>
633
+
634
+ {/* Mock UI - Complete Interface */}
635
+ <div className="border border-[var(--border-color)] rounded-lg overflow-hidden">
636
+ {/* Header */}
637
+ <div className="p-4 border-b border-[var(--border-color)] flex items-center justify-between">
638
+ <div>
639
+ <div className="font-bold">${ModuleName} Management</div>
640
+ <div className="text-sm text-[var(--text-secondary)]">Manage all ${module}</div>
641
+ </div>
642
+ <button className="px-4 py-2 bg-[var(--color-primary-600)] text-white rounded-lg flex items-center gap-2 text-sm">
643
+ <Plus className="w-4 h-4" />
644
+ New ${ModuleName}
645
+ </button>
646
+ </div>
647
+
648
+ ${kpiSectionUI}
649
+
650
+ {/* Table */}
651
+ ${tableMockUI}
652
+ </div>
653
+ </section>
654
+
655
+ ${formSectionUI}
656
+
657
+ {/* Section 5: API Reference */}
658
+ <section id="api" className="card p-6">
659
+ <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
660
+ <span className="w-8 h-8 rounded-full bg-[var(--color-primary-600)] text-white flex items-center justify-center text-sm font-bold">5</span>
661
+ API Reference
662
+ </h2>
663
+
664
+ <div className="overflow-x-auto">
665
+ <table className="w-full text-sm">
666
+ <thead>
667
+ <tr className="bg-[var(--bg-secondary)]">
668
+ <th className="text-left py-2 px-3 rounded-tl-lg">Method</th>
669
+ <th className="text-left py-2 px-3">Endpoint</th>
670
+ <th className="text-left py-2 px-3 rounded-tr-lg">Handler</th>
671
+ </tr>
672
+ </thead>
673
+ <tbody>
674
+ {apiEndpoints.map((endpoint, index) => (
675
+ <tr key={index} className="border-b border-[var(--border-color)]">
676
+ <td className="py-2 px-3">
677
+ <span className={\`px-2 py-0.5 rounded text-xs font-medium \${
678
+ endpoint.method === 'GET' ? 'bg-green-500/10 text-green-600' :
679
+ endpoint.method === 'POST' ? 'bg-yellow-500/10 text-yellow-600' :
680
+ endpoint.method === 'PUT' ? 'bg-blue-500/10 text-blue-600' :
681
+ 'bg-red-500/10 text-red-600'
682
+ }\`}>
683
+ {endpoint.method}
684
+ </span>
685
+ </td>
686
+ <td className="py-2 px-3 font-mono text-xs">{endpoint.path}</td>
687
+ <td className="py-2 px-3 text-[var(--text-secondary)]">{endpoint.handler}</td>
688
+ </tr>
689
+ ))}
690
+ </tbody>
691
+ </table>
692
+ </div>
693
+ </section>
694
+ </div>
695
+ );
696
+ }
697
+ `;
698
+ }
699
+
700
+ /**
701
+ * Capitalize first letter
702
+ */
703
+ function capitalize(str: string): string {
704
+ return str.charAt(0).toUpperCase() + str.slice(1);
705
+ }
706
+
707
+ /**
708
+ * Simple singularize function for common English plurals
709
+ */
710
+ function singularize(str: string): string {
711
+ if (str.endsWith('ies')) {
712
+ return str.slice(0, -3) + 'y';
713
+ }
714
+ if (str.endsWith('sses') || str.endsWith('shes') || str.endsWith('ches') || str.endsWith('xes')) {
715
+ return str.slice(0, -2);
716
+ }
717
+ if (str.endsWith('s') && !str.endsWith('ss')) {
718
+ return str.slice(0, -1);
719
+ }
720
+ return str;
721
+ }
722
+
723
+ /**
724
+ * Main execution
725
+ */
726
+ async function main() {
727
+ const moduleInfo = parseArgs();
728
+ const { module, application, appPath } = moduleInfo;
729
+
730
+ console.error(`\nšŸš€ Generating documentation for: ${application}/${module}\n`);
731
+
732
+ // 1. Find entity file
733
+ console.error('šŸ“ Finding entity file...');
734
+ const entityPath = await findEntityFile(appPath, module);
735
+ if (!entityPath) {
736
+ console.error(`āŒ Entity not found for module: ${module}`);
737
+ process.exit(1);
738
+ }
739
+ console.error(`āœ… Found: ${entityPath}`);
740
+
741
+ // 2. Extract entity properties
742
+ console.error('\nšŸ“Š Extracting entity properties...');
743
+ const properties = extractEntityProperties(entityPath);
744
+ console.error(`āœ… Extracted ${properties.length} properties`);
745
+
746
+ // 3. Find page file
747
+ console.error('\nšŸ“„ Finding React page...');
748
+ const pagePath = await findPageFile(appPath, module, application);
749
+ if (pagePath) {
750
+ console.error(`āœ… Found: ${pagePath}`);
751
+ } else {
752
+ console.error(`āš ļø Page not found (will use defaults)`);
753
+ }
754
+
755
+ // 4. Analyze page structure
756
+ const pageStructure = pagePath ? analyzePageStructure(pagePath) : {
757
+ hasTable: true,
758
+ hasKPIs: false,
759
+ hasForm: false,
760
+ hasFilters: false,
761
+ columns: [],
762
+ };
763
+
764
+ // 5. Extract API endpoints using existing script
765
+ console.error('\nšŸ”Œ Extracting API endpoints...');
766
+ let apiEndpoints: any[] = [];
767
+ try {
768
+ const endpointsOutput = execSync(
769
+ `npx tsx "${__dirname}/extract-api-endpoints.ts" --module ${module} --app-path "${appPath}"`,
770
+ { encoding: 'utf-8' }
771
+ );
772
+ apiEndpoints = JSON.parse(endpointsOutput);
773
+ console.error(`āœ… Extracted ${apiEndpoints.length} endpoints`);
774
+ } catch (error) {
775
+ console.error(`āš ļø Could not extract endpoints`);
776
+ }
777
+
778
+ // 6. Extract business rules using existing script
779
+ console.error('\nšŸ“‹ Extracting business rules...');
780
+ let businessRules: any[] = [];
781
+ try {
782
+ const rulesOutput = execSync(
783
+ `npx tsx "${__dirname}/extract-business-rules.ts" --module ${module} --app-path "${appPath}"`,
784
+ { encoding: 'utf-8' }
785
+ );
786
+ businessRules = JSON.parse(rulesOutput);
787
+ console.error(`āœ… Extracted ${businessRules.length} business rules`);
788
+ } catch (error) {
789
+ console.error(`āš ļø Could not extract business rules`);
790
+ }
791
+
792
+ // 7. Generate documentation TSX
793
+ console.error('\n✨ Generating documentation TSX...');
794
+ const tsx = generateDocumentationTSX(moduleInfo, properties, apiEndpoints, businessRules, pageStructure);
795
+
796
+ // 8. Output
797
+ console.log(tsx);
798
+ console.error('\nāœ… Documentation generated successfully!');
799
+ }
800
+
801
+ main().catch((error) => {
802
+ console.error('āŒ Fatal error:', error);
803
+ process.exit(1);
804
+ });