@team-codeme/crud-forge 0.0.0-stage → 1.0.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 (415) hide show
  1. package/.cursor/agents/generator-engineer.md +31 -0
  2. package/.cursor/agents/keycloak-engineer.md +33 -0
  3. package/.cursor/agents/qa-engineer.md +32 -0
  4. package/.cursor/agents/security-reviewer.md +30 -0
  5. package/.cursor/mcp.json +13 -0
  6. package/.cursor/rules/crudforge-precautions.mdc +16 -0
  7. package/.cursor/rules/playwright-browser.mdc +30 -0
  8. package/.cursor/rules/readme-todo-sync.mdc +13 -0
  9. package/.env.qa.example +19 -0
  10. package/.github/workflows/qa-live.yml +32 -0
  11. package/.github/workflows/qa.yml +27 -0
  12. package/.vscode/settings.json +32 -0
  13. package/QA/IAM-PLAN.md +25 -0
  14. package/QA/IAM-RESULTS.md +39 -0
  15. package/QA/IAM-TESTCASES.md +36 -0
  16. package/QA/IAM-TODO.md +7 -0
  17. package/QA/KEYCLOAK-BOOTSTRAP.md +105 -0
  18. package/QA/PLAN.md +43 -0
  19. package/QA/RESULTS.md +59 -0
  20. package/QA/TESTCASES.md +65 -0
  21. package/QA/TODO.md +14 -0
  22. package/QA/pmb-dev/README.md +49 -0
  23. package/QA/pmb-dev/config/config.yml +152 -0
  24. package/QA/pmb-dev/gdl/i.gdl +17 -0
  25. package/README.md +851 -2
  26. package/Todo.md +207 -0
  27. package/assets/branding/crudforge-logo.png +0 -0
  28. package/assets/branding/crudforge-mark.png +0 -0
  29. package/branding/poster-crudforge.jpg +0 -0
  30. package/chat/last-chat/Investigating Mock Data Configuration.md +428 -0
  31. package/cli.js +167 -0
  32. package/config/default-config.yml +245 -0
  33. package/docs/performance/README.md +217 -0
  34. package/docs/performance/after.json +111 -0
  35. package/docs/performance/before.json +111 -0
  36. package/docs/quality/README.md +276 -0
  37. package/e2e/crudforge.e2e.yml +47 -0
  38. package/e2e/crudforge.field-profile.yml +33 -0
  39. package/e2e/crudforge.iam-live.yml +124 -0
  40. package/e2e/crudforge.iam.yml +62 -0
  41. package/e2e/tests/field-profile.spec.js +152 -0
  42. package/e2e/tests/generated-crud.spec.js +251 -0
  43. package/e2e/tests/iam-live.spec.js +149 -0
  44. package/e2e/tests/iam-pack.spec.js +151 -0
  45. package/e2e/tests/list-state.spec.js +73 -0
  46. package/features.csv +27 -0
  47. package/fuse-starter-pack/branding/crudforge-mark-source.jpg +0 -0
  48. package/fuse-starter-pack/branding/crudforge-mark-source.png +0 -0
  49. package/fuse-starter-pack/branding/crudforge-mark.png +0 -0
  50. package/fuse-starter-pack/branding/crudforge-wordmark-source.jpg +0 -0
  51. package/fuse-starter-pack/branding/crudforge-wordmark-source.png +0 -0
  52. package/fuse-starter-pack/branding/crudforge-wordmark.png +0 -0
  53. package/fuse-starter-pack/fuse-v21.1/Dockerfile +14 -0
  54. package/fuse-starter-pack/fuse-v21.1/LICENSE.md +6 -0
  55. package/fuse-starter-pack/fuse-v21.1/README.md +59 -0
  56. package/fuse-starter-pack/fuse-v21.1/angular.json +113 -0
  57. package/fuse-starter-pack/fuse-v21.1/eslint.config.ts +150 -0
  58. package/fuse-starter-pack/fuse-v21.1/nginx.conf +23 -0
  59. package/fuse-starter-pack/fuse-v21.1/nginx.dev.conf +18 -0
  60. package/fuse-starter-pack/fuse-v21.1/package-lock.json +11513 -0
  61. package/fuse-starter-pack/fuse-v21.1/package.json +69 -0
  62. package/fuse-starter-pack/fuse-v21.1/postcss.config.json +5 -0
  63. package/fuse-starter-pack/fuse-v21.1/prettier.config.ts +15 -0
  64. package/fuse-starter-pack/fuse-v21.1/proxy.conf.json +8 -0
  65. package/fuse-starter-pack/fuse-v21.1/proxy.dev.conf.json +8 -0
  66. package/fuse-starter-pack/fuse-v21.1/public/favicon.png +0 -0
  67. package/fuse-starter-pack/fuse-v21.1/public/fonts/geist/Geist-Italic.woff2 +0 -0
  68. package/fuse-starter-pack/fuse-v21.1/public/fonts/geist/Geist.woff2 +0 -0
  69. package/fuse-starter-pack/fuse-v21.1/public/fonts/geist/GeistMono-Italic.woff2 +0 -0
  70. package/fuse-starter-pack/fuse-v21.1/public/fonts/geist/GeistMono.woff2 +0 -0
  71. package/fuse-starter-pack/fuse-v21.1/public/i18n/en.json +8 -0
  72. package/fuse-starter-pack/fuse-v21.1/public/i18n/es.json +8 -0
  73. package/fuse-starter-pack/fuse-v21.1/public/images/flags/ES.svg +79 -0
  74. package/fuse-starter-pack/fuse-v21.1/public/images/flags/US.svg +14 -0
  75. package/fuse-starter-pack/fuse-v21.1/public/images/flags/where-to-find-other-flags.txt +5 -0
  76. package/fuse-starter-pack/fuse-v21.1/public/images/logo/logo-mark.png +0 -0
  77. package/fuse-starter-pack/fuse-v21.1/public/images/logo/logo.png +0 -0
  78. package/fuse-starter-pack/fuse-v21.1/push.sh +27 -0
  79. package/fuse-starter-pack/fuse-v21.1/src/app/app.config.server.ts +10 -0
  80. package/fuse-starter-pack/fuse-v21.1/src/app/app.config.ts +64 -0
  81. package/fuse-starter-pack/fuse-v21.1/src/app/app.routes.server.ts +8 -0
  82. package/fuse-starter-pack/fuse-v21.1/src/app/app.routes.ts +39 -0
  83. package/fuse-starter-pack/fuse-v21.1/src/app/app.ts +22 -0
  84. package/fuse-starter-pack/fuse-v21.1/src/app/core/icons/index.ts +1 -0
  85. package/fuse-starter-pack/fuse-v21.1/src/app/core/icons/lucide.ts +1 -0
  86. package/fuse-starter-pack/fuse-v21.1/src/app/core/icons/provider.ts +23 -0
  87. package/fuse-starter-pack/fuse-v21.1/src/app/core/local-storage/index.ts +2 -0
  88. package/fuse-starter-pack/fuse-v21.1/src/app/core/local-storage/local-storage.ts +109 -0
  89. package/fuse-starter-pack/fuse-v21.1/src/app/core/local-storage/provider.ts +15 -0
  90. package/fuse-starter-pack/fuse-v21.1/src/app/core/media/index.ts +2 -0
  91. package/fuse-starter-pack/fuse-v21.1/src/app/core/media/media.ts +64 -0
  92. package/fuse-starter-pack/fuse-v21.1/src/app/core/media/provider.ts +15 -0
  93. package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/index.ts +3 -0
  94. package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/models/theming.ts +13 -0
  95. package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/palette.ts +209 -0
  96. package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/provider.ts +24 -0
  97. package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/theming.ts +129 -0
  98. package/fuse-starter-pack/fuse-v21.1/src/app/core/transloco/transloco-http-loader.ts +12 -0
  99. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/data/navigation.ts +176 -0
  100. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/layout.ts +77 -0
  101. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/language-switcher.ts +91 -0
  102. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/navigation.ts +238 -0
  103. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/notifications.ts +252 -0
  104. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/scheme-switcher.ts +58 -0
  105. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/sidebar.ts +31 -0
  106. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/user.ts +132 -0
  107. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/data/academy.ts +753 -0
  108. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/data/model.ts +27 -0
  109. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/features/course.ts +318 -0
  110. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/features/courses.ts +228 -0
  111. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/routes.ts +14 -0
  112. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/data/contacts.ts +4372 -0
  113. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/data/model.ts +34 -0
  114. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/features/contact.ts +239 -0
  115. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/features/contacts.ts +185 -0
  116. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/routes.ts +16 -0
  117. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/data/file-manager.ts +261 -0
  118. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/data/model.ts +12 -0
  119. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/features/file-manager.ts +131 -0
  120. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/routes.ts +15 -0
  121. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/ui/list.ts +164 -0
  122. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/features/faq.ts +288 -0
  123. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/features/guide.ts +134 -0
  124. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/features/home.ts +219 -0
  125. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/features/support.ts +161 -0
  126. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/routes.ts +33 -0
  127. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/data/model.ts +18 -0
  128. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/data/notes.ts +324 -0
  129. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/features/note.ts +152 -0
  130. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/features/notes.ts +118 -0
  131. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/routes.ts +16 -0
  132. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/data/model.ts +17 -0
  133. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/data/tasks.ts +562 -0
  134. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/features/task.ts +195 -0
  135. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/features/tasks.ts +271 -0
  136. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/routes.ts +16 -0
  137. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/data/analytics.ts +1620 -0
  138. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/data/finance.ts +1065 -0
  139. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/data/project.ts +376 -0
  140. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/features/analytics/analytics.ts +1096 -0
  141. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/features/finance/finance.ts +658 -0
  142. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/features/project/budget-table.ts +188 -0
  143. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/features/project/project.ts +565 -0
  144. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/routes.ts +23 -0
  145. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/features/changelog/changelog.ts +932 -0
  146. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/features/getting-started/building.ts +33 -0
  147. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/features/getting-started/development.ts +42 -0
  148. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/features/getting-started/installation.ts +47 -0
  149. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/layout.ts +9 -0
  150. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/routes.ts +45 -0
  151. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/error/features/error-page.ts +70 -0
  152. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/error/routes.ts +21 -0
  153. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/notifications/features/notifications.ts +262 -0
  154. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/notifications/routes.ts +10 -0
  155. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/account.ts +238 -0
  156. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/notifications.ts +134 -0
  157. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/plan-and-billing.ts +238 -0
  158. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/security.ts +211 -0
  159. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/team.ts +188 -0
  160. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/layout.ts +109 -0
  161. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/routes.ts +37 -0
  162. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/welcome/welcome.component.ts +22 -0
  163. package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/routes.ts +95 -0
  164. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/forgot-password/forgot-password.html +54 -0
  165. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/forgot-password/forgot-password.ts +51 -0
  166. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/reset-password/reset-password.html +82 -0
  167. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/reset-password/reset-password.ts +69 -0
  168. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/sign-in/sign-in.html +132 -0
  169. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/sign-in/sign-in.ts +54 -0
  170. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/sign-up/sign-up.html +183 -0
  171. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/sign-up/sign-up.ts +56 -0
  172. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/layout.ts +9 -0
  173. package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/routes.ts +34 -0
  174. package/fuse-starter-pack/fuse-v21.1/src/app/domains/coming-soon/features/coming-soon.ts +156 -0
  175. package/fuse-starter-pack/fuse-v21.1/src/app/domains/coming-soon/layout.ts +9 -0
  176. package/fuse-starter-pack/fuse-v21.1/src/app/domains/coming-soon/routes.ts +16 -0
  177. package/fuse-starter-pack/fuse-v21.1/src/app/domains/website/layout/layout.ts +9 -0
  178. package/fuse-starter-pack/fuse-v21.1/src/app/domains/website/modules/home/features/home.ts +23 -0
  179. package/fuse-starter-pack/fuse-v21.1/src/app/domains/website/modules/home/routes.ts +10 -0
  180. package/fuse-starter-pack/fuse-v21.1/src/app/domains/website/routes.ts +30 -0
  181. package/fuse-starter-pack/fuse-v21.1/src/environments/environment.mock.ts +5 -0
  182. package/fuse-starter-pack/fuse-v21.1/src/environments/environment.prod.ts +5 -0
  183. package/fuse-starter-pack/fuse-v21.1/src/environments/environment.ts +5 -0
  184. package/fuse-starter-pack/fuse-v21.1/src/index.html +66 -0
  185. package/fuse-starter-pack/fuse-v21.1/src/main.server.ts +11 -0
  186. package/fuse-starter-pack/fuse-v21.1/src/main.ts +5 -0
  187. package/fuse-starter-pack/fuse-v21.1/src/server.ts +70 -0
  188. package/fuse-starter-pack/fuse-v21.1/src/styles/base/base.css +63 -0
  189. package/fuse-starter-pack/fuse-v21.1/src/styles/base/typography.css +54 -0
  190. package/fuse-starter-pack/fuse-v21.1/src/styles/components/a.css +18 -0
  191. package/fuse-starter-pack/fuse-v21.1/src/styles/components/input.css +22 -0
  192. package/fuse-starter-pack/fuse-v21.1/src/styles/components/kbd.css +55 -0
  193. package/fuse-starter-pack/fuse-v21.1/src/styles/components/material.css +1149 -0
  194. package/fuse-starter-pack/fuse-v21.1/src/styles/styles.css +31 -0
  195. package/fuse-starter-pack/fuse-v21.1/src/styles/tailwind/theme.css +147 -0
  196. package/fuse-starter-pack/fuse-v21.1/src/styles/tailwind/utilities.css +563 -0
  197. package/fuse-starter-pack/fuse-v21.1/src/styles/tailwind/variants.css +4 -0
  198. package/fuse-starter-pack/fuse-v21.1/src/styles/third-party/lucide-icons.css +12 -0
  199. package/fuse-starter-pack/fuse-v21.1/tsconfig.app.json +16 -0
  200. package/fuse-starter-pack/fuse-v21.1/tsconfig.json +37 -0
  201. package/fuse-starter-pack/fuse-v21.1/tsconfig.spec.json +10 -0
  202. package/generator/README.md +12 -0
  203. package/generator/issues/.gitkeep +0 -0
  204. package/package.json +56 -4
  205. package/playwright.config.js +29 -0
  206. package/playwright.field-profile.config.js +6 -0
  207. package/playwright.iam-live.config.js +31 -0
  208. package/playwright.iam.config.js +29 -0
  209. package/playwright.list-state.config.js +6 -0
  210. package/playwright.performance.config.js +1 -0
  211. package/run-config-tests.sh +5 -0
  212. package/scripts/e2e-paths.js +89 -0
  213. package/scripts/e2e-prepare-field-profile.js +17 -0
  214. package/scripts/e2e-prepare-iam-live.js +135 -0
  215. package/scripts/e2e-prepare-iam.js +65 -0
  216. package/scripts/e2e-prepare.js +72 -0
  217. package/scripts/e2e-serve-iam-live.js +28 -0
  218. package/scripts/e2e-serve-iam.js +28 -0
  219. package/scripts/e2e-serve.js +28 -0
  220. package/scripts/performance/generate.js +17 -0
  221. package/scripts/performance/measure.js +55 -0
  222. package/scripts/postinstall.js +9 -0
  223. package/scripts/prepare-quality-apps.js +34 -0
  224. package/scripts/run-config-tests.js +63 -0
  225. package/src/assets/logo-with-lable.jpeg +0 -0
  226. package/src/assets/logo.jpeg +0 -0
  227. package/src/commands/bootstrap.js +92 -0
  228. package/src/commands/doctor.js +403 -0
  229. package/src/commands/generate.js +301 -0
  230. package/src/commands/init-config.js +310 -0
  231. package/src/commands/keycloak-options.js +182 -0
  232. package/src/commands/validate.js +52 -0
  233. package/src/config/auth-config.js +183 -0
  234. package/src/config/default-values.js +235 -0
  235. package/src/config/env-refs.js +71 -0
  236. package/src/config/field-preferences.js +99 -0
  237. package/src/config/input-sources.js +104 -0
  238. package/src/config/load-config.js +166 -0
  239. package/src/config/proxy-routes.js +44 -0
  240. package/src/generator/access-control-tools.js +334 -0
  241. package/src/generator/ai-docs.js +691 -0
  242. package/src/generator/application-tests.js +252 -0
  243. package/src/generator/auth-pack.js +965 -0
  244. package/src/generator/embed-config.js +431 -0
  245. package/src/generator/entity-layout.js +30 -0
  246. package/src/generator/fuse-build.js +57 -0
  247. package/src/generator/fuse-runtime.js +344 -0
  248. package/src/generator/generated-banner.js +137 -0
  249. package/src/generator/index.js +874 -0
  250. package/src/generator/project-output.js +126 -0
  251. package/src/generator/team-pack.js +220 -0
  252. package/src/index.js +68 -0
  253. package/src/parser/gdl-parser.js +169 -0
  254. package/src/parser/jdl-parser.js +171 -0
  255. package/src/presets/pmb-test.js +139 -0
  256. package/src/presets/static-source.js +73 -0
  257. package/src/presets/store.js +96 -0
  258. package/src/provision/admin-service.js +148 -0
  259. package/src/provision/bootstrap.js +147 -0
  260. package/src/provision/http.js +123 -0
  261. package/src/provision/keycloak-admin-rest.js +335 -0
  262. package/src/provision/state.js +51 -0
  263. package/src/provision/token.js +52 -0
  264. package/src/templates/angular/auth/access-control.service.ts.ejs +179 -0
  265. package/src/templates/angular/auth/access-ctrl.pipe.ts.ejs +20 -0
  266. package/src/templates/angular/auth/auth.guard.ts.ejs +27 -0
  267. package/src/templates/angular/auth/auth.interceptor.ts.ejs +53 -0
  268. package/src/templates/angular/auth/auth.service.ts.ejs +594 -0
  269. package/src/templates/angular/auth/auth.utils.ts.ejs +28 -0
  270. package/src/templates/angular/auth/current-user.ts.ejs +24 -0
  271. package/src/templates/angular/auth/disabled-account-overlay.component.css.ejs +95 -0
  272. package/src/templates/angular/auth/disabled-account-overlay.component.html.ejs +33 -0
  273. package/src/templates/angular/auth/disabled-account-overlay.component.ts.ejs +23 -0
  274. package/src/templates/angular/auth/fuse-account.ts.ejs +234 -0
  275. package/src/templates/angular/auth/fuse-user.ts.ejs +264 -0
  276. package/src/templates/angular/auth/has-permission.directive.ts.ejs +51 -0
  277. package/src/templates/angular/auth/index.ts.ejs +24 -0
  278. package/src/templates/angular/auth/keycloak-admin.service.ts.ejs +670 -0
  279. package/src/templates/angular/auth/landing.guard.ts.ejs +61 -0
  280. package/src/templates/angular/auth/no-auth.guard.ts.ejs +19 -0
  281. package/src/templates/angular/auth/permission-attribute.util.ts.ejs +182 -0
  282. package/src/templates/angular/auth/sign-in.ts.ejs +60 -0
  283. package/src/templates/angular/entity/_entity_.model.ts.ejs +64 -0
  284. package/src/templates/angular/entity/_entity_.routes.ts.ejs +9 -0
  285. package/src/templates/angular/entity/components/forms/form/_entity_-form.component.html.ejs +168 -0
  286. package/src/templates/angular/entity/components/forms/form/_entity_-form.component.ts.ejs +175 -0
  287. package/src/templates/angular/entity/components/forms/form-page/_entity_-form-page.component.html.ejs +10 -0
  288. package/src/templates/angular/entity/components/forms/form-page/_entity_-form-page.component.ts.ejs +86 -0
  289. package/src/templates/angular/entity/components/forms/update/_entity_-form.service.ts.ejs +136 -0
  290. package/src/templates/angular/entity/components/interaction/actions/_entity_-actions.component.html.ejs +68 -0
  291. package/src/templates/angular/entity/components/interaction/actions/_entity_-actions.component.ts.ejs +69 -0
  292. package/src/templates/angular/entity/components/interaction/filter/_entity_-filter.component.html.ejs +111 -0
  293. package/src/templates/angular/entity/components/interaction/filter/_entity_-filter.component.ts.ejs +102 -0
  294. package/src/templates/angular/entity/components/presentation/card/_entity_-card.component.css.ejs +33 -0
  295. package/src/templates/angular/entity/components/presentation/card/_entity_-card.component.html.ejs +29 -0
  296. package/src/templates/angular/entity/components/presentation/card/_entity_-card.component.ts.ejs +93 -0
  297. package/src/templates/angular/entity/components/presentation/detail/_entity_-detail.component.css.ejs +54 -0
  298. package/src/templates/angular/entity/components/presentation/detail/_entity_-detail.component.html.ejs +58 -0
  299. package/src/templates/angular/entity/components/presentation/detail/_entity_-detail.component.ts.ejs +47 -0
  300. package/src/templates/angular/entity/components/presentation/list/_entity_-list.component.html.ejs +419 -0
  301. package/src/templates/angular/entity/components/presentation/list/_entity_-list.component.scss.ejs +48 -0
  302. package/src/templates/angular/entity/components/presentation/list/_entity_-list.component.ts.ejs +592 -0
  303. package/src/templates/angular/entity/service/_entity_.service.ts.ejs +153 -0
  304. package/src/templates/angular/entity/settings/_entity_.settings.ts.ejs +49 -0
  305. package/src/templates/angular/enums/_enum_.model.ts.ejs +11 -0
  306. package/src/templates/angular/iam/change-password.component.html.ejs +39 -0
  307. package/src/templates/angular/iam/change-password.component.ts.ejs +44 -0
  308. package/src/templates/angular/iam/no-access.component.ts.ejs +17 -0
  309. package/src/templates/angular/iam/role-list.component.html.ejs +331 -0
  310. package/src/templates/angular/iam/role-list.component.scss.ejs +107 -0
  311. package/src/templates/angular/iam/role-list.component.ts.ejs +597 -0
  312. package/src/templates/angular/iam/role-management/role-header.component.html.ejs +51 -0
  313. package/src/templates/angular/iam/role-management/role-header.component.ts.ejs +45 -0
  314. package/src/templates/angular/iam/role-management/role-inheritance.component.html.ejs +15 -0
  315. package/src/templates/angular/iam/role-management/role-inheritance.component.ts.ejs +19 -0
  316. package/src/templates/angular/iam/role-management/role-permissions-panel.component.css.ejs +24 -0
  317. package/src/templates/angular/iam/role-management/role-permissions-panel.component.html.ejs +108 -0
  318. package/src/templates/angular/iam/role-management/role-permissions-panel.component.ts.ejs +122 -0
  319. package/src/templates/angular/iam/role-management/role-users.component.html.ejs +104 -0
  320. package/src/templates/angular/iam/role-management/role-users.component.ts.ejs +53 -0
  321. package/src/templates/angular/iam/role-management/user-select-dialog.component.html.ejs +113 -0
  322. package/src/templates/angular/iam/role-management/user-select-dialog.component.ts.ejs +157 -0
  323. package/src/templates/angular/iam/role-permission-matrix.component.html.ejs +355 -0
  324. package/src/templates/angular/iam/role-permission-matrix.component.scss.ejs +217 -0
  325. package/src/templates/angular/iam/role-permission-matrix.component.ts.ejs +800 -0
  326. package/src/templates/angular/iam/screen-catalog.ts.ejs +147 -0
  327. package/src/templates/angular/iam/shared/confirm-dialog.component.ts.ejs +83 -0
  328. package/src/templates/angular/iam/shared/matrix-hierarchy.util.ts.ejs +196 -0
  329. package/src/templates/angular/iam/shared/permission-matrix-sound.ts.ejs +59 -0
  330. package/src/templates/angular/iam/shared/role-display.util.ts.ejs +43 -0
  331. package/src/templates/angular/iam/shared/role-permission-skeleton.component.ts.ejs +54 -0
  332. package/src/templates/angular/iam/shared/screen-matrix.util.ts.ejs +554 -0
  333. package/src/templates/angular/iam/shared/screen-navigation-map.ts.ejs +187 -0
  334. package/src/templates/angular/iam/shared/screen-navigation.registry.ts.ejs +64 -0
  335. package/src/templates/angular/iam/shared/text-highlight.pipe.ts.ejs +39 -0
  336. package/src/templates/angular/iam/user-access-matrix.component.html.ejs +212 -0
  337. package/src/templates/angular/iam/user-access-matrix.component.scss.ejs +34 -0
  338. package/src/templates/angular/iam/user-access-matrix.component.ts.ejs +239 -0
  339. package/src/templates/angular/iam/user-detail.component.html.ejs +143 -0
  340. package/src/templates/angular/iam/user-detail.component.ts.ejs +108 -0
  341. package/src/templates/angular/iam/user-form.component.html.ejs +63 -0
  342. package/src/templates/angular/iam/user-form.component.ts.ejs +100 -0
  343. package/src/templates/angular/iam/user-list.component.html.ejs +369 -0
  344. package/src/templates/angular/iam/user-list.component.scss.ejs +242 -0
  345. package/src/templates/angular/iam/user-list.component.ts.ejs +446 -0
  346. package/src/templates/angular/iam/user-management.routes.ts.ejs +47 -0
  347. package/src/templates/angular/iam/user-permission-matrix.component.html.ejs +231 -0
  348. package/src/templates/angular/iam/user-permission-matrix.component.scss.ejs +216 -0
  349. package/src/templates/angular/iam/user-permission-matrix.component.ts.ejs +516 -0
  350. package/src/templates/angular/shared/base/audit-user-name.pipe.ts.ejs +69 -0
  351. package/src/templates/angular/shared/base/base-filter.component.ts.ejs +245 -0
  352. package/src/templates/angular/shared/base/base-form.component.ts.ejs +109 -0
  353. package/src/templates/angular/shared/base/base-list.component.ts.ejs +507 -0
  354. package/src/templates/angular/shared/base/filter-types.ts.ejs +55 -0
  355. package/src/templates/angular/shared/base/input-format.directive.ts.ejs +47 -0
  356. package/src/templates/angular/shared/base/input-format.ts.ejs +15 -0
  357. package/src/templates/angular/shared/confirm-with-input-dialog.component.ts.ejs +91 -0
  358. package/src/templates/angular/shared/confirmation-dialog.component.ts.ejs +80 -0
  359. package/src/templates/angular/shared/list-styles.css.ejs +103 -0
  360. package/src/templates/angular/shared/loading-overlay.component.ts.ejs +24 -0
  361. package/src/templates/angular/shared/resizable.directive.ts.ejs +115 -0
  362. package/src/templates/angular/shared/snackbar-styles.css.ejs +11 -0
  363. package/src/templates/fuse-packs/access-control-tools/access-control-sync.js +819 -0
  364. package/src/templates/fuse-packs/access-control-tools/build-rename-map.js +67 -0
  365. package/src/templates/fuse-packs/access-control-tools/inject-qa-ids.js +14 -0
  366. package/src/templates/fuse-packs/access-control-tools/lib/hierarchy-scanner.js +628 -0
  367. package/src/templates/fuse-packs/access-control-tools/lib/hierarchy-scanner.test.js +323 -0
  368. package/src/templates/fuse-packs/access-control-tools/lib/html-scanner.js +362 -0
  369. package/src/templates/fuse-packs/access-control-tools/lib/id-rules.duplicate.test.js +136 -0
  370. package/src/templates/fuse-packs/access-control-tools/lib/id-rules.js +1095 -0
  371. package/src/templates/fuse-packs/access-control-tools/lib/ts-component-index.js +482 -0
  372. package/src/templates/fuse-packs/access-control-tools/output/.gitkeep +0 -0
  373. package/src/templates/fuse-packs/access-control-tools/run.sh +223 -0
  374. package/src/templates/fuse-packs/access-control-tools/scan-access-control.js +14 -0
  375. package/src/templates/fuse-packs/iam-assets/sound/apple-play.mp3 +0 -0
  376. package/src/templates/fuse-packs/iam-assets/sound/remove.mp3 +0 -0
  377. package/src/templates/generator/README.md +12 -0
  378. package/src/templates/testing/ci.cjs +45 -0
  379. package/src/templates/testing/mock.cjs +149 -0
  380. package/src/templates/testing/playwright.config.cjs +25 -0
  381. package/src/templates/testing/serve.cjs +22 -0
  382. package/src/templates/testing/smoke.spec.cjs +180 -0
  383. package/src/utils/branding.js +39 -0
  384. package/src/utils/colors.js +18 -0
  385. package/src/utils/diff.js +109 -0
  386. package/src/utils/merger.js +115 -0
  387. package/src/validator/backend-diagnostics.js +30 -0
  388. package/src/validator/blueprint-validator.js +276 -0
  389. package/src/validator/diagnostics.js +608 -0
  390. package/src/validator/pattern.js +28 -0
  391. package/test/auth-interceptor.js +84 -0
  392. package/test/auth-provision-checks.js +297 -0
  393. package/test/field-preferences.js +145 -0
  394. package/test/fixtures/field-profile.gdl +7 -0
  395. package/test/fixtures/mock.jdl +17 -0
  396. package/test/fixtures/mock.png +0 -0
  397. package/test/fixtures/performance/config.yml +33 -0
  398. package/test/fixtures/performance/large.gdl +199 -0
  399. package/test/fixtures/performance/small.gdl +7 -0
  400. package/test/fixtures/quality/custom.yml +22 -0
  401. package/test/fixtures/quality/go-duck.yml +22 -0
  402. package/test/fixtures/quality/jhipster.yml +30 -0
  403. package/test/fixtures/quality/representative.gdl +14 -0
  404. package/test/list-state.js +138 -0
  405. package/test/micro-functions-layout.js +95 -0
  406. package/test/performance-generation.js +32 -0
  407. package/test/pmb-preset.js +127 -0
  408. package/test/project-workflow.js +111 -0
  409. package/test/quality-features.js +250 -0
  410. package/test/verify-commands.js +83 -0
  411. package/test/verify.js +959 -0
  412. package/test-files/GDL/example.gdl +15 -0
  413. package/test-files/JDL/example.jdl +15 -0
  414. package/test-files/config/crudforge.config.yml +127 -0
  415. package/test-run.sh +272 -0
