@team-codeme/crud-forge 0.0.0-stage โ 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/agents/generator-engineer.md +31 -0
- package/.cursor/agents/keycloak-engineer.md +33 -0
- package/.cursor/agents/qa-engineer.md +32 -0
- package/.cursor/agents/security-reviewer.md +30 -0
- package/.cursor/mcp.json +13 -0
- package/.cursor/rules/crudforge-precautions.mdc +16 -0
- package/.cursor/rules/playwright-browser.mdc +30 -0
- package/.cursor/rules/readme-todo-sync.mdc +13 -0
- package/.env.qa.example +19 -0
- package/.github/workflows/qa-live.yml +32 -0
- package/.github/workflows/qa.yml +27 -0
- package/.vscode/settings.json +32 -0
- package/QA/IAM-PLAN.md +25 -0
- package/QA/IAM-RESULTS.md +39 -0
- package/QA/IAM-TESTCASES.md +36 -0
- package/QA/IAM-TODO.md +7 -0
- package/QA/KEYCLOAK-BOOTSTRAP.md +105 -0
- package/QA/PLAN.md +43 -0
- package/QA/RESULTS.md +59 -0
- package/QA/TESTCASES.md +65 -0
- package/QA/TODO.md +14 -0
- package/QA/pmb-dev/README.md +49 -0
- package/QA/pmb-dev/config/config.yml +152 -0
- package/QA/pmb-dev/gdl/i.gdl +17 -0
- package/README.md +851 -2
- package/Todo.md +207 -0
- package/assets/branding/crudforge-logo.png +0 -0
- package/assets/branding/crudforge-mark.png +0 -0
- package/branding/poster-crudforge.jpg +0 -0
- package/chat/last-chat/Investigating Mock Data Configuration.md +428 -0
- package/cli.js +167 -0
- package/config/default-config.yml +245 -0
- package/docs/performance/README.md +217 -0
- package/docs/performance/after.json +111 -0
- package/docs/performance/before.json +111 -0
- package/docs/quality/README.md +276 -0
- package/e2e/crudforge.e2e.yml +47 -0
- package/e2e/crudforge.field-profile.yml +33 -0
- package/e2e/crudforge.iam-live.yml +124 -0
- package/e2e/crudforge.iam.yml +62 -0
- package/e2e/tests/field-profile.spec.js +152 -0
- package/e2e/tests/generated-crud.spec.js +251 -0
- package/e2e/tests/iam-live.spec.js +149 -0
- package/e2e/tests/iam-pack.spec.js +151 -0
- package/e2e/tests/list-state.spec.js +73 -0
- package/features.csv +27 -0
- package/fuse-starter-pack/branding/crudforge-mark-source.jpg +0 -0
- package/fuse-starter-pack/branding/crudforge-mark-source.png +0 -0
- package/fuse-starter-pack/branding/crudforge-mark.png +0 -0
- package/fuse-starter-pack/branding/crudforge-wordmark-source.jpg +0 -0
- package/fuse-starter-pack/branding/crudforge-wordmark-source.png +0 -0
- package/fuse-starter-pack/branding/crudforge-wordmark.png +0 -0
- package/fuse-starter-pack/fuse-v21.1/Dockerfile +14 -0
- package/fuse-starter-pack/fuse-v21.1/LICENSE.md +6 -0
- package/fuse-starter-pack/fuse-v21.1/README.md +59 -0
- package/fuse-starter-pack/fuse-v21.1/angular.json +113 -0
- package/fuse-starter-pack/fuse-v21.1/eslint.config.ts +150 -0
- package/fuse-starter-pack/fuse-v21.1/nginx.conf +23 -0
- package/fuse-starter-pack/fuse-v21.1/nginx.dev.conf +18 -0
- package/fuse-starter-pack/fuse-v21.1/package-lock.json +11513 -0
- package/fuse-starter-pack/fuse-v21.1/package.json +69 -0
- package/fuse-starter-pack/fuse-v21.1/postcss.config.json +5 -0
- package/fuse-starter-pack/fuse-v21.1/prettier.config.ts +15 -0
- package/fuse-starter-pack/fuse-v21.1/proxy.conf.json +8 -0
- package/fuse-starter-pack/fuse-v21.1/proxy.dev.conf.json +8 -0
- package/fuse-starter-pack/fuse-v21.1/public/favicon.png +0 -0
- package/fuse-starter-pack/fuse-v21.1/public/fonts/geist/Geist-Italic.woff2 +0 -0
- package/fuse-starter-pack/fuse-v21.1/public/fonts/geist/Geist.woff2 +0 -0
- package/fuse-starter-pack/fuse-v21.1/public/fonts/geist/GeistMono-Italic.woff2 +0 -0
- package/fuse-starter-pack/fuse-v21.1/public/fonts/geist/GeistMono.woff2 +0 -0
- package/fuse-starter-pack/fuse-v21.1/public/i18n/en.json +8 -0
- package/fuse-starter-pack/fuse-v21.1/public/i18n/es.json +8 -0
- package/fuse-starter-pack/fuse-v21.1/public/images/flags/ES.svg +79 -0
- package/fuse-starter-pack/fuse-v21.1/public/images/flags/US.svg +14 -0
- package/fuse-starter-pack/fuse-v21.1/public/images/flags/where-to-find-other-flags.txt +5 -0
- package/fuse-starter-pack/fuse-v21.1/public/images/logo/logo-mark.png +0 -0
- package/fuse-starter-pack/fuse-v21.1/public/images/logo/logo.png +0 -0
- package/fuse-starter-pack/fuse-v21.1/push.sh +27 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/app.config.server.ts +10 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/app.config.ts +64 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/app.routes.server.ts +8 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/app.routes.ts +39 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/app.ts +22 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/icons/index.ts +1 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/icons/lucide.ts +1 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/icons/provider.ts +23 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/local-storage/index.ts +2 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/local-storage/local-storage.ts +109 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/local-storage/provider.ts +15 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/media/index.ts +2 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/media/media.ts +64 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/media/provider.ts +15 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/index.ts +3 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/models/theming.ts +13 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/palette.ts +209 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/provider.ts +24 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/theming/theming.ts +129 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/core/transloco/transloco-http-loader.ts +12 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/data/navigation.ts +176 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/layout.ts +77 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/language-switcher.ts +91 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/navigation.ts +238 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/notifications.ts +252 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/scheme-switcher.ts +58 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/sidebar.ts +31 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/layout/ui/user.ts +132 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/data/academy.ts +753 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/data/model.ts +27 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/features/course.ts +318 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/features/courses.ts +228 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/academy/routes.ts +14 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/data/contacts.ts +4372 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/data/model.ts +34 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/features/contact.ts +239 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/features/contacts.ts +185 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/contacts/routes.ts +16 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/data/file-manager.ts +261 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/data/model.ts +12 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/features/file-manager.ts +131 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/routes.ts +15 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/file-manager/ui/list.ts +164 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/features/faq.ts +288 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/features/guide.ts +134 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/features/home.ts +219 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/features/support.ts +161 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/help-center/routes.ts +33 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/data/model.ts +18 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/data/notes.ts +324 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/features/note.ts +152 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/features/notes.ts +118 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/notes/routes.ts +16 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/data/model.ts +17 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/data/tasks.ts +562 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/features/task.ts +195 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/features/tasks.ts +271 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/apps/tasks/routes.ts +16 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/data/analytics.ts +1620 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/data/finance.ts +1065 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/data/project.ts +376 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/features/analytics/analytics.ts +1096 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/features/finance/finance.ts +658 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/features/project/budget-table.ts +188 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/features/project/project.ts +565 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/dashboards/routes.ts +23 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/features/changelog/changelog.ts +932 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/features/getting-started/building.ts +33 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/features/getting-started/development.ts +42 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/features/getting-started/installation.ts +47 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/layout.ts +9 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/documentation/routes.ts +45 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/error/features/error-page.ts +70 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/error/routes.ts +21 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/notifications/features/notifications.ts +262 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/notifications/routes.ts +10 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/account.ts +238 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/notifications.ts +134 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/plan-and-billing.ts +238 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/security.ts +211 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/features/team.ts +188 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/layout.ts +109 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/settings/routes.ts +37 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/modules/extras/welcome/welcome.component.ts +22 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/admin/routes.ts +95 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/forgot-password/forgot-password.html +54 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/forgot-password/forgot-password.ts +51 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/reset-password/reset-password.html +82 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/reset-password/reset-password.ts +69 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/sign-in/sign-in.html +132 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/sign-in/sign-in.ts +54 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/sign-up/sign-up.html +183 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/features/sign-up/sign-up.ts +56 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/layout.ts +9 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/auth/routes.ts +34 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/coming-soon/features/coming-soon.ts +156 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/coming-soon/layout.ts +9 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/coming-soon/routes.ts +16 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/website/layout/layout.ts +9 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/website/modules/home/features/home.ts +23 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/website/modules/home/routes.ts +10 -0
- package/fuse-starter-pack/fuse-v21.1/src/app/domains/website/routes.ts +30 -0
- package/fuse-starter-pack/fuse-v21.1/src/environments/environment.mock.ts +5 -0
- package/fuse-starter-pack/fuse-v21.1/src/environments/environment.prod.ts +5 -0
- package/fuse-starter-pack/fuse-v21.1/src/environments/environment.ts +5 -0
- package/fuse-starter-pack/fuse-v21.1/src/index.html +66 -0
- package/fuse-starter-pack/fuse-v21.1/src/main.server.ts +11 -0
- package/fuse-starter-pack/fuse-v21.1/src/main.ts +5 -0
- package/fuse-starter-pack/fuse-v21.1/src/server.ts +70 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/base/base.css +63 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/base/typography.css +54 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/components/a.css +18 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/components/input.css +22 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/components/kbd.css +55 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/components/material.css +1149 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/styles.css +31 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/tailwind/theme.css +147 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/tailwind/utilities.css +563 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/tailwind/variants.css +4 -0
- package/fuse-starter-pack/fuse-v21.1/src/styles/third-party/lucide-icons.css +12 -0
- package/fuse-starter-pack/fuse-v21.1/tsconfig.app.json +16 -0
- package/fuse-starter-pack/fuse-v21.1/tsconfig.json +37 -0
- package/fuse-starter-pack/fuse-v21.1/tsconfig.spec.json +10 -0
- package/generator/README.md +12 -0
- package/generator/issues/.gitkeep +0 -0
- package/package.json +56 -4
- package/playwright.config.js +29 -0
- package/playwright.field-profile.config.js +6 -0
- package/playwright.iam-live.config.js +31 -0
- package/playwright.iam.config.js +29 -0
- package/playwright.list-state.config.js +6 -0
- package/playwright.performance.config.js +1 -0
- package/run-config-tests.sh +5 -0
- package/scripts/e2e-paths.js +89 -0
- package/scripts/e2e-prepare-field-profile.js +17 -0
- package/scripts/e2e-prepare-iam-live.js +135 -0
- package/scripts/e2e-prepare-iam.js +65 -0
- package/scripts/e2e-prepare.js +72 -0
- package/scripts/e2e-serve-iam-live.js +28 -0
- package/scripts/e2e-serve-iam.js +28 -0
- package/scripts/e2e-serve.js +28 -0
- package/scripts/performance/generate.js +17 -0
- package/scripts/performance/measure.js +55 -0
- package/scripts/postinstall.js +9 -0
- package/scripts/prepare-quality-apps.js +34 -0
- package/scripts/run-config-tests.js +63 -0
- package/src/assets/logo-with-lable.jpeg +0 -0
- package/src/assets/logo.jpeg +0 -0
- package/src/commands/bootstrap.js +92 -0
- package/src/commands/doctor.js +403 -0
- package/src/commands/generate.js +301 -0
- package/src/commands/init-config.js +310 -0
- package/src/commands/keycloak-options.js +182 -0
- package/src/commands/validate.js +52 -0
- package/src/config/auth-config.js +183 -0
- package/src/config/default-values.js +235 -0
- package/src/config/env-refs.js +71 -0
- package/src/config/field-preferences.js +99 -0
- package/src/config/input-sources.js +104 -0
- package/src/config/load-config.js +166 -0
- package/src/config/proxy-routes.js +44 -0
- package/src/generator/access-control-tools.js +334 -0
- package/src/generator/ai-docs.js +691 -0
- package/src/generator/application-tests.js +252 -0
- package/src/generator/auth-pack.js +965 -0
- package/src/generator/embed-config.js +431 -0
- package/src/generator/entity-layout.js +30 -0
- package/src/generator/fuse-build.js +57 -0
- package/src/generator/fuse-runtime.js +344 -0
- package/src/generator/generated-banner.js +137 -0
- package/src/generator/index.js +874 -0
- package/src/generator/project-output.js +126 -0
- package/src/generator/team-pack.js +220 -0
- package/src/index.js +68 -0
- package/src/parser/gdl-parser.js +169 -0
- package/src/parser/jdl-parser.js +171 -0
- package/src/presets/pmb-test.js +139 -0
- package/src/presets/static-source.js +73 -0
- package/src/presets/store.js +96 -0
- package/src/provision/admin-service.js +148 -0
- package/src/provision/bootstrap.js +147 -0
- package/src/provision/http.js +123 -0
- package/src/provision/keycloak-admin-rest.js +335 -0
- package/src/provision/state.js +51 -0
- package/src/provision/token.js +52 -0
- package/src/templates/angular/auth/access-control.service.ts.ejs +179 -0
- package/src/templates/angular/auth/access-ctrl.pipe.ts.ejs +20 -0
- package/src/templates/angular/auth/auth.guard.ts.ejs +27 -0
- package/src/templates/angular/auth/auth.interceptor.ts.ejs +53 -0
- package/src/templates/angular/auth/auth.service.ts.ejs +594 -0
- package/src/templates/angular/auth/auth.utils.ts.ejs +28 -0
- package/src/templates/angular/auth/current-user.ts.ejs +24 -0
- package/src/templates/angular/auth/disabled-account-overlay.component.css.ejs +95 -0
- package/src/templates/angular/auth/disabled-account-overlay.component.html.ejs +33 -0
- package/src/templates/angular/auth/disabled-account-overlay.component.ts.ejs +23 -0
- package/src/templates/angular/auth/fuse-account.ts.ejs +234 -0
- package/src/templates/angular/auth/fuse-user.ts.ejs +264 -0
- package/src/templates/angular/auth/has-permission.directive.ts.ejs +51 -0
- package/src/templates/angular/auth/index.ts.ejs +24 -0
- package/src/templates/angular/auth/keycloak-admin.service.ts.ejs +670 -0
- package/src/templates/angular/auth/landing.guard.ts.ejs +61 -0
- package/src/templates/angular/auth/no-auth.guard.ts.ejs +19 -0
- package/src/templates/angular/auth/permission-attribute.util.ts.ejs +182 -0
- package/src/templates/angular/auth/sign-in.ts.ejs +60 -0
- package/src/templates/angular/entity/_entity_.model.ts.ejs +64 -0
- package/src/templates/angular/entity/_entity_.routes.ts.ejs +9 -0
- package/src/templates/angular/entity/components/forms/form/_entity_-form.component.html.ejs +168 -0
- package/src/templates/angular/entity/components/forms/form/_entity_-form.component.ts.ejs +175 -0
- package/src/templates/angular/entity/components/forms/form-page/_entity_-form-page.component.html.ejs +10 -0
- package/src/templates/angular/entity/components/forms/form-page/_entity_-form-page.component.ts.ejs +86 -0
- package/src/templates/angular/entity/components/forms/update/_entity_-form.service.ts.ejs +136 -0
- package/src/templates/angular/entity/components/interaction/actions/_entity_-actions.component.html.ejs +68 -0
- package/src/templates/angular/entity/components/interaction/actions/_entity_-actions.component.ts.ejs +69 -0
- package/src/templates/angular/entity/components/interaction/filter/_entity_-filter.component.html.ejs +111 -0
- package/src/templates/angular/entity/components/interaction/filter/_entity_-filter.component.ts.ejs +102 -0
- package/src/templates/angular/entity/components/presentation/card/_entity_-card.component.css.ejs +33 -0
- package/src/templates/angular/entity/components/presentation/card/_entity_-card.component.html.ejs +29 -0
- package/src/templates/angular/entity/components/presentation/card/_entity_-card.component.ts.ejs +93 -0
- package/src/templates/angular/entity/components/presentation/detail/_entity_-detail.component.css.ejs +54 -0
- package/src/templates/angular/entity/components/presentation/detail/_entity_-detail.component.html.ejs +58 -0
- package/src/templates/angular/entity/components/presentation/detail/_entity_-detail.component.ts.ejs +47 -0
- package/src/templates/angular/entity/components/presentation/list/_entity_-list.component.html.ejs +419 -0
- package/src/templates/angular/entity/components/presentation/list/_entity_-list.component.scss.ejs +48 -0
- package/src/templates/angular/entity/components/presentation/list/_entity_-list.component.ts.ejs +592 -0
- package/src/templates/angular/entity/service/_entity_.service.ts.ejs +153 -0
- package/src/templates/angular/entity/settings/_entity_.settings.ts.ejs +49 -0
- package/src/templates/angular/enums/_enum_.model.ts.ejs +11 -0
- package/src/templates/angular/iam/change-password.component.html.ejs +39 -0
- package/src/templates/angular/iam/change-password.component.ts.ejs +44 -0
- package/src/templates/angular/iam/no-access.component.ts.ejs +17 -0
- package/src/templates/angular/iam/role-list.component.html.ejs +331 -0
- package/src/templates/angular/iam/role-list.component.scss.ejs +107 -0
- package/src/templates/angular/iam/role-list.component.ts.ejs +597 -0
- package/src/templates/angular/iam/role-management/role-header.component.html.ejs +51 -0
- package/src/templates/angular/iam/role-management/role-header.component.ts.ejs +45 -0
- package/src/templates/angular/iam/role-management/role-inheritance.component.html.ejs +15 -0
- package/src/templates/angular/iam/role-management/role-inheritance.component.ts.ejs +19 -0
- package/src/templates/angular/iam/role-management/role-permissions-panel.component.css.ejs +24 -0
- package/src/templates/angular/iam/role-management/role-permissions-panel.component.html.ejs +108 -0
- package/src/templates/angular/iam/role-management/role-permissions-panel.component.ts.ejs +122 -0
- package/src/templates/angular/iam/role-management/role-users.component.html.ejs +104 -0
- package/src/templates/angular/iam/role-management/role-users.component.ts.ejs +53 -0
- package/src/templates/angular/iam/role-management/user-select-dialog.component.html.ejs +113 -0
- package/src/templates/angular/iam/role-management/user-select-dialog.component.ts.ejs +157 -0
- package/src/templates/angular/iam/role-permission-matrix.component.html.ejs +355 -0
- package/src/templates/angular/iam/role-permission-matrix.component.scss.ejs +217 -0
- package/src/templates/angular/iam/role-permission-matrix.component.ts.ejs +800 -0
- package/src/templates/angular/iam/screen-catalog.ts.ejs +147 -0
- package/src/templates/angular/iam/shared/confirm-dialog.component.ts.ejs +83 -0
- package/src/templates/angular/iam/shared/matrix-hierarchy.util.ts.ejs +196 -0
- package/src/templates/angular/iam/shared/permission-matrix-sound.ts.ejs +59 -0
- package/src/templates/angular/iam/shared/role-display.util.ts.ejs +43 -0
- package/src/templates/angular/iam/shared/role-permission-skeleton.component.ts.ejs +54 -0
- package/src/templates/angular/iam/shared/screen-matrix.util.ts.ejs +554 -0
- package/src/templates/angular/iam/shared/screen-navigation-map.ts.ejs +187 -0
- package/src/templates/angular/iam/shared/screen-navigation.registry.ts.ejs +64 -0
- package/src/templates/angular/iam/shared/text-highlight.pipe.ts.ejs +39 -0
- package/src/templates/angular/iam/user-access-matrix.component.html.ejs +212 -0
- package/src/templates/angular/iam/user-access-matrix.component.scss.ejs +34 -0
- package/src/templates/angular/iam/user-access-matrix.component.ts.ejs +239 -0
- package/src/templates/angular/iam/user-detail.component.html.ejs +143 -0
- package/src/templates/angular/iam/user-detail.component.ts.ejs +108 -0
- package/src/templates/angular/iam/user-form.component.html.ejs +63 -0
- package/src/templates/angular/iam/user-form.component.ts.ejs +100 -0
- package/src/templates/angular/iam/user-list.component.html.ejs +369 -0
- package/src/templates/angular/iam/user-list.component.scss.ejs +242 -0
- package/src/templates/angular/iam/user-list.component.ts.ejs +446 -0
- package/src/templates/angular/iam/user-management.routes.ts.ejs +47 -0
- package/src/templates/angular/iam/user-permission-matrix.component.html.ejs +231 -0
- package/src/templates/angular/iam/user-permission-matrix.component.scss.ejs +216 -0
- package/src/templates/angular/iam/user-permission-matrix.component.ts.ejs +516 -0
- package/src/templates/angular/shared/base/audit-user-name.pipe.ts.ejs +69 -0
- package/src/templates/angular/shared/base/base-filter.component.ts.ejs +245 -0
- package/src/templates/angular/shared/base/base-form.component.ts.ejs +109 -0
- package/src/templates/angular/shared/base/base-list.component.ts.ejs +507 -0
- package/src/templates/angular/shared/base/filter-types.ts.ejs +55 -0
- package/src/templates/angular/shared/base/input-format.directive.ts.ejs +47 -0
- package/src/templates/angular/shared/base/input-format.ts.ejs +15 -0
- package/src/templates/angular/shared/confirm-with-input-dialog.component.ts.ejs +91 -0
- package/src/templates/angular/shared/confirmation-dialog.component.ts.ejs +80 -0
- package/src/templates/angular/shared/list-styles.css.ejs +103 -0
- package/src/templates/angular/shared/loading-overlay.component.ts.ejs +24 -0
- package/src/templates/angular/shared/resizable.directive.ts.ejs +115 -0
- package/src/templates/angular/shared/snackbar-styles.css.ejs +11 -0
- package/src/templates/fuse-packs/access-control-tools/access-control-sync.js +819 -0
- package/src/templates/fuse-packs/access-control-tools/build-rename-map.js +67 -0
- package/src/templates/fuse-packs/access-control-tools/inject-qa-ids.js +14 -0
- package/src/templates/fuse-packs/access-control-tools/lib/hierarchy-scanner.js +628 -0
- package/src/templates/fuse-packs/access-control-tools/lib/hierarchy-scanner.test.js +323 -0
- package/src/templates/fuse-packs/access-control-tools/lib/html-scanner.js +362 -0
- package/src/templates/fuse-packs/access-control-tools/lib/id-rules.duplicate.test.js +136 -0
- package/src/templates/fuse-packs/access-control-tools/lib/id-rules.js +1095 -0
- package/src/templates/fuse-packs/access-control-tools/lib/ts-component-index.js +482 -0
- package/src/templates/fuse-packs/access-control-tools/output/.gitkeep +0 -0
- package/src/templates/fuse-packs/access-control-tools/run.sh +223 -0
- package/src/templates/fuse-packs/access-control-tools/scan-access-control.js +14 -0
- package/src/templates/fuse-packs/iam-assets/sound/apple-play.mp3 +0 -0
- package/src/templates/fuse-packs/iam-assets/sound/remove.mp3 +0 -0
- package/src/templates/generator/README.md +12 -0
- package/src/templates/testing/ci.cjs +45 -0
- package/src/templates/testing/mock.cjs +149 -0
- package/src/templates/testing/playwright.config.cjs +25 -0
- package/src/templates/testing/serve.cjs +22 -0
- package/src/templates/testing/smoke.spec.cjs +180 -0
- package/src/utils/branding.js +39 -0
- package/src/utils/colors.js +18 -0
- package/src/utils/diff.js +109 -0
- package/src/utils/merger.js +115 -0
- package/src/validator/backend-diagnostics.js +30 -0
- package/src/validator/blueprint-validator.js +276 -0
- package/src/validator/diagnostics.js +608 -0
- package/src/validator/pattern.js +28 -0
- package/test/auth-interceptor.js +84 -0
- package/test/auth-provision-checks.js +297 -0
- package/test/field-preferences.js +145 -0
- package/test/fixtures/field-profile.gdl +7 -0
- package/test/fixtures/mock.jdl +17 -0
- package/test/fixtures/mock.png +0 -0
- package/test/fixtures/performance/config.yml +33 -0
- package/test/fixtures/performance/large.gdl +199 -0
- package/test/fixtures/performance/small.gdl +7 -0
- package/test/fixtures/quality/custom.yml +22 -0
- package/test/fixtures/quality/go-duck.yml +22 -0
- package/test/fixtures/quality/jhipster.yml +30 -0
- package/test/fixtures/quality/representative.gdl +14 -0
- package/test/list-state.js +138 -0
- package/test/micro-functions-layout.js +95 -0
- package/test/performance-generation.js +32 -0
- package/test/pmb-preset.js +127 -0
- package/test/project-workflow.js +111 -0
- package/test/quality-features.js +250 -0
- package/test/verify-commands.js +83 -0
- package/test/verify.js +959 -0
- package/test-files/GDL/example.gdl +15 -0
- package/test-files/JDL/example.jdl +15 -0
- package/test-files/config/crudforge.config.yml +127 -0
- package/test-run.sh +272 -0
package/README.md
CHANGED
|
@@ -1,3 +1,852 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @team-codeme/crud-forge
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
```text
|
|
4
|
+
____ ____ _ _ ____ _____ _ ___
|
|
5
|
+
/ ___| _ \| | | | _ \| ___|__ _ __ __ _ ___ | | |_ _|
|
|
6
|
+
| | | |_) | | | | | | | |_ / _ \| '__/ _` |/ _ \ | | | |
|
|
7
|
+
| |___| _ <| |_| | |_| | _| (_) | | | (_| | __/ | |___ | |
|
|
8
|
+
\____|_| \_\___/|____/|_| \___/|_| \__, |\___| |_____|___|
|
|
9
|
+
|___/
|
|
10
|
+
Developed by TeamCodeMe
|
|
11
|
+
Official Website: https://crudforge.teamcodeme.com/
|
|
12
|
+
Documentation: https://crudforge-cli-doc.vercel.app
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
<div align="center">
|
|
18
|
+
|
|
19
|
+
[](https://crudforge.teamcodeme.com/)
|
|
20
|
+
[](https://crudforge-cli-doc.vercel.app)
|
|
21
|
+
[](https://www.npmjs.com/package/@team-codeme/crud-forge)
|
|
22
|
+
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
CRUDForge CLI is a high-performance, developer-configurable Angular Material CRUD code generator. It maps JDL (JHipster Domain Language) or GDL schemas directly into high-fidelity standalone Angular 17+ components, types, services, and routes.
|
|
26
|
+
|
|
27
|
+
- ๐ **Official Website:** [https://crudforge.teamcodeme.com/](https://crudforge.teamcodeme.com/)
|
|
28
|
+
- ๐ **Documentation:** [https://crudforge-cli-doc.vercel.app](https://crudforge-cli-doc.vercel.app)
|
|
29
|
+
- ๐ข **Organization:** [@team-codeme](https://www.npmjs.com/org/team-codeme)
|
|
30
|
+
|
|
31
|
+
**Product docs (deployable Starlight site):** Available live at [crudforge-cli-doc.vercel.app](https://crudforge-cli-doc.vercel.app) (source in sibling repo [`crud-fordge-doc`](../crud-fordge-doc)) โ splash uses the same poster; Features / Customization galleries with screenshots. Capture shots: `npm run e2e:serve` then `cd ../crud-fordge-doc && npm run shots:capture` (IAM: `e2e:serve:iam` + `shots:capture:iam`).
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## ๐ Layout Structure
|
|
36
|
+
|
|
37
|
+
CRUDForge structures entity templates under a responsibility-based directory layout:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
src/templates/angular/
|
|
41
|
+
โโโ entity/
|
|
42
|
+
โโโ _entity_.model.ts.ejs # Angular domain models
|
|
43
|
+
โโโ _entity_.routes.ts.ejs # Routing config
|
|
44
|
+
โโโ service/
|
|
45
|
+
โ โโโ _entity_.service.ts.ejs # REST client data services
|
|
46
|
+
โโโ components/
|
|
47
|
+
โ โโโ presentation/ # Read-only UI layouts
|
|
48
|
+
โ โ โโโ card/ # Compact tile displays
|
|
49
|
+
โ โ โโโ detail/ # Detailed properties sheet
|
|
50
|
+
โ โ โโโ list/ # Central pagination table
|
|
51
|
+
โ โโโ forms/ # Input and update logic
|
|
52
|
+
โ โ โโโ form/ # Reusable form component
|
|
53
|
+
โ โ โโโ form-page/ # Independent route page
|
|
54
|
+
โ โ โโโ update/ # Reactive FormGroup validation mapper
|
|
55
|
+
โ โโโ interaction/ # Control actions & query filtering
|
|
56
|
+
โ โโโ actions/ # Action buttons and query filters toolbar
|
|
57
|
+
โ โโโ filter/ # Advanced search/filter sidebar panel
|
|
58
|
+
โโโ shared/ # (Generated inside each entity or centralized)
|
|
59
|
+
โโโ base/ # Centralized abstract base classes
|
|
60
|
+
โ โโโ base-filter.component.ts.ejs # Shared filter logic & reactive forms
|
|
61
|
+
โ โโโ base-form.component.ts.ejs # Shared form state & error handling
|
|
62
|
+
โ โโโ base-list.component.ts.ejs # Shared pagination, export, & row states
|
|
63
|
+
โ โโโ filter-types.ts.ejs # Shared filter types
|
|
64
|
+
โโโ confirmation-dialog.component.ts.ejs # Generic confirmation dialog
|
|
65
|
+
โโโ resizable.directive.ts.ejs # Table column resizing directive
|
|
66
|
+
โโโ snackbar-styles.css.ejs # Global snackbar theming
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
When code is generated, the target directory matches this structure to promote strict modularity and clean imports in the generated Angular application.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## ๐ฆ Installation
|
|
74
|
+
|
|
75
|
+
To install CRUDForge CLI globally on your system:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm install -g @team-codeme/crud-forge
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Or run directly without installation using `npx`:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx @team-codeme/crud-forge init my-app
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## ๐ ๏ธ CLI Usage
|
|
90
|
+
|
|
91
|
+
### Initialize โ edit โ generate
|
|
92
|
+
|
|
93
|
+
Start with editable project inputs, before generating Angular:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
crudforge init crudforge-app
|
|
97
|
+
cd crudforge-app
|
|
98
|
+
# Edit config/crudforge.config.yml and gdl/example.gdl
|
|
99
|
+
crudforge generate
|
|
100
|
+
npm install
|
|
101
|
+
npm run dev
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`init` creates only these two files in a new or empty directory:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
crudforge-app/
|
|
108
|
+
โโโ config/
|
|
109
|
+
โ โโโ crudforge.config.yml
|
|
110
|
+
โโโ gdl/
|
|
111
|
+
โโโ example.gdl
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The default sample uses the supported GDL syntax (type before field name):
|
|
115
|
+
|
|
116
|
+
```gdl
|
|
117
|
+
entity Book {
|
|
118
|
+
string title required
|
|
119
|
+
bigDecimal price
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Supported entity annotations (GDL):
|
|
124
|
+
|
|
125
|
+
| Annotation | Effect |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `@Audited` | Injects configured audit fields (`createdBy`, `createdDate`, โฆ) |
|
|
128
|
+
| `@Searchable` | Marks the entity for list search; searchable columns prefer text/enum fields |
|
|
129
|
+
| `@ActiveStatus` | Injects `bool isActive` on the model (skipped if already declared); enables list activate/deactivate |
|
|
130
|
+
|
|
131
|
+
JDL equivalents: `@EnableAudit`, `@Searchable`, `@ActiveStatus`. Other annotations (e.g. `@SoftDelete`) still fail validation.
|
|
132
|
+
|
|
133
|
+
The generated configuration includes the existing project settings and these workflow defaults:
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
input:
|
|
137
|
+
type: gdl
|
|
138
|
+
file: ./gdl/example.gdl # single schema (legacy)
|
|
139
|
+
# Or multiple GDL/JDL files per backend service:
|
|
140
|
+
# sources:
|
|
141
|
+
# - name: identity-access
|
|
142
|
+
# file: ./GDL/identity-access.gdl
|
|
143
|
+
# microservice: identity-access-module
|
|
144
|
+
# - name: inventory
|
|
145
|
+
# file: ./GDL/inventory.gdl
|
|
146
|
+
# microservice: inventory-service
|
|
147
|
+
# Enums: src/app/domains/admin/modules/apps/micro-functions/<service-folder>/enum/
|
|
148
|
+
# Every service keeps enum/ with a .gitkeep, even without enum definitions.
|
|
149
|
+
# Generated entities: src/app/domains/admin/modules/apps/micro-functions/<service-folder>/entities/<entity>/
|
|
150
|
+
# sources[].folder can preserve module names such as identityAccessModule.
|
|
151
|
+
# Single-schema module folders use api.microservice; multi-source folders use sources[].folder or name.
|
|
152
|
+
output:
|
|
153
|
+
directory: .
|
|
154
|
+
overwritePolicy: fail
|
|
155
|
+
fuse:
|
|
156
|
+
enabled: true
|
|
157
|
+
rendering: spa
|
|
158
|
+
cleanLayout: true
|
|
159
|
+
includePrebuilt: false
|
|
160
|
+
theme:
|
|
161
|
+
scheme: system # system | light | dark
|
|
162
|
+
primary: "#0D1E3A" # default navy โ buttons / accents via root fuseTheme
|
|
163
|
+
error: "#dc2626"
|
|
164
|
+
api:
|
|
165
|
+
microservice: book-service # fallback when a source omits microservice
|
|
166
|
+
auth:
|
|
167
|
+
provider: none
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`input.sources[]` generates one nav group and `apps/<folder>/` tree per service (`name`),
|
|
171
|
+
and each entityโs HTTP client uses that sourceโs `microservice`. Entity names must stay unique
|
|
172
|
+
across all listed files. Prefer `sources` for multi-backend apps; keep `input.file` for one schema.
|
|
173
|
+
|
|
174
|
+
Update entities, relationships, the microservice identifier, and any supported settings before
|
|
175
|
+
running `crudforge generate`. It finds the project's configuration, validates it and the
|
|
176
|
+
referenced schema, and adds the Fuse application directly into the same folder:
|
|
177
|
+
|
|
178
|
+
```text
|
|
179
|
+
crudforge-app/
|
|
180
|
+
โโโ config/
|
|
181
|
+
โ โโโ crudforge.config.yml
|
|
182
|
+
โโโ gdl/
|
|
183
|
+
โ โโโ example.gdl
|
|
184
|
+
โโโ src/
|
|
185
|
+
โโโ angular.json
|
|
186
|
+
โโโ package.json
|
|
187
|
+
โโโ ...
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The source configuration and GDL remain unchanged, including comments. There is no nested
|
|
191
|
+
application folder. `input.file`, `input.sources[].file`, and `output.directory` are relative to the project root,
|
|
192
|
+
not `config/`. Without a positional schema, `--preferences /path/to/app/config/crudforge.config.yml`
|
|
193
|
+
also anchors relative paths at `/path/to/app`; a root-level config anchors at its containing
|
|
194
|
+
directory. Moving the whole initialized project therefore needs no path edits.
|
|
195
|
+
|
|
196
|
+
Discovery checks `config/crudforge.config.yml`, `config/crudforge.config.yaml`,
|
|
197
|
+
`crudforge.config.yml`, `crudforge.config.yaml`, `config/config.yml`, then `crudforge.config.json`.
|
|
198
|
+
An explicit `--preferences` takes precedence. Missing or malformed inputs fail with file paths
|
|
199
|
+
before project files are written; invalid config no longer silently falls back to defaults.
|
|
200
|
+
|
|
201
|
+
On regeneration, differing existing application files require an overwrite policy. The CLI
|
|
202
|
+
honors `output.overwritePolicy`, with an explicit flag taking precedence; the fallback is `fail`.
|
|
203
|
+
Fuse starter files and generated files follow the same policy. Source configuration and schema
|
|
204
|
+
files are protected even with `overwrite`. No stale or unrelated files are automatically deleted.
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
crudforge generate --dry-run # preview without changing project files
|
|
208
|
+
crudforge generate --overwrite-policy ask # resolve each conflict interactively
|
|
209
|
+
crudforge generate --overwrite-policy skip # keep differing existing files
|
|
210
|
+
crudforge generate --overwrite-policy merge # preserve matching cforge custom-code zones
|
|
211
|
+
crudforge generate --overwrite-policy overwrite # explicitly replace generated application files
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
`merge` preserves marked custom-code zones, not arbitrary edits; binary conflicts require
|
|
215
|
+
`ask`, `skip`, or `overwrite`. `ask` fails on conflicts in noninteractive CI. `--yes` does not
|
|
216
|
+
authorize overwriting files. `fail` checks all differing files before applying changes.
|
|
217
|
+
|
|
218
|
+
### Optional PMB development testing preset
|
|
219
|
+
|
|
220
|
+
Use Node 24+ for the generated application. Import the PMB development settings once:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
crudforge init crudforge-app --preset pmb-test --source /path/to/PMB/pmb-admin
|
|
224
|
+
cd crudforge-app
|
|
225
|
+
# Optional: edit config/crudforge.config.yml and gdl/example.gdl
|
|
226
|
+
crudforge generate
|
|
227
|
+
npm install
|
|
228
|
+
npm run dev -- --port 4200
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Open `http://localhost:4200/auth/sign-in` and enter your existing PMB login. The CLI prints
|
|
232
|
+
the actual port extracted from PMB's development settings. If that port is occupied, pass
|
|
233
|
+
a free port to `npm run dev -- --port <port>`. `npm start` selects the production build;
|
|
234
|
+
use the printed `npm run dev` command for this testing workflow.
|
|
235
|
+
|
|
236
|
+
The first command only creates the editable config and sample GDL. It reads PMB without
|
|
237
|
+
executing its scripts or modifying its files. The importer follows the development Angular
|
|
238
|
+
environment replacement and serve/proxy settings, checks the public-client token flow,
|
|
239
|
+
and maps the Province model/client to its reference-module route. Unsupported dynamic
|
|
240
|
+
settings or a changed authentication contract produce actionable errors instead of guesses.
|
|
241
|
+
|
|
242
|
+
The reusable preset is stored at `${XDG_CONFIG_HOME:-~/.config}/crudforge/presets/pmb-test/`:
|
|
243
|
+
|
|
244
|
+
```text
|
|
245
|
+
pmb-test/
|
|
246
|
+
โโโ config.yml
|
|
247
|
+
โโโ example.gdl
|
|
248
|
+
โโโ metadata.json
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
The metadata records source-file hashes, the source location, import time, sample endpoint,
|
|
252
|
+
and verification limitations. The source location is not copied into the generated app.
|
|
253
|
+
Configuration and schema paths in the app remain project-relative. The app does not need
|
|
254
|
+
access to the registry or PMB source after initialization.
|
|
255
|
+
|
|
256
|
+
After deleting a disposable generated app, recreate it without re-entering backend settings:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
crudforge init crudforge-app --preset pmb-test
|
|
260
|
+
cd crudforge-app
|
|
261
|
+
crudforge generate
|
|
262
|
+
npm install
|
|
263
|
+
npm run dev -- --port 4200
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Refresh the saved preset when the PMB source changes:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
crudforge preset refresh pmb-test --source /path/to/PMB/pmb-admin
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Refresh validates the new settings before replacing the preset, retains a timestamped backup
|
|
273
|
+
beside it, and leaves existing apps unchanged. Initial import refuses to replace an existing
|
|
274
|
+
preset; use `refresh` explicitly. Normal `crudforge init <directory>` remains independent of PMB.
|
|
275
|
+
|
|
276
|
+
The preset maps real public-client login, refresh and logout, PMB admin roles, idle timeout,
|
|
277
|
+
service targets and aliases. It includes `proxy.routes` for explicit proxy entries and
|
|
278
|
+
`devServer.port` for the development server. Explicit proxy routes override auto-generated
|
|
279
|
+
entries and apply to the files selected by `proxy.write`; specific routes precede catch-all
|
|
280
|
+
prefixes. Supported entry fields are `target`, `secure`, `changeOrigin`, `ws`, `logLevel`, and
|
|
281
|
+
`pathRewrite`. Headers, cookies, credentials and executable proxy hooks are not imported.
|
|
282
|
+
Both proxy files in this testing preset intentionally target PMB development services.
|
|
283
|
+
|
|
284
|
+
The sample `Province` uses PMB's frontend model and reference API path. Authentication and
|
|
285
|
+
API reachability still require runtime verification. Arbitrary new GDL entities do not create
|
|
286
|
+
backend endpoints. The importer does not copy DAD secondary-login credentials, confidential
|
|
287
|
+
internal clients, account passwords, or tokens; it never provisions or restarts services.
|
|
288
|
+
Live sign-in forms do not inherit `KEYCLOAK_ADMIN_*` credentials from the CLI environment.
|
|
289
|
+
|
|
290
|
+
Privileged IAM management screens are disabled by this preset. PMB's non-admin screen
|
|
291
|
+
permissions, profile/business context, and backend write constraints are not reproduced
|
|
292
|
+
by a frontend preset and require separate verification for the intended account. Automated
|
|
293
|
+
live checks should use only read-only API requests; a successful build is not proof of login
|
|
294
|
+
or backend permissions.
|
|
295
|
+
|
|
296
|
+
Validation commands for contributors:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
npm test # includes isolated preset import/reuse/refresh and generation checks
|
|
300
|
+
npm run test:auth # Node 24+: refresh/retry and session-error behavior
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Existing commands
|
|
304
|
+
|
|
305
|
+
Explicit schema/output generation remains supported. Explicit CLI paths and config-relative
|
|
306
|
+
paths in this legacy form resolve from the current working directory:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
crudforge generate <path-to-schema.jdl> <target-output-folder> [options]
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
The existing `init-config` command still creates `crudforge.config.yml`, `example.jdl`, and
|
|
313
|
+
`example.gdl` in the current directory, skipping existing files. Use `init <directory>` for
|
|
314
|
+
the project-owned input workflow:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
crudforge init-config
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Validate a schema blueprint against generation rules without writing files:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
crudforge validate <path-to-schema.jdl>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Bootstrap Keycloak resources (client, roles, initial users) without generating an app. **Does not run during `generate`.**
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
crudforge bootstrap --preferences ./crudforge.config.yml --env-file ./.env.qa
|
|
330
|
+
crudforge bootstrap --dry-run --preferences ./crudforge.config.yml --env-file ./.env.qa
|
|
331
|
+
crudforge bootstrap --cleanup --preferences ./crudforge.config.yml --env-file ./.env.qa
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Options
|
|
335
|
+
* `-m, --microservice` : Explicit microservice name for API route prefixes.
|
|
336
|
+
* `-p, --preferences` : Path to a custom config file (YAML/JSON) overriding defaults.
|
|
337
|
+
* `-d, --dry-run` : Preview files to be created and diff modifications without writing to disk.
|
|
338
|
+
* `-w, --overwrite-policy` : Overwrite policy for existing files (overwrite, skip, fail, ask, merge).
|
|
339
|
+
* `--fuse` : Scaffold and generate the entities into a Fuse Angular starter project layout.
|
|
340
|
+
* `--fuse-path` : Path to a local Fuse starter pack directory (if overriding the bundled default).
|
|
341
|
+
* `--clean-layout` : Hide all pre-built Fuse UI components (banners, alerts) for a minimal dashboard.
|
|
342
|
+
* `--sidebar-theme` : Configures sidebar navigation theme style ('white' or 'dark').
|
|
343
|
+
* `--folder-type` : Navigation/ACL group name (generated service modules live under `micro-functions`).
|
|
344
|
+
* `--keycloak` : Enable Keycloak when config `auth.provider` is still `none`.
|
|
345
|
+
* `--kc-*` : Optional overrides for server URL, middleware URL, client ID, realm, credentials.
|
|
346
|
+
* `--proxy-write` : Which Fuse proxy file(s) to update for services/Keycloak (`both` | `prod` | `dev`).
|
|
347
|
+
* `--yes` / `-y` : Skip interactive prompts (microservice / proxy-write).
|
|
348
|
+
* `--env-file` : (`bootstrap`) Load a gitignored env file for admin / seed-user credentials.
|
|
349
|
+
* `--cleanup` : (`bootstrap`) Delete only resources tracked in the provision state file.
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## ๐ Keycloak auth and IAM
|
|
354
|
+
|
|
355
|
+
Defaults keep `auth.provider: none` and `auth.provision.enabled: false`. Turn Keycloak on only when the app needs real identity. Do **not** model User or Role as JDL entities; IAM is an overlay (`iam.enabled`). Generated packs live under **`src/app/core/auth/`** (services / guards / interceptors + `AGENT_README.md`) and **`src/app/core/user-management/`** (Users, Roles, role/user screen matrices + `AGENT_README.md`). Product docs: [IAM overlay](../crud-fordge-doc/src/content/docs/features/iam.md) and [Users, roles & screen access](../crud-fordge-doc/src/content/docs/guides/iam-access.md).
|
|
356
|
+
|
|
357
|
+
Every Fuse generate also ships **access-control-tools** at `src/app/domains/admin/modules/apps/shared/access-control-tools/` (README + `AGENT_README.md` / `AGENT_MEMORY.md`). Use it after adding custom pages to stamp `SCREEN` / `accessCtrl` / QA ids and refresh `public/assets/screen-components.csv`:
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
npm run access-control:sync # dry-run
|
|
361
|
+
npm run access-control:apply # write
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Component ids follow semantic verbs (`create`, `open-filter`, `toggle-view`, `open-columns`). Entity `SCREEN` stays `{folder}/{entity}` (nav-aligned). Runtime aliases keep older Keycloak grants (`new`โ`create`, etc.) working.
|
|
365
|
+
|
|
366
|
+
**Permission matrices** and **Role / User Management** accents follow root `fuse.theme.primary` (default navy `#0D1E3A`) via Tailwind `primary-*` / `--theme-color-primary-*` โ not hardcoded emerald. Matrices keep sticky scrollable grids (`matrix-table` โ `width: max-content`), per-toggle busy lock, holder sync after role writes, grant/revoke sounds on permission matrices, confirm dialog + assigned/available role cards on user access (no sounds there). System roles (`offline_access`, `uma_authorization`, `default-roles-*`) are hidden.
|
|
367
|
+
|
|
368
|
+
**Role Management** (`roles/role-list`) follows PMB `role-management`: master-detail list with search/pagination, create role form, duplicate, Sync holders, Assign Users bottom-sheet, inheritance flow, and a screen-permissions summary panel that deep-links to the role matrix. Catalog is CSV-only (`public/assets/screen-components.csv`); no Access Control DB or PMB approval/region exclusions.
|
|
369
|
+
|
|
370
|
+
```yaml
|
|
371
|
+
auth:
|
|
372
|
+
provider: keycloak # or none
|
|
373
|
+
serverUrl: "" # Keycloak base, e.g. http://host:30080 (not the /admin/... console deep-link)
|
|
374
|
+
realm: CRUD-FORDGE
|
|
375
|
+
clientId: crudforge-client-QA
|
|
376
|
+
useMockAuth: false # true for deterministic Playwright / offline demos
|
|
377
|
+
forwardedProto: https # X-Forwarded-Proto when Keycloak requires HTTPS behind HTTP
|
|
378
|
+
adminRoles: [ROLE_ADMIN, ADMIN, ROLE_SUPER_ADMIN]
|
|
379
|
+
# Session: idleTimeoutMs 0 = stay signed in until explicit logout (default).
|
|
380
|
+
session:
|
|
381
|
+
idleTimeoutMs: 0 # set e.g. 900000 for 15-minute idle logout
|
|
382
|
+
persistAcrossReload: true
|
|
383
|
+
crossTabSync: true # sign out this tab when another tab clears tokens
|
|
384
|
+
refreshOnFocus: true # refresh access token when the tab becomes visible
|
|
385
|
+
statusProbeIntervalMs: 60000 # refresh-if-due probe when disabledAccount.enabled
|
|
386
|
+
disabledAccount:
|
|
387
|
+
enabled: false # true โ freeze shell + countdown overlay, then sign out
|
|
388
|
+
countdownSeconds: 20
|
|
389
|
+
message: "Your account has been disabled. Please contact your administrator."
|
|
390
|
+
sound: false
|
|
391
|
+
provision:
|
|
392
|
+
enabled: false # must be true for `crudforge bootstrap` only
|
|
393
|
+
adapter: keycloak-admin-rest # or admin-service (middleware wrapper)
|
|
394
|
+
adminServiceUrl: "" # Keycloak middleware / admin service, e.g. http://host:31740/
|
|
395
|
+
adminUsernameEnv: KEYCLOAK_ADMIN_USERNAME
|
|
396
|
+
adminPasswordEnv: KEYCLOAK_ADMIN_PASSWORD
|
|
397
|
+
clientId: crudforge-client-QA
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Session pack defaults keep the user signed in across reloads. Token refresh only clears the session on **terminal** auth errors (invalid/expired refresh); network blips and 5xx keep the session. When `disabledAccount.enabled` is true, an explicit Keycloak โaccount disabledโ grant error shows a root overlay (wired into Fuse `app.ts`) and signs out after the countdown โ never on generic `invalid_grant` alone.
|
|
401
|
+
### Developer generate with Keycloak
|
|
402
|
+
|
|
403
|
+
Fill Keycloak in **`crudforge.config.yml`** (not CLI prompts). Bootstrap operator passwords stay in a local **`.env`** via `adminUsernameEnv` / `adminPasswordEnv`. Live QA may also set `auth.signInPrefill` so the Angular login form is pre-bound to `crud` / `crud`.
|
|
404
|
+
|
|
405
|
+
```yaml
|
|
406
|
+
auth:
|
|
407
|
+
provider: keycloak
|
|
408
|
+
serverUrl: http://62.84.188.166:31740 # Admin Service gateway (not Keycloak :30080)
|
|
409
|
+
realm: CRUD-FORDGE
|
|
410
|
+
clientId: crudforge-client-QA
|
|
411
|
+
forwardedProto: https
|
|
412
|
+
signInPrefill:
|
|
413
|
+
username: crud
|
|
414
|
+
password: crud
|
|
415
|
+
provision:
|
|
416
|
+
adapter: admin-service
|
|
417
|
+
adminServiceUrl: http://62.84.188.166:31740/
|
|
418
|
+
adminUsernameEnv: KEYCLOAK_ADMIN_USERNAME
|
|
419
|
+
adminPasswordEnv: KEYCLOAK_ADMIN_PASSWORD
|
|
420
|
+
|
|
421
|
+
api:
|
|
422
|
+
microservice: book-service
|
|
423
|
+
services:
|
|
424
|
+
identityaccessmodule: http://62.84.188.166:30084
|
|
425
|
+
# Optional per-env targets:
|
|
426
|
+
# book-service:
|
|
427
|
+
# prod: http://host:30084
|
|
428
|
+
# dev: http://host:31704
|
|
429
|
+
# pathRewrite: /book-service
|
|
430
|
+
|
|
431
|
+
proxy:
|
|
432
|
+
write: both # both | prod (proxy.conf.json) | dev (proxy.dev.conf.json)
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Generate writes Keycloak + `api.services` into `src/environments/environment*.ts` (relative `/services/{name}` paths) and updates the chosen Fuse proxy file(s) with absolute targets. When `api.services` is set and you are on a TTY, generate asks **dev / prod / both** unless `proxy.write` or `--proxy-write` / `--yes` is set.
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
# .env (gitignored) next to the project or output app
|
|
439
|
+
KEYCLOAK_ADMIN_USERNAME=crud
|
|
440
|
+
KEYCLOAK_ADMIN_PASSWORD=crud
|
|
441
|
+
|
|
442
|
+
crudforge generate ./domain.jdl ./my-app --fuse --clean-layout --preferences ./crudforge.config.yml
|
|
443
|
+
crudforge bootstrap --preferences ./my-app/config/crudforge.config.yml --env-file ./my-app/.env
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
The admin console URL (`โฆ/admin/master/console/#/โฆ`) is a **UI link only** โ use the Keycloak base URL for APIs.
|
|
447
|
+
|
|
448
|
+
Passwords and admin credentials stay in the CLI process via `passwordEnv` / `admin*Env`. They are never written into Angular `environment.ts`, browser bundles, or committed fixtures. Generated SPAs use a **public** client (no confidential `clientSecret` in the browser).
|
|
449
|
+
|
|
450
|
+
Live Fuse apps proxy `/realms` (OIDC token) and `/services/keycloak-admin` to either the [Keycloak Admin Service](http://62.84.188.166:31740/) middleware (`useKeycloakAdminService: true` โ `/api/v1/*`) or native Keycloak Admin REST (`useKeycloakAdminService: false` โ `/admin/realms/...` via the same `/services/keycloak-admin` prefix). Broader `/auth` and `/admin` are **never** proxied so the Angular SPA shell stays intact โ bare `/admin/realms` calls hit Fuse `index.html`. Details: [QA/KEYCLOAK-BOOTSTRAP.md](QA/KEYCLOAK-BOOTSTRAP.md).
|
|
451
|
+
|
|
452
|
+
Structural backlog (session stay-signed-in, disabled-account overlay from PMB patterns, IAM registry, optional packs): see [Todo.md](Todo.md).
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## ๐งช QA and CI
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
# Mock (no remote Keycloak mutations)
|
|
460
|
+
./test-run.sh mock
|
|
461
|
+
npm test
|
|
462
|
+
npm run e2e:prepare && npm run test:e2e
|
|
463
|
+
npm run e2e:prepare:iam && npm run test:e2e:iam
|
|
464
|
+
|
|
465
|
+
# Live Keycloak (requires gitignored .env.qa โ copy from .env.qa.example for seeded user passwords only)
|
|
466
|
+
# Endpoints + operator crud/crud are hardcoded in test-run.sh and e2e/crudforge.iam-live.yml:
|
|
467
|
+
# Keycloak Admin Service http://62.84.188.166:31740/ realm CRUD-FORDGE client crudforge-client-QA
|
|
468
|
+
# `./test-run.sh` (mock) runs mock Playwright, then regenerates the shared testing-area app
|
|
469
|
+
# on LIVE middleware wiring so `npm start` has:
|
|
470
|
+
# proxy `/realms` + `/services/keycloak-admin` โ :31740
|
|
471
|
+
# environment.ts live links + sign-in prefill crud/crud (passwords stay in .env, not proxy)
|
|
472
|
+
./test-run.sh live
|
|
473
|
+
npm run e2e:prepare:iam:live
|
|
474
|
+
npm run test:e2e:iam:live
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
`test-run.sh` resolves paths from its own location (any cwd), refuses unsafe cleanup paths, and distinguishes mock vs live. By default it writes **one** Fuse app under:
|
|
478
|
+
|
|
479
|
+
`/Users/abdulla/Work/CRUD-FORDGE-SETUP/crud-fordge-testing-area/crudforge-app`
|
|
480
|
+
|
|
481
|
+
Mock CRUD, mock IAM, and live IAM all regenerate that same folder (no parallel `.mock-app` / `.iam-app` trees). Override with `CRUDFORGE_TESTING_AREA` / `CRUDFORGE_E2E_APP_DIR`. Local prepares default to that external sandbox whenever `CRUD-FORDGE-SETUP` exists (or `.env.qa` sets the path). Set `CRUDFORGE_USE_IN_REPO_E2E=1` to force the historical in-repo `e2e/.app` (CI without the external tree).
|
|
482
|
+
|
|
483
|
+
### Generated Fuse root extras (default on)
|
|
484
|
+
|
|
485
|
+
When `fuse.enabled` is true, generate also:
|
|
486
|
+
|
|
487
|
+
- Writes **`config/crudforge.config.yml`** (dated header, section comments, secrets stripped)
|
|
488
|
+
- Seeds **GO-DUCK-style agent docs** (each stamped **Generated by `@crudforge/cli`**): root `AGENT_README.md`, `docs/ai/README.md` + topic maps (`ENTITIES.md` uses real `fieldName`/`fieldType` + relationship index), pack-level auth/IAM `AGENT_README.md`, `.crudforge/config.yaml`
|
|
489
|
+
- Stamps **`@generated by @crudforge/cli`** on generated Fuse sources written through the engine (`.ts` / `.html` / `.scss` / `.css` / utils / IAM / shared / docs) โ skip binary + JSON; regenerate instead of hand-editing as source of truth
|
|
490
|
+
- Seeds keep-team folders: `.cursor/agents/`, `.codex/agents/`, `.agents/agents/` + `.agents/rules/` (Antigravity), `.vscode/extensions/` (+ `extensions.json`)
|
|
491
|
+
- If `project.repositoryUrl` is set: `git init` (if needed) and `git remote add origin <url>` (never pushes; will not overwrite an existing different origin)
|
|
492
|
+
|
|
493
|
+
```yaml
|
|
494
|
+
project:
|
|
495
|
+
repositoryUrl: "https://github.com/org/my-app.git" # optional
|
|
496
|
+
output:
|
|
497
|
+
embedConfig: true
|
|
498
|
+
aiDocs:
|
|
499
|
+
enabled: true
|
|
500
|
+
teamPack:
|
|
501
|
+
enabled: true
|
|
502
|
+
cursorAgents: true
|
|
503
|
+
codexAgents: true
|
|
504
|
+
antigravityAgents: true # Google Antigravity: .agents/agents + .agents/rules
|
|
505
|
+
vscodeExtensions: true
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
`loadConfig` prefers `config/crudforge.config.yml` inside a generated app.
|
|
509
|
+
|
|
510
|
+
### Branding
|
|
511
|
+
|
|
512
|
+
The Fuse starter ships the navy/blue/orange CRUDForge wordmark at `public/images/logo/logo.png` and the forged-C mark at `logo-mark.png`. Sidebar header and sign-in use the wordmark; favicon uses the mark. With Keycloak auth, the sidebar footer user chip matches PMB (avatar / initials icon, Super Admin badge when ACL admin, name + email, emerald power-button logout with confirm). Default Material primary is navy `#0D1E3A` via root `fuseTheme` / `fuse.theme.primary` โ override in config, do not hardcode entity colors. Unused Fuse stock folders (`photos`, `cards`, `pages`, `apps`, `ui`) are not shipped.
|
|
513
|
+
|
|
514
|
+
Keep-team specialist agents live under `.cursor/agents/`, `.codex/agents/`, and Antigravity `.agents/` (when `teamPack.antigravityAgents` is on).
|
|
515
|
+
|
|
516
|
+
Latest local run notes: see [QA/KEYCLOAK-BOOTSTRAP.md](QA/KEYCLOAK-BOOTSTRAP.md).
|
|
517
|
+
|
|
518
|
+
| Workflow | When | What |
|
|
519
|
+
|---|---|---|
|
|
520
|
+
| `.github/workflows/qa.yml` | PR / push | Generator tests + mock Playwright |
|
|
521
|
+
| `.github/workflows/qa-live.yml` | Manual / weekly | Bootstrap + live Keycloak (secrets via GitHub environment `keycloak-qa`) |
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## โ๏ธ Configuration Preferences
|
|
526
|
+
|
|
527
|
+
CRUDForge accepts a configuration file (e.g. `crudforge.config.yml`). You can scaffold a default configuration via the `init-config` command:
|
|
528
|
+
|
|
529
|
+
```yaml
|
|
530
|
+
# Options matrix
|
|
531
|
+
fuse:
|
|
532
|
+
enabled: false
|
|
533
|
+
|
|
534
|
+
generate:
|
|
535
|
+
models: true
|
|
536
|
+
services: true
|
|
537
|
+
formServices: true
|
|
538
|
+
routes: true
|
|
539
|
+
enums: true
|
|
540
|
+
relationships: true
|
|
541
|
+
components:
|
|
542
|
+
list: true
|
|
543
|
+
card: true
|
|
544
|
+
detail: true
|
|
545
|
+
forms:
|
|
546
|
+
form: true
|
|
547
|
+
formPage: true
|
|
548
|
+
update: true
|
|
549
|
+
validators: true
|
|
550
|
+
mappers: true
|
|
551
|
+
interaction:
|
|
552
|
+
actions: true
|
|
553
|
+
filter: true
|
|
554
|
+
globals:
|
|
555
|
+
constants: true
|
|
556
|
+
tests: false
|
|
557
|
+
sharedAssets: true
|
|
558
|
+
registrations:
|
|
559
|
+
navigation: true
|
|
560
|
+
routes: true
|
|
561
|
+
|
|
562
|
+
output:
|
|
563
|
+
structure: "shared-central" # 'shared-central' (unified) or 'entity-folder' (duplicated)
|
|
564
|
+
directory: "./src/app"
|
|
565
|
+
|
|
566
|
+
formBehavior:
|
|
567
|
+
uppercaseInputs: false
|
|
568
|
+
showErrorMessages: true
|
|
569
|
+
|
|
570
|
+
ui:
|
|
571
|
+
viewMode: "table" # default fallback view
|
|
572
|
+
formMode: "sidebar" # sidebar drawer or page โ new and edit share one mode
|
|
573
|
+
searchMode: "field" # field.contains by default; use global only when API accepts query
|
|
574
|
+
cardBreakpointPx: 640
|
|
575
|
+
gridCols:
|
|
576
|
+
tablet: 2
|
|
577
|
+
desktop: 3
|
|
578
|
+
|
|
579
|
+
auth:
|
|
580
|
+
provider: none
|
|
581
|
+
provision:
|
|
582
|
+
enabled: false
|
|
583
|
+
|
|
584
|
+
iam:
|
|
585
|
+
enabled: false
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### Generated list and form state
|
|
589
|
+
|
|
590
|
+
Audit columns (`createdBy`, `createdDate`, `lastModifiedBy`, `lastModifiedDate`)
|
|
591
|
+
start unchecked in **Column Preferences**. They remain available to select.
|
|
592
|
+
`fields.audit.hideInLists: false` opts into showing them initially. Saved browser
|
|
593
|
+
column selections take precedence; **Reset** applies the configured defaults.
|
|
594
|
+
|
|
595
|
+
Technical plumbing fields (`debug`, `refType`, `refId`) are hidden from all UI
|
|
596
|
+
surfaces by default via `fields.technical` (list, form, detail, card, filter,
|
|
597
|
+
search). They remain on the TypeScript model and form group for API round-trips.
|
|
598
|
+
Set `fields.technical.enabled: false` (or clear `names`) to show them.
|
|
599
|
+
|
|
600
|
+
With Fuse Keycloak authentication, the shared `AuditUserNamePipe` displays audit
|
|
601
|
+
UUIDs as first + last name in lists, cards, and details using the configured user
|
|
602
|
+
middleware. Lookups are cached in memory; existing names pass through, and missing
|
|
603
|
+
or inaccessible users retain their original ID. Entity values and write payloads
|
|
604
|
+
are unchanged. Applications without a configured directory retain the ID.
|
|
605
|
+
|
|
606
|
+
Lists observe their available width and use cards below `ui.cardBreakpointPx`
|
|
607
|
+
(default `640`). Actions saves the explicit card/table preference in localStorage;
|
|
608
|
+
widening the list restores that preference. New/Edit drawer openings mount a fresh
|
|
609
|
+
form, and closing clears its selected entity. Late edit responses cannot replace a
|
|
610
|
+
newer form session.
|
|
611
|
+
|
|
612
|
+
Regression checks: `npm run test:ui-state` (Node 24+). Browser checks live in
|
|
613
|
+
`e2e/tests/list-state.spec.js`; run them against a generated **mock** app, never a
|
|
614
|
+
live backend. For an isolated server on port 4201, use
|
|
615
|
+
`npx playwright test --config=playwright.list-state.config.js`. Set
|
|
616
|
+
`CRUDFORGE_BROWSER_CHANNEL=chrome` to use installed Chrome, or install Playwright's
|
|
617
|
+
Chromium with `npm run test:e2e:install`.
|
|
618
|
+
|
|
619
|
+
### Per-field input formatting and audit inputs
|
|
620
|
+
|
|
621
|
+
Configure exact GDL/JDL entity and field names in the project's
|
|
622
|
+
`config/crudforge.config.yml`, then run `crudforge generate` using the existing
|
|
623
|
+
file-overwrite policy. For example, with `Province.provinceCode` and
|
|
624
|
+
`Province.provinceName` defined as strings:
|
|
625
|
+
|
|
626
|
+
```yaml
|
|
627
|
+
fields:
|
|
628
|
+
entities:
|
|
629
|
+
Province:
|
|
630
|
+
fields:
|
|
631
|
+
provinceCode: { inputFormat: uppercase }
|
|
632
|
+
provinceName: { inputFormat: lowercase }
|
|
633
|
+
index: { inputFormat: none }
|
|
634
|
+
audit:
|
|
635
|
+
hideInForms: true
|
|
636
|
+
hideInFilters: true
|
|
637
|
+
hideInSearch: true
|
|
638
|
+
technical:
|
|
639
|
+
enabled: true
|
|
640
|
+
names: [debug, refType, refId]
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
`uppercase` and `lowercase` change typed/pasted values, create defaults, loaded
|
|
644
|
+
edit values and outgoing service payloads. `none` preserves case and is the
|
|
645
|
+
default. Only editable `String` and `TextBlob` fields support these preferences;
|
|
646
|
+
unknown entities/fields, enum/number/date/UUID/audit/technical fields and unsupported options
|
|
647
|
+
are rejected before generation. Existing validators still run on the formatted
|
|
648
|
+
value. The shared text accessor preserves cursor/selection positions and waits
|
|
649
|
+
for composition input to finish. Null values remain null, and partial payloads
|
|
650
|
+
retain only their original keys.
|
|
651
|
+
|
|
652
|
+
The generator emits the resolved `fields` map into each entity's existing
|
|
653
|
+
`settings/settings.config.ts`. Edit the YAML source to retain preferences across
|
|
654
|
+
regeneration. Legacy `formBehavior.uppercaseInputs: true` supplies uppercase for
|
|
655
|
+
otherwise unconfigured text fields; an explicit per-field `none` overrides it.
|
|
656
|
+
|
|
657
|
+
Audit controls, filter entries and search-field choices are hidden by default.
|
|
658
|
+
These flags can independently opt them back in with `false`. Hidden controls do
|
|
659
|
+
not erase existing audit model values. A saved search-field choice that is no
|
|
660
|
+
longer available resets to the first supported choice. Global search continues
|
|
661
|
+
to use the backend's existing `query` contract; its server-side search scope is
|
|
662
|
+
not redefined by these UI preferences.
|
|
663
|
+
|
|
664
|
+
### Authenticated Fuse identity
|
|
665
|
+
|
|
666
|
+
Keycloak builds bind the shared Fuse user menu and optional Account settings page
|
|
667
|
+
to `AuthService.profile`, derived from the configured provider's authenticated
|
|
668
|
+
JWT claims. Display-name priority is `name`, `given_name` + `family_name`, username,
|
|
669
|
+
then email. The `picture` claim supplies an avatar when present; otherwise initials
|
|
670
|
+
are shown. Missing email stays blank. UTF-8 names are decoded correctly. Profile
|
|
671
|
+
state updates on token hydration/refresh and clears on logout, with no sample-user
|
|
672
|
+
fallback for real authentication. Demo claims are used only by `auth.useMockAuth`.
|
|
673
|
+
No additional profile endpoint or client secret is required.
|
|
674
|
+
|
|
675
|
+
Run `npm run test:field-preferences` for field/profile behavior checks (Node 24+).
|
|
676
|
+
For browser regressions, generate an isolated fixture with
|
|
677
|
+
`npm run e2e:prepare:field-profile`, start it on port 4201, then run
|
|
678
|
+
`npx playwright test --config=playwright.field-profile.config.js`.
|
|
679
|
+
Set `CRUDFORGE_BROWSER_CHANNEL=chrome` to use installed Chrome. These tests intercept
|
|
680
|
+
authentication and backend calls, verify profile refresh/account switching and
|
|
681
|
+
formatted payloads, and attach complete console errors/stacks to their results.
|
|
682
|
+
They do not replace verification with real accounts.
|
|
683
|
+
|
|
684
|
+
## Generated application performance and rendering
|
|
685
|
+
|
|
686
|
+
Fuse applications default to a client-side SPA. `npm start` uses the development
|
|
687
|
+
configuration; `npm run build` creates production browser assets for the supplied
|
|
688
|
+
Nginx Dockerfile. Strict TypeScript and Angular template checks remain enabled.
|
|
689
|
+
|
|
690
|
+
To explicitly generate a Node SSR application, set these project inputs before generation:
|
|
691
|
+
|
|
692
|
+
```yaml
|
|
693
|
+
fuse:
|
|
694
|
+
enabled: true
|
|
695
|
+
rendering: ssr
|
|
696
|
+
ssrAllowedHosts: [localhost, 127.0.0.1, admin.example.com]
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
Use `crudforge generate`, `npm ci`, `npm run build`, then `npm run serve:ssr`
|
|
700
|
+
(default port 4000). The generated Dockerfile uses Node for SSR. Configure your
|
|
701
|
+
actual deployment host in `ssrAllowedHosts`. Browser-stored authentication remains
|
|
702
|
+
a browser flow; SSR does not acquire the user's browser session on the server.
|
|
703
|
+
Switching rendering modes requires reviewing generated deployment/package changes
|
|
704
|
+
and reinstalling dependencies. Old server files are not automatically deleted from
|
|
705
|
+
existing projects, but are excluded from SPA compilation.
|
|
706
|
+
|
|
707
|
+
Entity screens and relationship dialogs load on demand. Shared confirmation dialogs,
|
|
708
|
+
resizing, base classes and list styles are generated once. For non-Fuse output, add
|
|
709
|
+
`shared/styles/list-styles.css` and `shared/styles/snackbar-styles.css` to the host's
|
|
710
|
+
global styles. `generate.globals.sharedAssets: false` means you supply the shared
|
|
711
|
+
files yourself. Existing legacy copies are not deleted automatically.
|
|
712
|
+
|
|
713
|
+
For an existing initialized project, run `crudforge generate --dry-run` first and
|
|
714
|
+
review conflicts. The normal overwrite policy still applies; use explicit overwrite
|
|
715
|
+
only after preserving custom changes. Per-entity list SCSS remains a customization
|
|
716
|
+
hook. Generated lists retain server pagination; relationship selects request the
|
|
717
|
+
first 50 options, so large relationships still need a searchable/paged selector.
|
|
718
|
+
|
|
719
|
+
See [the performance investigation and reproducible measurements](docs/performance/README.md)
|
|
720
|
+
for the PMB audit comparison, exact benchmark commands and verification limits.
|
|
721
|
+
Run `npm run test:performance` for generator regressions.
|
|
722
|
+
|
|
723
|
+
---
|
|
724
|
+
|
|
725
|
+
## ๐ Stronger Schema & GDL Validation
|
|
726
|
+
|
|
727
|
+
CRUDForge validates schemas before any application code is generated. Run validation directly:
|
|
728
|
+
|
|
729
|
+
```bash
|
|
730
|
+
crudforge validate gdl/example.gdl
|
|
731
|
+
crudforge validate gdl/example.gdl --json
|
|
732
|
+
crudforge validate gdl/example.gdl -p config/crudforge.config.yml
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
### Diagnostics Checks
|
|
736
|
+
- **Syntax & Declarations:** Unclosed braces, invalid directives, malformed field or relationship declarations.
|
|
737
|
+
- **Naming & Identifier Safety:** Duplicate entity/field/enum names, invalid TypeScript reserved words, and output path collisions (e.g. `FooBar` vs `Foo_Bar` both mapping to `foo-bar`).
|
|
738
|
+
- **Types & Field Rules:** Unsupported primitives, enum type existence, valid regex syntax for `pattern(...)`, numeric vs string validation constraints (`min`, `max`, `minlength`, `maxlength`), and inverted ranges (`min > max`).
|
|
739
|
+
- **Relationships:** Undefined source or target entities, undefined relationship display fields, and collisions with scalar/foreign-key fields.
|
|
740
|
+
- **Backend Metadata & Interoperability:** Backend labels (`backend.kind: go-duck | jhipster | custom`) are reported with clear diagnostics without forcing specific vendor naming conventions on custom backends.
|
|
741
|
+
- **Annotations:** Supported entity annotations are `@Audited` / `@EnableAudit`, `@Searchable`, and `@ActiveStatus` (`isActive` injection). Unimplemented annotations (e.g. `@SoftDelete`) produce clear diagnostics rather than silently discarding behavior.
|
|
742
|
+
- **List / IAM tables:** Generated lists follow the tw-hipster / PMB approval layout (slate header band, overlapping white card, outline search toolbar, sticky Actions that match the header band, visible empty state). ACL screen ids match navigation (`micro-functions/{entity}`); button component ids are semantic (`create`, `open-filter`, โฆ). Custom-page stamping: `shared/access-control-tools/` + `npm run access-control:*`. **User Management** matches the PMB IAM list (live count, rocker enabled toggle, pin/flag state, column prefs, skeleton rows); accents use root `fuseTheme` / `fuse.theme.primary` (`primary-*` tokens), not hardcoded emerald. User Details drawer uses a navy identity band, consistent account rows, formatted role chips (system roles hidden), and sticky footer actions.
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
## ๐ฉบ Project Diagnostics (`crudforge doctor`)
|
|
747
|
+
|
|
748
|
+
Run `doctor` to diagnose local environment, project setup, dependencies, ports, and configuration consistency:
|
|
749
|
+
|
|
750
|
+
```bash
|
|
751
|
+
crudforge doctor
|
|
752
|
+
crudforge doctor --json
|
|
753
|
+
crudforge doctor --live
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
### Local Checks (Offline)
|
|
757
|
+
- **Node & Engine Compatibility:** Validates the active Node version against `package.json` engines or starter requirements.
|
|
758
|
+
- **Configuration & Schema:** Verifies configuration syntax, project root anchoring, and schema accessibility.
|
|
759
|
+
- **Lockfile & Dependencies:** Detects lockfile drift between `package.json` and `package-lock.json`, checks for missing `node_modules`, and supports Yarn PnP.
|
|
760
|
+
- **Port Availability:** Tests IPv4 loopback binding for the configured development server port (`devServer.port`, default `4200`).
|
|
761
|
+
- **Service Targets & Proxy Routes:** Ensures valid HTTP(S) URLs, verifies Keycloak authentication fields (`realm`, `clientId`, `serverUrl`), and checks proxy routes.
|
|
762
|
+
- **Secret Redaction:** Automatically redacts passwords, tokens, client secrets, and authorization values from diagnostic output.
|
|
763
|
+
|
|
764
|
+
### Live Checks (`--live`)
|
|
765
|
+
Optional probe mode for configured `doctor.endpoints`:
|
|
766
|
+
```yaml
|
|
767
|
+
doctor:
|
|
768
|
+
timeoutMs: 3000
|
|
769
|
+
endpoints:
|
|
770
|
+
- url: "http://62.84.188.166:31698/realms/PMB-DEV/.well-known/openid-configuration"
|
|
771
|
+
description: "Keycloak OIDC Discovery"
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
### Troubleshooting `crudforge: command not found`
|
|
775
|
+
If `crudforge` is not in your shell's `PATH`:
|
|
776
|
+
1. **Run directly via Node:**
|
|
777
|
+
```bash
|
|
778
|
+
node /path/to/crud-fordge/cli.js <command>
|
|
779
|
+
```
|
|
780
|
+
2. **Install globally:**
|
|
781
|
+
```bash
|
|
782
|
+
npm install -g /path/to/crud-fordge
|
|
783
|
+
# or
|
|
784
|
+
npm link
|
|
785
|
+
```
|
|
786
|
+
3. **Verify npm global bin path:** Ensure `$(npm bin -g)` or `$(npm config get prefix)/bin` is in your shell `PATH` in `~/.zshrc` or `~/.bashrc`.
|
|
787
|
+
|
|
788
|
+
---
|
|
789
|
+
|
|
790
|
+
## ๐งช Generated Application Tests & CI
|
|
791
|
+
|
|
792
|
+
CRUDForge can generate a standalone Playwright smoke suite and CI configuration inside the generated Fuse Angular application:
|
|
793
|
+
|
|
794
|
+
```yaml
|
|
795
|
+
generate:
|
|
796
|
+
globals:
|
|
797
|
+
tests: true
|
|
798
|
+
|
|
799
|
+
testing:
|
|
800
|
+
ci: true
|
|
801
|
+
fixtures:
|
|
802
|
+
Farmer:
|
|
803
|
+
referenceCode: "AB12" # Required for regex/pattern-constrained fields
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
### Generated Smoke Test Suite
|
|
807
|
+
- **Directory Structure:**
|
|
808
|
+
- `tests/generated/`: Generator-managed mock server (`mock.cjs`), Playwright config (`playwright.config.cjs`), and smoke test cases (`smoke.spec.cjs`).
|
|
809
|
+
- `tests/custom/`: Dedicated developer test folder. Files placed in `tests/custom/*.spec.cjs` are preserved and never overwritten.
|
|
810
|
+
- **Mock Backend Isolation:** Intercepts all API calls and Keycloak authentication locally using synthetic fixtures. Unmapped outgoing network requests are blocked with `blockedbyclient` to prevent accidental requests to real backends.
|
|
811
|
+
- **Coverage:** Tests application startup, entity navigation, server-side pagination, required-field form validation, create/edit flows, error banner display, loading animations, and Keycloak profile refresh.
|
|
812
|
+
- **Running Smoke Tests in the Generated App:**
|
|
813
|
+
```bash
|
|
814
|
+
npm ci
|
|
815
|
+
npm run test:smoke:install # Installs Playwright Chromium
|
|
816
|
+
npm run test:smoke # Runs headless Playwright test suite
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
### Continuous Integration (GitHub Actions)
|
|
820
|
+
When `testing.ci: true`, CRUDForge generates `.github/workflows/crudforge-smoke.yml` using `tests/generated/ci.cjs`:
|
|
821
|
+
- Supports `npm`, `pnpm`, and `yarn` based on lockfile detection.
|
|
822
|
+
- Installs frozen dependencies (`npm ci` / `pnpm install --frozen-lockfile` / `yarn install --immutable`).
|
|
823
|
+
- Runs strict production Angular build (`npm run build`).
|
|
824
|
+
- Installs Playwright browser dependencies and executes `test:smoke`.
|
|
825
|
+
- Uploads test failure reports and screenshots as artifacts on test failure without exposing secrets.
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
## Application tests, validation and setup diagnostics
|
|
829
|
+
|
|
830
|
+
Enable `generate.globals.tests: true` to generate isolated Playwright smoke tests.
|
|
831
|
+
Set `testing.ci: true` to also generate a GitHub Actions build/test workflow. Custom
|
|
832
|
+
tests belong in `tests/custom/`; normal regeneration conflict policies remain in effect.
|
|
833
|
+
|
|
834
|
+
```bash
|
|
835
|
+
crudforge validate gdl/example.gdl --json
|
|
836
|
+
crudforge doctor
|
|
837
|
+
crudforge doctor --live --json # only explicitly configured read-only endpoints
|
|
838
|
+
crudforge generate
|
|
839
|
+
npm ci
|
|
840
|
+
npm run test:smoke:install
|
|
841
|
+
npm run build
|
|
842
|
+
npm run test:smoke
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
Validation now uses the same fail-fast pipeline for validate and generate, including
|
|
846
|
+
unsupported annotations and relationship/name collisions. `validation: false` no
|
|
847
|
+
longer permits invalid schemas to generate files. Doctor is read-only; local checks
|
|
848
|
+
work without HTTP access, and live checks require explicit configured endpoints.
|
|
849
|
+
|
|
850
|
+
See [quality features and exact configuration](docs/quality/README.md) for test
|
|
851
|
+
isolation, custom tests, package managers/CI, diagnostic exit codes, backend contract
|
|
852
|
+
limits, and recovery when the shell cannot find `crudforge`.
|