@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
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: generator-engineer
|
|
3
|
+
description: Generator configuration, validation, templates, and generated-app integration for CRUDForge. Use for auth/IAM config schema, CLI commands, auth-pack environment wiring, and template changes that must not leak secrets.
|
|
4
|
+
model: inherit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Generator engineer
|
|
8
|
+
|
|
9
|
+
## Responsibilities
|
|
10
|
+
|
|
11
|
+
- Extend `auth` / `iam` configuration in defaults, YAML, `init-config`, and loaders without competing keys.
|
|
12
|
+
- Validate required settings with actionable errors.
|
|
13
|
+
- Resolve secret references (`passwordEnv`, `adminUsernameEnv`, `adminPasswordEnv`) in CLI/server-side code only.
|
|
14
|
+
- Wire generated Angular auth to `serverUrl` / realm / public `clientId`. Never emit provision passwords or confidential client secrets into Angular environments, templates, or fixtures.
|
|
15
|
+
- Keep `generate` from mutating remote Keycloak. Provisioning is a separate explicit command.
|
|
16
|
+
- Preserve mock IAM (`useMockAuth: true`) and existing entity templates.
|
|
17
|
+
|
|
18
|
+
## Constraints
|
|
19
|
+
|
|
20
|
+
- Source of truth: `src/templates`, `src/generator`, `src/config`, `src/commands`.
|
|
21
|
+
- Do not hand-edit testing-area `crudforge-app`, or `test/output*`.
|
|
22
|
+
- Do not JDL-model User or Role.
|
|
23
|
+
- Do not scatter hardcoded Keycloak hostnames in reusable defaults.
|
|
24
|
+
|
|
25
|
+
## Report
|
|
26
|
+
|
|
27
|
+
- Files changed
|
|
28
|
+
- Config contract actually implemented (field names)
|
|
29
|
+
- Backward-compat notes
|
|
30
|
+
- Validation cases added
|
|
31
|
+
- Anything that still emits secrets into generated apps
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: keycloak-engineer
|
|
3
|
+
description: Keycloak discovery, client provisioning, initial users/roles, and authentication integration. Use when bootstrapping realms via the project admin service, not assumed native Admin REST.
|
|
4
|
+
model: inherit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Keycloak engineer
|
|
8
|
+
|
|
9
|
+
## Responsibilities
|
|
10
|
+
|
|
11
|
+
- Discover the **real** admin-service API from code, docs, OpenAPI, or live introspection. Do not invent endpoints or assume native Keycloak Admin REST.
|
|
12
|
+
- Verify realm, client, and privilege of supplied credentials before mutating anything.
|
|
13
|
+
- Provision only configured resources: application client, roles, initial users, role assignments.
|
|
14
|
+
- Idempotent bootstrap: check-then-create, no duplicate resources, no password reset unless `resetExistingPasswords` is true.
|
|
15
|
+
- Dry run with zero remote mutations.
|
|
16
|
+
- Track created resource IDs in a local state file for optional cleanup of **those** resources only.
|
|
17
|
+
- Preserve unrelated clients (especially existing realm clients), users, realm settings, and role assignments.
|
|
18
|
+
- Default QA application client ID: `crudforge-client-QA`. If it already exists unmanaged, use it as-is — never mutate unmanaged clients. Only create when missing (stamp `crudforge.owned=true` on creates).
|
|
19
|
+
|
|
20
|
+
## Constraints
|
|
21
|
+
|
|
22
|
+
- Provision credentials and initial-user passwords stay in CLI/server-side process. Never log them, never write them into Angular, git, screenshots, or fixtures.
|
|
23
|
+
- Browser clients must be public (no confidential secret in the SPA).
|
|
24
|
+
- If credentials lack privileges, finish local + mock coverage and report the exact blocked live operation and minimum access needed. Never call mock coverage a live pass.
|
|
25
|
+
- Limit changes to configured resources.
|
|
26
|
+
|
|
27
|
+
## Report
|
|
28
|
+
|
|
29
|
+
- Discovered API contract (endpoints actually used)
|
|
30
|
+
- Auth method and whether `crud` is admin, realm user, or neither
|
|
31
|
+
- Resources created or modified (ids, names)
|
|
32
|
+
- Dry-run vs apply results
|
|
33
|
+
- Blockers and least privilege required
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-engineer
|
|
3
|
+
description: Generator tests, Playwright, live Keycloak integration tests, CI, and failure evidence for CRUDForge. Use after generator/provision changes; keep mock IAM deterministic.
|
|
4
|
+
model: inherit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# QA engineer
|
|
8
|
+
|
|
9
|
+
## Responsibilities
|
|
10
|
+
|
|
11
|
+
- Keep `npm test`, `test:e2e`, and `test:e2e:iam` (mock) passing.
|
|
12
|
+
- Add a separately enabled **live** Keycloak suite with `useMockAuth: false`. Do not change `e2e-prepare-iam.js` to force live auth.
|
|
13
|
+
- Cover config validation, idempotent bootstrap, generated app build, seeded login, bad password, anonymous redirect, RBAC (UI **and** backend/API where the service supports it), logout, IAM flows against real Keycloak, and useful errors for missing/insufficient/unreachable services.
|
|
14
|
+
- `test-run.sh` must work from any cwd, load gitignored env, refuse unsafe cleanup, stop on failure, distinguish mock vs live.
|
|
15
|
+
- CI: PR runs generator + mock Playwright. Live Keycloak is manual/scheduled with protected secrets. Untrusted PRs must not get live secrets.
|
|
16
|
+
- Record failures with evidence. Redact tokens and passwords. Disable traces/screenshots that would capture credentials when redaction cannot be guaranteed.
|
|
17
|
+
- Isolated, attributable test users. Serialize tests that mutate shared remote state. No fixed sleeps as the primary wait.
|
|
18
|
+
|
|
19
|
+
## Constraints
|
|
20
|
+
|
|
21
|
+
- Do not delete tests, weaken assertions, or hide failures.
|
|
22
|
+
- After three unsuccessful attempts at the same failure, stop and report diagnosis + blocker.
|
|
23
|
+
- Never report a blocked live run as passed.
|
|
24
|
+
- Edit generator sources, not the testing-area `crudforge-app` / `test/output*`, as source of truth.
|
|
25
|
+
|
|
26
|
+
## Report
|
|
27
|
+
|
|
28
|
+
- Commands run and exit codes
|
|
29
|
+
- Mock vs live distinction
|
|
30
|
+
- Pass/fail/blocked per case
|
|
31
|
+
- Artifacts (paths only; no secrets)
|
|
32
|
+
- Remaining gaps
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-reviewer
|
|
3
|
+
description: Independent review of secret handling, authorization, Keycloak client configuration, and provisioning safety. Use after implementation; do not implement features in this role.
|
|
4
|
+
model: inherit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Security reviewer
|
|
8
|
+
|
|
9
|
+
## Responsibilities
|
|
10
|
+
|
|
11
|
+
- Independent review of the **final** diff for this Keycloak bootstrap work.
|
|
12
|
+
- Check: secrets never in Angular bundles, committed fixtures, logs, or Playwright artifacts.
|
|
13
|
+
- Check: confidential client secrets not sent to the browser; password grant vs public client implications.
|
|
14
|
+
- Check: provisioning cannot run as a side effect of `generate`.
|
|
15
|
+
- Check: env-ref resolution cannot leak unused secrets; dry-run does not send passwords to the server if avoidable.
|
|
16
|
+
- Check: state-file cleanup cannot delete unrelated Keycloak resources.
|
|
17
|
+
- Check: test users are isolated; admin credentials are not hardcoded.
|
|
18
|
+
- Check: CI does not expose live secrets to untrusted pull requests.
|
|
19
|
+
|
|
20
|
+
## Constraints
|
|
21
|
+
|
|
22
|
+
- Review only. Do not “fix” by weakening tests or deleting coverage.
|
|
23
|
+
- Do not request or paste production secrets into the report.
|
|
24
|
+
- Findings must be severity-tagged: blocker / high / medium / low, with file paths.
|
|
25
|
+
|
|
26
|
+
## Report
|
|
27
|
+
|
|
28
|
+
- Verdict: approve / request changes
|
|
29
|
+
- Findings list with severity and path
|
|
30
|
+
- Residual risk (password grant, admin-service trust, QA host exposure)
|
package/.cursor/mcp.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: CRUDForge generator precautions the agent must follow on every task
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CRUDForge precautions
|
|
7
|
+
|
|
8
|
+
- Edit generator sources (`src/templates/**/*.ejs`, `src/generator`, `src/config`, `src/commands`). Do not hand-edit `test/output*` or a generated app unless the user is debugging that output.
|
|
9
|
+
- Treat `new` and `edit` as the same `formMode`. Sidebar mode must open the list drawer for both. Page mode may route to `new` / `:id/edit`. Never leave edit on a full page while new uses the sidebar.
|
|
10
|
+
- Change Fuse button and accent colors only through root `fuseTheme` in `src/app/app.ts` (wired by `provideTheming`) or `fuse.theme` in `crudforge.config.yml`. Do not scatter hardcoded primary colors in entity templates.
|
|
11
|
+
- Default list search is `ui.searchMode: field` (JHipster `field.contains`). Use `global` only when the backend accepts a `query` param (Elasticsearch-style). Do not assume Elasticsearch is present.
|
|
12
|
+
- Respect `output.overwritePolicy`. Never strip custom `// cforge-` merge zones. Do not rewrite the Fuse starter pack except through generator patches.
|
|
13
|
+
- Bind generated HTTP servers to `0.0.0.0:$PORT`. The filesystem is ephemeral — do not rely on local writes for persistence.
|
|
14
|
+
- After generator or template changes, run `node test/verify.js`. For UI bugs, use Playwright: `npm run e2e:prepare`, then `npm run e2e:serve` or `npm run test:e2e`. Generated Fuse app lives under `$CRUDFORGE_TESTING_AREA/crudforge-app` (default `/Users/abdulla/Work/CRUD-FORDGE-SETUP/crud-fordge-testing-area/crudforge-app`) — do not treat that copy as source.
|
|
15
|
+
- Keycloak auth/IAM is an overlay (`auth.provider: keycloak`, `iam.enabled`). Do not model User or Role as JDL entities. Leave `auth.provider: none` unless the app needs real identity.
|
|
16
|
+
- Never commit secrets, credentials, or live `.env` files.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: How the agent uses Playwright to browser-test generated CRUDForge apps
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Playwright browser testing
|
|
7
|
+
|
|
8
|
+
The agent has Playwright access in two ways:
|
|
9
|
+
|
|
10
|
+
1. **Playwright MCP** (`playwright-*` tools) for interactive exploration after the user reloads MCP.
|
|
11
|
+
2. **`npm run test:e2e`** for repeatable checks against a generated Fuse mock app.
|
|
12
|
+
|
|
13
|
+
## Before clicking around
|
|
14
|
+
|
|
15
|
+
- Prepare the app once: `npm run e2e:prepare` (generates `$CRUDFORGE_TESTING_AREA/crudforge-app`, default `/Users/abdulla/Work/CRUD-FORDGE-SETUP/crud-fordge-testing-area/crudforge-app`).
|
|
16
|
+
- Serve it: `npm run e2e:serve` (http://127.0.0.1:4200, mock configuration).
|
|
17
|
+
- Demo sign-in is prefilled. Click **Sign in**, then open `/admin/book` or `/admin/author`.
|
|
18
|
+
|
|
19
|
+
## What to verify
|
|
20
|
+
|
|
21
|
+
- New and Edit both honor `formMode`. Sidebar mode must open `mat-drawer` / `.cforge-form-drawer`. Edit must not land on `/:id/edit` as a full page while New stays in the drawer.
|
|
22
|
+
- Search-by is visible when `searchMode` is `field`. A single box is enough when `searchMode` is `global`.
|
|
23
|
+
- Fuse button/accent color comes from root `fuseTheme` in `app.ts`, not hardcoded entity styles.
|
|
24
|
+
- Hunt regressions on list, card, filter, confirm dialogs, and save/cancel.
|
|
25
|
+
|
|
26
|
+
## Rules
|
|
27
|
+
|
|
28
|
+
- Edit generator templates in `src/`, then re-run `e2e:prepare` before retesting. Do not patch the testing-area app as the source of truth.
|
|
29
|
+
- Prefer accessibility snapshots and role/text locators over brittle CSS.
|
|
30
|
+
- After UI fixes, run `npm run test:e2e` and `node test/verify.js`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Keep README.md and Todo.md current after meaningful project updates
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# README and Todo sync
|
|
7
|
+
|
|
8
|
+
Whenever you complete a meaningful feature, fix, config change, QA addition, or CLI change in this repo:
|
|
9
|
+
|
|
10
|
+
1. Update `README.md` with user-facing commands, options, config keys, and how-to notes that changed.
|
|
11
|
+
2. Update `Todo.md`: check off finished backlog items, add new known gaps, and refresh the "Suggested next slice" if priorities shifted.
|
|
12
|
+
|
|
13
|
+
Do this in the same turn as the implementation—do not wait to be asked. Keep both files accurate; do not invent completed work.
|
package/.env.qa.example
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Copy to .env.qa (gitignored). Never commit real production passwords.
|
|
2
|
+
#
|
|
3
|
+
# Real Keycloak endpoints are hardcoded in test-run.sh + e2e/crudforge.iam-live.yml.
|
|
4
|
+
# Operator / SPA login (adminUsernameEnv / adminPasswordEnv) = crud / crud.
|
|
5
|
+
|
|
6
|
+
KEYCLOAK_ADMIN_USERNAME=crud
|
|
7
|
+
KEYCLOAK_ADMIN_PASSWORD=crud
|
|
8
|
+
|
|
9
|
+
# Seeded application users (CLI bootstrap / live Playwright ACL cases)
|
|
10
|
+
CRUDFORGE_QA_ADMIN_PASSWORD=change-me-admin
|
|
11
|
+
CRUDFORGE_QA_USER_PASSWORD=change-me-user
|
|
12
|
+
|
|
13
|
+
# Live Playwright / test-run paths
|
|
14
|
+
CRUDFORGE_TESTING_AREA=/Users/abdulla/Work/CRUD-FORDGE-SETUP/crud-fordge-testing-area
|
|
15
|
+
CRUDFORGE_E2E_APP_NAME=crudforge-app
|
|
16
|
+
CRUDFORGE_LIVE_OUTPUT_DIR=
|
|
17
|
+
CRUDFORGE_LIVE_BASE_URL=http://127.0.0.1:4202
|
|
18
|
+
CRUDFORGE_LIVE_ADMIN_USERNAME=crudforge-qa-admin
|
|
19
|
+
CRUDFORGE_LIVE_USER_USERNAME=crudforge-qa-user
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: QA (live Keycloak)
|
|
2
|
+
|
|
3
|
+
# Protected secrets only. Do not run on untrusted pull_request forks.
|
|
4
|
+
on:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: "0 4 * * 1"
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
live:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 40
|
|
13
|
+
environment: keycloak-qa
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: "20"
|
|
19
|
+
cache: npm
|
|
20
|
+
- run: npm ci
|
|
21
|
+
- run: npx playwright install --with-deps chromium
|
|
22
|
+
- name: Live Keycloak bootstrap + Playwright
|
|
23
|
+
env:
|
|
24
|
+
CRUDFORGE_KC_SERVER_URL: ${{ secrets.CRUDFORGE_KC_SERVER_URL }}
|
|
25
|
+
CRUDFORGE_KC_REALM: ${{ secrets.CRUDFORGE_KC_REALM }}
|
|
26
|
+
CRUDFORGE_KC_CLIENT_ID: ${{ secrets.CRUDFORGE_KC_CLIENT_ID }}
|
|
27
|
+
CRUDFORGE_KC_FORWARDED_PROTO: https
|
|
28
|
+
KEYCLOAK_ADMIN_USERNAME: ${{ secrets.KEYCLOAK_ADMIN_USERNAME }}
|
|
29
|
+
KEYCLOAK_ADMIN_PASSWORD: ${{ secrets.KEYCLOAK_ADMIN_PASSWORD }}
|
|
30
|
+
CRUDFORGE_QA_ADMIN_PASSWORD: ${{ secrets.CRUDFORGE_QA_ADMIN_PASSWORD }}
|
|
31
|
+
CRUDFORGE_QA_USER_PASSWORD: ${{ secrets.CRUDFORGE_QA_USER_PASSWORD }}
|
|
32
|
+
run: bash test-run.sh live
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: QA (mock)
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main, master]
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
mock:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
timeout-minutes: 30
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-node@v4
|
|
15
|
+
with:
|
|
16
|
+
node-version: "20"
|
|
17
|
+
cache: npm
|
|
18
|
+
- run: npm ci
|
|
19
|
+
- run: npx playwright install --with-deps chromium
|
|
20
|
+
- name: Generator tests
|
|
21
|
+
run: npm test
|
|
22
|
+
- name: Mock Playwright (CRUD + IAM)
|
|
23
|
+
run: |
|
|
24
|
+
npm run e2e:prepare
|
|
25
|
+
npm run test:e2e
|
|
26
|
+
npm run e2e:prepare:iam
|
|
27
|
+
npm run test:e2e:iam
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"workbench.colorCustomizations": {
|
|
3
|
+
"activityBar.activeBackground": "#ab307e",
|
|
4
|
+
"activityBar.background": "#ab307e",
|
|
5
|
+
"activityBar.foreground": "#e7e7e7",
|
|
6
|
+
"activityBar.inactiveForeground": "#e7e7e799",
|
|
7
|
+
"activityBarBadge.background": "#25320e",
|
|
8
|
+
"activityBarBadge.foreground": "#e7e7e7",
|
|
9
|
+
"activityBarTop.activeBackground": "#ab307e",
|
|
10
|
+
"activityBarTop.background": "#ab307e",
|
|
11
|
+
"activityBarTop.foreground": "#e7e7e7",
|
|
12
|
+
"activityBarTop.inactiveForeground": "#e7e7e799",
|
|
13
|
+
"commandCenter.border": "#e7e7e799",
|
|
14
|
+
"commandCenter.foreground": "#e7e7e7",
|
|
15
|
+
"sash.hoverBorder": "#ab307e",
|
|
16
|
+
"statusBar.background": "#832561",
|
|
17
|
+
"statusBar.debuggingBackground": "#832561",
|
|
18
|
+
"statusBar.debuggingForeground": "#e7e7e7",
|
|
19
|
+
"statusBar.foreground": "#e7e7e7",
|
|
20
|
+
"statusBarItem.hoverBackground": "#ab307e",
|
|
21
|
+
"statusBarItem.remoteBackground": "#121907",
|
|
22
|
+
"statusBarItem.remoteForeground": "#e7e7e7",
|
|
23
|
+
"titleBar.activeBackground": "#832561",
|
|
24
|
+
"titleBar.activeForeground": "#e7e7e7",
|
|
25
|
+
"titleBar.inactiveBackground": "#83256199",
|
|
26
|
+
"titleBar.inactiveForeground": "#e7e7e799",
|
|
27
|
+
"activityBar.activeBorder": "#e7e7e7",
|
|
28
|
+
"activityBarTop.activeBorder": "#e7e7e7",
|
|
29
|
+
"statusBar.inactiveBackground": "#832561"
|
|
30
|
+
},
|
|
31
|
+
"peacock.color": "#832561"
|
|
32
|
+
}
|
package/QA/IAM-PLAN.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# IAM pack QA plan
|
|
2
|
+
|
|
3
|
+
**Target:** generated Fuse IAM mock app (`e2e/.iam-app`) at http://127.0.0.1:4201
|
|
4
|
+
**Build:** `npm run e2e:prepare:iam` then `npm run e2e:serve:iam`
|
|
5
|
+
**Sign-in:** `demo@crudforge.com` / `admin` (`auth.useMockAuth: true`)
|
|
6
|
+
**Pack under test:** Keycloak auth overlay + user-management IAM
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
In scope: mock Keycloak sign-in, AuthGuard, Identity nav, users CRUD dialog, user detail, change password, roles, role-permission matrix, user-access matrix, user-permission matrix.
|
|
11
|
+
|
|
12
|
+
Out of scope: live Keycloak, PMB-specific extras, existing Book/Author CRUD (covered by `QA/TESTCASES.md`).
|
|
13
|
+
|
|
14
|
+
## Entry criteria
|
|
15
|
+
|
|
16
|
+
- `e2e/.iam-app` generated from current `src/templates/angular/auth` and `iam`
|
|
17
|
+
- App serves on port 4201 without compile errors
|
|
18
|
+
- Playwright Chromium installed
|
|
19
|
+
|
|
20
|
+
## Exit criteria
|
|
21
|
+
|
|
22
|
+
- Every case in `IAM-TESTCASES.md` has Pass / Fail / Blocked
|
|
23
|
+
- Failures logged in `IAM-RESULTS.md` with severity and repro
|
|
24
|
+
- `npm run test:e2e:iam` matches the automated subset
|
|
25
|
+
- Defects filed against `src/templates/**`, not `e2e/.iam-app`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# IAM pack QA results
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-09-05
|
|
4
|
+
**Target:** `e2e/.iam-app` at http://127.0.0.1:4201
|
|
5
|
+
**Suite:** `npx playwright test --config=playwright.iam.config.js`
|
|
6
|
+
**Generator check:** `node test/verify.js` passed
|
|
7
|
+
|
|
8
|
+
## Summary
|
|
9
|
+
|
|
10
|
+
All 13 automated IAM cases passed after applying the PMB user-management UI/UX concept to the generated pack (Fuse list shell, side drawer create/edit/view, master-detail roles, card-style matrices).
|
|
11
|
+
|
|
12
|
+
| Result | Count |
|
|
13
|
+
|---|---|
|
|
14
|
+
| Pass | 13 |
|
|
15
|
+
| Fail | 0 |
|
|
16
|
+
| Blocked | 0 |
|
|
17
|
+
|
|
18
|
+
## Cases
|
|
19
|
+
|
|
20
|
+
| ID | Result | Notes |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| IAM-AUTH-01 | Pass | Mock admin reaches `/admin`. |
|
|
23
|
+
| IAM-AUTH-02 | Pass | Bad password stays on sign-in. |
|
|
24
|
+
| IAM-AUTH-03 | Pass | Anonymous `/admin/user-management` redirects to sign-in. |
|
|
25
|
+
| IAM-NAV-01 | Pass | Sidebar group is User Management. Users, Roles, Role permissions visible. |
|
|
26
|
+
| IAM-USER-01 | Pass | List heading and mock admin row. |
|
|
27
|
+
| IAM-USER-02 | Pass | New opens the list drawer (`New User`), Save adds the row. |
|
|
28
|
+
| IAM-USER-03 | Pass | View opens the profile drawer. |
|
|
29
|
+
| IAM-USER-04 | Pass | Change password dialog closes after Save. |
|
|
30
|
+
| IAM-ROLE-01 | Pass | `ROLE_ADMIN` in the left role list. |
|
|
31
|
+
| IAM-ROLE-02 | Pass | Create Role panel creates and selects the role. |
|
|
32
|
+
| IAM-PERM-01 | Pass | Role matrix shows ROLE_ADMIN and screen rows. |
|
|
33
|
+
| IAM-ACCESS-01 | Pass | Created ROLE_READER can be toggled on the user access matrix. |
|
|
34
|
+
| IAM-UPERM-01 | Pass | User screen toggle flips. |
|
|
35
|
+
|
|
36
|
+
## Defects fixed during this pass
|
|
37
|
+
|
|
38
|
+
1. **Role create UX** — inline Material form left Create disabled under Playwright `fill()`. Replaced with PMB-style Create Role panel and native fields.
|
|
39
|
+
2. **Mock store reset** — full navigation wiped in-memory users/roles. Mock Keycloak state now persists in `sessionStorage` (`cforge-iam-mock`).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# IAM pack test cases
|
|
2
|
+
|
|
3
|
+
Automated cases are tagged `[auto]`.
|
|
4
|
+
|
|
5
|
+
## Auth
|
|
6
|
+
|
|
7
|
+
| ID | Title | Steps | Expected | Tag |
|
|
8
|
+
|---|---|---|---|---|
|
|
9
|
+
| IAM-AUTH-01 | Mock admin sign-in | Open `/auth/sign-in`. Use `demo@crudforge.com` / `admin`. | Lands on `/admin/welcome`. | [auto] |
|
|
10
|
+
| IAM-AUTH-02 | Bad password | Sign in with a wrong password. | Stays on sign-in. Shows invalid credentials. | [auto] |
|
|
11
|
+
| IAM-AUTH-03 | Auth guard | Open `/admin/user-management` signed out. | Redirects to `/auth/sign-in`. | [auto] |
|
|
12
|
+
|
|
13
|
+
## Navigation
|
|
14
|
+
|
|
15
|
+
| ID | Title | Steps | Expected | Tag |
|
|
16
|
+
|---|---|---|---|---|
|
|
17
|
+
| IAM-NAV-01 | User Management menu | Sign in as admin. | Sidebar group is User Management. Users, Roles, Role permissions appear. | [auto] |
|
|
18
|
+
|
|
19
|
+
## Users
|
|
20
|
+
|
|
21
|
+
| ID | Title | Steps | Expected | Tag |
|
|
22
|
+
|---|---|---|---|---|
|
|
23
|
+
| IAM-USER-01 | Users list | Open `/admin/user-management`. | Heading User Management. Mock `admin` row. | [auto] |
|
|
24
|
+
| IAM-USER-02 | Create user | Click New. Fill username and save. | Dialog closes. New username is in the table. | [auto] |
|
|
25
|
+
| IAM-USER-03 | View details | Click View on admin. | Drawer shows User Details. | [auto] |
|
|
26
|
+
| IAM-USER-04 | Change password | On detail, change password and save. | Dialog closes without error. | [auto] |
|
|
27
|
+
|
|
28
|
+
## Roles and matrices
|
|
29
|
+
|
|
30
|
+
| ID | Title | Steps | Expected | Tag |
|
|
31
|
+
|---|---|---|---|---|
|
|
32
|
+
| IAM-ROLE-01 | Roles list | Open `/admin/user-management/roles`. | `ROLE_ADMIN` appears in the left list. | [auto] |
|
|
33
|
+
| IAM-ROLE-02 | Create role | Click Create Role, enter a name, Create. | Role is selected in the master-detail pane. | [auto] |
|
|
34
|
+
| IAM-PERM-01 | Role matrix | Open role-permissions. | ROLE_ADMIN column and screen rows render. | [auto] |
|
|
35
|
+
| IAM-ACCESS-01 | Assign role | Create ROLE_READER. On admin access, toggle it on. | Switch stays checked. | [auto] |
|
|
36
|
+
| IAM-UPERM-01 | User screens | On admin permissions, toggle a book screen. | Switch flips. | [auto] |
|
package/QA/IAM-TODO.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# IAM QA agent todo
|
|
2
|
+
|
|
3
|
+
- [x] Confirm `e2e/.iam-app` exists and `npm run e2e:serve:iam` is healthy on :4201
|
|
4
|
+
- [x] Run `npm run test:e2e:iam`
|
|
5
|
+
- [x] Record results in `QA/IAM-RESULTS.md`
|
|
6
|
+
- [x] File template defects against `src/templates/angular/auth` or `iam`
|
|
7
|
+
- [x] Re-run prepare + tests after template fixes
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Keycloak bootstrap and live QA
|
|
2
|
+
|
|
3
|
+
CRUDForge can **configure** Keycloak for generated apps and **optionally provision** a client, realm roles, initial users, and role assignments. `generate` never mutates a remote realm.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Mock (no Keycloak mutations)
|
|
9
|
+
./test-run.sh mock
|
|
10
|
+
npm test
|
|
11
|
+
npm run e2e:prepare && npm run test:e2e
|
|
12
|
+
npm run e2e:prepare:iam && npm run test:e2e:iam
|
|
13
|
+
|
|
14
|
+
# Live (requires .env.qa)
|
|
15
|
+
cp .env.qa.example .env.qa # gitignored
|
|
16
|
+
./test-run.sh live
|
|
17
|
+
# or:
|
|
18
|
+
node cli.js bootstrap --preferences e2e/crudforge.iam-live.yml --env-file .env.qa
|
|
19
|
+
node cli.js bootstrap --preferences e2e/crudforge.iam-live.yml --env-file .env.qa # idempotent
|
|
20
|
+
npm run e2e:prepare:iam:live
|
|
21
|
+
npm run e2e:serve:iam:live # http://127.0.0.1:4202 (development config, not mock)
|
|
22
|
+
npm run test:e2e:iam:live
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`test-run.sh` resolves paths from its own location, so it can be invoked from any cwd.
|
|
26
|
+
|
|
27
|
+
## Environment
|
|
28
|
+
|
|
29
|
+
| Variable | Purpose |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `CRUDFORGE_KC_SERVER_URL` | Keycloak base URL (e.g. `http://62.84.188.166:30080`) — not the admin console deep-link |
|
|
32
|
+
| `CRUDFORGE_KC_REALM` | Realm name (`CRUD-FORDGE`) |
|
|
33
|
+
| `CRUDFORGE_KC_CLIENT_ID` | Public SPA client (`crudforge-client-QA`) |
|
|
34
|
+
| `CRUDFORGE_KC_ADMIN_SERVICE_URL` | Keycloak middleware / admin service (`http://62.84.188.166:31740/`) |
|
|
35
|
+
| `CRUDFORGE_KC_FORWARDED_PROTO` | Sent as `X-Forwarded-Proto` when Keycloak requires HTTPS behind HTTP |
|
|
36
|
+
| `KEYCLOAK_ADMIN_USERNAME` / `KEYCLOAK_ADMIN_PASSWORD` | CLI bootstrap operator (QA: `crud` / `crud`) |
|
|
37
|
+
| `CRUDFORGE_QA_ADMIN_PASSWORD` / `CRUDFORGE_QA_USER_PASSWORD` | Seeded app users |
|
|
38
|
+
|
|
39
|
+
Passwords stay in the CLI process. They are not written to Angular `environment.ts`.
|
|
40
|
+
|
|
41
|
+
## Adapters
|
|
42
|
+
|
|
43
|
+
- `auth.provision.adapter: admin-service` — documented `GET /api/v1/*` on the custom wrapper. **Create client/user/role is not in that contract.** Requires realm role `KEYCLOAK_ADMIN_ACCESS`.
|
|
44
|
+
- `auth.provision.adapter: keycloak-admin-rest` — native Keycloak Admin REST on `auth.serverUrl`. Used for QA bootstrap against public SPA client `crudforge-client-QA` (uses existing client as-is when unmanaged).
|
|
45
|
+
|
|
46
|
+
Existing unmanaged clients are **not** modified. Live test-run targets `crudforge-client-QA` with operator `crud` / middleware `http://62.84.188.166:31740/`.
|
|
47
|
+
|
|
48
|
+
## Browser auth compatibility
|
|
49
|
+
|
|
50
|
+
Password grant uses a **public** client (no secret in the SPA). When `auth.forwardedProto` is set, token and API calls send `X-Forwarded-Proto`. Live apps proxy `/realms` and `/admin/realms` to Keycloak `serverUrl` so token and Admin REST calls avoid browser CORS. Broader `/auth` and `/admin` prefixes are **not** proxied: `/auth` would steal the Fuse sign-in page, and `/admin` would steal Angular admin routes (Keycloak console also lives under `/admin`).
|
|
51
|
+
|
|
52
|
+
## CI
|
|
53
|
+
|
|
54
|
+
- `.github/workflows/qa.yml` — PRs: `npm test` + mock Playwright (`test:e2e` ignores `iam-live.spec.js`). No live secrets.
|
|
55
|
+
- `.github/workflows/qa-live.yml` — `workflow_dispatch` / weekly schedule, GitHub environment `keycloak-qa`, repository secrets. Do not enable this on untrusted forks.
|
|
56
|
+
|
|
57
|
+
## Cleanup
|
|
58
|
+
|
|
59
|
+
`node cli.js bootstrap --cleanup --preferences e2e/crudforge.iam-live.yml --env-file .env.qa` deletes **only** IDs recorded in `.crudforge/provision-state.json`.
|
|
60
|
+
|
|
61
|
+
## Live QA results (2026-09-20)
|
|
62
|
+
|
|
63
|
+
Prerequisites: gitignored `.env.qa`, Keycloak `http://62.84.188.166:30080`, realm `CRUD-FORDGE`, Playwright Chromium with default browser path (`env -u PLAYWRIGHT_BROWSERS_PATH` if a sandbox path is set).
|
|
64
|
+
|
|
65
|
+
| Check | Result |
|
|
66
|
+
|---|---|
|
|
67
|
+
| Default `auth.provider: none`, `provision.enabled: false` | Pass (`node test/verify.js`) |
|
|
68
|
+
| Env-ref validation and secret stripping | Pass |
|
|
69
|
+
| Bootstrap client `crudforge-client-QA` + roles + users | Pass (native Admin REST; unmanaged client used as-is) |
|
|
70
|
+
| Second bootstrap idempotent, passwords not reset | Pass |
|
|
71
|
+
| Generated live app `tsc --noEmit` | Pass |
|
|
72
|
+
| LIVE-AUTH-01 seeded admin sign-in | Pass |
|
|
73
|
+
| LIVE-AUTH-02 unknown user / bad password rejected | Pass |
|
|
74
|
+
| LIVE-AUTH-03 anonymous redirect to sign-in | Pass |
|
|
75
|
+
| LIVE-AUTH-04 Sign out clears session | Pass |
|
|
76
|
+
| LIVE-RBAC-01 limited user → `/admin/no-access` | Pass |
|
|
77
|
+
| LIVE-API-01 limited user denied Admin REST | Pass |
|
|
78
|
+
| LIVE-API-02 realm operator can GET `/admin/realms/.../users` | Pass |
|
|
79
|
+
| LIVE-IAM-01 ROLE_ADMIN opens User Management shell | Pass |
|
|
80
|
+
| LIVE-IAM-02 realm operator `crud` denied Angular IAM screens | Pass (no `ROLE_ADMIN`) |
|
|
81
|
+
| Admin wrapper `:31740` create client/user/role | **Blocked** (see below) |
|
|
82
|
+
| Combined IAM UI + Admin REST as one seeded user | **Blocked** (see below) |
|
|
83
|
+
|
|
84
|
+
`npm run test:e2e:iam:live` — **9 passed** (also re-run via `./test-run.sh live` into `/Users/abdulla/Work/CRUD-FORDGE-SETUP/crud-fordge-testing-area`).
|
|
85
|
+
|
|
86
|
+
`./test-run.sh mock` — generator verify + CRUD + mock IAM **passed** into the same testing area (`.app`, `.iam-app`).
|
|
87
|
+
|
|
88
|
+
## Blockers
|
|
89
|
+
|
|
90
|
+
1. **Admin service adapter (`:31740`)**
|
|
91
|
+
The wrapper is not the Keycloak Admin REST API. Documented `GET /api/v1/*` requires realm role `KEYCLOAK_ADMIN_ACCESS`. The supplied `crud` user can authenticate to native Keycloak on `:30080` (realm-management) but **does not** have `KEYCLOAK_ADMIN_ACCESS`, so wrapper calls return **403**. Create client/user/role is **not** in that contract. Live bootstrap therefore uses `auth.provision.adapter: keycloak-admin-rest` against `:30080`. Minimum access to use the wrapper: `KEYCLOAK_ADMIN_ACCESS` plus whatever write APIs the service actually exposes (confirm from its HTML API reference; do not assume native Admin REST paths).
|
|
92
|
+
|
|
93
|
+
2. **`crudforge-client-QA`**
|
|
94
|
+
Live QA uses this application client ID. If it already exists unmanaged, bootstrap uses it without modification. Closest legacy public client `crude-fordge-QA` remains untouched.
|
|
95
|
+
|
|
96
|
+
3. **Single identity for IAM UI + Keycloak Admin REST**
|
|
97
|
+
Angular ACL treats `ROLE_ADMIN` as app admin. Keycloak user CRUD needs `realm-management` client roles. Seeded `crudforge-qa-admin` has `ROLE_ADMIN` only (UI shell works; Admin REST as that user is denied). Operator `crud` has realm-management only (Admin REST works; Angular IAM shows “No screens assigned”). We did not grant `realm-admin` to seeded app users and did not add `ROLE_ADMIN` to `crud`. Full in-browser create/edit/delete of users against live Keycloak therefore remains blocked until a dedicated QA user is given **both** sets of roles.
|
|
98
|
+
|
|
99
|
+
4. **GitHub Actions live job**
|
|
100
|
+
`.github/workflows/qa-live.yml` is `workflow_dispatch` / weekly schedule with environment `keycloak-qa`. It is not run on pull requests. Creating that GitHub environment and secrets is an operator step; this session did not execute the hosted live workflow.
|
|
101
|
+
|
|
102
|
+
## Security review
|
|
103
|
+
|
|
104
|
+
Independent review requested changes: `stripSecretsForGenerate` must run on the CLI `generate` path so `auth.clientSecret` cannot be embedded in entity `preferences`. Fixed in `src/commands/generate.js` and `src/generator/index.js`, with generator tests that fail if those secrets are emitted.
|
|
105
|
+
|
package/QA/PLAN.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# CRUDForge QA plan
|
|
2
|
+
|
|
3
|
+
**Target:** generated Fuse mock app (`e2e/.app`) at http://127.0.0.1:4200
|
|
4
|
+
**Build:** `npm run e2e:prepare` then `npm run e2e:serve`
|
|
5
|
+
**Sign-in:** prefilled `demo@crudforge.com` / click Sign in
|
|
6
|
+
**Entities under test:** Book, Author
|
|
7
|
+
**Config under test:** `formMode: sidebar`, `viewMode: table`, `searchMode: field`, mock data on
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
In scope: auth, admin navigation, list table, card toggle, field search, filter drawer, new/edit sidebar forms, validation, detail, delete confirm, pagination, pin/flag, export control presence, Author parity.
|
|
12
|
+
|
|
13
|
+
Out of scope this pass: real backend APIs, Elasticsearch, page-mode forms, overwrite-policy CLI, generator unit internals (covered by `node test/verify.js`).
|
|
14
|
+
|
|
15
|
+
## Entry criteria
|
|
16
|
+
|
|
17
|
+
- `e2e/.app` generated from current templates
|
|
18
|
+
- App serves on port 4200 without compile errors
|
|
19
|
+
- Playwright Chromium installed (`npm run test:e2e:install`)
|
|
20
|
+
|
|
21
|
+
## Exit criteria
|
|
22
|
+
|
|
23
|
+
- Every case in `TESTCASES.md` has Pass / Fail / Blocked
|
|
24
|
+
- Failures logged in `RESULTS.md` with severity and repro
|
|
25
|
+
- `npm run test:e2e` matches the automated subset
|
|
26
|
+
- Defects that belong in generator templates are filed against `src/templates`, not `e2e/.app`
|
|
27
|
+
|
|
28
|
+
## Severity
|
|
29
|
+
|
|
30
|
+
| Level | Meaning |
|
|
31
|
+
|---|---|
|
|
32
|
+
| S1 | Cannot sign in or open an entity list |
|
|
33
|
+
| S2 | Create/edit/delete wrong surface or data loss |
|
|
34
|
+
| S3 | Feature works but UX/a11y/visual is wrong |
|
|
35
|
+
| S4 | Cosmetic / copy |
|
|
36
|
+
|
|
37
|
+
## How the QA agent runs a pass
|
|
38
|
+
|
|
39
|
+
1. Confirm server is up (`e2e:serve`).
|
|
40
|
+
2. Execute automated specs: `npm run test:e2e`.
|
|
41
|
+
3. Walk remaining manual cases in Chromium (Playwright MCP when available).
|
|
42
|
+
4. Update `RESULTS.md` and the QA canvas.
|
|
43
|
+
5. If a generator bug is found, fix `src/templates/**`, re-run `e2e:prepare`, retest.
|
package/QA/RESULTS.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# QA results — existing features
|
|
2
|
+
|
|
3
|
+
**Pass date:** 2026-09-05
|
|
4
|
+
**App:** http://127.0.0.1:4200
|
|
5
|
+
**Config:** `formMode: sidebar`, `viewMode: table`, `searchMode: field`, mock 12 rows
|
|
6
|
+
**Runner:** Playwright Chromium (`npm run test:e2e`)
|
|
7
|
+
|
|
8
|
+
## Summary
|
|
9
|
+
|
|
10
|
+
| Bucket | Count |
|
|
11
|
+
|---|---|
|
|
12
|
+
| Automated executed | 22 |
|
|
13
|
+
| Automated passed | 22 |
|
|
14
|
+
| Automated failed | 0 |
|
|
15
|
+
| Manual still open | 0 |
|
|
16
|
+
| Defects found | 2 (both fixed in templates on the first pass) |
|
|
17
|
+
|
|
18
|
+
## Automated results
|
|
19
|
+
|
|
20
|
+
| ID | Result | Notes |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| AUTH-01 | Pass | Demo sign-in reaches `/admin` |
|
|
23
|
+
| AUTH-02 | Pass | Logo + Welcome copy. Sign-in button uses Fuse `--theme-color-primary-600` (oklch from `#0f766e`) |
|
|
24
|
+
| NAV-01 | Pass | Book Management + New |
|
|
25
|
+
| NAV-02 | Pass | Author Management + New |
|
|
26
|
+
| LIST-01 | Pass | Mock titles and `of 12` |
|
|
27
|
+
| LIST-02 | Pass | Next page shows 11–12 of 12 |
|
|
28
|
+
| LIST-03 | Pass | Pin row → Unpin row |
|
|
29
|
+
| LIST-04 | Pass | Blue flag applies `tr.has-flag` |
|
|
30
|
+
| LIST-05 | Pass | Export menu: Filtered + All |
|
|
31
|
+
| SEARCH-01 | Pass | Search-by + Search field |
|
|
32
|
+
| SEARCH-02 | Pass | `Mock title 1` keeps 4 rows (`1`, `10`, `11`, `12`); `Mock title 2` gone |
|
|
33
|
+
| FILTER-01 | Pass | Advanced Filters drawer |
|
|
34
|
+
| FILTER-02 | Pass | Title contains `Mock title 1` closes drawer and yields `1 – 4 of 4` |
|
|
35
|
+
| FORM-01 | Pass | New stays on list, sidebar New Book |
|
|
36
|
+
| FORM-02 | Pass | Edit stays on list, sidebar Edit Book |
|
|
37
|
+
| FORM-03 | Pass | Save disabled without required title |
|
|
38
|
+
| FORM-04 | Pass | Cancel closes drawer |
|
|
39
|
+
| FORM-05 | Pass | Author New is sidebar |
|
|
40
|
+
| DETAIL-01 | Pass | `/admin/book/:id/view` |
|
|
41
|
+
| DETAIL-02 | Pass after fix | First run 404 — see DEF-01 |
|
|
42
|
+
| DELETE-01 | Pass | Cancel keeps Mock title 1 |
|
|
43
|
+
| CARD-01 | Pass after fix | First run could not find toggle — see DEF-02 |
|
|
44
|
+
|
|
45
|
+
## Defects
|
|
46
|
+
|
|
47
|
+
### DEF-01 — S2 Detail Back 404 (fixed)
|
|
48
|
+
|
|
49
|
+
- **Case:** DETAIL-02
|
|
50
|
+
- **Repro:** View a book, click Back.
|
|
51
|
+
- **Was:** navigated to `/admin/book/:id` (no route) → 404.
|
|
52
|
+
- **Cause:** `goBack()` used `../` from `:id/view`.
|
|
53
|
+
- **Fix:** `src/templates/angular/entity/components/presentation/detail/_entity_-detail.component.ts.ejs` now navigates `../../`.
|
|
54
|
+
|
|
55
|
+
### DEF-02 — S3 View/filter icon buttons had no accessible name (fixed)
|
|
56
|
+
|
|
57
|
+
- **Case:** CARD-01
|
|
58
|
+
- **Repro:** `matTooltip` is not a DOM attribute, so the card toggle was not findable by name.
|
|
59
|
+
- **Fix:** aria-label on view-mode and filter buttons in `_entity_-actions.component.html.ejs`.
|