@@ -0,0 +1,111 @@
1
+ {
2
+ "machine": {
3
+ "platform": "darwin",
4
+ "arch": "arm64",
5
+ "cpus": 11,
6
+ "node": "v24.19.0"
7
+ },
8
+ "commands": {
9
+ "build": "node node_modules/@angular/cli/bin/ng.js build --configuration production --stats-json",
10
+ "serve": "node node_modules/@angular/cli/bin/ng.js serve --host 127.0.0.1 --port 4301",
11
+ "workers": 2
12
+ },
13
+ "fixtures": {
14
+ "small": {
15
+ "coldBuildSeconds": 4.325572875,
16
+ "warmBuildSeconds": 2.783962625,
17
+ "initialBytes": 655268,
18
+ "initialFiles": [
19
+ "styles-3TRNVMYE.css",
20
+ "chunk-NDOSOM7F.js",
21
+ "chunk-BWAQPUGJ.js",
22
+ "chunk-NSEZI5HP.js",
23
+ "chunk-2CGR3MGZ.js",
24
+ "chunk-JKJ4OYD6.js",
25
+ "chunk-UTORK2V4.js",
26
+ "chunk-QWS5T5GV.js",
27
+ "chunk-KWCZCL72.js",
28
+ "chunk-O7K3GK2S.js",
29
+ "chunk-SFBWYKT6.js",
30
+ "main-CFTZP4TH.js"
31
+ ],
32
+ "serverBundle": false,
33
+ "coldDevStartupSeconds": 2.122047791000001,
34
+ "browser": [
35
+ {
36
+ "interactiveMs": 954.5875830000004,
37
+ "fcpMs": null,
38
+ "entityLoadMs": 296.59912500000064,
39
+ "reloadMs": 314.25275000000147,
40
+ "paginationReads": 1,
41
+ "errors": []
42
+ },
43
+ {
44
+ "interactiveMs": 132.7291669999995,
45
+ "fcpMs": null,
46
+ "entityLoadMs": 274.55783299999894,
47
+ "reloadMs": 282.9455419999995,
48
+ "paginationReads": 1,
49
+ "errors": []
50
+ },
51
+ {
52
+ "interactiveMs": 132.1135830000003,
53
+ "fcpMs": null,
54
+ "entityLoadMs": 270.77529200000026,
55
+ "reloadMs": 300.5688339999997,
56
+ "paginationReads": 1,
57
+ "errors": []
58
+ }
59
+ ],
60
+ "rebuildSeconds": 1.1119830419999999
61
+ },
62
+ "large": {
63
+ "coldBuildSeconds": 8.916114916,
64
+ "warmBuildSeconds": 7.083413082999999,
65
+ "initialBytes": 657476,
66
+ "initialFiles": [
67
+ "styles-3TRNVMYE.css",
68
+ "chunk-NDOSOM7F.js",
69
+ "chunk-BWAQPUGJ.js",
70
+ "chunk-KES7LWDN.js",
71
+ "chunk-2CGR3MGZ.js",
72
+ "chunk-JKJ4OYD6.js",
73
+ "chunk-UTORK2V4.js",
74
+ "chunk-QWS5T5GV.js",
75
+ "chunk-KWCZCL72.js",
76
+ "chunk-O7K3GK2S.js",
77
+ "chunk-SFBWYKT6.js",
78
+ "main-PW4HZ76G.js"
79
+ ],
80
+ "serverBundle": false,
81
+ "coldDevStartupSeconds": 6.968824999999997,
82
+ "browser": [
83
+ {
84
+ "interactiveMs": 1120.5042499999981,
85
+ "fcpMs": null,
86
+ "entityLoadMs": 317.80737500000396,
87
+ "reloadMs": 333.49874999999884,
88
+ "paginationReads": 1,
89
+ "errors": []
90
+ },
91
+ {
92
+ "interactiveMs": 134.8382500000007,
93
+ "fcpMs": null,
94
+ "entityLoadMs": 296.3120409999974,
95
+ "reloadMs": 381.8153749999983,
96
+ "paginationReads": 1,
97
+ "errors": []
98
+ },
99
+ {
100
+ "interactiveMs": 137.86237499999697,
101
+ "fcpMs": null,
102
+ "entityLoadMs": 295.4111669999984,
103
+ "reloadMs": 291.98920799999905,
104
+ "paginationReads": 1,
105
+ "errors": []
106
+ }
107
+ ],
108
+ "rebuildSeconds": 6.060445290999996
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,111 @@
1
+ {
2
+ "machine": {
3
+ "platform": "darwin",
4
+ "arch": "arm64",
5
+ "cpus": 11,
6
+ "node": "v24.19.0"
7
+ },
8
+ "commands": {
9
+ "build": "node node_modules/@angular/cli/bin/ng.js build --configuration production --stats-json",
10
+ "serve": "node node_modules/@angular/cli/bin/ng.js serve --host 127.0.0.1 --port 4301",
11
+ "workers": 2
12
+ },
13
+ "fixtures": {
14
+ "small": {
15
+ "coldBuildSeconds": 7.520871584,
16
+ "warmBuildSeconds": 5.613279083,
17
+ "initialBytes": 1002588,
18
+ "initialFiles": [
19
+ "styles-4E7FUNNQ.css",
20
+ "chunk-BYVIJEIQ.js",
21
+ "chunk-XDBVZKKQ.js",
22
+ "chunk-7EHZJMZS.js",
23
+ "chunk-RTKC6PBC.js",
24
+ "chunk-CO7JMNBJ.js",
25
+ "chunk-DCCJNBDI.js",
26
+ "chunk-G523QTT6.js",
27
+ "chunk-P5WENFS4.js",
28
+ "chunk-CGQZTJAX.js",
29
+ "chunk-CBEDY7LG.js",
30
+ "main-5LKUABOL.js"
31
+ ],
32
+ "serverBundle": true,
33
+ "coldDevStartupSeconds": 3.029542209000001,
34
+ "browser": [
35
+ {
36
+ "interactiveMs": 3774.997625,
37
+ "fcpMs": 3612,
38
+ "entityLoadMs": 442.23766700000124,
39
+ "reloadMs": 428.81758400000035,
40
+ "paginationReads": 2,
41
+ "errors": []
42
+ },
43
+ {
44
+ "interactiveMs": 190.69912499999919,
45
+ "fcpMs": 92,
46
+ "entityLoadMs": 345.5164999999979,
47
+ "reloadMs": 373.8043749999997,
48
+ "paginationReads": 2,
49
+ "errors": []
50
+ },
51
+ {
52
+ "interactiveMs": 177.2548330000027,
53
+ "fcpMs": 76,
54
+ "entityLoadMs": 342.033958,
55
+ "reloadMs": 519.2770000000019,
56
+ "paginationReads": 2,
57
+ "errors": []
58
+ }
59
+ ],
60
+ "rebuildSeconds": 1.6145452910000022
61
+ },
62
+ "large": {
63
+ "coldBuildSeconds": 14.040262583000004,
64
+ "warmBuildSeconds": 9.634600542,
65
+ "initialBytes": 1004796,
66
+ "initialFiles": [
67
+ "styles-4E7FUNNQ.css",
68
+ "chunk-BYVIJEIQ.js",
69
+ "chunk-XDBVZKKQ.js",
70
+ "chunk-334JRSXR.js",
71
+ "chunk-RTKC6PBC.js",
72
+ "chunk-CO7JMNBJ.js",
73
+ "chunk-DCCJNBDI.js",
74
+ "chunk-G523QTT6.js",
75
+ "chunk-P5WENFS4.js",
76
+ "chunk-CGQZTJAX.js",
77
+ "chunk-CBEDY7LG.js",
78
+ "main-AX5WANX6.js"
79
+ ],
80
+ "serverBundle": true,
81
+ "coldDevStartupSeconds": 8.382417332999998,
82
+ "browser": [
83
+ {
84
+ "interactiveMs": 4752.308290999994,
85
+ "fcpMs": 4576,
86
+ "entityLoadMs": 695.3545000000013,
87
+ "reloadMs": 480.5537089999998,
88
+ "paginationReads": 2,
89
+ "errors": []
90
+ },
91
+ {
92
+ "interactiveMs": 171.2327920000098,
93
+ "fcpMs": 84,
94
+ "entityLoadMs": 521.7752499999915,
95
+ "reloadMs": 488.31937499999185,
96
+ "paginationReads": 2,
97
+ "errors": []
98
+ },
99
+ {
100
+ "interactiveMs": 182.0655839999963,
101
+ "fcpMs": 76,
102
+ "entityLoadMs": 469.2784580000007,
103
+ "reloadMs": 405.61333300000115,
104
+ "paginationReads": 2,
105
+ "errors": []
106
+ }
107
+ ],
108
+ "rebuildSeconds": 6.975476750000001
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,276 @@
1
+ # Generated tests, validation, and doctor
2
+
3
+ These features are optional additions to initialize → edit → generate. They do not
4
+ create backend infrastructure, change authentication providers, or infer backend
5
+ capabilities from a product name.
6
+
7
+ ## Project configuration
8
+
9
+ Add this to `config/crudforge.config.yml` before generation:
10
+
11
+ ```yaml
12
+ generate:
13
+ globals:
14
+ tests: true
15
+
16
+ testing:
17
+ ci: true
18
+ fixtures:
19
+ Farmer:
20
+ referenceCode: AB12
21
+
22
+ backend:
23
+ kind: custom
24
+
25
+ doctor:
26
+ timeoutMs: 3000
27
+ endpoints: []
28
+ ```
29
+
30
+ `generate.globals.tests` defaults to false; previously it emitted no tests. The
31
+ older example's `generate.tests` is not the supported setting. `testing.ci` defaults
32
+ to false and requires test generation. Tests currently target complete Fuse apps,
33
+ with generated list components, forms and routes. Component-only output has no
34
+ standalone application to start, so requesting tests for that output is rejected.
35
+
36
+ `testing.fixtures` supplies synthetic field values, particularly for pattern rules
37
+ that cannot be safely guessed. Omit this mapping when unnecessary. Do not store real
38
+ passwords, tokens, or customer records in fixtures. Primitive fields and enums get
39
+ sample values; relationships reference records in the related entity's mock collection.
40
+
41
+ `backend.kind` is informational and can identify GO-DUCK, JHipster, or a custom backend.
42
+ It never changes naming conventions or certifies a live contract. Configure the
43
+ existing `api.microservice`, `api.baseUrl`, `api.services`, proxy, and auth settings
44
+ for the actual deployment. Current generated services use zero-based page/size,
45
+ array responses and `X-Total-Count`, with kebab-plural paths and Dayjs dates. A backend
46
+ with different behavior needs a tested adapter; unsupported service modes produce
47
+ explicit diagnostics instead of being silently ignored.
48
+
49
+ ## Run the application tests
50
+
51
+ ```bash
52
+ crudforge generate --dry-run
53
+ # Review conflicts; use the existing explicit overwrite policy when appropriate.
54
+ crudforge generate
55
+ npm ci
56
+ npm run test:smoke:install
57
+ npm run build
58
+ npm run test:smoke
59
+ ```
60
+
61
+ The generated app declares its required Node version in `package.json`; the bundled
62
+ Angular 21 starter requires Node 24+. Playwright is pinned in both the generated
63
+ manifest and lockfile. Generation itself does not install packages or browsers.
64
+
65
+ The test server uses port **4297** on `127.0.0.1`. It starts its own server and refuses
66
+ to reuse an existing one. Tests use a separate Angular build configuration, an empty
67
+ proxy configuration, and SSR disabled. HTTP/API/auth requests are intercepted in the
68
+ browser; unknown requests are blocked. Service workers are disabled and external
69
+ WebSocket connections are blocked. Only local application assets and the local dev
70
+ server's WebSocket are allowed. Production environments and normal `npm start` are
71
+ not switched to mock mode.
72
+
73
+ The suite covers startup, each entity's navigation and pagination, required text or
74
+ numeric fields when present, create/edit submissions, failed-save recovery, loading
75
+ and failed-list recovery. Authentication-enabled apps also check the synthetic user
76
+ identity across refresh. Generated tests verify UI and HTTP behavior against mocks;
77
+ they do **not** verify real credentials, server-side permissions, database persistence,
78
+ production routing, or full backend compatibility.
79
+
80
+ Tests use a development build for observable loading behavior; CI separately runs
81
+ the unchanged strict production build. They are smoke tests, not exhaustive
82
+ business-rule coverage. Advanced custom controls/workflows need custom tests.
83
+
84
+ ## Add a developer-owned test
85
+
86
+ Generator-managed files are in `tests/generated/`. Create your own file at
87
+ `tests/custom/dashboard.spec.cjs`:
88
+
89
+ ```js
90
+ const { test, expect } = require('../generated/mock.cjs');
91
+
92
+ test('my dashboard opens', async ({ page, backend }) => {
93
+ await backend.login(page);
94
+ await page.goto('/admin/my-dashboard');
95
+ await expect(page.getByRole('heading', { name: 'My Dashboard' })).toBeVisible();
96
+ });
97
+ ```
98
+
99
+ Replace the route and heading with your screen. Both folders run through
100
+ `npm run test:smoke`. The generator never emits files into `tests/custom/`.
101
+ Normal conflict policies apply to generated tests, package files, and the generated
102
+ CI workflow. Changes to generator-managed files are not silently accepted or overwritten
103
+ by the project generation command. Prefer custom tests for application-specific assertions.
104
+
105
+ ## CI
106
+
107
+ `testing.ci: true` emits `.github/workflows/crudforge-smoke.yml`. It checks out source,
108
+ selects Node using package.json, installs dependencies, runs the strict production
109
+ build, installs Chromium, and runs the smoke suite. Failure artifacts include the
110
+ HTML report and screenshots, retained for seven days. Tracing/video are disabled.
111
+ Fixtures are synthetic; do not introduce live secrets or live requests into custom tests
112
+ whose screenshots may be uploaded.
113
+
114
+ The underlying commands also work outside GitHub Actions:
115
+
116
+ ```bash
117
+ node tests/generated/ci.cjs install
118
+ node tests/generated/ci.cjs build
119
+ node tests/generated/ci.cjs browsers
120
+ node tests/generated/ci.cjs test
121
+ ```
122
+
123
+ The helper requires exactly one lockfile matching `package.json.packageManager`
124
+ when that field is declared. It uses npm ci, pnpm frozen-lockfile, Yarn 1 frozen-lockfile,
125
+ or modern Yarn immutable installs. Fresh CRUDForge apps use npm and package-lock.json.
126
+ Changing package managers and converting the lockfile is a deliberate developer action,
127
+ not something the generator or doctor does automatically. Pin non-npm manager versions
128
+ in `packageManager`; the workflow installs Corepack to make those managers available.
129
+
130
+ The test server working directory is explicit, as documented by
131
+ [Playwright](https://playwright.dev/docs/test-webserver). Service-worker isolation follows
132
+ [Playwright's routing guidance](https://playwright.dev/docs/service-workers).
133
+ Node selection follows [setup-node's version-file support](https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md).
134
+
135
+ ## Shared schema validation
136
+
137
+ ```bash
138
+ crudforge validate gdl/example.gdl --preferences config/crudforge.config.yml
139
+ crudforge validate gdl/example.gdl --preferences config/crudforge.config.yml --json
140
+ crudforge generate --json --yes
141
+ ```
142
+
143
+ `validate-gdl` and `validate-jdl` accept the same options. The CLI validate and generate
144
+ commands and `generateFromSource` use one diagnostic/parse pipeline. It checks syntax,
145
+ duplicate declarations/fields, known types, enum values, rule applicability and ranges,
146
+ relationship targets, display-field references, relationship/scalar/FK collisions,
147
+ audit-field collisions, TypeScript-safe identifiers, output filename collisions,
148
+ unsupported annotations, and configured field preferences. Balanced blocks are parsed
149
+ without truncating regex quantifier braces in fields.
150
+
151
+ Diagnostics have `severity`, `code`, `file`, `line`, `column`, optional `entity`/`field`,
152
+ `message`, and `suggestion`. JSON output is a single object with `ok`, `diagnostics`,
153
+ and entity count. Generate also accepts `--json` (progress goes to stderr). Errors exit 1; warnings alone exit 0. Configuration/read failures
154
+ also exit 1. Backend contract checks are kept separate from general schema checks.
155
+
156
+ Unknown annotations and unimplemented behavior are errors. The frontend supports
157
+ `@Audited` in GDL and `@EnableAudit` in JDL. Backend-only annotations such as SoftDelete
158
+ are not silently discarded. Custom relationship display-field arguments are currently
159
+ rejected: selectors use name, title or id. Plain relationship fields are supported.
160
+ Naming styles are not forced to GO-DUCK or JHipster conventions.
161
+
162
+ **Compatibility change:** `validation: false` no longer bypasses the fail-fast gate.
163
+ Invalid schemas stop generation before application files are written. The existing
164
+ low-level parser exports remain available, but generation uses the validated structure.
165
+
166
+ ## Doctor: local checks
167
+
168
+ ```bash
169
+ cd crudforge-app
170
+ crudforge doctor
171
+ crudforge doctor --json
172
+ crudforge doctor --preferences config/crudforge.config.yml
173
+ ```
174
+
175
+ Local checks make no HTTP requests. They check CLI version, project/config discovery,
176
+ schema diagnostics, Node engine compatibility, starter/output paths, dependency
177
+ presence, package-manager/lockfile consistency, npm root dependency drift, development
178
+ port availability, and API/proxy/auth configuration. Port checks briefly bind and close
179
+ an IPv4 loopback socket; an occupied or unbindable port is a warning, never a reason to
180
+ kill a process. Yarn PnP resolution is reported as unverified rather than executed.
181
+
182
+ Doctor never installs dependencies, modifies files, provisions services, or sends
183
+ write requests. It prints pass/warning/fail results and next steps. Known sensitive
184
+ configuration values are redacted. Malformed configuration is reported without dumping
185
+ its contents. Exit 0 means no failed checks; warnings remain visible. Exit 1 means a
186
+ failed check or inability to complete diagnosis. It is not proof that CRUD works.
187
+
188
+ ## Optional live checks
189
+
190
+ Only configure endpoints that your backend documents as read-only:
191
+
192
+ ```yaml
193
+ doctor:
194
+ timeoutMs: 2000
195
+ endpoints:
196
+ - url: http://127.0.0.1:8080/documented-read-only-status
197
+ description: Replace this URL with the service's documented read-only status endpoint.
198
+ ```
199
+
200
+ ```bash
201
+ crudforge doctor --live
202
+ crudforge doctor --live --json
203
+ ```
204
+
205
+ Doctor does not invent a health endpoint or attach credentials. Endpoints must use
206
+ HTTP(S), with no URL credentials, query parameters or fragments. It sends GET only,
207
+ does not follow redirects, and applies a 100–10000 ms deadline per endpoint. Responses
208
+ are categorized as reachable, authentication required (401), access denied (403),
209
+ endpoint/client failure, server failure, transport failure, or timeout. Authentication
210
+ requirements/denials are warnings, not proof of a broken server. No response bodies
211
+ or tokens are printed.
212
+
213
+ ## If `crudforge` is not found
214
+
215
+ A shell PATH problem occurs before doctor can run. Use the repository entry point:
216
+
217
+ ```bash
218
+ node /Users/abdulla/Work/crud-fordge/cli.js doctor \
219
+ --preferences /path/to/crudforge-app/config/crudforge.config.yml
220
+ ```
221
+
222
+ If dependencies are missing, run `npm ci` in the CRUDForge repository yourself. To
223
+ make the short command available, run `npm link` there, then `command -v crudforge`.
224
+ Check that your active Node installation's npm global bin directory is on PATH.
225
+ Doctor does not perform installation or change shell settings.
226
+
227
+ ## Maintainer verification
228
+
229
+ ```bash
230
+ npm test
231
+ npm run test:quality
232
+ npm run test:field-preferences
233
+ npm run test:auth
234
+ npm run test:ui-state
235
+ npm run test:performance
236
+ node scripts/prepare-quality-apps.js /tmp/crudforge-quality-check
237
+ ```
238
+
239
+ The last command requires a new output directory and generates GO-DUCK-labelled,
240
+ JHipster-labelled and custom configurations with different API prefixes and auth
241
+ modes. Each uses the same documented HTTP response contract; the labels do not claim
242
+ live vendor integration. In each generated directory, run the CI commands above.
243
+ The representative GDL includes enums, required values, dates, booleans, a regex pattern,
244
+ and a relationship. No live backend is involved.
245
+
246
+ ## Verification results (October 11, 2026)
247
+
248
+ The repository test suite and the field-preference, authentication, UI-state, and
249
+ performance regressions passed. The quality regression suite also passed after
250
+ final validation changes. It covers malformed schemas, structured CLI failures,
251
+ custom-test preservation, local doctor failures, HTTP status classification and
252
+ timeouts, and package-manager command selection.
253
+
254
+ Fresh generated applications passed these checks on this machine:
255
+
256
+ - A clean `npm ci` and strict production build in the representative application.
257
+ - GO-DUCK-labelled configuration: 8 mocked browser tests passed.
258
+ - JHipster-labelled configuration: 9 mocked browser tests and production build passed.
259
+ - Custom API-prefix configuration: 8 mocked browser tests and production build passed.
260
+ - SSR-configured application: 8 browser tests passed using the isolated browser-only
261
+ smoke configuration. Its normal SSR production build was not run in this task.
262
+
263
+ Browser verification used installed Chrome through
264
+ `CRUDFORGE_BROWSER_CHANNEL=chrome npm run test:smoke`. Generated CI instead installs
265
+ Playwright Chromium. The GitHub-hosted workflow was not executed; npm installation
266
+ was exercised locally, while pnpm/Yarn command selection was regression-tested.
267
+ No real backend, real account, or production record was used. These results verify
268
+ frontend behavior against configured mock contracts, not GO-DUCK/JHipster server
269
+ compatibility or live authentication.
270
+
271
+ The implementation is concentrated in `src/generator/application-tests.js` and
272
+ `src/templates/testing/`, the shared `src/validator/diagnostics.js` pipeline and
273
+ backend/pattern helpers, and `src/commands/doctor.js`. CLI wiring, configuration
274
+ schemas/defaults, generation/validation entry points, and the form-validation
275
+ template integrate these features. Fixtures and regressions live in
276
+ `test/fixtures/quality/` and `test/quality-features.js`.
@@ -0,0 +1,47 @@
1
+ project:
2
+ name: CRUDForge E2E
3
+ description: Generated Fuse app used by Playwright
4
+
5
+ output:
6
+ # Overridden by scripts/e2e-prepare*.js → $CRUDFORGE_TESTING_AREA/crudforge-app
7
+ directory: "./e2e/.app"
8
+ structure: "entity-folder"
9
+ overwritePolicy: "overwrite"
10
+ embedConfig: true
11
+ teamPack:
12
+ enabled: true
13
+
14
+ validation: true
15
+
16
+ fuse:
17
+ enabled: true
18
+ cleanLayout: true
19
+ includePrebuilt: false
20
+ folderType: ""
21
+ theme:
22
+ scheme: "light"
23
+ primary: "#0f766e"
24
+ error: "#b91c1c"
25
+
26
+ ui:
27
+ framework: "material"
28
+ viewMode: "table"
29
+ formMode: "sidebar"
30
+ searchMode: "field"
31
+ snackbarPositionTop: false
32
+
33
+ api:
34
+ baseUrl: "/api"
35
+ microservice: "book-service"
36
+ endpointStyle: "kebab-plural"
37
+ dateLibrary: "dayjs"
38
+ responseType: "http-response"
39
+
40
+ mock:
41
+ enabled: true
42
+ recordsPerEntity: 12
43
+ values:
44
+ stringPrefix: "Mock "
45
+ numberMin: 1
46
+ numberMax: 1000
47
+ booleanDefault: true
@@ -0,0 +1,33 @@
1
+ project:
2
+ name: Field and profile regression fixture
3
+ output:
4
+ directory: ./e2e/.field-profile
5
+ overwritePolicy: overwrite
6
+ fuse:
7
+ enabled: true
8
+ cleanLayout: true
9
+ includePrebuilt: false
10
+ api:
11
+ microservice: pmb-reference-module
12
+ baseUrl: /api
13
+ mock:
14
+ enabled: false
15
+ fields:
16
+ entities:
17
+ Province:
18
+ fields:
19
+ provinceCode: { inputFormat: uppercase }
20
+ provinceName: { inputFormat: lowercase }
21
+ index: { inputFormat: none }
22
+ auth:
23
+ provider: keycloak
24
+ realm: test
25
+ clientId: test-client
26
+ # Deliberately non-live: Playwright intercepts every auth and API request.
27
+ serverUrl: http://127.0.0.1:9999
28
+ useMockAuth: false
29
+ provision:
30
+ enabled: false
31
+ adminServiceUrl: http://127.0.0.1:9999
32
+ iam:
33
+ enabled: false