@shanyucoder/flowgrid 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +194 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/IntegrationContext.cs +56 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/IntegrationGen.csproj +16 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/NameUtil.cs +18 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/Program.cs +265 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/Templates/application_service.cs.scriban +27 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/Templates/handoff.md.scriban +15 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/Templates/infrastructure_mock.cs.scriban +20 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/Templates/presenter.cs.scriban +41 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/Templates/service_test.cs.scriban +17 -0
- package/adapters/dotnet-integration/codegen/runners/IntegrationGen/YamlMap.cs +49 -0
- package/adapters/dotnet-integration/registries/dotnet-integration.codegen.registry.json +8 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/LineContext.cs +43 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/LineGen.csproj +16 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/NameUtil.cs +12 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/Program.cs +201 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/TemplateRenderer.cs +22 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/Templates/handoff.md.scriban +15 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/Templates/service.cs.scriban +21 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/Templates/service_interface.cs.scriban +20 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/Templates/view_model.cs.scriban +28 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/Templates/view_model_test.cs.scriban +22 -0
- package/adapters/dotnet-line/codegen/runners/LineGen/YamlMap.cs +49 -0
- package/adapters/dotnet-line/registries/dotnet-line.codegen.registry.json +8 -0
- package/adapters/fastapi/codegen/runners/fast_gen/__init__.py +1 -0
- package/adapters/fastapi/codegen/runners/fast_gen/__main__.py +3 -0
- package/adapters/fastapi/codegen/runners/fast_gen/cli.py +175 -0
- package/adapters/fastapi/codegen/runners/fast_gen/plan.py +285 -0
- package/adapters/fastapi/codegen/runners/fast_gen/read_spec.py +34 -0
- package/adapters/fastapi/codegen/runners/fast_gen/registry.py +9 -0
- package/adapters/fastapi/codegen/runners/fast_gen/wire.py +28 -0
- package/adapters/fastapi/codegen/runners/fast_gen/write_files.py +232 -0
- package/adapters/fastapi/codegen/runners/generate +5 -0
- package/adapters/fastapi/codegen/runners/validate-registry.mjs +54 -0
- package/adapters/fastapi/codegen/templates/presenter.py.j2 +11 -0
- package/adapters/fastapi/codegen/templates/router.py.j2 +69 -0
- package/adapters/fastapi/codegen/templates/schemas_request.py.j2 +26 -0
- package/adapters/fastapi/codegen/templates/schemas_response.py.j2 +7 -0
- package/adapters/fastapi/codegen/templates/service_create.py.j2 +10 -0
- package/adapters/fastapi/codegen/templates/service_delete.py.j2 +10 -0
- package/adapters/fastapi/codegen/templates/service_search.py.j2 +9 -0
- package/adapters/fastapi/codegen/templates/service_update.py.j2 +11 -0
- package/adapters/fastapi/codegen/templates/store.py.j2 +1 -0
- package/adapters/fastapi/codegen/templates/test_router.py.j2 +13 -0
- package/adapters/fastapi/registries/codegen.registry.json +47 -0
- package/adapters/fastapi/registries/common.registry.json +23 -0
- package/adapters/fastapi/registries/unit-test.registry.json +12 -0
- package/adapters/fastapi/unitgen/runners/fast_unit_gen/__init__.py +1 -0
- package/adapters/fastapi/unitgen/runners/fast_unit_gen/cli.py +188 -0
- package/adapters/fastapi/unitgen/runners/generate +5 -0
- package/adapters/fastapi/unitgen/runners/validate-registry.mjs +48 -0
- package/adapters/fastapi/unitgen/templates/test_service.py.j2 +12 -0
- package/adapters/laravel/codegen/runners/README.md +45 -0
- package/adapters/laravel/codegen/runners/generate.mjs +296 -0
- package/adapters/laravel/codegen/runners/lib/codegen-registry.mjs +60 -0
- package/adapters/laravel/codegen/runners/lib/detect-existing.mjs +84 -0
- package/adapters/laravel/codegen/runners/lib/exec-artisan.mjs +86 -0
- package/adapters/laravel/codegen/runners/lib/parse-tags.mjs +49 -0
- package/adapters/laravel/codegen/runners/lib/plan.mjs +122 -0
- package/adapters/laravel/codegen/runners/lib/read-spec.mjs +30 -0
- package/adapters/laravel/codegen/runners/lib/resolve-commands.mjs +234 -0
- package/adapters/laravel/codegen/runners/lib/stub-services.mjs +91 -0
- package/adapters/laravel/codegen/runners/lib/tag-plan.mjs +155 -0
- package/adapters/laravel/codegen/runners/lib/validate.mjs +77 -0
- package/adapters/laravel/codegen/runners/lib/workspace-analysis.mjs +202 -0
- package/adapters/laravel/codegen/runners/lib/write-handoff.mjs +149 -0
- package/adapters/laravel/codegen/runners/lib/write-manifest.mjs +81 -0
- package/adapters/laravel/codegen/runners/validate-registry.mjs +52 -0
- package/adapters/laravel/php/README.md +26 -0
- package/adapters/laravel/php/bin/unit-gen.php +307 -0
- package/adapters/laravel/php/bin/validate-registry.php +61 -0
- package/adapters/laravel/php/composer.json +16 -0
- package/adapters/laravel/php/src/ArtisanRunner.php +56 -0
- package/adapters/laravel/php/src/Autoload.php +15 -0
- package/adapters/laravel/php/src/CodegenManifest.php +28 -0
- package/adapters/laravel/php/src/ParseTags.php +62 -0
- package/adapters/laravel/php/src/ProjectResolver.php +100 -0
- package/adapters/laravel/php/src/SpecExtract.php +193 -0
- package/adapters/laravel/php/src/SpecReader.php +57 -0
- package/adapters/laravel/php/src/TemplateRenderer.php +134 -0
- package/adapters/laravel/php/src/UnitPlanner.php +396 -0
- package/adapters/laravel/php/src/UnitRegistry.php +100 -0
- package/adapters/laravel/php/src/WhenEval.php +111 -0
- package/adapters/laravel/php/src/WorkspaceInspector.php +240 -0
- package/adapters/laravel/php/src/WriteFiles.php +194 -0
- package/adapters/laravel/php/templates/actions/relationship-sync.behavior.test.php.stub +50 -0
- package/adapters/laravel/php/templates/controllers/controller-invoke.test.php.stub +34 -0
- package/adapters/laravel/php/templates/queries/chain-scope.behavior.test.php.stub +34 -0
- package/adapters/laravel/php/templates/requests/default-per-page.behavior.test.php.stub +19 -0
- package/adapters/laravel/php/templates/requests/request-enriched.test.php.stub +66 -0
- package/adapters/laravel/php/templates/requests/rules-keys.behavior.test.php.stub +19 -0
- package/adapters/laravel/php/templates/resources/nested-relations.behavior.test.php.stub +25 -0
- package/adapters/laravel/php/templates/resources/openapi-shape.behavior.test.php.stub +28 -0
- package/adapters/laravel/php/templates/support/ModuleTestSupport.php.stub +32 -0
- package/adapters/laravel/registries/codegen.registry.json +190 -0
- package/adapters/laravel/registries/unit-test.registry.json +179 -0
- package/adapters/laravel/shared/project.mjs +62 -0
- package/adapters/nestjs/README.md +16 -0
- package/adapters/nestjs/nest-unitgen/runners/README.md +17 -0
- package/adapters/nestjs/nest-unitgen/runners/generate.mjs +113 -0
- package/adapters/nestjs/nest-unitgen/runners/lib/render.mjs +14 -0
- package/adapters/nestjs/nest-unitgen/runners/lib/write-files.mjs +40 -0
- package/adapters/nestjs/nest-unitgen/runners/validate-registry.mjs +35 -0
- package/adapters/nestjs/nest-unitgen/templates/commands/create.handler.spec.ts.hbs +32 -0
- package/adapters/nestjs/nest-unitgen/templates/commands/delete.handler.spec.ts.hbs +32 -0
- package/adapters/nestjs/nest-unitgen/templates/commands/update.handler.spec.ts.hbs +32 -0
- package/adapters/nestjs/nest-unitgen/templates/handlers/search.handler.spec.ts.hbs +33 -0
- package/adapters/nestjs/nest-unitgen/templates/resource/entity.resource.spec.ts.hbs +22 -0
- package/adapters/nestjs/nestgen/runners/README.md +30 -0
- package/adapters/nestjs/nestgen/runners/generate.mjs +87 -0
- package/adapters/nestjs/nestgen/runners/lib/orm-fields.mjs +253 -0
- package/adapters/nestjs/nestgen/runners/lib/plan.mjs +124 -0
- package/adapters/nestjs/nestgen/runners/lib/read-spec.mjs +52 -0
- package/adapters/nestjs/nestgen/runners/lib/render.mjs +52 -0
- package/adapters/nestjs/nestgen/runners/lib/workspace-analysis.mjs +80 -0
- package/adapters/nestjs/nestgen/runners/lib/write-files.mjs +49 -0
- package/adapters/nestjs/nestgen/runners/validate-registry.mjs +36 -0
- package/adapters/nestjs/nestgen/templates/commands/create.command.ts.hbs +3 -0
- package/adapters/nestjs/nestgen/templates/commands/create.handler.ts.hbs +34 -0
- package/adapters/nestjs/nestgen/templates/commands/delete.command.ts.hbs +3 -0
- package/adapters/nestjs/nestgen/templates/commands/delete.handler.ts.hbs +33 -0
- package/adapters/nestjs/nestgen/templates/commands/update.command.ts.hbs +6 -0
- package/adapters/nestjs/nestgen/templates/commands/update.handler.ts.hbs +34 -0
- package/adapters/nestjs/nestgen/templates/entity.controller.ts.hbs +51 -0
- package/adapters/nestjs/nestgen/templates/entity.resource.ts.hbs +45 -0
- package/adapters/nestjs/nestgen/templates/module.module.ts.hbs +38 -0
- package/adapters/nestjs/nestgen/templates/orm/prisma.entity.ts.hbs +10 -0
- package/adapters/nestjs/nestgen/templates/orm/prisma.model.prisma.hbs +9 -0
- package/adapters/nestjs/nestgen/templates/orm/typeorm.entity.ts.hbs +20 -0
- package/adapters/nestjs/nestgen/templates/queries/search.handler.ts.hbs +36 -0
- package/adapters/nestjs/nestgen/templates/queries/search.query.ts.hbs +3 -0
- package/adapters/nestjs/registries/nest-codegen.registry.json +41 -0
- package/adapters/nestjs/registries/nest-unit-test.registry.json +31 -0
- package/adapters/nextjs/codegen/runners/README.md +68 -0
- package/adapters/nextjs/codegen/runners/generate.mjs +236 -0
- package/adapters/nextjs/codegen/runners/lib/component-resolve.mjs +79 -0
- package/adapters/nextjs/codegen/runners/lib/design-registry.mjs +333 -0
- package/adapters/nextjs/codegen/runners/lib/naming.mjs +236 -0
- package/adapters/nextjs/codegen/runners/lib/page-lifecycle.mjs +258 -0
- package/adapters/nextjs/codegen/runners/lib/plan.mjs +399 -0
- package/adapters/nextjs/codegen/runners/lib/read-spec.mjs +7 -0
- package/adapters/nextjs/codegen/runners/lib/render.mjs +47 -0
- package/adapters/nextjs/codegen/runners/lib/resolve-hub-id.mjs +288 -0
- package/adapters/nextjs/codegen/runners/lib/slots.mjs +121 -0
- package/adapters/nextjs/codegen/runners/lib/web-paths.mjs +64 -0
- package/adapters/nextjs/codegen/runners/lib/write-files.mjs +106 -0
- package/adapters/nextjs/codegen/runners/validate-registry.mjs +99 -0
- package/adapters/nextjs/codegen/templates/common/confirm-dialog.hbs +81 -0
- package/adapters/nextjs/codegen/templates/common/delete-flow.hbs +106 -0
- package/adapters/nextjs/codegen/templates/create/form.tsx.hbs +45 -0
- package/adapters/nextjs/codegen/templates/create/mock.ts.hbs +15 -0
- package/adapters/nextjs/codegen/templates/create/page.tsx.hbs +12 -0
- package/adapters/nextjs/codegen/templates/create/service.ts.hbs +25 -0
- package/adapters/nextjs/codegen/templates/create/useForm.ts.hbs +59 -0
- package/adapters/nextjs/codegen/templates/create/validation.ts.hbs +16 -0
- package/adapters/nextjs/codegen/templates/list/mock.ts.hbs +25 -0
- package/adapters/nextjs/codegen/templates/list/page.custom.tsx.hbs +65 -0
- package/adapters/nextjs/codegen/templates/list/page.tsx.hbs +37 -0
- package/adapters/nextjs/codegen/templates/list/service.ts.hbs +37 -0
- package/adapters/nextjs/codegen/templates/list/useList.ts.hbs +93 -0
- package/adapters/nextjs/codegen/templates/list/useListColumns.ts.hbs +27 -0
- package/adapters/nextjs/codegen/templates/list/useListExport.ts.hbs +31 -0
- package/adapters/nextjs/codegen/templates/list/useListFilters.ts.hbs +50 -0
- package/adapters/nextjs/codegen/templates/store/store.ts.hbs +28 -0
- package/adapters/nextjs/contractgen/runners/README.md +47 -0
- package/adapters/nextjs/contractgen/runners/generate.mjs +108 -0
- package/adapters/nextjs/contractgen/runners/lib/field-zod.mjs +83 -0
- package/adapters/nextjs/contractgen/runners/lib/naming.mjs +46 -0
- package/adapters/nextjs/contractgen/runners/lib/plan.mjs +147 -0
- package/adapters/nextjs/contractgen/runners/lib/render.mjs +57 -0
- package/adapters/nextjs/contractgen/runners/lib/write-files.mjs +54 -0
- package/adapters/nextjs/contractgen/runners/validate-registry.mjs +54 -0
- package/adapters/nextjs/contractgen/templates/index.ts.hbs +8 -0
- package/adapters/nextjs/contractgen/templates/read.schema.ts.hbs +22 -0
- package/adapters/nextjs/contractgen/templates/relationships.meta.ts.hbs +23 -0
- package/adapters/nextjs/contractgen/templates/types.ts.hbs +15 -0
- package/adapters/nextjs/contractgen/templates/write.schema.ts.hbs +11 -0
- package/adapters/nextjs/registries/contract-field.registry.json +22 -0
- package/adapters/nextjs/unitgen/runners/README.md +12 -0
- package/adapters/nextjs/unitgen/runners/generate.mjs +201 -0
- package/adapters/nextjs/unitgen/runners/lib/parse-tags.mjs +67 -0
- package/adapters/nextjs/unitgen/runners/lib/plan.mjs +563 -0
- package/adapters/nextjs/unitgen/runners/lib/read-codegen.mjs +42 -0
- package/adapters/nextjs/unitgen/runners/lib/render.mjs +32 -0
- package/adapters/nextjs/unitgen/runners/lib/resolve-model.mjs +28 -0
- package/adapters/nextjs/unitgen/runners/lib/unit-registry.mjs +52 -0
- package/adapters/nextjs/unitgen/runners/lib/write-files.mjs +103 -0
- package/adapters/nextjs/unitgen/runners/lib/write-spec-tags.mjs +37 -0
- package/adapters/nextjs/unitgen/runners/validate-registry.mjs +74 -0
- package/adapters/nextjs/unitgen/templates/hooks/use-form.test.ts.hbs +51 -0
- package/adapters/nextjs/unitgen/templates/hooks/use-list.test.ts.hbs +63 -0
- package/adapters/nextjs/unitgen/templates/models/schema.test.ts.hbs +24 -0
- package/adapters/nextjs/unitgen/templates/services/service.create.test.ts.hbs +28 -0
- package/adapters/nextjs/unitgen/templates/services/service.export.test.ts.hbs +20 -0
- package/adapters/nextjs/unitgen/templates/services/service.search.test.ts.hbs +25 -0
- package/adapters/nextjs/unitgen/templates/services/service.wire.test.ts.hbs +37 -0
- package/adapters/nextjs/unitgen/templates/validations/schemas.test.ts.hbs +19 -0
- package/adapters/nuxt4/codegen/runners/README.md +83 -0
- package/adapters/nuxt4/codegen/runners/generate.mjs +236 -0
- package/adapters/nuxt4/codegen/runners/lib/component-resolve.mjs +66 -0
- package/adapters/nuxt4/codegen/runners/lib/design-registry.mjs +332 -0
- package/adapters/nuxt4/codegen/runners/lib/naming.mjs +246 -0
- package/adapters/nuxt4/codegen/runners/lib/page-lifecycle.mjs +254 -0
- package/adapters/nuxt4/codegen/runners/lib/plan.mjs +370 -0
- package/adapters/nuxt4/codegen/runners/lib/read-spec.mjs +7 -0
- package/adapters/nuxt4/codegen/runners/lib/render.mjs +47 -0
- package/adapters/nuxt4/codegen/runners/lib/resolve-hub-id.mjs +288 -0
- package/adapters/nuxt4/codegen/runners/lib/slots.mjs +121 -0
- package/adapters/nuxt4/codegen/runners/lib/write-files.mjs +106 -0
- package/adapters/nuxt4/codegen/runners/validate-registry.mjs +121 -0
- package/adapters/nuxt4/codegen/templates/create/form.vue.hbs +26 -0
- package/adapters/nuxt4/codegen/templates/create/mock.ts.hbs +11 -0
- package/adapters/nuxt4/codegen/templates/create/model.schema.ts.hbs +14 -0
- package/adapters/nuxt4/codegen/templates/create/model.types.ts.hbs +9 -0
- package/adapters/nuxt4/codegen/templates/create/page.vue.hbs +11 -0
- package/adapters/nuxt4/codegen/templates/create/service.ts.hbs +25 -0
- package/adapters/nuxt4/codegen/templates/create/useForm.ts.hbs +29 -0
- package/adapters/nuxt4/codegen/templates/create/validation.ts.hbs +12 -0
- package/adapters/nuxt4/codegen/templates/list/mock.ts.hbs +27 -0
- package/adapters/nuxt4/codegen/templates/list/model.index.ts.hbs +2 -0
- package/adapters/nuxt4/codegen/templates/list/model.schema.ts.hbs +16 -0
- package/adapters/nuxt4/codegen/templates/list/model.types.ts.hbs +9 -0
- package/adapters/nuxt4/codegen/templates/list/page.custom.vue.hbs +105 -0
- package/adapters/nuxt4/codegen/templates/list/page.vue.hbs +55 -0
- package/adapters/nuxt4/codegen/templates/list/service.ts.hbs +37 -0
- package/adapters/nuxt4/codegen/templates/list/useList.ts.hbs +82 -0
- package/adapters/nuxt4/codegen/templates/list/useListColumns.ts.hbs +21 -0
- package/adapters/nuxt4/codegen/templates/list/useListExport.ts.hbs +26 -0
- package/adapters/nuxt4/codegen/templates/list/useListFilters.ts.hbs +45 -0
- package/adapters/nuxt4/codegen/templates/partials/component-stub.vue.hbs +44 -0
- package/adapters/nuxt4/codegen/templates/store/store.ts.hbs +30 -0
- package/adapters/nuxt4/unitgen/runners/README.md +12 -0
- package/adapters/nuxt4/unitgen/runners/generate.mjs +201 -0
- package/adapters/nuxt4/unitgen/runners/lib/parse-tags.mjs +49 -0
- package/adapters/nuxt4/unitgen/runners/lib/plan.mjs +567 -0
- package/adapters/nuxt4/unitgen/runners/lib/read-codegen.mjs +42 -0
- package/adapters/nuxt4/unitgen/runners/lib/render.mjs +32 -0
- package/adapters/nuxt4/unitgen/runners/lib/unit-registry.mjs +52 -0
- package/adapters/nuxt4/unitgen/runners/lib/write-files.mjs +103 -0
- package/adapters/nuxt4/unitgen/runners/lib/write-spec-tags.mjs +37 -0
- package/adapters/nuxt4/unitgen/runners/validate-registry.mjs +74 -0
- package/adapters/nuxt4/unitgen/templates/composables/use-form.test.ts.hbs +56 -0
- package/adapters/nuxt4/unitgen/templates/composables/use-list.test.ts.hbs +59 -0
- package/adapters/nuxt4/unitgen/templates/models/schema.test.ts.hbs +24 -0
- package/adapters/nuxt4/unitgen/templates/services/service.create.test.ts.hbs +28 -0
- package/adapters/nuxt4/unitgen/templates/services/service.export.test.ts.hbs +20 -0
- package/adapters/nuxt4/unitgen/templates/services/service.search.test.ts.hbs +25 -0
- package/adapters/nuxt4/unitgen/templates/services/service.wire.test.ts.hbs +37 -0
- package/adapters/nuxt4/unitgen/templates/validations/schemas.test.ts.hbs +19 -0
- package/adapters/shared/common-gen.mjs +599 -0
- package/adapters/shared/common-ui.catalog.json +224 -0
- package/adapters/shared/css-adapters/shadcn.mjs +56 -0
- package/adapters/shared/css-adapters/winforms.mjs +46 -0
- package/adapters/shared/css-gen.mjs +87 -0
- package/adapters/shared/fe-layout-profiles.mjs +74 -0
- package/adapters/shared/fe-ui-inventory.mjs +62 -0
- package/adapters/shared/i18n-merge.mjs +56 -0
- package/adapters/shared/read-fe-ir.mjs +64 -0
- package/adapters/shared/resolve-cli.mjs +16 -0
- package/adapters/shared/resolve-hub-id.mjs +381 -0
- package/adapters/shared/surface-common.mjs +41 -0
- package/bin/flowgrid-mcp.mjs +29 -0
- package/bin/flowgrid.mjs +915 -0
- package/bin/lib/agent-mcp.mjs +70 -0
- package/bin/lib/agent-profiles.mjs +127 -0
- package/bin/lib/audit-run.mjs +96 -0
- package/bin/lib/cli-update.mjs +254 -0
- package/bin/lib/doctor.mjs +163 -0
- package/bin/lib/harness-overlay.mjs +80 -0
- package/bin/lib/harness-sync.mjs +427 -0
- package/bin/lib/init-scaffold.mjs +158 -0
- package/bin/lib/npm-registry.mjs +45 -0
- package/bin/lib/project-gitignore.mjs +39 -0
- package/dist/codegen/adapters/run-be.d.ts +13 -0
- package/dist/codegen/adapters/run-be.js +190 -0
- package/dist/codegen/adapters/run-be.js.map +1 -0
- package/dist/codegen/adapters/run.d.ts +44 -0
- package/dist/codegen/adapters/run.js +146 -0
- package/dist/codegen/adapters/run.js.map +1 -0
- package/dist/codegen/config/project-root.d.ts +13 -0
- package/dist/codegen/config/project-root.js +64 -0
- package/dist/codegen/config/project-root.js.map +1 -0
- package/dist/codegen/mcp/tools.d.ts +2 -0
- package/dist/codegen/mcp/tools.js +138 -0
- package/dist/codegen/mcp/tools.js.map +1 -0
- package/dist/codegen/registries/common.d.ts +28 -0
- package/dist/codegen/registries/common.js +54 -0
- package/dist/codegen/registries/common.js.map +1 -0
- package/dist/dna/config/project-root.d.ts +12 -0
- package/dist/dna/config/project-root.js +41 -0
- package/dist/dna/config/project-root.js.map +1 -0
- package/dist/dna/profile/detect.d.ts +14 -0
- package/dist/dna/profile/detect.js +159 -0
- package/dist/dna/profile/detect.js.map +1 -0
- package/dist/dna/profile/manifest.d.ts +17 -0
- package/dist/dna/profile/manifest.js +10 -0
- package/dist/dna/profile/manifest.js.map +1 -0
- package/dist/docs/cli/engines.d.ts +13 -0
- package/dist/docs/cli/engines.js +53 -0
- package/dist/docs/cli/engines.js.map +1 -0
- package/dist/docs/config/docs-root.d.ts +8 -0
- package/dist/docs/config/docs-root.js +66 -0
- package/dist/docs/config/docs-root.js.map +1 -0
- package/dist/docs/mcp/tools.d.ts +2 -0
- package/dist/docs/mcp/tools.js +351 -0
- package/dist/docs/mcp/tools.js.map +1 -0
- package/dist/docs/scan/ids.d.ts +29 -0
- package/dist/docs/scan/ids.js +237 -0
- package/dist/docs/scan/ids.js.map +1 -0
- package/dist/docs/scan/links.d.ts +10 -0
- package/dist/docs/scan/links.js +98 -0
- package/dist/docs/scan/links.js.map +1 -0
- package/dist/docs/scan/route.d.ts +8 -0
- package/dist/docs/scan/route.js +114 -0
- package/dist/docs/scan/route.js.map +1 -0
- package/dist/graph/analyze/analyze-bullets.d.ts +17 -0
- package/dist/graph/analyze/analyze-bullets.js +137 -0
- package/dist/graph/analyze/analyze-bullets.js.map +1 -0
- package/dist/graph/analyze/analyze-spec.d.ts +12 -0
- package/dist/graph/analyze/analyze-spec.js +249 -0
- package/dist/graph/analyze/analyze-spec.js.map +1 -0
- package/dist/graph/analyze/api-routes.d.ts +66 -0
- package/dist/graph/analyze/api-routes.js +370 -0
- package/dist/graph/analyze/api-routes.js.map +1 -0
- package/dist/graph/analyze/context-orphan.d.ts +12 -0
- package/dist/graph/analyze/context-orphan.js +229 -0
- package/dist/graph/analyze/context-orphan.js.map +1 -0
- package/dist/graph/analyze/grill-check.d.ts +31 -0
- package/dist/graph/analyze/grill-check.js +92 -0
- package/dist/graph/analyze/grill-check.js.map +1 -0
- package/dist/graph/analyze/parity-check.d.ts +25 -0
- package/dist/graph/analyze/parity-check.js +406 -0
- package/dist/graph/analyze/parity-check.js.map +1 -0
- package/dist/graph/analyze/product-paths.d.ts +13 -0
- package/dist/graph/analyze/product-paths.js +29 -0
- package/dist/graph/analyze/product-paths.js.map +1 -0
- package/dist/graph/analyze/surface-paths.d.ts +13 -0
- package/dist/graph/analyze/surface-paths.js +29 -0
- package/dist/graph/analyze/surface-paths.js.map +1 -0
- package/dist/graph/config/load-config.d.ts +30 -0
- package/dist/graph/config/load-config.js +112 -0
- package/dist/graph/config/load-config.js.map +1 -0
- package/dist/graph/config/platform-repos.d.ts +36 -0
- package/dist/graph/config/platform-repos.js +124 -0
- package/dist/graph/config/platform-repos.js.map +1 -0
- package/dist/graph/config/resolve-paths.d.ts +45 -0
- package/dist/graph/config/resolve-paths.js +121 -0
- package/dist/graph/config/resolve-paths.js.map +1 -0
- package/dist/graph/db/index-store.d.ts +67 -0
- package/dist/graph/db/index-store.js +179 -0
- package/dist/graph/db/index-store.js.map +1 -0
- package/dist/graph/gen/run-command.d.ts +40 -0
- package/dist/graph/gen/run-command.js +110 -0
- package/dist/graph/gen/run-command.js.map +1 -0
- package/dist/graph/lexicon/infer-lane.d.ts +11 -0
- package/dist/graph/lexicon/infer-lane.js +28 -0
- package/dist/graph/lexicon/infer-lane.js.map +1 -0
- package/dist/graph/lexicon/load-lexicon.d.ts +60 -0
- package/dist/graph/lexicon/load-lexicon.js +492 -0
- package/dist/graph/lexicon/load-lexicon.js.map +1 -0
- package/dist/graph/mcp/tools.d.ts +9 -0
- package/dist/graph/mcp/tools.js +326 -0
- package/dist/graph/mcp/tools.js.map +1 -0
- package/dist/graph/registry/load-registries.d.ts +27 -0
- package/dist/graph/registry/load-registries.js +111 -0
- package/dist/graph/registry/load-registries.js.map +1 -0
- package/dist/graph/types.d.ts +208 -0
- package/dist/graph/types.js +11 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/test/config/project-root.d.ts +5 -0
- package/dist/test/config/project-root.js +29 -0
- package/dist/test/config/project-root.js.map +1 -0
- package/dist/test/engines/run.d.ts +10 -0
- package/dist/test/engines/run.js +16 -0
- package/dist/test/engines/run.js.map +1 -0
- package/dist/test/mcp/tools.d.ts +2 -0
- package/dist/test/mcp/tools.js +43 -0
- package/dist/test/mcp/tools.js.map +1 -0
- package/dist/test/optional/fallback-evidence.d.ts +34 -0
- package/dist/test/optional/fallback-evidence.js +103 -0
- package/dist/test/optional/fallback-evidence.js.map +1 -0
- package/engines/cases/README.md +12 -0
- package/engines/cases/check-coverage.mjs +103 -0
- package/engines/cases/check-plans.mjs +31 -0
- package/engines/cases/gate.mjs +215 -0
- package/engines/cases/lib/audit-tc-traceability.mjs +139 -0
- package/engines/cases/lib/list-case-yaml.mjs +27 -0
- package/engines/cases/lib/parse-bundle-traceability.mjs +77 -0
- package/engines/cases/lib/render-github-catalog.mjs +141 -0
- package/engines/cases/lib/resolve-bundle-from-screen.mjs +73 -0
- package/engines/cases/lib/screen-facet-coverage.mjs +42 -0
- package/engines/cases/lib/validate-tc-schema.mjs +61 -0
- package/engines/cases/publish.mjs +4 -0
- package/engines/cases/render-cases.mjs +182 -0
- package/engines/cases/vitepress/config.ts +171 -0
- package/engines/cases/vitepress/theme/custom.css +418 -0
- package/engines/cases/vitepress/theme/index.ts +46 -0
- package/engines/codegen/adapters/shadcn.mjs +58 -0
- package/engines/codegen/adapters/winforms.mjs +46 -0
- package/engines/codegen/tokens.mjs +64 -0
- package/engines/docs/lib/load-dev-base-url.mjs +38 -0
- package/engines/docs/lib/markdown-table.mjs +65 -0
- package/engines/docs/lib/render-bundle-markdown.mjs +95 -0
- package/engines/docs/lib/render-design-tables.mjs +695 -0
- package/engines/docs/lib/render-github-catalog.mjs +194 -0
- package/engines/docs/lib/render-qa-list.mjs +57 -0
- package/engines/docs/lib/render-spec-markdown.mjs +19 -0
- package/engines/docs/lib/render-template.mjs +76 -0
- package/engines/docs/lib/route-page-probe.mjs +54 -0
- package/engines/docs/publish.mjs +4 -0
- package/engines/docs/render-docs.mjs +195 -0
- package/engines/docs/vitepress/config.ts +442 -0
- package/engines/docs/vitepress/surfaces-nav.mjs +171 -0
- package/engines/docs/vitepress/theme/custom.css +418 -0
- package/engines/docs/vitepress/theme/index.ts +46 -0
- package/engines/openapi/build-openapi-ui.mjs +72 -0
- package/engines/openapi/build-swagger-ui.mjs +72 -0
- package/engines/openapi/check-backend-spec.mjs +66 -0
- package/engines/openapi/gen-openapi.mjs +337 -0
- package/engines/openapi/render-backend-spec.mjs +170 -0
- package/engines/openapi/render-openapi.mjs +155 -0
- package/engines/shared/flowgrid-tests-docs.mjs +32 -0
- package/engines/spec/extract-i18n.mjs +74 -0
- package/engines/spec/legacy-dynamics-validate.mjs +67 -0
- package/engines/spec/lib/audit-api-gaps.mjs +198 -0
- package/engines/spec/lib/audit-bundle-gaps.mjs +582 -0
- package/engines/spec/lib/audit-e2e-coverage.mjs +381 -0
- package/engines/spec/lib/audit-fe-be-alignment.mjs +183 -0
- package/engines/spec/lib/audit-flow-gaps.mjs +151 -0
- package/engines/spec/lib/audit-legacy-gaps.mjs +73 -0
- package/engines/spec/lib/audit-scenario-coverage.mjs +175 -0
- package/engines/spec/lib/audit-testcase-bundle-cross.mjs +145 -0
- package/engines/spec/lib/audit-testcase-gaps.mjs +79 -0
- package/engines/spec/lib/audit-testcase-plan-gaps.mjs +131 -0
- package/engines/spec/lib/audit-testcase-tc.mjs +182 -0
- package/engines/spec/lib/audit-ux-affordance.mjs +269 -0
- package/engines/spec/lib/bundle-ir.mjs +360 -0
- package/engines/spec/lib/bundle-schema.mjs +199 -0
- package/engines/spec/lib/collect-screen-api-intents.mjs +69 -0
- package/engines/spec/lib/hydrate-design-api.mjs +58 -0
- package/engines/spec/lib/open-qa.mjs +66 -0
- package/engines/spec/lib/project-business-layout.mjs +214 -0
- package/engines/spec/lib/testcase-matrix-facets.mjs +9 -0
- package/engines/spec/merge-bundle.mjs +27 -0
- package/engines/spec/normalize-bundle-gen.mjs +69 -0
- package/engines/spec/split-all.mjs +78 -0
- package/engines/spec/split-bundle.mjs +45 -0
- package/engines/template-builder/runner.mjs +96 -0
- package/engines/template-builder/scanner.mjs +138 -0
- package/engines/testcase/_staging-from-portal/README-STAGING.md +13 -0
- package/engines/testcase/_staging-from-portal/runners/README.md +15 -0
- package/engines/testcase/_staging-from-portal/runners/generate.mjs +123 -0
- package/engines/testcase/_staging-from-portal/runners/lib/e2e-registry.mjs +77 -0
- package/engines/testcase/_staging-from-portal/runners/lib/plan.mjs +97 -0
- package/engines/testcase/_staging-from-portal/runners/lib/read-testcase.mjs +166 -0
- package/engines/testcase/_staging-from-portal/runners/lib/render.mjs +18 -0
- package/engines/testcase/_staging-from-portal/runners/lib/semantic-plan.mjs +178 -0
- package/engines/testcase/_staging-from-portal/runners/lib/write-files.mjs +42 -0
- package/engines/testcase/_staging-from-portal/runners/validate-registry.mjs +75 -0
- package/engines/testcase/_staging-from-portal/templates/page.ts.hbs +52 -0
- package/engines/testcase/_staging-from-portal/templates/partials/README.md +5 -0
- package/engines/testcase/_staging-from-portal/templates/spec.ts.hbs +214 -0
- package/engines/testcase/runners/README.md +27 -0
- package/engines/testcase/runners/generate-api.mjs +121 -0
- package/engines/testcase/runners/generate.mjs +161 -0
- package/engines/testcase/runners/lib/api-plan.mjs +64 -0
- package/engines/testcase/runners/lib/e2e-registry.mjs +77 -0
- package/engines/testcase/runners/lib/plan.mjs +123 -0
- package/engines/testcase/runners/lib/read-spec.mjs +37 -0
- package/engines/testcase/runners/lib/read-testcase.mjs +179 -0
- package/engines/testcase/runners/lib/render.mjs +18 -0
- package/engines/testcase/runners/lib/resolve-hub-id.mjs +324 -0
- package/engines/testcase/runners/lib/semantic-plan.mjs +178 -0
- package/engines/testcase/runners/lib/write-files.mjs +145 -0
- package/engines/testcase/runners/validate-registry.mjs +75 -0
- package/engines/testcase/templates/api.spec.ts.hbs +40 -0
- package/engines/testcase/templates/page.ts.hbs +69 -0
- package/engines/testcase/templates/partials/README.md +5 -0
- package/engines/testcase/templates/spec.ts.hbs +231 -0
- package/harness/agents/claude/rules/claude-flowgrid.mdc +9 -0
- package/harness/agents/cursor/rules/cursor-flowgrid.mdc +9 -0
- package/harness/agents/gemini_antigravity/rules/antigravity-mcp.mdc +10 -0
- package/harness/agents/kiro/rules/kiro-flowgrid.mdc +9 -0
- package/harness/be/adapters/dotnet-integration/skills/framework-rules-be/SKILL.md +21 -0
- package/harness/be/adapters/fastapi/skills/framework-rules-be/SKILL.md +27 -0
- package/harness/be/adapters/laravel/skills/framework-rules-be/SKILL.md +27 -0
- package/harness/be/extracts/artifactgraph-hooks-be.md +21 -0
- package/harness/be/extracts/risk-classes.md +69 -0
- package/harness/be/skills/api/SKILL.md +116 -0
- package/harness/be/skills/api-unit/SKILL.md +76 -0
- package/harness/be/skills/grill-api/SKILL.md +69 -0
- package/harness/be/skills/grill-api-unit/SKILL.md +57 -0
- package/harness/common/extracts/artifact-graph.md +23 -0
- package/harness/common/extracts/artifactgraph-hooks-core.md +17 -0
- package/harness/common/extracts/artifactgraph-phase-hooks.md +106 -0
- package/harness/common/extracts/core/agent-discipline.md +8 -0
- package/harness/common/extracts/docs-mark-detect.md +48 -0
- package/harness/common/extracts/docs-mark.md +62 -0
- package/harness/common/extracts/extract-registry.json +29 -0
- package/harness/common/extracts/ux-common-patterns.md +172 -0
- package/harness/common/rules/artifactgraph.mdc +26 -0
- package/harness/common/rules/cross-repo-index.mdc +47 -0
- package/harness/common/rules/flowgrid-ux-common.mdc +39 -0
- package/harness/common/rules/platform-code-size.mdc +24 -0
- package/harness/common/rules/team-flow-harness-state.mdc +12 -0
- package/harness/common/skills/business-impact-review/SKILL.md +106 -0
- package/harness/common/skills/configure-repo-maps/SKILL.md +58 -0
- package/harness/common/skills/docs-mark/SKILL.md +67 -0
- package/harness/common/skills/legacy/SKILL.md +29 -0
- package/harness/common/skills/ui-proposal/SKILL.md +28 -0
- package/harness/docs/extracts/agent-execution-protocol.md +31 -0
- package/harness/docs/extracts/architecture-core.md +71 -0
- package/harness/docs/extracts/artifactgraph-hooks-docs.md +15 -0
- package/harness/docs/extracts/artifactgraph-parity.md +10 -0
- package/harness/docs/extracts/business-process-trace.md +66 -0
- package/harness/docs/extracts/codegen/readiness.md +8 -0
- package/harness/docs/extracts/common-scope.md +65 -0
- package/harness/docs/extracts/docs-phase-hooks.md +22 -0
- package/harness/docs/extracts/extract-registry.docs.json +45 -0
- package/harness/docs/extracts/extract-registry.flowgrid-process.json +12 -0
- package/harness/docs/extracts/grill/validation.md +9 -0
- package/harness/docs/extracts/grill-docs-reconcile.md +5 -0
- package/harness/docs/extracts/qa-inbox.md +36 -0
- package/harness/docs/extracts/risk-classes.md +69 -0
- package/harness/docs/extracts/spec-core.md +5 -0
- package/harness/docs/extracts/spec-requirement.md +5 -0
- package/harness/docs/extracts/tpl-adr.md +23 -0
- package/harness/docs/extracts/tpl-arc42-chapter.md +29 -0
- package/harness/docs/extracts/tpl-cross-cutting.md +24 -0
- package/harness/docs/extracts/tpl-deployment.md +23 -0
- package/harness/docs/extracts/tpl-module.md +33 -0
- package/harness/docs/extracts/update-spec-delta.md +5 -0
- package/harness/docs/rules/agent-compliance.mdc +26 -0
- package/harness/docs/rules/docs-hub.mdc +54 -0
- package/harness/docs/rules/flowgrid-process.mdc +25 -0
- package/harness/docs/rules/team-flow-grill.mdc +31 -0
- package/harness/docs/rules/team-flow-harness-state.mdc +16 -0
- package/harness/docs/rules/team-flow-spec.mdc +36 -0
- package/harness/docs/schemas/flowgrid-docs/backend-api.schema.json +175 -0
- package/harness/docs/schemas/flowgrid-docs/missing-optional-event.schema.json +39 -0
- package/harness/docs/schemas/flowgrid-docs/spec.schema.json +643 -0
- package/harness/docs/schemas/flowgrid-docs/testcase.schema.json +29 -0
- package/harness/docs/schemas/flowgrid-process/missing-optional-event.schema.json +39 -0
- package/harness/docs/skills/adopt/SKILL.md +140 -0
- package/harness/docs/skills/api/SKILL.md +40 -0
- package/harness/docs/skills/api-integration/SKILL.md +110 -0
- package/harness/docs/skills/api-spec/SKILL.md +136 -0
- package/harness/docs/skills/api-update/SKILL.md +82 -0
- package/harness/docs/skills/architecture/SKILL.md +57 -0
- package/harness/docs/skills/architecture-grill/SKILL.md +29 -0
- package/harness/docs/skills/background-logic/SKILL.md +100 -0
- package/harness/docs/skills/build-templates/SKILL.md +47 -0
- package/harness/docs/skills/business-process/SKILL.md +109 -0
- package/harness/docs/skills/call-external/SKILL.md +32 -0
- package/harness/docs/skills/common/SKILL.md +46 -0
- package/harness/docs/skills/common-spec/SKILL.md +55 -0
- package/harness/docs/skills/cross-cutting/SKILL.md +33 -0
- package/harness/docs/skills/cross-entity-service/SKILL.md +32 -0
- package/harness/docs/skills/cross-service/SKILL.md +37 -0
- package/harness/docs/skills/db-erd/SKILL.md +29 -0
- package/harness/docs/skills/decision/SKILL.md +30 -0
- package/harness/docs/skills/deployment/SKILL.md +34 -0
- package/harness/docs/skills/docs-hub/SKILL.md +65 -0
- package/harness/docs/skills/grill/SKILL.md +46 -0
- package/harness/docs/skills/grill-api/SKILL.md +26 -0
- package/harness/docs/skills/grill-api-spec/SKILL.md +57 -0
- package/harness/docs/skills/grill-bqa/SKILL.md +119 -0
- package/harness/docs/skills/grill-common-spec/SKILL.md +43 -0
- package/harness/docs/skills/grill-dev/SKILL.md +172 -0
- package/harness/docs/skills/grill-docs/SKILL.md +79 -0
- package/harness/docs/skills/grill-integration-spec/SKILL.md +51 -0
- package/harness/docs/skills/module/SKILL.md +58 -0
- package/harness/docs/skills/openapi/SKILL.md +37 -0
- package/harness/docs/skills/overview/SKILL.md +42 -0
- package/harness/docs/skills/qa-resolve/SKILL.md +91 -0
- package/harness/docs/skills/spec/SKILL.md +240 -0
- package/harness/docs/skills/surfaces/SKILL.md +52 -0
- package/harness/docs/skills/update-spec/SKILL.md +83 -0
- package/harness/fe/adapters/dotnet-line/skills/framework-rules/SKILL.md +27 -0
- package/harness/fe/adapters/nextjs/skills/framework-rules/SKILL.md +29 -0
- package/harness/fe/adapters/nuxt4/skills/framework-rules/SKILL.md +33 -0
- package/harness/fe/extracts/artifactgraph-hooks-fe.md +15 -0
- package/harness/fe/extracts/risk-classes.md +69 -0
- package/harness/fe/rules/cross-repo-index-routing.mdc +24 -0
- package/harness/fe/rules/flowgrid-test-optional-accelerators.mdc +21 -0
- package/harness/fe/rules/platform-code-size.mdc +43 -0
- package/harness/fe/rules/platform-design-vocabulary.mdc +33 -0
- package/harness/fe/rules/team-flow-prototype.mdc +32 -0
- package/harness/fe/rules/team-flow-unit.mdc +27 -0
- package/harness/fe/skills/build-template-code/SKILL.md +42 -0
- package/harness/fe/skills/gen-common/SKILL.md +93 -0
- package/harness/fe/skills/grill-prototype/SKILL.md +41 -0
- package/harness/fe/skills/grill-test/SKILL.md +32 -0
- package/harness/fe/skills/grill-unit/SKILL.md +31 -0
- package/harness/fe/skills/model/SKILL.md +48 -0
- package/harness/fe/skills/prototype/SKILL.md +100 -0
- package/harness/fe/skills/test/SKILL.md +37 -0
- package/harness/fe/skills/unit/SKILL.md +55 -0
- package/harness/fe/skills/wire/SKILL.md +60 -0
- package/harness/shared/AGENTS.md +169 -0
- package/harness/shared/SSOT_AGENT_PROTOCOL.md +167 -0
- package/harness/shared/rules/flowgrid-code-optional-integrations.mdc +53 -0
- package/harness/shared/schemas/flowgrid-code/missing-optional-event.schema.json +62 -0
- package/harness/tests/extracts/artifactgraph-hooks-test.md +13 -0
- package/harness/tests/extracts/plans/readiness.md +14 -0
- package/harness/tests/rules/cross-repo-index-routing.mdc +24 -0
- package/harness/tests/rules/flowgrid-test-optional-accelerators.mdc +21 -0
- package/harness/tests/rules/plans-docs-first.mdc +13 -0
- package/harness/tests/skills/grill-testcase/SKILL.md +55 -0
- package/harness/tests/skills/scenario/SKILL.md +64 -0
- package/harness/tests/skills/test-api/SKILL.md +65 -0
- package/harness/tests/skills/testcase/SKILL.md +98 -0
- package/harness/tests/templates/SC.example.md +86 -0
- package/harness/tests/templates/TC.example-api.yaml +45 -0
- package/harness/tests/templates/TC.example.yaml +127 -0
- package/lexicon/registry-tags.en.txt +173 -0
- package/lexicon/testcase-taxonomy.en.txt +117 -0
- package/package.json +98 -0
- package/schemas/missing-optional-event.schema.json +37 -0
- package/schemas/testcase.schema.json +239 -0
- package/scripts/prepare-install.mjs +25 -0
- package/stacks/docs.json +21 -0
- package/stacks/dotnet-integration.json +66 -0
- package/stacks/dotnet-line.json +64 -0
- package/stacks/fastapi.json +98 -0
- package/stacks/generic.json +11 -0
- package/stacks/laravel.json +92 -0
- package/stacks/nextjs-nest.json +93 -0
- package/stacks/nextjs.json +132 -0
- package/stacks/nuxt4-nest.json +123 -0
- package/stacks/nuxt4.json +148 -0
- package/templates/project-skeleton/architecture/01-introduction/index.md +33 -0
- package/templates/project-skeleton/architecture/02-constraints/index.md +34 -0
- package/templates/project-skeleton/architecture/03-business-process/FLOW-login.md +101 -0
- package/templates/project-skeleton/architecture/03-business-process/FLOW-template.md +149 -0
- package/templates/project-skeleton/architecture/04-solution-strategy/index.md +26 -0
- package/templates/project-skeleton/architecture/07-deployment/index.md +26 -0
- package/templates/project-skeleton/architecture/08-cross-cutting/configuration.md +18 -0
- package/templates/project-skeleton/architecture/08-cross-cutting/index.md +27 -0
- package/templates/project-skeleton/architecture/08-cross-cutting/observability.md +18 -0
- package/templates/project-skeleton/architecture/08-cross-cutting/security.md +18 -0
- package/templates/project-skeleton/architecture/09-decisions/ADR-001-arc42-toc.md +31 -0
- package/templates/project-skeleton/architecture/09-decisions/index.md +13 -0
- package/templates/project-skeleton/architecture/10-quality/index.md +27 -0
- package/templates/project-skeleton/architecture/11-risks/index.md +25 -0
- package/templates/project-skeleton/architecture/12-glossary/index.md +31 -0
- package/templates/project-skeleton/architecture/index.md +1 -0
- package/templates/project-skeleton/architecture/model/workspace.dsl +71 -0
- package/templates/project-skeleton/index.md +2 -0
- package/templates/project-skeleton/overview/.gitkeep +1 -0
- package/templates/project-skeleton/overview/index.md +2 -0
- package/templates/project-skeleton/qa/README.md +11 -0
- package/templates/project-skeleton/qa/open/.gitkeep +0 -0
- package/templates/project-skeleton/surfaces/common/code/API-CMN-HEALTH-001/health.api.yaml +12 -0
- package/templates/project-skeleton/surfaces/common/code/API-CMN-HEALTH-001/index.md +12 -0
- package/templates/project-skeleton/surfaces/common/code/UI-CMN-EMPTY-001/empty.ui.yaml +14 -0
- package/templates/project-skeleton/surfaces/common/code/UI-CMN-EMPTY-001/index.md +11 -0
- package/templates/project-skeleton/surfaces/common/data-model/derived-data.md +26 -0
- package/templates/project-skeleton/surfaces/common/data-model/index.md +16 -0
- package/templates/project-skeleton/surfaces/common/index.md +32 -0
- package/templates/project-skeleton/surfaces/common/md/breadcrumb-flow/common-breadcrumb-flow.md +72 -0
- package/templates/project-skeleton/surfaces/common/md/buttons/common-buttons.md +160 -0
- package/templates/project-skeleton/surfaces/common/md/confirm-dialog/common-confirm-dialog.md +98 -0
- package/templates/project-skeleton/surfaces/common/md/data-table/common-data-table.md +91 -0
- package/templates/project-skeleton/surfaces/common/md/delete-flow/common-delete-flow.md +68 -0
- package/templates/project-skeleton/surfaces/common/md/feedback/common-feedback.md +140 -0
- package/templates/project-skeleton/surfaces/common/md/flat-design/common-flat-design.md +78 -0
- package/templates/project-skeleton/surfaces/common/md/form-validation/common-form-validation.md +74 -0
- package/templates/project-skeleton/surfaces/common/md/import-csv/common-import-csv.md +89 -0
- package/templates/project-skeleton/surfaces/common/md/list-page/common-list-page.md +102 -0
- package/templates/project-skeleton/surfaces/common/md/list-toolbar/common-list-toolbar.md +81 -0
- package/templates/project-skeleton/surfaces/common/md/navigation/common-navigation.md +70 -0
- package/templates/project-skeleton/surfaces/common/md/pagination/common-pagination.md +86 -0
- package/templates/project-skeleton/surfaces/common/md/search-filter/common-search-filter.md +96 -0
- package/templates/project-skeleton/surfaces/common/md/status-chip/common-status-chip.md +93 -0
- package/templates/project-skeleton/surfaces/common/md/table-action-column/common-table-action-column.md +90 -0
- package/templates/project-skeleton/surfaces/common/patterns/breadcrumb-flow.md +83 -0
- package/templates/project-skeleton/surfaces/common/patterns/delete-flow.md +30 -0
- package/templates/project-skeleton/surfaces/common/patterns/ui-spec.md +15 -0
- package/templates/project-skeleton/surfaces/common/yaml/breadcrumb-flow/common-breadcrumb-flow.bundle.yaml +60 -0
- package/templates/project-skeleton/surfaces/common/yaml/breadcrumb-flow/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/breadcrumb-flow/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/breadcrumb-flow/ir/spec.yaml +31 -0
- package/templates/project-skeleton/surfaces/common/yaml/buttons/common-buttons.bundle.yaml +147 -0
- package/templates/project-skeleton/surfaces/common/yaml/buttons/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/buttons/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/buttons/ir/spec.yaml +118 -0
- package/templates/project-skeleton/surfaces/common/yaml/confirm-dialog/common-confirm-dialog.bundle.yaml +89 -0
- package/templates/project-skeleton/surfaces/common/yaml/confirm-dialog/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/confirm-dialog/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/confirm-dialog/ir/spec.yaml +60 -0
- package/templates/project-skeleton/surfaces/common/yaml/data-table/common-data-table.bundle.yaml +85 -0
- package/templates/project-skeleton/surfaces/common/yaml/data-table/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/data-table/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/data-table/ir/spec.yaml +56 -0
- package/templates/project-skeleton/surfaces/common/yaml/delete-flow/common-delete-flow.bundle.yaml +59 -0
- package/templates/project-skeleton/surfaces/common/yaml/delete-flow/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/delete-flow/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/delete-flow/ir/spec.yaml +30 -0
- package/templates/project-skeleton/surfaces/common/yaml/design-system.bundle.yaml +29 -0
- package/templates/project-skeleton/surfaces/common/yaml/feedback/common-feedback.bundle.yaml +126 -0
- package/templates/project-skeleton/surfaces/common/yaml/feedback/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/feedback/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/feedback/ir/spec.yaml +97 -0
- package/templates/project-skeleton/surfaces/common/yaml/flat-design/common-flat-design.bundle.yaml +77 -0
- package/templates/project-skeleton/surfaces/common/yaml/flat-design/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/flat-design/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/flat-design/ir/spec.yaml +48 -0
- package/templates/project-skeleton/surfaces/common/yaml/form-validation/common-form-validation.bundle.yaml +66 -0
- package/templates/project-skeleton/surfaces/common/yaml/form-validation/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/form-validation/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/form-validation/ir/spec.yaml +37 -0
- package/templates/project-skeleton/surfaces/common/yaml/import-csv/common-import-csv.bundle.yaml +74 -0
- package/templates/project-skeleton/surfaces/common/yaml/import-csv/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/import-csv/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/import-csv/ir/spec.yaml +45 -0
- package/templates/project-skeleton/surfaces/common/yaml/list-page/common-list-page.bundle.yaml +90 -0
- package/templates/project-skeleton/surfaces/common/yaml/list-page/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/list-page/ir/legacy.yaml +14 -0
- package/templates/project-skeleton/surfaces/common/yaml/list-page/ir/spec.yaml +58 -0
- package/templates/project-skeleton/surfaces/common/yaml/list-toolbar/common-list-toolbar.bundle.yaml +86 -0
- package/templates/project-skeleton/surfaces/common/yaml/list-toolbar/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/list-toolbar/ir/legacy.yaml +12 -0
- package/templates/project-skeleton/surfaces/common/yaml/list-toolbar/ir/spec.yaml +56 -0
- package/templates/project-skeleton/surfaces/common/yaml/navigation/common-navigation.bundle.yaml +68 -0
- package/templates/project-skeleton/surfaces/common/yaml/navigation/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/navigation/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/navigation/ir/spec.yaml +39 -0
- package/templates/project-skeleton/surfaces/common/yaml/pagination/common-pagination.bundle.yaml +84 -0
- package/templates/project-skeleton/surfaces/common/yaml/pagination/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/pagination/ir/legacy.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/pagination/ir/spec.yaml +53 -0
- package/templates/project-skeleton/surfaces/common/yaml/search-filter/common-search-filter.bundle.yaml +88 -0
- package/templates/project-skeleton/surfaces/common/yaml/search-filter/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/search-filter/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/search-filter/ir/spec.yaml +59 -0
- package/templates/project-skeleton/surfaces/common/yaml/status-chip/common-status-chip.bundle.yaml +89 -0
- package/templates/project-skeleton/surfaces/common/yaml/status-chip/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/status-chip/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/status-chip/ir/spec.yaml +60 -0
- package/templates/project-skeleton/surfaces/common/yaml/table-action-column/common-table-action-column.bundle.yaml +81 -0
- package/templates/project-skeleton/surfaces/common/yaml/table-action-column/ir/design.yaml +13 -0
- package/templates/project-skeleton/surfaces/common/yaml/table-action-column/ir/legacy.yaml +11 -0
- package/templates/project-skeleton/surfaces/common/yaml/table-action-column/ir/spec.yaml +52 -0
- package/templates/project-skeleton/surfaces/index.md +1 -0
- package/templates/schemas/backend-api.schema.json +174 -0
- package/templates/schemas/legacy-repos.schema.json +24 -0
- package/templates/schemas/platform-repos.schema.json +29 -0
- package/templates/schemas/spec.schema.json +718 -0
- package/templates/schemas/testcase.schema.json +28 -0
- package/templates/shared/AUTHORING-COMMON.md +109 -0
- package/templates/shared/api-contract-test.yaml +33 -0
- package/templates/shared/backend-api-integration.yaml +152 -0
- package/templates/shared/backend-api.bundle.yaml +177 -0
- package/templates/shared/backend-api.yaml +188 -0
- package/templates/shared/breadcrumb-flow.ejs +45 -0
- package/templates/shared/bundle-authoring.md +288 -0
- package/templates/shared/clients-line.yaml +18 -0
- package/templates/shared/default-layout.ejs +234 -0
- package/templates/shared/design-spec.yaml +85 -0
- package/templates/shared/entity-delta.example.yaml +45 -0
- package/templates/shared/feature.bundle.yaml +575 -0
- package/templates/shared/integration-adapter.bundle.yaml +77 -0
- package/templates/shared/integration-spec.yaml +37 -0
- package/templates/shared/ir-design.yaml +34 -0
- package/templates/shared/ir-legacy.yaml +12 -0
- package/templates/shared/ir-spec.yaml +18 -0
- package/templates/shared/line-client.bundle.yaml +65 -0
- package/templates/shared/mock-data.yaml +22 -0
- package/templates/shared/openapi.yaml +144 -0
- package/templates/shared/patterns/.gitkeep +0 -0
- package/templates/shared/patterns/admin-crud.pattern.yaml +37 -0
- package/templates/shared/qa-item.yaml +15 -0
- package/templates/shared/spec.yaml +162 -0
- package/templates/shared/testcase.yaml +2 -0
- package/templates/tests-skeleton/cases/README.md +5 -0
- package/templates/tests-skeleton/catalog/locale.yaml +7 -0
- package/templates/tests-skeleton/index.md +7 -0
- package/templates/tests-skeleton/scenarios/README.md +3 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# [Flow] <%= spec.title || spec.id %>
|
|
2
|
+
|
|
3
|
+
<% if (context.testcases && context.testcases.length) { %>
|
|
4
|
+
- **Testcase plans:** <%= context.testcases.map(tc => '`' + (tc.data.title || tc.data.id || tc.file) + '`').join(' · ') %> (hub: [base_test](https://github.com/raintr91/base_test))
|
|
5
|
+
<% } else { %>
|
|
6
|
+
- **Testcase plans:** [base_test](https://github.com/raintr91/base_test) (`pnpm cases:render` on tests hub) — see docs-hub TESTS-HUB
|
|
7
|
+
<% } %>
|
|
8
|
+
|
|
9
|
+
<%
|
|
10
|
+
const route = spec.ui?.routes?.[0];
|
|
11
|
+
const path = route?.path || '';
|
|
12
|
+
const testId = route?.pageTestId || '';
|
|
13
|
+
let screenLine = '- **Screen:** None';
|
|
14
|
+
if (path) {
|
|
15
|
+
const screen = context.renderScreenLink ? context.renderScreenLink(path) : '`' + path + '`';
|
|
16
|
+
const suffix = testId ? ` · \`${testId}\`` : '';
|
|
17
|
+
screenLine = `- **Screen:** ${screen}${suffix}`;
|
|
18
|
+
}
|
|
19
|
+
%>
|
|
20
|
+
<%= screenLine %>
|
|
21
|
+
|
|
22
|
+
> [!NOTE]
|
|
23
|
+
> This document was rendered using the specialized **breadcrumb-flow** template.
|
|
24
|
+
|
|
25
|
+
<% if (spec.summary) { %>
|
|
26
|
+
<%= spec.summary %>
|
|
27
|
+
<% } %>
|
|
28
|
+
|
|
29
|
+
<%
|
|
30
|
+
// Render other spec sections
|
|
31
|
+
const skipKeys = new Set(['id', 'title', 'summary', 'acceptance', 'ui', 'design', 'legacy', 'review', 'template']);
|
|
32
|
+
Object.entries(spec).forEach(([key, value]) => {
|
|
33
|
+
if (skipKeys.has(key) || value == null) return;
|
|
34
|
+
%>
|
|
35
|
+
## <%= key %>
|
|
36
|
+
|
|
37
|
+
<% if (typeof value === 'string') { %>
|
|
38
|
+
<%= value %>
|
|
39
|
+
<% } else { %>
|
|
40
|
+
```yaml
|
|
41
|
+
<%= context.stringify(value).trim() %>
|
|
42
|
+
```
|
|
43
|
+
<% } %>
|
|
44
|
+
|
|
45
|
+
<% }); %>
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# portal-feature-bundle/v1 — authoring rules (PHASE 1)
|
|
2
|
+
|
|
3
|
+
Hub: `docs/templates/feature.bundle.yaml` · split: `pnpm spec:split`
|
|
4
|
+
|
|
5
|
+
## Top-level
|
|
6
|
+
|
|
7
|
+
| Key | Purpose |
|
|
8
|
+
|-----|---------|
|
|
9
|
+
| `page-id` | Screen identity (`cmp-adm-000-01`). Split copies this onto `ir/spec.yaml` as `page-id` (not `id`, so it does not collide with requirement/section ids). Legacy bundles may still use `id`. |
|
|
10
|
+
| `summary` | Phải trình bày dạng bullet. Bắt buộc có các tiêu đề (chuẩn Arc42 business): **mục tiêu nghiệp vụ** (business_goals), **các bên liên quan** (stakeholders), **kịch bản người dùng** (user_journey), **bối cảnh** (description, input liên kết cross-page/module, output) và **cách giải quyết** (tùy chọn). Mục đích để 100% Non-tech Stakeholder hiểu và duyệt. |
|
|
11
|
+
| `userStories` | **Khối User Stories chuyên sâu cho màn hình:** `primary`, `contextAndHandoff` (+ `screenAccess`), `scenarios` (5 kịch bản chuẩn + **scenario thứ 6 “Affordances UX”** khi màn có delete/filter/breadcrumb/disabled/import — xem `feature.bundle.yaml`), `acceptanceCriteria` (kèm checkbox UX khi áp dụng). **Split:** `pnpm spec:split` copy nguyên khối sang `ir/spec.yaml` (business prose); **không** tự sinh từ `design` — Agent phải cập nhật `userStories` khi bổ sung DSL/`#needs-component`/audit `UX_*`. Render → `## User Stories & Screen Journey` trong Markdown. |
|
|
12
|
+
| `spec` | Design v1 — actors, requirements, `ui.routes`, **`ui.list` / `ui.form` / `ui.detail`**, `acceptance`. **Không** author `spec.api` — API SSOT là `api/<seq>/01-backend-spec.yaml`. |
|
|
13
|
+
| `gen` | **Bắt buộc trước flowgrid gen:** `codegen.profile` (`auth` login/forgot/reset; `change-password`; `public`; `not-found`/`error`; `list`/`create`/`admin-crud`) + entity/module, `tags`, derived `ui.*`. `/grill-dev` ghi. Endpoint `action` ghi trên **01**, không trên bundle. |
|
|
14
|
+
| `legacy` | Legacy facts + evidence pointers |
|
|
15
|
+
| `design` | Nested **`sections[]`** (card/container/form + `meaning` + `purpose` + `visual` + `interaction` + `validation` + `messages` + `states` + `bind`/`db`) · **`nav`** (`screenAccess` & `sidebar.hierarchy`) · `zones[]` fallback · `behavior` · **`actions[]`** (onSuccess, onSpecificError, backgroundTrigger) |
|
|
16
|
+
| `review` | BA prose only — **không** split sang `ir/*` |
|
|
17
|
+
|
|
18
|
+
## /spec authoring (complete when information exists)
|
|
19
|
+
|
|
20
|
+
- Fill `userStories` chi tiết theo mẫu trong `feature.bundle.yaml`. Tuyệt đối không để trống hoặc chỉ ghi 1 câu qua loa.
|
|
21
|
+
- **Quy tắc Khai báo Cách thức Truy cập Màn hình (screenAccess BẮT BUỘC):** Phải chọn đúng 1 trong 3 loại:
|
|
22
|
+
- `directRoute`: Dành cho trang truy cập trực tiếp bằng URL (Login, Register, Guest Page, Public Landing, 404). Khai báo `routePath`, `isPublic`.
|
|
23
|
+
- `sidebarMenu`: Dành cho Dashboard, Danh sách Admin CRUD. Khai báo `menuHierarchy` (mảng danh mục dropdown đa cấp `["Group", "Subgroup"]`), `menuLabel` (text nhãn menu), `icon`.
|
|
24
|
+
- `contextualAction`: Dành cho Trang chi tiết, Edit Modal, Settings. Khai báo `sourceScreen`, `triggerControl` (mô tả nút bấm kích hoạt từ màn hình A), `navigationType` (`pageRedirect`, `modalDialog`, `drawer`, `tabSwitch`).
|
|
25
|
+
- **Quy tắc Meaning vs Purpose BẮT BUỘC:** Trên từng element (section, item, column, filter, action), BẮT BUỘC khai báo cả 2 trường:
|
|
26
|
+
- `meaning`: **Ý nghĩa nghiệp vụ** — Bản chất kinh doanh của trường dữ liệu/nút bấm trong thế giới thực, ảnh hưởng đến luồng tính toán hay quyết định nào.
|
|
27
|
+
- `purpose`: **Mục đích thao tác** — Người dùng thao tác gì với control này trên UI (nhập, tìm kiếm, bấm, xem).
|
|
28
|
+
- **Thẩm định dữ liệu (Validation & Messages):** Mọi trường có `validation` (required, min/max, pattern, accept) PHẢI đi kèm trường `messages` chứa câu thông báo lỗi tiếng Việt tương ứng.
|
|
29
|
+
- **Hành động & Tương tác (Actions):** Nút bấm nộp/lưu phải có đầy đủ: `validateFormBeforeSubmit`, `feedback` (loadingText, disableWhileSubmitting), `apiRefs`, `onSuccess` (toast, navigation handoff, backgroundTrigger), `onSpecificError` (map lỗi 422, 409 conflict, 403), `onCommonError`.
|
|
30
|
+
- Fill `design.sections[]` as a **dynamic nested tree** for that page (any depth). Same node shape everywhere: `kind` + `meaning` + `purpose` + `visual` + `tags`/`extract` + `items[]` + nested `sections[]`. Do not assume login or any one layout.
|
|
31
|
+
- When the page has app chrome: `design.nav.sidebar.levels` (đa cấp) + `design.nav.breadcrumb`. Full-bleed pages: `sidebar.enabled: false`.
|
|
32
|
+
- Flat `design.zones[]` is only a fallback if there is no nested card tree.
|
|
33
|
+
- Fill the matching profile: list → `spec.ui.list`; form → `spec.ui.form` (do not merge form into the page shell); detail → `spec.ui.detail`.
|
|
34
|
+
- Do **not** dump the screen into `requirements` prose instead of inventory.
|
|
35
|
+
- **UI Metrics Policy:** DO NOT declare basic CSS properties (e.g., `font-size`, `padding`, exact colors) in feature specs. These are governed by the global Design System (e.g., Shadcn/Tailwind). Only declare them if the feature requires a specific, exceptional override.
|
|
36
|
+
- Missing hard facts → `#missing_info` on that field. Do not wait for grill to invent inventory.
|
|
37
|
+
- `/grill-bqa`, `/grill-dev`, `/grill-docs` only re-check, fill gaps, or fix conflicts.
|
|
38
|
+
|
|
39
|
+
## spec (design v1) — có
|
|
40
|
+
|
|
41
|
+
- `actors`, `entities`, `relationships`
|
|
42
|
+
- `requirements` (BẮT BUỘC chứa Edge Cases. CHÚ Ý: Field Validations, State Machine, UI Permissions phải được map vào từng item trong `design.sections`, KHÔNG liệt kê chung chung ở đây)
|
|
43
|
+
- `ui.routes`, `ui.list`, `ui.form`, `ui.detail`, `ui.toolbar` (intent)
|
|
44
|
+
- `acceptance`
|
|
45
|
+
|
|
46
|
+
API: **chỉ** `…/api/<seq>/01-backend-spec.yaml` (`/api-spec`). Split **chiếu** `api.endpoints` (id/method/path/action) sang `ir/design.yaml` cho FE/bộ test — không author trên bundle.
|
|
47
|
+
|
|
48
|
+
## spec — không (thuộc `gen`)
|
|
49
|
+
|
|
50
|
+
- `codegen`, `tags`
|
|
51
|
+
- root `ui.filters`, `ui.columns`, `ui.composition`, `ui.testIds` (derive after inventory exists)
|
|
52
|
+
- Prose layout blob — dùng `design.sections[]` (nested) + `design.nav` + `review.layoutNotes`
|
|
53
|
+
|
|
54
|
+
## Split output
|
|
55
|
+
|
|
56
|
+
Split exists so agents **Read the entire `ir/design.yaml`** (tech) or **entire `ir/spec.yaml`** (prose). Do **not** instruct “only Read `design.sections` / `spec.ui` from the bundle” — that misses fields and is why IR is split.
|
|
57
|
+
|
|
58
|
+
Authoring (`/spec`, grill-*) still **writes** `*.bundle.yaml`, then split.
|
|
59
|
+
|
|
60
|
+
### UX affordance ↔ `userStories` (before `pnpm spec:split`)
|
|
61
|
+
|
|
62
|
+
| Design / audit signal | Business layer (`userStories` → `ir/spec.yaml`) |
|
|
63
|
+
|----------------------|--------------------------------------------------|
|
|
64
|
+
| `design.nav.breadcrumb`, `CONFIRM_UX_BREADCRUMB_*` | Scenario **Initial Load** + scenario **Affordances UX**; AC deep link |
|
|
65
|
+
| `spec.ui.list.filters`, `CONFIRM_UX_FILTER_*` | Scenario **Initial Load** / **Affordances UX**; AC empty “no results” |
|
|
66
|
+
| `#pattern: delete-flow`, `UX_GAP_DELETE_*` | Scenario **Affordances UX** + **Exceptions**; AC delete confirm + result dialog |
|
|
67
|
+
| `disabledReason`, `UX_GAP_DISABLED_REASON` | Scenario **Affordances UX**; AC disabled explanation |
|
|
68
|
+
| Status column + chip, `CONFIRM_UX_STATUS_CHIP` | Scenario **Initial Load**; AC status readable |
|
|
69
|
+
| `#needs-component` / `#needs-ui` | `primary.iWant` or scenario step naming the custom block in Vietnamese |
|
|
70
|
+
| `flowgrid audit spec` `suggestedStoryPatch` on UX items | Apply verbatim to matching scenario step or AC |
|
|
71
|
+
|
|
72
|
+
**Không** chỉ ghi tech vào `design.actions` — stakeholder đọc `ir/spec.yaml` / rendered MD phải thấy cùng hành vi.
|
|
73
|
+
|
|
74
|
+
| Artifact | Đọc bởi | Nội dung |
|
|
75
|
+
|----------|---------|----------|
|
|
76
|
+
| `*.bundle.yaml` | **Ghi** `/spec`, grill-*; **đọc cả file** `/testcase`, `/grill-testcase` | Đầy đủ spec+gen+design+`userStories`; tests hub read-only |
|
|
77
|
+
| `ir/design.yaml` | **Đọc cả file** — grill-*, FE `/prototype`, codegen | Tech sau split; `api` chiếu từ 01. |
|
|
78
|
+
| `ir/spec.yaml` | VitePress + stakeholder | Business page + requirements/acceptance. Không id/tag/bind. `"Q&A"`. Không stub `legacy` rỗng. |
|
|
79
|
+
| `…/api/<seq>/01-backend-spec.yaml` | BE `/api`, `openapi:gen`, **author API** | Tech BE — SSOT duy nhất cho endpoint |
|
|
80
|
+
| `<slug>.md` | Người (BA/QA) | Render từ **`ir/spec.yaml`** (chưa split thì không có trang) |
|
|
81
|
+
|
|
82
|
+
Không còn `ir/legacy.yaml`. `legacy:` trên `ir/spec.yaml` chỉ khi có evidence thật.
|
|
83
|
+
|
|
84
|
+
Thiếu fact → `#missing_info` trên field đó. Grill không bịa CSS/API.
|
|
85
|
+
|
|
86
|
+
## design.nav + nested sections (dynamic)
|
|
87
|
+
|
|
88
|
+
Cùng một schema cho mọi page. Agent điền cây theo màn thực tế — không dùng một màn (login, list, …) làm mặc định.
|
|
89
|
+
|
|
90
|
+
```yaml
|
|
91
|
+
nav:
|
|
92
|
+
sidebar:
|
|
93
|
+
enabled: true # false nếu không có menu trái
|
|
94
|
+
position: left
|
|
95
|
+
levels: [] # { id, label, href, active, children[] } lồng đa cấp
|
|
96
|
+
breadcrumb: [] # { label, href }
|
|
97
|
+
|
|
98
|
+
**LƯU Ý ĐẶC BIỆT VỀ ĐA NGÔN NGỮ (i18n):**
|
|
99
|
+
1. **Text hiển thị UI (cần i18n)**: Các thuộc tính như `label`, `value`, `copy.placeholder`, text của component lib... BẮT BUỘC dùng cho i18n (sẽ được map với file ngôn ngữ). Áp dụng cho các component lá như `input`, `text`, `button`, v.v.
|
|
100
|
+
2. **Text ngữ cảnh (không i18n)**: Các thuộc tính giải thích/cấu trúc như `name`, `description`, `purpose` chỉ dùng cho BA/Dev, KHÔNG dùng để render UI, KHÔNG mang đi dịch. Tùy thuộc vào `kind` mà khai báo cho đúng bản chất, **tuyệt đối không dùng `label` để mô tả một node ẩn (như container)**.
|
|
101
|
+
- **BA**: `name`, `description`, `purpose`, `copy`, `position`, `color`, `visual` (width/height/max-*/scroll), `interaction`, `validation` (mặt UI), `db` (thông tin lưu trữ schema, field, enumMapping)
|
|
102
|
+
- **Tech**: `kind`/`widget`, `tags`, `extract`, `bind` (field/hidden/apiRef), `apiRefs`, `hidden`, `testId`, `states`
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
sections:
|
|
106
|
+
# LOẠI 1: KHỐI STATS BANNER / HEADER KPI CARD (#ui: Card, #ui: Badge)
|
|
107
|
+
- id: sec_kpi_banner
|
|
108
|
+
name: "Khối Thống Kê Tổng Quan"
|
|
109
|
+
kind: card
|
|
110
|
+
primitive: "#ui: Card" # Gắn tag primitive Shadcn UI
|
|
111
|
+
meaning: "Cung cấp chỉ số hiệu suất tổng quan của tài khoản giúp nhân viên đưa ra quyết định xử lý nhanh"
|
|
112
|
+
purpose: "Hiển thị các thẻ KPI thống kê tổng số bản ghi và trạng thái"
|
|
113
|
+
visual:
|
|
114
|
+
colorToken: "#common:card-surface"
|
|
115
|
+
className: "grid grid-cols-1 md:grid-cols-3 gap-4 p-6 bg-card border rounded-xl shadow-xs"
|
|
116
|
+
typography: "text-card-foreground"
|
|
117
|
+
dynamicProps:
|
|
118
|
+
layoutMode: "responsive-grid"
|
|
119
|
+
columns: 3
|
|
120
|
+
items:
|
|
121
|
+
- id: kpi_total_records
|
|
122
|
+
kind: badge
|
|
123
|
+
primitive: "#ui: Badge"
|
|
124
|
+
label: "Tổng hồ sơ"
|
|
125
|
+
meaning: "Số lượng bản ghi đang quản lý trong hệ thống"
|
|
126
|
+
purpose: "Theo dõi số lượng hồ sơ hiện có"
|
|
127
|
+
colorToken: "#common:primary"
|
|
128
|
+
visual:
|
|
129
|
+
className: "text-2xl font-bold tracking-tight text-primary"
|
|
130
|
+
|
|
131
|
+
# LOẠI 2: KHỐI FORM NHẬP LIỆU ĐỘNG (#ui: Form, #ui: Select, #ui: Input)
|
|
132
|
+
- id: sec_main_info
|
|
133
|
+
name: "Khối Thông Tin Nhập Liệu Hồ Sơ"
|
|
134
|
+
kind: form_grid
|
|
135
|
+
primitive: "#ui: Form"
|
|
136
|
+
meaning: "Gom nhóm các thuộc tính nhận diện cốt lõi của bản ghi phục vụ tra cứu và kiểm toán"
|
|
137
|
+
purpose: "Khu vực nhập liệu thông tin chính của hồ sơ"
|
|
138
|
+
visual:
|
|
139
|
+
className: "space-y-6 border p-6 rounded-xl bg-background shadow-xs"
|
|
140
|
+
layoutMode: "two-column"
|
|
141
|
+
dynamicProps:
|
|
142
|
+
responsiveGrid: "grid grid-cols-1 lg:grid-cols-2 gap-6"
|
|
143
|
+
sections:
|
|
144
|
+
# Component nhập liệu có validation & messages & styling
|
|
145
|
+
- id: fld_record_name
|
|
146
|
+
name: "Record Name Field"
|
|
147
|
+
kind: input
|
|
148
|
+
primitive: "#ui: Input"
|
|
149
|
+
label: "Tên hồ sơ"
|
|
150
|
+
meaning: "Tên định danh giao dịch của khách hàng dùng làm tiêu đề hiển thị trên mọi báo cáo"
|
|
151
|
+
purpose: "Nhập tên hồ sơ hiển thị"
|
|
152
|
+
visual:
|
|
153
|
+
className: "w-full focus:ring-2 focus:ring-ring"
|
|
154
|
+
copy:
|
|
155
|
+
placeholder: "Nhập tên đầy đủ..."
|
|
156
|
+
helper: "Tối thiểu 3 ký tự, không chứa ký tự đặc biệt"
|
|
157
|
+
bind:
|
|
158
|
+
field: record_name
|
|
159
|
+
db:
|
|
160
|
+
schema: records
|
|
161
|
+
field: name
|
|
162
|
+
validation:
|
|
163
|
+
required: true
|
|
164
|
+
minLength: 3
|
|
165
|
+
maxLength: 100
|
|
166
|
+
messages:
|
|
167
|
+
required: "Vui lòng nhập tên hồ sơ."
|
|
168
|
+
minLength: "Tên hồ sơ phải có ít nhất 3 ký tự."
|
|
169
|
+
|
|
170
|
+
# Component chọn có điều kiện động (Dropdown + States)
|
|
171
|
+
- id: fld_service_level
|
|
172
|
+
name: "Service Level Select"
|
|
173
|
+
kind: select
|
|
174
|
+
primitive: "#ui: Select"
|
|
175
|
+
label: "Cấp độ dịch vụ"
|
|
176
|
+
meaning: "Xác định gói dịch vụ để áp dụng chính sách giá và kích hoạt tự động Zalo VIP"
|
|
177
|
+
purpose: "Chọn gói dịch vụ áp dụng"
|
|
178
|
+
visual:
|
|
179
|
+
className: "w-full border-input"
|
|
180
|
+
bind:
|
|
181
|
+
field: service_level
|
|
182
|
+
db:
|
|
183
|
+
schema: records
|
|
184
|
+
field: service_level
|
|
185
|
+
enumMapping:
|
|
186
|
+
"STANDARD": "Tiêu chuẩn"
|
|
187
|
+
"PREMIUM": "Cao cấp VIP"
|
|
188
|
+
validation:
|
|
189
|
+
required: true
|
|
190
|
+
messages:
|
|
191
|
+
required: "Vui lòng chọn cấp độ dịch vụ."
|
|
192
|
+
|
|
193
|
+
# Component hiển thị động theo trạng thái
|
|
194
|
+
- id: fld_vip_request
|
|
195
|
+
name: "VIP Special Request"
|
|
196
|
+
kind: textarea
|
|
197
|
+
primitive: "#ui: Textarea"
|
|
198
|
+
label: "Yêu cầu đặc biệt cho gói VIP"
|
|
199
|
+
meaning: "Chi tiết yêu cầu cá nhân hóa bổ sung"
|
|
200
|
+
purpose: "Nhập ghi chú yêu cầu riêng cho gói dịch vụ VIP"
|
|
201
|
+
visual:
|
|
202
|
+
className: "col-span-full border-muted bg-muted/20"
|
|
203
|
+
states:
|
|
204
|
+
visibleWhen: "service_level == 'PREMIUM'"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Minh họa lồng (không phải template cố định): container → card → form, hoặc sidebar → toolbar → table.
|
|
208
|
+
|
|
209
|
+
## design.zones (flat fallback)
|
|
210
|
+
|
|
211
|
+
```yaml
|
|
212
|
+
zones:
|
|
213
|
+
- id: search
|
|
214
|
+
label: Khu vực tìm kiếm
|
|
215
|
+
kind: container
|
|
216
|
+
items:
|
|
217
|
+
- id: keyword
|
|
218
|
+
kind: search
|
|
219
|
+
widget: search
|
|
220
|
+
label: Ô tìm kiếm
|
|
221
|
+
purpose: "User tìm bản ghi theo tên hoặc mã"
|
|
222
|
+
copy:
|
|
223
|
+
placeholder: Search by name or code
|
|
224
|
+
bind: { field: keyword }
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## design.behavior (CRUD table trong md render)
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
behavior:
|
|
231
|
+
create: { enabled: true, surface: page }
|
|
232
|
+
delete: { enabled: true, mode: confirm_dialog }
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## design.actions (API calls + UI error handling)
|
|
236
|
+
|
|
237
|
+
Không còn `bundle.spec.api`. Màn gọi API nào = `design.actions` (và button/item trong `sections`/`zones`) trên **`ir/design.yaml`** sau split.
|
|
238
|
+
|
|
239
|
+
- Unique API của màn: `apiRefs` (sau `/api-spec` ghi trio `api/<seq>/`).
|
|
240
|
+
- API đã có (màn khác / common): `tags: ["#reuse-api"]` + `reuseFrom: …/01-backend-spec.yaml`. **Không** tạo trio mới.
|
|
241
|
+
|
|
242
|
+
```yaml
|
|
243
|
+
actions:
|
|
244
|
+
- id: submit_form
|
|
245
|
+
label: Submit Form
|
|
246
|
+
purpose: "Lưu form và báo kết quả cho user"
|
|
247
|
+
variant: primary
|
|
248
|
+
position: form_footer
|
|
249
|
+
trigger: button_click
|
|
250
|
+
apiRefs: [ feature.create ]
|
|
251
|
+
# tags: ["#reuse-api"]
|
|
252
|
+
# reuseFrom: surfaces/admin/CMP-01/auth/01/01/01/api/01/01-backend-spec.yaml
|
|
253
|
+
onSuccess:
|
|
254
|
+
- Navigate to list page
|
|
255
|
+
- Show success toast "Created successfully"
|
|
256
|
+
onCommonError:
|
|
257
|
+
override: false
|
|
258
|
+
notes: "Inherit #ui-common:error-handler (Global toast 500/401)"
|
|
259
|
+
onSpecificError:
|
|
260
|
+
- condition: "422 Validation"
|
|
261
|
+
notes: "Show inline field errors below inputs"
|
|
262
|
+
- condition: "403 IDOR"
|
|
263
|
+
notes: "Redirect to safety page, show warning"
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Agent output (/spec)
|
|
267
|
+
|
|
268
|
+
YAML only per schema. No explanation. No markdown.
|
|
269
|
+
|
|
270
|
+
## Questions: AskQuestion wizard or hub `qa/open/`
|
|
271
|
+
|
|
272
|
+
Do **not** write `openQuestions` anywhere. Schema/render không còn field này.
|
|
273
|
+
|
|
274
|
+
- Member trả lời **ngay:** AskQuestion (options + Recommended + **Other**) → **STOP** → ghi field thật.
|
|
275
|
+
- Member chọn **Other** mà **chưa quyết:** `.cursor/extracts/qa-inbox.md` → `qa/open/QA-<bundle.id>-NNNN.yaml`. Đóng sau bằng **`/qa-resolve <id>` + giải pháp**.
|
|
276
|
+
- `grillStatus` có thể `done` khi vẫn còn file QA.
|
|
277
|
+
|
|
278
|
+
## YAML Syntax & Escaping Rules
|
|
279
|
+
|
|
280
|
+
- **ALWAYS quote colons in strings:** Any string containing `:` (e.g., `summary: "Case 1: Token..."`, `label: "Hàng nút: [Secondary]"`) MUST be wrapped in double quotes `"..."`.
|
|
281
|
+
- **Multiline text:** Use `|` block scalar for multiline strings or list items containing formatting symbols.
|
|
282
|
+
|
|
283
|
+
## ir/spec.yaml vs ir/design.yaml
|
|
284
|
+
|
|
285
|
+
`pnpm spec:split` ghi hai file. FlowGrid bộ docs grill **không** đọc `ir/*` khi author — chỉ bundle. Split ghi `"Q&A":` trên **`ir/spec.yaml`** (id `QA-<bundle.id>-NNNN` cách nhau bởi `, `) từ `qa/open/` — không nhét list vào bundle.
|
|
286
|
+
|
|
287
|
+
Downstream (UI gen, API gen, testcase) đọc **chỉ `ir/design.yaml`**. Thiếu file = split/spec chưa xong. Story/copy chưa đủ thì **bổ sung design** (bundle.gen + split), không đọc `ir/spec.yaml`. `ir/spec.yaml` chỉ văn mô tả + `legacy` + `qa` (id treo).
|
|
288
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# clients.line — append to ir/spec.yaml when feature has shop-floor UI
|
|
2
|
+
|
|
3
|
+
clients:
|
|
4
|
+
line:
|
|
5
|
+
profile: kiosk # kiosk | tablet
|
|
6
|
+
screens:
|
|
7
|
+
- id: check-in
|
|
8
|
+
route: workforce/check-in
|
|
9
|
+
automationIds:
|
|
10
|
+
page: {module}-page
|
|
11
|
+
submit-btn: {module}-submit-btn
|
|
12
|
+
devices:
|
|
13
|
+
- badgeReader
|
|
14
|
+
api:
|
|
15
|
+
endpoints:
|
|
16
|
+
checkIn:
|
|
17
|
+
method: POST
|
|
18
|
+
path: /workforce/check-in
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# <%= spec.title || spec.id %>
|
|
2
|
+
|
|
3
|
+
<% if (context.testcases && context.testcases.length) { %>
|
|
4
|
+
- **Testcase plans:** <%= context.testcases.map(tc => '`' + (tc.data.title || tc.data.id || tc.file) + '`').join(' · ') %> (hub: [base_test](https://github.com/raintr91/base_test))
|
|
5
|
+
<% } else { %>
|
|
6
|
+
- **Testcase plans:** [base_test](https://github.com/raintr91/base_test) (`pnpm cases:render` on tests hub) — see docs-hub TESTS-HUB
|
|
7
|
+
<% } %>
|
|
8
|
+
|
|
9
|
+
<%
|
|
10
|
+
const route = spec.ui?.routes?.[0];
|
|
11
|
+
const path = route?.path || '';
|
|
12
|
+
const testId = route?.pageTestId || '';
|
|
13
|
+
let screenLine = '- **Screen:** None';
|
|
14
|
+
if (path) {
|
|
15
|
+
const screen = context.renderScreenLink ? context.renderScreenLink(path) : '`' + path + '`';
|
|
16
|
+
const suffix = testId ? ` · \`${testId}\`` : '';
|
|
17
|
+
screenLine = `- **Screen:** ${screen}${suffix}`;
|
|
18
|
+
}
|
|
19
|
+
%>
|
|
20
|
+
<%= screenLine %>
|
|
21
|
+
|
|
22
|
+
<% if (spec.summary) { %>
|
|
23
|
+
<%= spec.summary %>
|
|
24
|
+
<% } %>
|
|
25
|
+
|
|
26
|
+
<% if (spec.userStories) { %>
|
|
27
|
+
## User Stories & Screen Journey
|
|
28
|
+
|
|
29
|
+
<% if (typeof spec.userStories === 'string') { %>
|
|
30
|
+
<%= spec.userStories %>
|
|
31
|
+
<% } else if (Array.isArray(spec.userStories)) { %>
|
|
32
|
+
<% spec.userStories.forEach(story => { %>
|
|
33
|
+
### <%= story.title || story.name || 'User Story' %>
|
|
34
|
+
<% if (story.asA || story.role) { %>
|
|
35
|
+
> **Là một** <%= story.asA || story.role %>,
|
|
36
|
+
> **Tôi muốn** <%= story.iWant || story.action %>,
|
|
37
|
+
> **Để** <%= story.soThat || story.benefit %>.
|
|
38
|
+
<% } else if (story.story) { %>
|
|
39
|
+
> <%= story.story %>
|
|
40
|
+
<% } %>
|
|
41
|
+
|
|
42
|
+
<% if (story.preConditions && story.preConditions.length) { %>
|
|
43
|
+
**Điều kiện tiên quyết (Pre-conditions):**
|
|
44
|
+
<% (Array.isArray(story.preConditions) ? story.preConditions : [story.preConditions]).forEach(p => { %>
|
|
45
|
+
- <%= p %>
|
|
46
|
+
<% }); %>
|
|
47
|
+
<% } %>
|
|
48
|
+
|
|
49
|
+
<% if (story.scenarios && story.scenarios.length) { %>
|
|
50
|
+
**Kịch bản chi tiết trên màn hình (Scenarios):**
|
|
51
|
+
<% story.scenarios.forEach(sc => { %>
|
|
52
|
+
- **<%= sc.name || sc.title %>:** <%= sc.description || sc.steps || sc %>
|
|
53
|
+
<% }); %>
|
|
54
|
+
<% } %>
|
|
55
|
+
|
|
56
|
+
<% if (story.acceptanceCriteria && story.acceptanceCriteria.length) { %>
|
|
57
|
+
**Tiêu chí nghiệm thu (Acceptance Criteria):**
|
|
58
|
+
<% (Array.isArray(story.acceptanceCriteria) ? story.acceptanceCriteria : [story.acceptanceCriteria]).forEach(ac => { %>
|
|
59
|
+
- [ ] <%= ac %>
|
|
60
|
+
<% }); %>
|
|
61
|
+
<% } %>
|
|
62
|
+
|
|
63
|
+
<% }); %>
|
|
64
|
+
<% } else if (typeof spec.userStories === 'object') { %>
|
|
65
|
+
<% if (spec.userStories.primary) { %>
|
|
66
|
+
### User Story Chính
|
|
67
|
+
> **Là một** <%= spec.userStories.primary.asA || spec.userStories.primary.role %>,
|
|
68
|
+
> **Tôi muốn** <%= spec.userStories.primary.iWant || spec.userStories.primary.action %>,
|
|
69
|
+
> **Để** <%= spec.userStories.primary.soThat || spec.userStories.primary.benefit %>.
|
|
70
|
+
<% } %>
|
|
71
|
+
|
|
72
|
+
<% if (spec.userStories.contextAndHandoff) { %>
|
|
73
|
+
### Cách thức Truy cập & Chuyển giao Màn hình (Screen Access & Handoff)
|
|
74
|
+
<% if (spec.userStories.contextAndHandoff.screenAccess) { %>
|
|
75
|
+
<% const sa = spec.userStories.contextAndHandoff.screenAccess; %>
|
|
76
|
+
- **Loại truy cập (Access Type):** `<%= sa.accessType || 'N/A' %>`
|
|
77
|
+
<% if (sa.accessType === 'directRoute' && sa.directRoute) { %>
|
|
78
|
+
- **Đường dẫn URL (Path Router):** `<%= sa.directRoute.routePath || '' %>` <%= sa.directRoute.isPublic ? '(Công khai / Public)' : '(Cần đăng nhập / Authenticated)' %>
|
|
79
|
+
<% } else if (sa.accessType === 'sidebarMenu' && sa.sidebarMenu) { %>
|
|
80
|
+
- **Menu Sidebar:** <%= sa.sidebarMenu.menuHierarchy ? sa.sidebarMenu.menuHierarchy.join(' > ') : '' %> > **<%= sa.sidebarMenu.menuLabel || '' %>**
|
|
81
|
+
<% } else if (sa.accessType === 'contextualAction' && sa.contextualAction) { %>
|
|
82
|
+
- **Kích hoạt từ (Triggered By):** <%= sa.contextualAction.triggerControl || '' %> từ màn hình `<%= sa.contextualAction.sourceScreen || '' %>` (Loại: `<%= sa.contextualAction.navigationType || 'pageRedirect' %>`)
|
|
83
|
+
<% } %>
|
|
84
|
+
<% } %>
|
|
85
|
+
- **Màn hình nguồn (Source Screen):** `<%= spec.userStories.contextAndHandoff.sourceScreen || 'Direct' %>`
|
|
86
|
+
<% if (spec.userStories.contextAndHandoff.inputsReceived && spec.userStories.contextAndHandoff.inputsReceived.length) { %>
|
|
87
|
+
- **Dữ liệu tiếp nhận (Inputs):** <%= Array.isArray(spec.userStories.contextAndHandoff.inputsReceived) ? spec.userStories.contextAndHandoff.inputsReceived.join(' · ') : spec.userStories.contextAndHandoff.inputsReceived %>
|
|
88
|
+
<% } %>
|
|
89
|
+
- **Điều hướng tiếp theo (Next Screen):** `<%= spec.userStories.contextAndHandoff.nextScreenOnSuccess || 'None' %>`
|
|
90
|
+
<% } %>
|
|
91
|
+
|
|
92
|
+
<% if (spec.userStories.scenarios && spec.userStories.scenarios.length) { %>
|
|
93
|
+
### Kịch bản Chi tiết trên Màn hình (Scenarios)
|
|
94
|
+
<% spec.userStories.scenarios.forEach(sc => { %>
|
|
95
|
+
#### <%= sc.name || sc.title %>
|
|
96
|
+
<% if (sc.steps && sc.steps.length) { %>
|
|
97
|
+
<% (Array.isArray(sc.steps) ? sc.steps : [sc.steps]).forEach(step => { %>
|
|
98
|
+
- <%= step %>
|
|
99
|
+
<% }); %>
|
|
100
|
+
<% } else if (sc.description) { %>
|
|
101
|
+
<%= sc.description %>
|
|
102
|
+
<% } %>
|
|
103
|
+
<% }); %>
|
|
104
|
+
<% } %>
|
|
105
|
+
|
|
106
|
+
<% if (spec.userStories.acceptanceCriteria && spec.userStories.acceptanceCriteria.length) { %>
|
|
107
|
+
### Tiêu chí Nghiệm thu (Acceptance Criteria)
|
|
108
|
+
<% spec.userStories.acceptanceCriteria.forEach(ac => { %>
|
|
109
|
+
- [ ] <%= ac %>
|
|
110
|
+
<% }); %>
|
|
111
|
+
<% } %>
|
|
112
|
+
|
|
113
|
+
<% } %>
|
|
114
|
+
<% } %>
|
|
115
|
+
|
|
116
|
+
<%
|
|
117
|
+
// 1. Executive Summary & Screen Journey
|
|
118
|
+
const pageSections = spec.sections || spec.design?.sections || [];
|
|
119
|
+
const pageActions = spec.actions || spec.design?.actions || [];
|
|
120
|
+
const pageStateMatrix = spec.stateMatrix || spec.design?.stateMatrix;
|
|
121
|
+
|
|
122
|
+
const page = {
|
|
123
|
+
nav: spec.nav || spec.design?.nav,
|
|
124
|
+
sections: pageSections,
|
|
125
|
+
zones: spec.zones || spec.design?.zones,
|
|
126
|
+
behavior: spec.behavior || spec.design?.behavior,
|
|
127
|
+
actions: pageActions
|
|
128
|
+
}
|
|
129
|
+
%>
|
|
130
|
+
|
|
131
|
+
<% if (pageStateMatrix) { %>
|
|
132
|
+
## Ma Trận Trạng Thái Giao Diện & Phân Quyền (State & Permission Matrix)
|
|
133
|
+
|
|
134
|
+
<%- context.renderStateMatrixTable(pageStateMatrix) %>
|
|
135
|
+
|
|
136
|
+
<% } %>
|
|
137
|
+
|
|
138
|
+
<%
|
|
139
|
+
const validationTableMd = context.renderValidationDictionaryTable(pageSections);
|
|
140
|
+
if (validationTableMd) {
|
|
141
|
+
%>
|
|
142
|
+
## Danh Mục Trường Nhập Liệu & Quy Tắc Kiểm Tra Hợp Lệ (Data Dictionary & Validation)
|
|
143
|
+
|
|
144
|
+
<%- validationTableMd %>
|
|
145
|
+
|
|
146
|
+
<% } %>
|
|
147
|
+
|
|
148
|
+
<%
|
|
149
|
+
const customWidgetMd = context.renderCustomWidgetSpecs(pageSections);
|
|
150
|
+
if (customWidgetMd) {
|
|
151
|
+
%>
|
|
152
|
+
<%- customWidgetMd %>
|
|
153
|
+
|
|
154
|
+
<% } %>
|
|
155
|
+
|
|
156
|
+
<%
|
|
157
|
+
const actionFlowsMd = context.renderActionFlowsDetailed(pageActions);
|
|
158
|
+
if (actionFlowsMd) {
|
|
159
|
+
%>
|
|
160
|
+
## Đặc Tả Quy Trình Hành Động (Action Flows)
|
|
161
|
+
|
|
162
|
+
<%- actionFlowsMd %>
|
|
163
|
+
|
|
164
|
+
<% } else { %>
|
|
165
|
+
<%- context.renderPageComposition(page, { businessOnly: true }) %>
|
|
166
|
+
<% } %>
|
|
167
|
+
|
|
168
|
+
<%
|
|
169
|
+
const skipKeys = new Set([
|
|
170
|
+
'id', 'page-id', 'title', 'summary', 'userStories', 'acceptance', 'ui', 'design', 'legacy', 'review', 'template',
|
|
171
|
+
'nav', 'sections', 'zones', 'behavior', 'actions', 'stateMatrix', 'grillStatus', 'specOrigin',
|
|
172
|
+
'status', 'owner', 'schema', 'qa', 'Q&A', 'pendingTechDebt', 'i18n', 'gen', '_meta'
|
|
173
|
+
]);
|
|
174
|
+
Object.entries(spec).forEach(([key, value]) => {
|
|
175
|
+
if (skipKeys.has(key) || value == null) return;
|
|
176
|
+
%>
|
|
177
|
+
## <%= key %>
|
|
178
|
+
|
|
179
|
+
<% if (typeof value === 'string') { %>
|
|
180
|
+
<%= value %>
|
|
181
|
+
<% } else { %>
|
|
182
|
+
```yaml
|
|
183
|
+
<%= context.stringify(value).trim() %>
|
|
184
|
+
```
|
|
185
|
+
<% } %>
|
|
186
|
+
|
|
187
|
+
<% }); %>
|
|
188
|
+
|
|
189
|
+
<% if (spec.pendingTechDebt && spec.pendingTechDebt.length) { %>
|
|
190
|
+
## Pending tech debt
|
|
191
|
+
|
|
192
|
+
| ID | Status | Summary |
|
|
193
|
+
| --- | --- | --- |
|
|
194
|
+
<% spec.pendingTechDebt.forEach(d => { %>
|
|
195
|
+
| <%= d.id %> | <%= d.status %> | <%= d.summary || '' %> |
|
|
196
|
+
<% }); %>
|
|
197
|
+
|
|
198
|
+
<% } %>
|
|
199
|
+
|
|
200
|
+
<% if (spec.review && (spec.review.layoutNotes || spec.review.summary)) { %>
|
|
201
|
+
## Review — layout notes
|
|
202
|
+
|
|
203
|
+
<% if (spec.review.layoutNotes) { %>
|
|
204
|
+
<% if (Array.isArray(spec.review.layoutNotes)) { %>
|
|
205
|
+
<%= spec.review.layoutNotes.map(n => `- ${n}`).join('\n') %>
|
|
206
|
+
<% } else { %>
|
|
207
|
+
- <%= spec.review.layoutNotes %>
|
|
208
|
+
<% } %>
|
|
209
|
+
<% } %>
|
|
210
|
+
<% } %>
|
|
211
|
+
|
|
212
|
+
<% if (spec.legacy && (spec.legacy.behaviors?.length || spec.legacy.fields?.length || spec.legacy.evidence?.length)) { %>
|
|
213
|
+
## Legacy evidence
|
|
214
|
+
|
|
215
|
+
<% if (spec.legacy.behaviors && spec.legacy.behaviors.length) { %>
|
|
216
|
+
### Behaviors
|
|
217
|
+
|
|
218
|
+
| ID | Fact | Confidence |
|
|
219
|
+
| --- | --- | --- |
|
|
220
|
+
<% spec.legacy.behaviors.forEach(b => { %>
|
|
221
|
+
| <%= b.id || '' %> | `<%= JSON.stringify(b.fact || {}) %>` | <%= b.confidence || '' %> |
|
|
222
|
+
<% }); %>
|
|
223
|
+
<% } %>
|
|
224
|
+
|
|
225
|
+
<% if (spec.legacy.fields && spec.legacy.fields.length) { %>
|
|
226
|
+
### Fields
|
|
227
|
+
|
|
228
|
+
| Name | Via | Confidence |
|
|
229
|
+
| --- | --- | --- |
|
|
230
|
+
<% spec.legacy.fields.forEach(f => { %>
|
|
231
|
+
| <%= f.name || '' %> | <%= f.via || '' %> | <%= f.confidence || '' %> |
|
|
232
|
+
<% }); %>
|
|
233
|
+
<% } %>
|
|
234
|
+
<% } %>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Design spec v1 — /spec (round 1)
|
|
2
|
+
# Do NOT add codegen, ui.filters, ui.columns, or portal-gen tags here.
|
|
3
|
+
# After /grill-docs → see docs/templates/spec.yaml (portal-gen-ready).
|
|
4
|
+
|
|
5
|
+
id: role-page-function
|
|
6
|
+
title: Feature title
|
|
7
|
+
status: draft
|
|
8
|
+
owner: portal-team
|
|
9
|
+
summary: Short business summary for BA, QA, dev, and AI.
|
|
10
|
+
|
|
11
|
+
actors: []
|
|
12
|
+
# - id: admin
|
|
13
|
+
# legacyRoleCode: master
|
|
14
|
+
|
|
15
|
+
entities: []
|
|
16
|
+
# - name: Entity
|
|
17
|
+
# table: entities
|
|
18
|
+
# importantFields: [id, name, created_at]
|
|
19
|
+
|
|
20
|
+
relationships: []
|
|
21
|
+
|
|
22
|
+
requirements:
|
|
23
|
+
- id: REQ-FEATURE-001
|
|
24
|
+
title: Main behavior
|
|
25
|
+
description: User can complete the main behavior.
|
|
26
|
+
priority: must
|
|
27
|
+
|
|
28
|
+
ui:
|
|
29
|
+
routes:
|
|
30
|
+
- path: /feature-path
|
|
31
|
+
legacyPath: /legacy/path
|
|
32
|
+
pageTestId: feature-page
|
|
33
|
+
# Page profiles for design v1. Keep prose short; move validation/source/message details to form fields.
|
|
34
|
+
validationMessages:
|
|
35
|
+
required: This field is required
|
|
36
|
+
email: Email format is invalid
|
|
37
|
+
phone: Phone number format is invalid
|
|
38
|
+
minLength: Must be at least {n} characters
|
|
39
|
+
maxLength: Must be at most {n} characters
|
|
40
|
+
min: Must be at least {n}
|
|
41
|
+
max: Must be at most {n}
|
|
42
|
+
pattern: Invalid format
|
|
43
|
+
list:
|
|
44
|
+
columns: []
|
|
45
|
+
filters: []
|
|
46
|
+
rowActions: []
|
|
47
|
+
bulkActions: []
|
|
48
|
+
pagination:
|
|
49
|
+
defaultPageSize: 20
|
|
50
|
+
pageSizeOptions: [20, 50, 100]
|
|
51
|
+
form:
|
|
52
|
+
layout:
|
|
53
|
+
mode: single-column # single-column | two-column | custom
|
|
54
|
+
sections: []
|
|
55
|
+
fields:
|
|
56
|
+
# - key: name
|
|
57
|
+
# label: Name
|
|
58
|
+
# type: string
|
|
59
|
+
# widget: text
|
|
60
|
+
# purpose: "Tên hiển thị trên hồ sơ"
|
|
61
|
+
# required: true
|
|
62
|
+
# validation:
|
|
63
|
+
# maxLength: 255
|
|
64
|
+
# messages:
|
|
65
|
+
# required: Name is required.
|
|
66
|
+
detail:
|
|
67
|
+
header:
|
|
68
|
+
titleField: name
|
|
69
|
+
subtitleField: code
|
|
70
|
+
sections: []
|
|
71
|
+
actions:
|
|
72
|
+
- id: edit
|
|
73
|
+
text: Edit
|
|
74
|
+
- id: delete
|
|
75
|
+
text: Delete
|
|
76
|
+
|
|
77
|
+
# api.endpoints — not authored here. spec:split copies from …/api/<seq>/01-backend-spec.yaml
|
|
78
|
+
|
|
79
|
+
acceptance:
|
|
80
|
+
- Main behavior is testable end to end.
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
notes:
|
|
84
|
+
- YAML is source of truth. Render with pnpm docs:render.
|
|
85
|
+
- Portal-gen blocks added in /grill-docs — see .cursor/extracts/codegen/readiness.md
|