@stackonward/cli 0.0.1 → 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/dist/index.js +4588 -205
- package/dist/index.js.map +1 -1
- package/dist/resources/apple/.claude/docs/architecture-template.md +54 -0
- package/dist/resources/apple/.claude/docs/architecture.md +52 -0
- package/dist/resources/apple/.claude/docs/index.md +13 -0
- package/dist/resources/apple/.claude/docs/security-lifecycle.md +57 -0
- package/dist/resources/apple/.claude/docs/stack.md +93 -0
- package/dist/resources/apple/.claude/docs/verification.md +63 -0
- package/dist/resources/apple/AGENTS.md +397 -0
- package/dist/resources/apple/CLAUDE.md +397 -0
- package/dist/resources/apple/Gemfile +2 -0
- package/dist/resources/apple/Gemfile.lock +365 -0
- package/dist/resources/apple/_gitignore +14 -0
- package/dist/resources/apple/fastlane/Fastfile +123 -0
- package/dist/resources/components/nuxt/site-source/app/app.vue +42 -0
- package/dist/resources/components/nuxt/site-source/app/assets/css/site-shell.css +1035 -0
- package/dist/resources/components/nuxt/site-source/app/assets/icons/brand/.gitkeep +0 -0
- package/dist/resources/components/nuxt/site-source/app/assets/icons/common/.gitkeep +0 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationHeader.vue +35 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationShell.vue +56 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationSidebar.vue +40 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/BackToTop.vue +42 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/ContentArticlePage.vue +40 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/ContentListPage.vue +30 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/CookieConsent.vue +18 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/MarketingFooter.vue +52 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/MarketingHeader.vue +106 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/MarketingShell.vue +35 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/SiteBrand.vue +10 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/StaticPage.vue +21 -0
- package/dist/resources/components/nuxt/site-source/app/components/site/ToastViewport.vue +25 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/BaseButton.vue +86 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/BaseGradientBorder.vue +59 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/BaseModal.vue +131 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/BasePopover.vue +150 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/BaseText.vue +138 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/CheckoutStatus.vue +112 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/CheckoutSummary.vue +172 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/GoogleSignInButton.vue +113 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/InfiniteScroll.vue +123 -0
- package/dist/resources/components/nuxt/site-source/app/components/ui/YoutubeEmbed.vue +126 -0
- package/dist/resources/components/nuxt/site-source/app/composables/useAnalytics.ts +24 -0
- package/dist/resources/components/nuxt/site-source/app/composables/useCheckout.ts +121 -0
- package/dist/resources/components/nuxt/site-source/app/composables/useConsent.ts +31 -0
- package/dist/resources/components/nuxt/site-source/app/composables/useGoogleIdentity.ts +163 -0
- package/dist/resources/components/nuxt/site-source/app/composables/useNavigation.ts +11 -0
- package/dist/resources/components/nuxt/site-source/app/composables/useSeo.ts +33 -0
- package/dist/resources/components/nuxt/site-source/app/composables/useSiteShell.ts +58 -0
- package/dist/resources/components/nuxt/site-source/app/composables/useToasts.ts +48 -0
- package/dist/resources/components/nuxt/site-source/app/layouts/app.vue +5 -0
- package/dist/resources/components/nuxt/site-source/app/layouts/default.vue +5 -0
- package/dist/resources/components/nuxt/site-source/app/plugins/analytics.client.ts +121 -0
- package/dist/resources/components/nuxt/site-source/app/plugins/google-identity.client.ts +24 -0
- package/dist/resources/components/nuxt/site-source/app/theme/accordion.ts +9 -0
- package/dist/resources/components/nuxt/site-source/app/theme/breadcrumb.ts +8 -0
- package/dist/resources/components/nuxt/site-source/app/theme/button.ts +92 -0
- package/dist/resources/components/nuxt/site-source/app/theme/carousel.ts +11 -0
- package/dist/resources/components/nuxt/site-source/app/theme/checkbox.ts +12 -0
- package/dist/resources/components/nuxt/site-source/app/theme/index.ts +30 -0
- package/dist/resources/components/nuxt/site-source/app/theme/input.ts +47 -0
- package/dist/resources/components/nuxt/site-source/app/theme/modal.ts +9 -0
- package/dist/resources/components/nuxt/site-source/app/theme/pagination.ts +6 -0
- package/dist/resources/components/nuxt/site-source/app/theme/select.ts +23 -0
- package/dist/resources/components/nuxt/site-source/app/theme/stepper.ts +10 -0
- package/dist/resources/components/nuxt/site-source/app/theme/toast.ts +8 -0
- package/dist/resources/components/nuxt/site-source/app/theme/tooltip.ts +6 -0
- package/dist/resources/components/nuxt/site-source/app/types/site-shell.ts +85 -0
- package/dist/resources/components/react/ui/Button.tsx +73 -0
- package/dist/resources/components/react/ui/Input.tsx +44 -0
- package/dist/resources/components/registry.json +355 -0
- package/dist/resources/components/vue/feedback/Toast.vue +120 -0
- package/dist/resources/components/vue/feedback/useToast.ts +70 -0
- package/dist/resources/components/vue/media/FileUpload.vue +229 -0
- package/dist/resources/components/vue/media/VideoPlayer.vue +157 -0
- package/dist/resources/components/vue/ui/AppImage.vue +147 -0
- package/dist/resources/components/vue/ui/BottomSheet.vue +217 -0
- package/dist/resources/components/vue/ui/Button.vue +154 -0
- package/dist/resources/components/vue/ui/Card.vue +111 -0
- package/dist/resources/components/vue/ui/Input.vue +113 -0
- package/dist/resources/components/vue/ui/Modal.vue +193 -0
- package/dist/resources/components/vue/ui/ScrollArea.vue +163 -0
- package/dist/resources/components/vue/ui/Tooltip.vue +115 -0
- package/dist/resources/registry.json +158 -0
- package/dist/resources/snippets/node/cache.ts +116 -0
- package/dist/resources/snippets/node/date.ts +126 -0
- package/dist/resources/snippets/node/logger.ts +104 -0
- package/dist/resources/snippets/node/validation.ts +132 -0
- package/dist/resources/snippets/react/useDebounce.ts +90 -0
- package/dist/resources/snippets/registry.json +65 -0
- package/dist/resources/snippets/vue/useAsync.ts +96 -0
- package/dist/resources/snippets/vue/usePagination.ts +102 -0
- package/dist/resources/templates/base/.claude/docs/architecture-template.md +459 -0
- package/dist/resources/templates/base/.claude/docs/architecture.md +137 -0
- package/dist/resources/templates/base/.claude/docs/index.md +42 -0
- package/dist/resources/templates/base/.claude/docs/security-lifecycle.md +129 -0
- package/dist/resources/templates/base/.claude/docs/verification.md +121 -0
- package/dist/resources/templates/base/AGENTS.md +415 -0
- package/dist/resources/templates/base/CLAUDE.md +415 -0
- package/dist/resources/templates/go-backend/.claude/docs/api-design.md +486 -0
- package/dist/resources/templates/go-backend/.claude/docs/architecture-template.md +449 -0
- package/dist/resources/templates/go-backend/.claude/docs/check-list.md +155 -0
- package/dist/resources/templates/go-backend/.claude/docs/database.md +369 -0
- package/dist/resources/templates/go-backend/.claude/docs/e2e-standards.md +161 -0
- package/dist/resources/templates/go-backend/.claude/docs/error-handling.md +558 -0
- package/dist/resources/templates/go-backend/.claude/docs/event-runtime-boundary.md +124 -0
- package/dist/resources/templates/go-backend/.claude/docs/identifier-contract.md +195 -0
- package/dist/resources/templates/go-backend/.claude/docs/index.md +22 -0
- package/dist/resources/templates/go-backend/.claude/docs/logging.md +314 -0
- package/dist/resources/templates/go-backend/.claude/docs/mediagen-provider-onboarding-sop.md +917 -0
- package/dist/resources/templates/go-backend/.claude/docs/mediagen-provider-quick-reference.md +195 -0
- package/dist/resources/templates/go-backend/.claude/docs/module-standards.md +309 -0
- package/dist/resources/templates/go-backend/.claude/docs/openapi-contract.md +141 -0
- package/dist/resources/templates/go-backend/.claude/docs/payment-gateway-onboarding.md +283 -0
- package/dist/resources/templates/go-backend/.claude/docs/platform-boundary.md +191 -0
- package/dist/resources/templates/go-backend/.claude/docs/quality-gates.md +112 -0
- package/dist/resources/templates/go-backend/.dockerignore +6 -0
- package/dist/resources/templates/go-backend/.env.example +13 -0
- package/dist/resources/templates/go-backend/.gitattributes +2 -0
- package/dist/resources/templates/go-backend/AGENTS.md +1139 -0
- package/dist/resources/templates/go-backend/CLAUDE.md +1139 -0
- package/dist/resources/templates/go-backend/Dockerfile +14 -0
- package/dist/resources/templates/go-backend/Makefile +71 -0
- package/dist/resources/templates/go-backend/README.md +66 -0
- package/dist/resources/templates/go-backend/_gitignore +10 -0
- package/dist/resources/templates/go-backend/api/openapi/README.md +29 -0
- package/dist/resources/templates/go-backend/api/openapi/dist/artifact-manifest.json +19 -0
- package/dist/resources/templates/go-backend/api/openapi/dist/conformance-matrix.json +276 -0
- package/dist/resources/templates/go-backend/api/openapi/document.go +30 -0
- package/dist/resources/templates/go-backend/api/openapi/package.json +28 -0
- package/dist/resources/templates/go-backend/api/openapi/pnpm-lock.yaml +3052 -0
- package/dist/resources/templates/go-backend/api/openapi/redocly-source.yaml +18 -0
- package/dist/resources/templates/go-backend/api/openapi/redocly.yaml +8 -0
- package/dist/resources/templates/go-backend/api/openapi/sdk-generators.json +16 -0
- package/dist/resources/templates/go-backend/api/openapi/service-registry.json +39 -0
- package/dist/resources/templates/go-backend/api/openapi/services/product-api/conformance/runtime.arazzo.yaml +65 -0
- package/dist/resources/templates/go-backend/api/openapi/services/product-api/dist/internal.openapi.json +327 -0
- package/dist/resources/templates/go-backend/api/openapi/services/product-api/dist/runtime-contract.json +56 -0
- package/dist/resources/templates/go-backend/api/openapi/services/product-api/openapi.yaml +222 -0
- package/dist/resources/templates/go-backend/api/openapi/services/worker/conformance/runtime.arazzo.yaml +65 -0
- package/dist/resources/templates/go-backend/api/openapi/services/worker/dist/internal.openapi.json +327 -0
- package/dist/resources/templates/go-backend/api/openapi/services/worker/dist/runtime-contract.json +56 -0
- package/dist/resources/templates/go-backend/api/openapi/services/worker/openapi.yaml +222 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/breaking.mjs +416 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/build.mjs +103 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/conformance_coverage.mjs +111 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/contract_compiler.mjs +62 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/contract_policy.mjs +208 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/delegated_contract.mjs +302 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/deterministic_archive.mjs +69 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/documentation_example_privacy.mjs +93 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/documentation_projection.mjs +498 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/documentation_quality.mjs +346 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/git_artifact_history.mjs +188 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/manifest.mjs +170 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/overlay.mjs +98 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/project.mjs +549 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/route_contract.mjs +156 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/runtime_conformance.mjs +193 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/scalar_asset_localization.mjs +164 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/sdk_generator.mjs +229 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/semantic_version.mjs +64 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/service_contract_inputs.mjs +16 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/breaking.test.mjs +365 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/build.test.mjs +42 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/conformance_coverage.test.mjs +88 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/contract_policy.test.mjs +257 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/delegated_contract.test.mjs +205 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/documentation_example_privacy.test.mjs +51 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/documentation_projection.test.mjs +368 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/documentation_quality.test.mjs +151 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/git_artifact_history.test.mjs +60 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/head_policy.test.mjs +8 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/overlay.test.mjs +44 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/projection.test.mjs +270 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/redocly_documentation_rules.test.mjs +146 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/release_manifest.test.mjs +76 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/route_contract.test.mjs +119 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/runtime_conformance.test.mjs +75 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/scalar_asset_localization.test.mjs +50 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/sdk_generator.test.mjs +31 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/semantic_version.test.mjs +60 -0
- package/dist/resources/templates/go-backend/api/openapi/tooling/test/service_contract_inputs.test.mjs +27 -0
- package/dist/resources/templates/go-backend/cmd/internal/runtime/resources.go +125 -0
- package/dist/resources/templates/go-backend/cmd/internal/runtime/runtime.go +102 -0
- package/dist/resources/templates/go-backend/cmd/internal/runtime/runtime_test.go +70 -0
- package/dist/resources/templates/go-backend/cmd/product-api/lifecycle_test.go +58 -0
- package/dist/resources/templates/go-backend/cmd/product-api/main.go +32 -0
- package/dist/resources/templates/go-backend/cmd/product-api/wire.go +13 -0
- package/dist/resources/templates/go-backend/cmd/product-api/wire_gen.go +94 -0
- package/dist/resources/templates/go-backend/cmd/worker/main.go +47 -0
- package/dist/resources/templates/go-backend/cmd/worker/wire.go +14 -0
- package/dist/resources/templates/go-backend/cmd/worker/wire_gen.go +111 -0
- package/dist/resources/templates/go-backend/configs/config.yaml +37 -0
- package/dist/resources/templates/go-backend/deployments/compose.yaml +71 -0
- package/dist/resources/templates/go-backend/docs/openapi-provenance.json +489 -0
- package/dist/resources/templates/go-backend/docs/runtime-provenance.json +175 -0
- package/dist/resources/templates/go-backend/docs/source-provenance.json +3568 -0
- package/dist/resources/templates/go-backend/docs/standards-provenance.json +1624 -0
- package/dist/resources/templates/go-backend/go.mod +256 -0
- package/dist/resources/templates/go-backend/go.sum +805 -0
- package/dist/resources/templates/go-backend/internal/common/canonicaljson/canonical.go +370 -0
- package/dist/resources/templates/go-backend/internal/common/canonicaljson/canonical_test.go +223 -0
- package/dist/resources/templates/go-backend/internal/common/checkoutbff/contracts.go +125 -0
- package/dist/resources/templates/go-backend/internal/common/checkoutbff/platform_client.go +212 -0
- package/dist/resources/templates/go-backend/internal/common/checkoutbff/platform_client_test.go +319 -0
- package/dist/resources/templates/go-backend/internal/common/contentaccess/contentaccess.go +50 -0
- package/dist/resources/templates/go-backend/internal/common/contracts/contact.go +85 -0
- package/dist/resources/templates/go-backend/internal/common/ctxutil/identity.go +20 -0
- package/dist/resources/templates/go-backend/internal/common/ctxutil/product.go +53 -0
- package/dist/resources/templates/go-backend/internal/common/enumdomain/payment.go +12 -0
- package/dist/resources/templates/go-backend/internal/common/enums/dto_admin.go +9 -0
- package/dist/resources/templates/go-backend/internal/common/enums/enum.go +1247 -0
- package/dist/resources/templates/go-backend/internal/common/enums/handler_admin.go +66 -0
- package/dist/resources/templates/go-backend/internal/common/enums/module.go +46 -0
- package/dist/resources/templates/go-backend/internal/common/enums/provider.go +10 -0
- package/dist/resources/templates/go-backend/internal/common/enums/register.go +11 -0
- package/dist/resources/templates/go-backend/internal/common/enums/register_audit.go +274 -0
- package/dist/resources/templates/go-backend/internal/common/enums/register_command_replay.go +12 -0
- package/dist/resources/templates/go-backend/internal/common/enums/register_config.go +27 -0
- package/dist/resources/templates/go-backend/internal/common/enums/register_locale.go +37 -0
- package/dist/resources/templates/go-backend/internal/common/enums/register_ops.go +14 -0
- package/dist/resources/templates/go-backend/internal/common/enums/register_outbox.go +15 -0
- package/dist/resources/templates/go-backend/internal/common/enums/register_rule_expression.go +63 -0
- package/dist/resources/templates/go-backend/internal/common/enums/registry.go +77 -0
- package/dist/resources/templates/go-backend/internal/common/httporigin/origin.go +62 -0
- package/dist/resources/templates/go-backend/internal/common/httporigin/origin_test.go +38 -0
- package/dist/resources/templates/go-backend/internal/common/iamcredential/plaintext.go +35 -0
- package/dist/resources/templates/go-backend/internal/common/iamcredential/plaintext_test.go +29 -0
- package/dist/resources/templates/go-backend/internal/common/iamscope/scope.go +212 -0
- package/dist/resources/templates/go-backend/internal/common/iamscope/scope_binding.go +26 -0
- package/dist/resources/templates/go-backend/internal/common/iamscope/scope_filter.go +173 -0
- package/dist/resources/templates/go-backend/internal/common/iamscope/scope_filter_test.go +279 -0
- package/dist/resources/templates/go-backend/internal/common/internalapi/authorization_details.go +10 -0
- package/dist/resources/templates/go-backend/internal/common/internalapi/route_permission_policies.go +660 -0
- package/dist/resources/templates/go-backend/internal/common/internalapi/route_permission_policies_test.go +331 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/audience_token_source.go +166 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/bootstrap_token_exchanger.go +183 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/bound_service_token_signer.go +52 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/delegated_access_token_exchanger.go +189 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/delegated_access_token_exchanger_test.go +159 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/product_scoped_service_token_signer.go +92 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/provider.go +25 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/request_signer.go +86 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/resolver.go +69 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/resolver_test.go +42 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/route_scope.go +95 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/route_scope_test.go +78 -0
- package/dist/resources/templates/go-backend/internal/common/internalservice/service_identity_test.go +387 -0
- package/dist/resources/templates/go-backend/internal/common/jsonschema/compiler.go +100 -0
- package/dist/resources/templates/go-backend/internal/common/jsonschema/compiler_test.go +41 -0
- package/dist/resources/templates/go-backend/internal/common/jwksapi/handler.go +83 -0
- package/dist/resources/templates/go-backend/internal/common/jwksapi/handler_test.go +104 -0
- package/dist/resources/templates/go-backend/internal/common/locale/locale.go +145 -0
- package/dist/resources/templates/go-backend/internal/common/locale/locale_test.go +75 -0
- package/dist/resources/templates/go-backend/internal/common/mediaref/mediaref.go +54 -0
- package/dist/resources/templates/go-backend/internal/common/mediaref/mediaref_test.go +77 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/apikey_auth.go +320 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/apikey_throttle.go +158 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/auth.go +40 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/auth_test.go +50 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/client_context.go +86 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/cors.go +68 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/event_context.go +18 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/gateway_identity.go +279 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/helpers.go +159 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/iam_delegated_route_permission.go +171 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/iam_delegated_token_auth.go +151 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/iam_delegated_token_auth_test.go +99 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/iam_service_identity.go +138 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/iam_service_token_auth.go +74 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/idempotent.go +273 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/idempotent_test.go +83 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/internal_route_permission.go +45 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/internal_route_permission_test.go +186 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/logging.go +191 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/metrics.go +45 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/middleware_test.go +1516 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/principal_context.go +160 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/principal_context_test.go +355 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/product_context.go +100 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/recovery.go +40 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/referral_attribution.go +178 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/requestid.go +48 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/resource_permission.go +790 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/resource_permission_test.go +440 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/service_credential_auth.go +67 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/tenant.go +148 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/throttle.go +310 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/trusted_client_ip.go +23 -0
- package/dist/resources/templates/go-backend/internal/common/middleware/trusted_client_ip_test.go +60 -0
- package/dist/resources/templates/go-backend/internal/common/money/currency.go +25 -0
- package/dist/resources/templates/go-backend/internal/common/money/errors.go +23 -0
- package/dist/resources/templates/go-backend/internal/common/money/format.go +123 -0
- package/dist/resources/templates/go-backend/internal/common/money/format_test.go +204 -0
- package/dist/resources/templates/go-backend/internal/common/money/gateway.go +144 -0
- package/dist/resources/templates/go-backend/internal/common/money/gateway_test.go +165 -0
- package/dist/resources/templates/go-backend/internal/common/money/rounding.go +56 -0
- package/dist/resources/templates/go-backend/internal/common/money/rounding_test.go +51 -0
- package/dist/resources/templates/go-backend/internal/common/principal/context.go +56 -0
- package/dist/resources/templates/go-backend/internal/common/principal/principal.go +49 -0
- package/dist/resources/templates/go-backend/internal/common/productcode/code.go +24 -0
- package/dist/resources/templates/go-backend/internal/common/productcode/code_test.go +35 -0
- package/dist/resources/templates/go-backend/internal/common/providerconfig/schema.go +577 -0
- package/dist/resources/templates/go-backend/internal/common/providerconfig/schema_test.go +47 -0
- package/dist/resources/templates/go-backend/internal/common/requestprivacy/request.go +246 -0
- package/dist/resources/templates/go-backend/internal/common/requestprivacy/request_test.go +170 -0
- package/dist/resources/templates/go-backend/internal/common/response/pagination.go +60 -0
- package/dist/resources/templates/go-backend/internal/common/response/response.go +110 -0
- package/dist/resources/templates/go-backend/internal/common/response/response_test.go +463 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/ast.go +141 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/ast_test.go +81 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/canonical.go +184 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/canonical_test.go +319 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/decoder.go +555 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/decoder_test.go +260 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/errors.go +55 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/evaluator.go +96 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/evaluator_test.go +220 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/fuzz_test.go +116 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/limits.go +331 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/schema.go +412 -0
- package/dist/resources/templates/go-backend/internal/common/ruleexpression/schema_test.go +164 -0
- package/dist/resources/templates/go-backend/internal/common/runtimeinput/runtime_input.go +627 -0
- package/dist/resources/templates/go-backend/internal/common/runtimeinput/runtime_input_test.go +245 -0
- package/dist/resources/templates/go-backend/internal/common/semver/errors.go +6 -0
- package/dist/resources/templates/go-backend/internal/common/semver/semver.go +125 -0
- package/dist/resources/templates/go-backend/internal/common/semver/semver_test.go +205 -0
- package/dist/resources/templates/go-backend/internal/common/serviceidentity/audience.go +48 -0
- package/dist/resources/templates/go-backend/internal/common/serviceidentity/audience_test.go +35 -0
- package/dist/resources/templates/go-backend/internal/common/serviceidentity/resource_identifier.go +33 -0
- package/dist/resources/templates/go-backend/internal/common/serviceidentity/resource_identifier_test.go +32 -0
- package/dist/resources/templates/go-backend/internal/common/tradeno/generator.go +99 -0
- package/dist/resources/templates/go-backend/internal/common/tradeno/generator_test.go +396 -0
- package/dist/resources/templates/go-backend/internal/common/tradeno/prefix.go +247 -0
- package/dist/resources/templates/go-backend/internal/common/types/asset_url.go +11 -0
- package/dist/resources/templates/go-backend/internal/common/types/billing.go +89 -0
- package/dist/resources/templates/go-backend/internal/common/types/billing_test.go +77 -0
- package/dist/resources/templates/go-backend/internal/common/types/country.go +74 -0
- package/dist/resources/templates/go-backend/internal/common/types/country_test.go +28 -0
- package/dist/resources/templates/go-backend/internal/common/types/currency.go +60 -0
- package/dist/resources/templates/go-backend/internal/common/types/identifiers.go +41 -0
- package/dist/resources/templates/go-backend/internal/common/types/operator.go +28 -0
- package/dist/resources/templates/go-backend/internal/common/types/subscription_entitlement.go +24 -0
- package/dist/resources/templates/go-backend/internal/common/types/subscription_entitlement_test.go +35 -0
- package/dist/resources/templates/go-backend/internal/common/types/tier.go +72 -0
- package/dist/resources/templates/go-backend/internal/common/types/types.go +411 -0
- package/dist/resources/templates/go-backend/internal/common/types/types_test.go +295 -0
- package/dist/resources/templates/go-backend/internal/common/utils/constants.go +100 -0
- package/dist/resources/templates/go-backend/internal/common/utils/crypto.go +158 -0
- package/dist/resources/templates/go-backend/internal/common/utils/crypto_test.go +345 -0
- package/dist/resources/templates/go-backend/internal/common/utils/duration.go +25 -0
- package/dist/resources/templates/go-backend/internal/common/utils/helpers.go +18 -0
- package/dist/resources/templates/go-backend/internal/common/utils/json.go +62 -0
- package/dist/resources/templates/go-backend/internal/common/utils/json_test.go +76 -0
- package/dist/resources/templates/go-backend/internal/common/utils/pagination.go +51 -0
- package/dist/resources/templates/go-backend/internal/common/utils/pagination_test.go +45 -0
- package/dist/resources/templates/go-backend/internal/common/utils/pointer.go +107 -0
- package/dist/resources/templates/go-backend/internal/common/utils/pointer_test.go +15 -0
- package/dist/resources/templates/go-backend/internal/common/utils/slice.go +24 -0
- package/dist/resources/templates/go-backend/internal/common/utils/snowflake.go +110 -0
- package/dist/resources/templates/go-backend/internal/common/utils/snowflake_test.go +316 -0
- package/dist/resources/templates/go-backend/internal/common/utils/string.go +16 -0
- package/dist/resources/templates/go-backend/internal/common/utils/timefmt.go +42 -0
- package/dist/resources/templates/go-backend/internal/common/validator/validator.go +136 -0
- package/dist/resources/templates/go-backend/internal/common/validator/validator_test.go +240 -0
- package/dist/resources/templates/go-backend/internal/common/youtubeapi/client.go +224 -0
- package/dist/resources/templates/go-backend/internal/core/apicontract/document.go +269 -0
- package/dist/resources/templates/go-backend/internal/core/apicontract/document_test.go +104 -0
- package/dist/resources/templates/go-backend/internal/core/apicontract/route_validator.go +78 -0
- package/dist/resources/templates/go-backend/internal/core/apicontract/route_validator_test.go +108 -0
- package/dist/resources/templates/go-backend/internal/core/apidocs/assets/scalar-api-reference.js +2385 -0
- package/dist/resources/templates/go-backend/internal/core/apidocs/assets/scalar-api-reference.metadata.json +10 -0
- package/dist/resources/templates/go-backend/internal/core/apidocs/route.go +107 -0
- package/dist/resources/templates/go-backend/internal/core/apidocs/route_test.go +200 -0
- package/dist/resources/templates/go-backend/internal/core/apidocs/scalar.go +117 -0
- package/dist/resources/templates/go-backend/internal/core/apidocs/scalar_test.go +99 -0
- package/dist/resources/templates/go-backend/internal/core/audit/access_log_policy.go +91 -0
- package/dist/resources/templates/go-backend/internal/core/audit/access_log_policy_test.go +51 -0
- package/dist/resources/templates/go-backend/internal/core/audit/actor_resolver.go +36 -0
- package/dist/resources/templates/go-backend/internal/core/audit/constants.go +30 -0
- package/dist/resources/templates/go-backend/internal/core/audit/context.go +119 -0
- package/dist/resources/templates/go-backend/internal/core/audit/context_test.go +310 -0
- package/dist/resources/templates/go-backend/internal/core/audit/dto.go +468 -0
- package/dist/resources/templates/go-backend/internal/core/audit/dto_admin.go +172 -0
- package/dist/resources/templates/go-backend/internal/core/audit/enum.go +460 -0
- package/dist/resources/templates/go-backend/internal/core/audit/enum_test.go +314 -0
- package/dist/resources/templates/go-backend/internal/core/audit/errors.go +9 -0
- package/dist/resources/templates/go-backend/internal/core/audit/handler.go +568 -0
- package/dist/resources/templates/go-backend/internal/core/audit/listener.go +319 -0
- package/dist/resources/templates/go-backend/internal/core/audit/listener_test.go +98 -0
- package/dist/resources/templates/go-backend/internal/core/audit/middleware.go +669 -0
- package/dist/resources/templates/go-backend/internal/core/audit/middleware_test.go +268 -0
- package/dist/resources/templates/go-backend/internal/core/audit/model.go +306 -0
- package/dist/resources/templates/go-backend/internal/core/audit/partition_job.go +316 -0
- package/dist/resources/templates/go-backend/internal/core/audit/ports.go +9 -0
- package/dist/resources/templates/go-backend/internal/core/audit/provider.go +30 -0
- package/dist/resources/templates/go-backend/internal/core/audit/repository.go +1007 -0
- package/dist/resources/templates/go-backend/internal/core/audit/repository_test.go +934 -0
- package/dist/resources/templates/go-backend/internal/core/audit/router.go +85 -0
- package/dist/resources/templates/go-backend/internal/core/audit/service.go +770 -0
- package/dist/resources/templates/go-backend/internal/core/audit/service_test.go +331 -0
- package/dist/resources/templates/go-backend/internal/core/audit/vo_admin.go +475 -0
- package/dist/resources/templates/go-backend/internal/core/cache/config.go +30 -0
- package/dist/resources/templates/go-backend/internal/core/cache/key.go +41 -0
- package/dist/resources/templates/go-backend/internal/core/cache/key_test.go +62 -0
- package/dist/resources/templates/go-backend/internal/core/cache/l1.go +153 -0
- package/dist/resources/templates/go-backend/internal/core/cache/l1_test.go +212 -0
- package/dist/resources/templates/go-backend/internal/core/cache/manager.go +278 -0
- package/dist/resources/templates/go-backend/internal/core/cache/manager_provider.go +24 -0
- package/dist/resources/templates/go-backend/internal/core/cache/metrics.go +126 -0
- package/dist/resources/templates/go-backend/internal/core/cache/namespace.go +46 -0
- package/dist/resources/templates/go-backend/internal/core/cache/namespace_test.go +90 -0
- package/dist/resources/templates/go-backend/internal/core/cache/options.go +39 -0
- package/dist/resources/templates/go-backend/internal/core/cache/options_test.go +96 -0
- package/dist/resources/templates/go-backend/internal/core/cache/redis.go +311 -0
- package/dist/resources/templates/go-backend/internal/core/cache/redis_test.go +51 -0
- package/dist/resources/templates/go-backend/internal/core/cache/serializer.go +31 -0
- package/dist/resources/templates/go-backend/internal/core/cache/serializer_test.go +139 -0
- package/dist/resources/templates/go-backend/internal/core/cache/singleflight.go +53 -0
- package/dist/resources/templates/go-backend/internal/core/cache/singleflight_test.go +211 -0
- package/dist/resources/templates/go-backend/internal/core/cache/warming.go +86 -0
- package/dist/resources/templates/go-backend/internal/core/clock/clock.go +66 -0
- package/dist/resources/templates/go-backend/internal/core/clock/clock_test.go +26 -0
- package/dist/resources/templates/go-backend/internal/core/clock/runtime_clock.go +283 -0
- package/dist/resources/templates/go-backend/internal/core/clock/runtime_clock_test.go +98 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/errors.go +6 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/model.go +90 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/model_test.go +79 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/namespace.go +7 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/persistence.go +269 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/persistence_test.go +185 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/provider.go +9 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/repository.go +22 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/service.go +853 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/service_persistence_test.go +432 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/service_test.go +891 -0
- package/dist/resources/templates/go-backend/internal/core/commandreplay/types.go +121 -0
- package/dist/resources/templates/go-backend/internal/core/config/config.go +2069 -0
- package/dist/resources/templates/go-backend/internal/core/config/config_test.go +1122 -0
- package/dist/resources/templates/go-backend/internal/core/config/contract/contract_test.go +388 -0
- package/dist/resources/templates/go-backend/internal/core/config/contract/docs.go +198 -0
- package/dist/resources/templates/go-backend/internal/core/config/contract/verify.go +424 -0
- package/dist/resources/templates/go-backend/internal/core/config/enum.go +46 -0
- package/dist/resources/templates/go-backend/internal/core/config/metadata.go +717 -0
- package/dist/resources/templates/go-backend/internal/core/config/metadata_test.go +228 -0
- package/dist/resources/templates/go-backend/internal/core/config/product_admin_config_test.go +210 -0
- package/dist/resources/templates/go-backend/internal/core/crypto/aes_gcm.go +111 -0
- package/dist/resources/templates/go-backend/internal/core/crypto/aes_gcm_test.go +364 -0
- package/dist/resources/templates/go-backend/internal/core/crypto/encryptor.go +12 -0
- package/dist/resources/templates/go-backend/internal/core/crypto/envelope_encryptor.go +134 -0
- package/dist/resources/templates/go-backend/internal/core/crypto/envelope_encryptor_test.go +118 -0
- package/dist/resources/templates/go-backend/internal/core/crypto/pem.go +112 -0
- package/dist/resources/templates/go-backend/internal/core/crypto/pem_test.go +44 -0
- package/dist/resources/templates/go-backend/internal/core/crypto/provider.go +130 -0
- package/dist/resources/templates/go-backend/internal/core/crypto/provider_test.go +92 -0
- package/dist/resources/templates/go-backend/internal/core/database/base_model.go +24 -0
- package/dist/resources/templates/go-backend/internal/core/database/clickhouse.go +121 -0
- package/dist/resources/templates/go-backend/internal/core/database/database.go +112 -0
- package/dist/resources/templates/go-backend/internal/core/database/database_logger_test.go +95 -0
- package/dist/resources/templates/go-backend/internal/core/database/errors.go +25 -0
- package/dist/resources/templates/go-backend/internal/core/database/metrics_plugin.go +105 -0
- package/dist/resources/templates/go-backend/internal/core/database/pool_collector.go +71 -0
- package/dist/resources/templates/go-backend/internal/core/database/read_replica.go +520 -0
- package/dist/resources/templates/go-backend/internal/core/database/transaction.go +170 -0
- package/dist/resources/templates/go-backend/internal/core/database/transaction_test.go +282 -0
- package/dist/resources/templates/go-backend/internal/core/distlock/lock.go +353 -0
- package/dist/resources/templates/go-backend/internal/core/distlock/lock_test.go +106 -0
- package/dist/resources/templates/go-backend/internal/core/errors/handler.go +189 -0
- package/dist/resources/templates/go-backend/internal/core/errors/handler_test.go +515 -0
- package/dist/resources/templates/go-backend/internal/core/eventbus/eventbus.go +667 -0
- package/dist/resources/templates/go-backend/internal/core/eventbus/eventbus_test.go +792 -0
- package/dist/resources/templates/go-backend/internal/core/eventstream/noop.go +22 -0
- package/dist/resources/templates/go-backend/internal/core/eventstream/provider.go +20 -0
- package/dist/resources/templates/go-backend/internal/core/eventstream/publisher.go +38 -0
- package/dist/resources/templates/go-backend/internal/core/eventstream/redis.go +109 -0
- package/dist/resources/templates/go-backend/internal/core/eventstream/routing.go +104 -0
- package/dist/resources/templates/go-backend/internal/core/eventstream/routing_test.go +71 -0
- package/dist/resources/templates/go-backend/internal/core/geoip/model.go +19 -0
- package/dist/resources/templates/go-backend/internal/core/geoip/service.go +88 -0
- package/dist/resources/templates/go-backend/internal/core/health/health.go +333 -0
- package/dist/resources/templates/go-backend/internal/core/health/health_test.go +27 -0
- package/dist/resources/templates/go-backend/internal/core/httpclient/client.go +772 -0
- package/dist/resources/templates/go-backend/internal/core/httpclient/client_test.go +287 -0
- package/dist/resources/templates/go-backend/internal/core/httpclient/download.go +578 -0
- package/dist/resources/templates/go-backend/internal/core/httpclient/download_test.go +374 -0
- package/dist/resources/templates/go-backend/internal/core/jwtkeyring/jwk.go +38 -0
- package/dist/resources/templates/go-backend/internal/core/jwtkeyring/keyring.go +144 -0
- package/dist/resources/templates/go-backend/internal/core/jwtkeyring/keyring_test.go +128 -0
- package/dist/resources/templates/go-backend/internal/core/jwtkeyring/registry.go +60 -0
- package/dist/resources/templates/go-backend/internal/core/logger/logger.go +53 -0
- package/dist/resources/templates/go-backend/internal/core/logger/logger_test.go +194 -0
- package/dist/resources/templates/go-backend/internal/core/observability/metrics.go +358 -0
- package/dist/resources/templates/go-backend/internal/core/observability/sentry.go +445 -0
- package/dist/resources/templates/go-backend/internal/core/observability/sentry_privacy_test.go +175 -0
- package/dist/resources/templates/go-backend/internal/core/observability/tracing.go +187 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/model.go +314 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/model_test.go +77 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/persistence.go +51 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/provider.go +23 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/relay.go +1138 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/relay_postgres_test.go +257 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/relay_test.go +690 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/rescheduler.go +164 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/rescheduler_test.go +209 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/writer.go +249 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/writer_postgres_test.go +170 -0
- package/dist/resources/templates/go-backend/internal/core/outbox/writer_test.go +123 -0
- package/dist/resources/templates/go-backend/internal/core/provider.go +198 -0
- package/dist/resources/templates/go-backend/internal/core/queue/metrics_middleware.go +38 -0
- package/dist/resources/templates/go-backend/internal/core/queue/metrics_middleware_test.go +12 -0
- package/dist/resources/templates/go-backend/internal/core/queue/queue.go +288 -0
- package/dist/resources/templates/go-backend/internal/core/queue/queue_test.go +159 -0
- package/dist/resources/templates/go-backend/internal/core/resilience/bulkhead.go +514 -0
- package/dist/resources/templates/go-backend/internal/core/resilience/bulkhead_test.go +984 -0
- package/dist/resources/templates/go-backend/internal/core/resilience/circuitbreaker.go +358 -0
- package/dist/resources/templates/go-backend/internal/core/resilience/circuitbreaker_test.go +788 -0
- package/dist/resources/templates/go-backend/internal/core/resilience/retry.go +318 -0
- package/dist/resources/templates/go-backend/internal/core/resilience/retry_test.go +735 -0
- package/dist/resources/templates/go-backend/internal/core/schedule/recorder.go +305 -0
- package/dist/resources/templates/go-backend/internal/core/schedule/run_context.go +124 -0
- package/dist/resources/templates/go-backend/internal/core/schedule/run_context_test.go +85 -0
- package/dist/resources/templates/go-backend/internal/core/schedule/scheduler.go +1589 -0
- package/dist/resources/templates/go-backend/internal/core/schedule/scheduler_control_test.go +808 -0
- package/dist/resources/templates/go-backend/internal/core/storage/oss_provider.go +398 -0
- package/dist/resources/templates/go-backend/internal/core/storage/oss_provider_test.go +89 -0
- package/dist/resources/templates/go-backend/internal/core/storage/path.go +110 -0
- package/dist/resources/templates/go-backend/internal/core/storage/path_test.go +301 -0
- package/dist/resources/templates/go-backend/internal/core/storage/s3_provider.go +489 -0
- package/dist/resources/templates/go-backend/internal/core/storage/s3_provider_test.go +60 -0
- package/dist/resources/templates/go-backend/internal/core/storage/storage.go +268 -0
- package/dist/resources/templates/go-backend/internal/core/storage/validation.go +225 -0
- package/dist/resources/templates/go-backend/internal/core/storage/validation_test.go +495 -0
- package/dist/resources/templates/go-backend/internal/core/temporal/logger.go +38 -0
- package/dist/resources/templates/go-backend/internal/core/temporal/provider.go +126 -0
- package/dist/resources/templates/go-backend/internal/core/temporal/provider_test.go +67 -0
- package/dist/resources/templates/go-backend/internal/core/websocket/client.go +282 -0
- package/dist/resources/templates/go-backend/internal/core/websocket/client_test.go +81 -0
- package/dist/resources/templates/go-backend/internal/core/websocket/config.go +58 -0
- package/dist/resources/templates/go-backend/internal/core/websocket/handler.go +53 -0
- package/dist/resources/templates/go-backend/internal/core/websocket/hub.go +269 -0
- package/dist/resources/templates/go-backend/internal/core/websocket/message.go +273 -0
- package/dist/resources/templates/go-backend/internal/core/websocket/notifier.go +92 -0
- package/dist/resources/templates/go-backend/internal/core/websocket/provider.go +33 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/action.go +77 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/action_test.go +238 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/condition.go +107 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/decision.go +256 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/enum.go +643 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/errors.go +102 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/principal_record.go +21 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/product_context.go +486 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/resource.go +215 -0
- package/dist/resources/templates/go-backend/internal/integrations/onex/iam/resource_test.go +242 -0
- package/dist/resources/templates/go-backend/internal/products/README.md +5 -0
- package/dist/resources/templates/go-backend/internal/sharedevents/README.md +5 -0
- package/dist/resources/templates/go-backend/migrations/000001_infrastructure.down.sql +13 -0
- package/dist/resources/templates/go-backend/migrations/000001_infrastructure.up.sql +886 -0
- package/dist/resources/templates/go-backend/pkg/apierror/error.go +327 -0
- package/dist/resources/templates/go-backend/pkg/apierror/error_code.go +65 -0
- package/dist/resources/templates/go-backend/pkg/apierror/error_test.go +41 -0
- package/dist/resources/templates/go-backend/pkg/apierror/error_type.go +14 -0
- package/dist/resources/templates/go-backend/pkg/apierror/http_response.go +216 -0
- package/dist/resources/templates/go-backend/pkg/apierror/http_response_test.go +216 -0
- package/dist/resources/templates/go-backend/scripts/check-openapi-clean-deletion.sh +54 -0
- package/dist/resources/templates/go-backend/scripts/test-migrations.sh +32 -0
- package/dist/resources/templates/go-backend/tests/infrastructure.sql +69 -0
- package/dist/resources/templates/mcp-server/.claude/docs/stack.md +338 -0
- package/dist/resources/templates/mcp-server/.editorconfig +13 -0
- package/dist/resources/templates/mcp-server/.env.example +8 -0
- package/dist/resources/templates/mcp-server/.github/ISSUE_TEMPLATE/bug_report.yml +104 -0
- package/dist/resources/templates/mcp-server/.github/ISSUE_TEMPLATE/feature_request.yml +54 -0
- package/dist/resources/templates/mcp-server/.github/PULL_REQUEST_TEMPLATE.md +36 -0
- package/dist/resources/templates/mcp-server/.github/workflows/ci.yml +78 -0
- package/dist/resources/templates/mcp-server/.husky/commit-msg +1 -0
- package/dist/resources/templates/mcp-server/.husky/pre-commit +1 -0
- package/dist/resources/templates/mcp-server/.lintstagedrc.json +4 -0
- package/dist/resources/templates/mcp-server/.nvmrc +1 -0
- package/dist/resources/templates/mcp-server/.prettierrc +8 -0
- package/dist/resources/templates/mcp-server/CONTRIBUTING.md +184 -0
- package/dist/resources/templates/mcp-server/Dockerfile +23 -0
- package/dist/resources/templates/mcp-server/LICENSE +21 -0
- package/dist/resources/templates/mcp-server/README.md +123 -0
- package/dist/resources/templates/mcp-server/_gitignore +26 -0
- package/dist/resources/templates/mcp-server/commitlint.config.js +24 -0
- package/dist/resources/templates/mcp-server/eslint.config.js +30 -0
- package/dist/resources/templates/mcp-server/package.json +72 -0
- package/dist/resources/templates/mcp-server/src/index.ts +27 -0
- package/dist/resources/templates/mcp-server/src/resources.ts +33 -0
- package/dist/resources/templates/mcp-server/src/services/.gitkeep +0 -0
- package/dist/resources/templates/mcp-server/src/tools.ts +43 -0
- package/dist/resources/templates/mcp-server/src/types/index.ts +19 -0
- package/dist/resources/templates/mcp-server/src/utils/index.ts +31 -0
- package/dist/resources/templates/mcp-server/tsconfig.json +22 -0
- package/dist/resources/templates/mcp-server/tsup.config.ts +14 -0
- package/dist/resources/templates/mcp-server/vitest.config.ts +15 -0
- package/dist/resources/templates/nuxt/.claude/docs/stack.md +666 -0
- package/dist/resources/templates/nuxt/.editorconfig +15 -0
- package/dist/resources/templates/nuxt/.env.example +22 -0
- package/dist/resources/templates/nuxt/.github/workflows/ci.yml +34 -0
- package/dist/resources/templates/nuxt/.husky/commit-msg +1 -0
- package/dist/resources/templates/nuxt/.husky/pre-commit +1 -0
- package/dist/resources/templates/nuxt/.nvmrc +1 -0
- package/dist/resources/templates/nuxt/.prettierignore +9 -0
- package/dist/resources/templates/nuxt/.prettierrc +1 -0
- package/dist/resources/templates/nuxt/README.md +23 -0
- package/dist/resources/templates/nuxt/_gitignore +7 -0
- package/dist/resources/templates/nuxt/app/app.config.ts +105 -0
- package/dist/resources/templates/nuxt/app/i18n/locales/en.json +5 -0
- package/dist/resources/templates/nuxt/app/pages/app/index.vue +224 -0
- package/dist/resources/templates/nuxt/app/pages/authors/[slug].vue +37 -0
- package/dist/resources/templates/nuxt/app/pages/blog/[slug].vue +55 -0
- package/dist/resources/templates/nuxt/app/pages/blog/category/[category].vue +38 -0
- package/dist/resources/templates/nuxt/app/pages/blog/index.vue +46 -0
- package/dist/resources/templates/nuxt/app/pages/index.vue +626 -0
- package/dist/resources/templates/nuxt/app/pages/legal/privacy.vue +21 -0
- package/dist/resources/templates/nuxt/app/pages/legal/terms.vue +21 -0
- package/dist/resources/templates/nuxt/app/pages/ui/index.vue +397 -0
- package/dist/resources/templates/nuxt/commitlint.config.mjs +1 -0
- package/dist/resources/templates/nuxt/eslint.config.mjs +4 -0
- package/dist/resources/templates/nuxt/lint-staged.config.mjs +8 -0
- package/dist/resources/templates/nuxt/nuxt.config.ts +71 -0
- package/dist/resources/templates/nuxt/package.json +67 -0
- package/dist/resources/templates/nuxt/public/apple-touch-icon.png +0 -0
- package/dist/resources/templates/nuxt/public/favicon.ico +0 -0
- package/dist/resources/templates/nuxt/public/favicon.svg +5 -0
- package/dist/resources/templates/nuxt/public/icon-16x16.png +0 -0
- package/dist/resources/templates/nuxt/public/icon-192x192.png +0 -0
- package/dist/resources/templates/nuxt/public/icon-32x32.png +0 -0
- package/dist/resources/templates/nuxt/public/icon-512x512.png +0 -0
- package/dist/resources/templates/nuxt/public/logo.svg +6 -0
- package/dist/resources/templates/nuxt/public/media/hero-product-gallery.png +0 -0
- package/dist/resources/templates/nuxt/server/api/content/sitemap-urls.get.ts +12 -0
- package/dist/resources/templates/nuxt/server/api/preview.get.ts +9 -0
- package/dist/resources/templates/nuxt/stylelint.config.mjs +3 -0
- package/dist/resources/templates/nuxt/test/e2e/rendering.test.ts +13 -0
- package/dist/resources/templates/nuxt/tsconfig.json +3 -0
- package/dist/resources/templates/nuxt/vitest.config.ts +8 -0
- package/package.json +8 -5
|
@@ -0,0 +1,666 @@
|
|
|
1
|
+
# Nuxt Application Coding Standard
|
|
2
|
+
|
|
3
|
+
> **Stack**: Nuxt 4.4, Vue 3.5, TypeScript 5.9, Nuxt UI 4, Tailwind CSS 4, Pinia 3, Pinia Colada, VueUse, Nuxt Image, i18n, SEO and Scripts modules.
|
|
4
|
+
> **Composition**: `@stackonward/nuxt-site-shell` extends reusable layers; routes, app configuration and registry-installed source belong to the generated application.
|
|
5
|
+
> Exact versions and executable scripts are controlled by `package.json` and the lockfile.
|
|
6
|
+
|
|
7
|
+
## I. Commands and Environment
|
|
8
|
+
|
|
9
|
+
### Commands
|
|
10
|
+
|
|
11
|
+
| Command | Behavior |
|
|
12
|
+
| ---------------------- | ---------------------------------------------------------------- |
|
|
13
|
+
| `pnpm install` | Resolve dependencies, prepare Nuxt and register repository hooks |
|
|
14
|
+
| `pnpm dev` | Start the Nuxt development server |
|
|
15
|
+
| `pnpm prepare:nuxt` | Regenerate Nuxt framework/types preparation |
|
|
16
|
+
| `pnpm lint` | Run Nuxt-aware code lint and CSS/Vue style lint |
|
|
17
|
+
| `pnpm lint:code:fix` | Fix supported JavaScript, TypeScript and Vue lint findings |
|
|
18
|
+
| `pnpm lint:styles:fix` | Fix supported CSS and Vue-style findings |
|
|
19
|
+
| `pnpm format` | Format application source, tests and root configuration |
|
|
20
|
+
| `pnpm format:check` | Check formatting without writes |
|
|
21
|
+
| `pnpm typecheck` | Run `nuxt typecheck` |
|
|
22
|
+
| `pnpm test` | Run the Nuxt application test suite |
|
|
23
|
+
| `pnpm build` | Build the application and Nitro output |
|
|
24
|
+
| `pnpm check` | Run format, lint, typecheck, test and build gates |
|
|
25
|
+
| `pnpm preview` | Preview the built application |
|
|
26
|
+
|
|
27
|
+
ESLint composes the Nuxt-generated flat configuration with `@stackonward/eslint-config/nuxt`. Stylelint, Prettier and Commitlint load their versioned StackOnward policies through application-owned root configuration. Husky owns clone-local hook registration; lint-staged owns staged-file selection. The full `pnpm check` result is the application gate.
|
|
28
|
+
|
|
29
|
+
### Environment Variables
|
|
30
|
+
|
|
31
|
+
`nuxt.config.ts` owns public runtime mapping; `.env.example` documents available values. Public means readable by browser users.
|
|
32
|
+
|
|
33
|
+
| Variable family | Consumer and meaning |
|
|
34
|
+
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
35
|
+
| `NUXT_PUBLIC_API_BASE_URL`, `NUXT_PUBLIC_API_TIMEOUT` | Public API URL and timeout configuration |
|
|
36
|
+
| `NUXT_PUBLIC_SITE_URL`, `SITE_ENV`, `SITE_NAME`, `SITE_DESCRIPTION` | Canonical site identity and environment under the same prefix |
|
|
37
|
+
| `NUXT_PUBLIC_ANALYTICS_ENABLED`, `ANALYTICS_DEBUG` | Analytics enable/debug configuration |
|
|
38
|
+
| `NUXT_PUBLIC_ANALYTICS_REQUIRE_CONSENT`, `ANALYTICS_PAGE_TRACKING` | Consent requirement and route tracking |
|
|
39
|
+
| `NUXT_PUBLIC_ANALYTICS_DATA_LAYER`, `GA_ID`, `GTM_ID` | Public analytics integration IDs under the same prefix |
|
|
40
|
+
| `NUXT_PUBLIC_GOOGLE_IDENTITY_ENABLED`, `GOOGLE_CLIENT_ID` | Google client-side identity configuration |
|
|
41
|
+
| `NUXT_PUBLIC_GOOGLE_CREDENTIAL_ENDPOINT`, `GOOGLE_ONE_TAP`, `GOOGLE_AUTO_PROMPT` | Configured credential exchange endpoint and prompting options |
|
|
42
|
+
| `NUXT_PUBLIC_CHECKOUT_URL`, `CHECKOUT_RESULT_PARAM` | Checkout destination and return parameter |
|
|
43
|
+
| `NUXT_PUBLIC_YOUTUBE_PRIVACY_ENHANCED` | Video privacy configuration |
|
|
44
|
+
| `NUXT_PUBLIC_OG_IMAGE_ENABLED` | SEO layer option; verify the installed layer consumer before changing behavior |
|
|
45
|
+
|
|
46
|
+
Never place OAuth secrets, service credentials or provider API keys here. An enabled client feature does not prove backend credentials or permission are configured. Validate numeric input at its actual consumer rather than relying on `Number.parseInt` alone.
|
|
47
|
+
|
|
48
|
+
## II. Project Structure and Imports
|
|
49
|
+
|
|
50
|
+
| Owner | Responsibility |
|
|
51
|
+
| --------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
|
52
|
+
| `nuxt.config.ts` | Layer/module composition, public runtime config, imports and icons |
|
|
53
|
+
| `app/app.config.ts` | Brand, theme composition, site navigation and consent copy |
|
|
54
|
+
| `app/pages/` | File-based routes: home, app shell, UI, blog, author and legal views |
|
|
55
|
+
| `app/i18n/locales/en.json` | Application locale content |
|
|
56
|
+
| `server/api/preview.get.ts` | Current preview capability response |
|
|
57
|
+
| `server/api/content/sitemap-urls.get.ts` | Current sitemap URL list |
|
|
58
|
+
| `public/` | Static app-owned icons and media |
|
|
59
|
+
| Registry-installed `app/components`, `app/composables`, theme and CSS | Editable application source delivered by the CLI |
|
|
60
|
+
|
|
61
|
+
The template's preview endpoint currently returns `preview: false` and an inspected path. It is not an authenticated CMS preview session. Sitemap URLs are the current source list, not proof that a content backend exists.
|
|
62
|
+
|
|
63
|
+
### Import Order
|
|
64
|
+
|
|
65
|
+
1. Explicit type imports.
|
|
66
|
+
2. Vue/framework imports where auto-import is not provided.
|
|
67
|
+
3. Public StackOnward package exports.
|
|
68
|
+
4. Installed third-party exports.
|
|
69
|
+
5. Application owners through Nuxt aliases or relative paths.
|
|
70
|
+
|
|
71
|
+
Use `~/` for Nuxt app source and `~~/` for the project root where Nuxt's context requires it. Do not copy OneX Admin `#/` aliases, Vben imports or TanStack Query calls into this Pinia Colada application. Verify auto-import declarations before adding redundant imports or assuming a package symbol is globally available.
|
|
72
|
+
|
|
73
|
+
## III. Pre-edit and Ownership Gate (CRITICAL)
|
|
74
|
+
|
|
75
|
+
Read root rules, this document, the actual page, child/shared components, installed layers, API owner and nearest equivalent page before editing. Inventory visible regions, overlays, slots, form controls, data states and route/context ownership.
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
PRE_PATCH_EVIDENCE:
|
|
79
|
+
- target: route, source design, viewport, identity and selected object
|
|
80
|
+
- source_inventory: page, children, layer, API/configuration and nearest equivalents
|
|
81
|
+
- runtime_inventory: regions, menus, overlays, controls and async states
|
|
82
|
+
- reuse: installed primitive/composable and actual public import
|
|
83
|
+
- verification: typecheck/build scope plus browser and network evidence
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Every new file must have a precise owner. Business fields and protocol types do not belong inline in page templates. Component props/emits stay with the component; API types stay with the API owner; shared types require genuine consumers.
|
|
87
|
+
|
|
88
|
+
### Placement Decision Tree
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
Request/response type? → API/service owner
|
|
92
|
+
Component props/emits? → component
|
|
93
|
+
Pure function without Vue? → feature-local utility, share after reuse is proven
|
|
94
|
+
Reactive reusable state? → composable
|
|
95
|
+
Global client state? → Pinia owner
|
|
96
|
+
Server query cache? → existing Pinia Colada/query owner
|
|
97
|
+
Single page presentation? → page-private component
|
|
98
|
+
Used by multiple pages? → existing shared app component or package
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
File names follow installed conventions: Vue components use descriptive PascalCase, composables `useFeature.ts`, Nuxt pages/routes use filesystem route syntax, and server endpoints include method suffixes such as `.get.ts`. Avoid generic `helper`, `manager`, `new` or caller-branded names.
|
|
102
|
+
|
|
103
|
+
## IV. Forbidden Patterns
|
|
104
|
+
|
|
105
|
+
| ID | Forbidden | Required behavior |
|
|
106
|
+
| ------ | --------------------------------------------------------- | ------------------------------------------------------- |
|
|
107
|
+
| NX-S1 | Hardcoded deployment API origins | Public runtime configuration |
|
|
108
|
+
| NX-S2 | Ad-hoc token storage and credential forwarding | Actual identity adapter/session contract |
|
|
109
|
+
| NX-S3 | Untrusted `v-html` | Escaped text or the declared sanitized-content boundary |
|
|
110
|
+
| NX-S4 | Private secrets in public config or committed env | Private server/process configuration |
|
|
111
|
+
| NX-A1 | Business workflow in page markup | Service/composable owner |
|
|
112
|
+
| NX-A2 | HTTP calls in template event expressions | Typed API action through state coordination |
|
|
113
|
+
| NX-A3 | Module-global mutable SSR state | Request/application-scoped state |
|
|
114
|
+
| NX-A4 | Duplicated API types in views and stores | Canonical API types |
|
|
115
|
+
| NX-A5 | Navigation bypassing configured locale/base-path behavior | Framework navigation and existing route composition |
|
|
116
|
+
| NX-A6 | Undeclared imports or missing public exports | Manifest and export agreement |
|
|
117
|
+
| NX-A7 | Copying Vben table/form/modal adapters | Installed Nuxt UI and app primitives |
|
|
118
|
+
| NX-A8 | Duplicate loading/cache owners for one query | Existing query lifecycle |
|
|
119
|
+
| NX-A9 | Watch/refetch loops for reactive query identity | Declarative reactive key/parameters |
|
|
120
|
+
| NX-A10 | Duplicated pagination shapes across APIs | Shared contract at the actual API boundary |
|
|
121
|
+
| NX-T1 | `any` or unsafe casts used as validation | Concrete types and unknown parsing |
|
|
122
|
+
| NX-T2 | Untyped service results | Typed request/result/error contracts |
|
|
123
|
+
| NX-C1 | Hidden controls treated as authorization | Server-enforced resource policy |
|
|
124
|
+
| NX-C2 | Swallowing remote error into empty success | Preserve safe semantic failure |
|
|
125
|
+
| NX-C3 | Display labels used as machine identifiers | Stable contract codes and localized labels |
|
|
126
|
+
| NX-H1 | Credential/user payload debug logs | Safe diagnostics only |
|
|
127
|
+
| NX-H2 | Dead code, unused imports, deferred handlers | Delete or implement complete behavior |
|
|
128
|
+
| NX-H3 | Per-page hardcoded theme overrides | Existing token/theme owner |
|
|
129
|
+
| NX-H4 | Direct DOM mutation for reactive UI | Vue refs and state |
|
|
130
|
+
| NX-H5 | Global component CSS leaking across routes | Utility classes or scoped owner styles |
|
|
131
|
+
| NX-E1 | Business enum metadata copied into pages | Actual backend metadata/generated contract |
|
|
132
|
+
| NX-E2 | Invented `useEnum` endpoint | Use installed owner and declared contract |
|
|
133
|
+
| NX-M1 | Mixed locale persistence formats | Explicit locale boundary mapping |
|
|
134
|
+
| NX-M2 | Page-local locale lists/fallback policy | Existing i18n owner |
|
|
135
|
+
| NX-P1 | Generic layer branches on a customer/product | Application composition or named adapter |
|
|
136
|
+
| NX-P2 | Registry metadata reconstructed in frontend | Authoritative service contract |
|
|
137
|
+
| NX-P3 | Caller-supplied scope treated as permission | Validate and authorize at backend |
|
|
138
|
+
|
|
139
|
+
## V. API and Result Contracts
|
|
140
|
+
|
|
141
|
+
API adapters own transport formats and safe failures. Components consume typed state and actions. Do not add a parallel fetch client with different token, timeout or error behavior to make one page work.
|
|
142
|
+
|
|
143
|
+
For HTTP services following the shared platform contract:
|
|
144
|
+
|
|
145
|
+
| Operation | Status | Body |
|
|
146
|
+
| --------------- | ------ | --------------------------------------- |
|
|
147
|
+
| Read resource | 200 | Direct resource object |
|
|
148
|
+
| Read collection | 200 | Agreed collection and pagination object |
|
|
149
|
+
| Create | 201 | Created resource |
|
|
150
|
+
| Update | 200 | Updated resource |
|
|
151
|
+
| Delete | 204 | No body |
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"error": {
|
|
156
|
+
"type": "validation_error",
|
|
157
|
+
"code": "invalid_parameters",
|
|
158
|
+
"message": "Request validation failed"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The producer contract remains authoritative. Do not invent `{ code: 200, data: ... }` wrapping or strip collection metadata in a generic interceptor. API request/response types are co-located and exported through existing public entrypoints. A transport generic is not a response validator.
|
|
164
|
+
|
|
165
|
+
✅ Correct: a mutation completes through the API owner, then invalidates affected queries and reports success.
|
|
166
|
+
|
|
167
|
+
❌ Wrong: display success and clear the draft before awaiting the write; catch failures by returning `[]`.
|
|
168
|
+
|
|
169
|
+
## VI. State Management and SSR
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
API/service adapter → typed transport results
|
|
173
|
+
Query composable → server cache, request identity and invalidation
|
|
174
|
+
Pinia store → client preferences/session projection/UI state
|
|
175
|
+
Page/component → local draft and presentation
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Read the installed Pinia Colada integration before selecting query calls. Do not copy TanStack-specific `queryClient` APIs or invent a cache TTL. Keys include all identity, scope and filter values that change the response. Reactive values must remain reactive across composable boundaries.
|
|
179
|
+
|
|
180
|
+
Pinia stores use Composition API style and stable IDs. Identity-owned stores expose meaningful reset behavior; logout clears private state and invalidates in-flight results. Do not put request-specific mutable state at module scope.
|
|
181
|
+
|
|
182
|
+
Browser APIs run only within a client lifecycle. Initial server/client rendering must agree; use deterministic placeholders for browser-only data and hydrate through its owner. Register cleanup for subscriptions, observers, timers and requests.
|
|
183
|
+
|
|
184
|
+
### Complete Scoped Query and Mutation Example
|
|
185
|
+
|
|
186
|
+
The following files form one complete framework example. `ItemService` is an injected, typed application boundary; the caller supplies its real validated API adapter. These examples do not install an `/items` endpoint or pretend a backend exists. A scope key isolates cached identity/resource context; authorization still belongs to the service. The installed `@pinia/colada-nuxt` module exports query composables through Nuxt `#imports`, so consumers do not need an undeclared direct package import.
|
|
187
|
+
|
|
188
|
+
**Contract and key owner — `app/api/items.ts`:**
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
export interface Item {
|
|
192
|
+
id: string;
|
|
193
|
+
name: string;
|
|
194
|
+
}
|
|
195
|
+
export interface ItemFilters {
|
|
196
|
+
keyword: string;
|
|
197
|
+
}
|
|
198
|
+
export interface ItemDraft {
|
|
199
|
+
name: string;
|
|
200
|
+
}
|
|
201
|
+
export interface ItemService {
|
|
202
|
+
list(scope: string, filters: ItemFilters, signal: AbortSignal): Promise<Item[]>;
|
|
203
|
+
detail(scope: string, id: string, signal: AbortSignal): Promise<Item>;
|
|
204
|
+
save(scope: string, id: string | null, draft: ItemDraft, signal: AbortSignal): Promise<Item>;
|
|
205
|
+
}
|
|
206
|
+
export const itemKeys = {
|
|
207
|
+
scope: (scope: string) => ["items", scope] as const,
|
|
208
|
+
lists: (scope: string) => [...itemKeys.scope(scope), "list"] as const,
|
|
209
|
+
list: (scope: string, filters: ItemFilters) =>
|
|
210
|
+
[...itemKeys.lists(scope), filters.keyword] as const,
|
|
211
|
+
detail: (scope: string, id: string) => [...itemKeys.scope(scope), "detail", id] as const,
|
|
212
|
+
};
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Query/mutation owner — `app/composables/useItems.ts`:**
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
import type { MaybeRefOrGetter } from "vue";
|
|
219
|
+
import type { ItemDraft, ItemFilters, ItemService } from "~/api/items";
|
|
220
|
+
import { toValue } from "vue";
|
|
221
|
+
import { useMutation, useQuery, useQueryCache } from "#imports";
|
|
222
|
+
import { itemKeys } from "~/api/items";
|
|
223
|
+
|
|
224
|
+
export function useItemList(
|
|
225
|
+
api: ItemService,
|
|
226
|
+
scope: MaybeRefOrGetter<string>,
|
|
227
|
+
filters: MaybeRefOrGetter<ItemFilters>,
|
|
228
|
+
) {
|
|
229
|
+
return useQuery({
|
|
230
|
+
key: () => itemKeys.list(toValue(scope), toValue(filters)),
|
|
231
|
+
query: ({ signal }) => api.list(toValue(scope), { ...toValue(filters) }, signal),
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function useItemDetail(
|
|
236
|
+
api: ItemService,
|
|
237
|
+
scope: MaybeRefOrGetter<string>,
|
|
238
|
+
id: MaybeRefOrGetter<string>,
|
|
239
|
+
) {
|
|
240
|
+
return useQuery({
|
|
241
|
+
key: () => itemKeys.detail(toValue(scope), toValue(id)),
|
|
242
|
+
query: ({ signal }) => api.detail(toValue(scope), toValue(id), signal),
|
|
243
|
+
enabled: () => toValue(id).length > 0,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
interface SaveItemVariables {
|
|
248
|
+
scope: string;
|
|
249
|
+
id: string | null;
|
|
250
|
+
draft: ItemDraft;
|
|
251
|
+
signal: AbortSignal;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export function useSaveItem(api: ItemService) {
|
|
255
|
+
const cache = useQueryCache();
|
|
256
|
+
const mutation = useMutation({
|
|
257
|
+
mutation: (variables: SaveItemVariables) =>
|
|
258
|
+
api.save(variables.scope, variables.id, variables.draft, variables.signal),
|
|
259
|
+
onSuccess: async (saved, variables) => {
|
|
260
|
+
// 失效作用域的完成结果不能重新写回私有缓存。
|
|
261
|
+
if (variables.signal.aborted) return;
|
|
262
|
+
const detailKey = itemKeys.detail(variables.scope, saved.id);
|
|
263
|
+
// 取消旧详情读取,避免晚到响应覆盖服务端已确认的保存结果。
|
|
264
|
+
cache.cancelQueries({ key: detailKey, exact: true });
|
|
265
|
+
cache.setQueryData(detailKey, saved);
|
|
266
|
+
// 写入已成功;把网络刷新作为独立结果处理,避免误导用户重复提交。
|
|
267
|
+
await cache.invalidateQueries({ key: itemKeys.lists(variables.scope) }, false);
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
function refreshSavedScope(scope: string) {
|
|
272
|
+
return cache.invalidateQueries({ key: itemKeys.lists(scope) });
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return { ...mutation, refreshSavedScope };
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
The function form of `key` retains reactive scope/filter dependencies. `query` captures current values before the asynchronous boundary and forwards the library's abort signal. A detail query is disabled when its required identifier is absent. The save variables retain the submitting scope; a later account change must never invalidate the new account's cache.
|
|
280
|
+
|
|
281
|
+
Before writing the confirmed detail result, cancel the exact detail key in that same submitted scope. Colada `setQueryData` does not clear an older pending read; cancellation clears its pending identity so even a service that ignores abort cannot overwrite the saved value when that read resolves. Do not cancel another scope or unrelated detail queries.
|
|
282
|
+
|
|
283
|
+
✅ Use `useItemList(api, () => props.scope, () => ({ keyword: filters.keyword }))`. A filter or scope change chooses a different key and the query owner handles loading, cache and cancellation.
|
|
284
|
+
|
|
285
|
+
❌ Do not use `useItemList(api, props.scope, { keyword: filters.keyword })` when those values must remain reactive. Do not add a second `watch(..., refetch)` loop or copy the query result into another store.
|
|
286
|
+
|
|
287
|
+
### Complete Composition Store and Scope Reset
|
|
288
|
+
|
|
289
|
+
**Client-state owner — `app/stores/item-filters.ts`:**
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
import { defineStore } from "pinia";
|
|
293
|
+
import { ref } from "vue";
|
|
294
|
+
|
|
295
|
+
export const useItemFiltersStore = defineStore("item-filters", () => {
|
|
296
|
+
const keyword = ref("");
|
|
297
|
+
const selectedId = ref<string | null>(null);
|
|
298
|
+
|
|
299
|
+
function $reset() {
|
|
300
|
+
keyword.value = "";
|
|
301
|
+
selectedId.value = null;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return { keyword, selectedId, $reset };
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
The store owns only shared client preferences/selection. It does not hold a duplicate `items` list or create an immortal query. Its complete reset assigns every state field; `Object.assign(filters, {})` does not remove old properties and is not a reset.
|
|
309
|
+
|
|
310
|
+
For a full identity-scope transition, cancel and remove private cache entries **after switching the active identity/scope**. The following helper runs inside a Nuxt setup/plugin context; its `previousScope` is the authenticated scope being retired, not caller input used for authorization:
|
|
311
|
+
|
|
312
|
+
**Scope lifecycle owner — `app/composables/useItemScopeReset.ts`:**
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
import { useQueryCache } from "#imports";
|
|
316
|
+
import { itemKeys } from "~/api/items";
|
|
317
|
+
import { useItemFiltersStore } from "~/stores/item-filters";
|
|
318
|
+
|
|
319
|
+
export function useItemScopeReset() {
|
|
320
|
+
const cache = useQueryCache();
|
|
321
|
+
const filters = useItemFiltersStore();
|
|
322
|
+
|
|
323
|
+
return (previousScope: string) => {
|
|
324
|
+
cache.cancelQueries({ key: itemKeys.scope(previousScope) });
|
|
325
|
+
for (const entry of cache.getEntries({ key: itemKeys.scope(previousScope) })) {
|
|
326
|
+
cache.remove(entry);
|
|
327
|
+
}
|
|
328
|
+
filters.$reset();
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
An ordinary component unmount must not remove a cache entry shared by other active consumers. Query observer cleanup belongs to Pinia Colada; identity retirement owns private-cache removal. Mutation cancellation remains the submitting component/service owner's responsibility. The examples use the installed Colada `key`, `query`, `mutation`, `useQueryCache` and filter APIs, not TanStack `queryKey`, `queryFn` or `useQueryClient` APIs.
|
|
334
|
+
|
|
335
|
+
## VII. Component and Theme Standards (CRITICAL)
|
|
336
|
+
|
|
337
|
+
Read the installed layer, app theme and existing component before introducing another implementation. Nuxt UI primitives and registry-owned components are the component system; Ant Design/Vben rules are not installed APIs here.
|
|
338
|
+
|
|
339
|
+
| Need | Component responsibility |
|
|
340
|
+
| ------------------ | ---------------------------------------------------------- |
|
|
341
|
+
| Form | Typed validation, labels, field errors and submit state |
|
|
342
|
+
| Table/list | Dataset identity, pagination, stable keys and row actions |
|
|
343
|
+
| Modal/action sheet | Bounded choice or confirmation, focus trapping and restore |
|
|
344
|
+
| Drawer/detail | Owned object context, navigation and editing lifecycle |
|
|
345
|
+
| Tooltip/copy | Accessible description and actual copyable value |
|
|
346
|
+
| Toast/status | Confirmed operation result, not primary error recovery |
|
|
347
|
+
| History | Real ordered events with source metadata |
|
|
348
|
+
| Theme | Central tokens and app configuration |
|
|
349
|
+
|
|
350
|
+
```vue
|
|
351
|
+
<script setup lang="ts">
|
|
352
|
+
interface Props {
|
|
353
|
+
pending: boolean;
|
|
354
|
+
}
|
|
355
|
+
defineProps<Props>();
|
|
356
|
+
const emit = defineEmits<{ submit: [] }>();
|
|
357
|
+
</script>
|
|
358
|
+
|
|
359
|
+
<template>
|
|
360
|
+
<UButton :loading="pending" :disabled="pending" @click="emit('submit')"> Save </UButton>
|
|
361
|
+
</template>
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
✅ The component exposes a typed action and pending state; the caller owns the write.
|
|
365
|
+
|
|
366
|
+
❌ A presentational button creates an HTTP client, chooses credentials and reports success without a server result.
|
|
367
|
+
|
|
368
|
+
Use Tailwind utilities and theme tokens. Scoped CSS is for behavior that utilities cannot express cleanly. Dark/light modes must use the same semantic tokens; never fix one page with a hardcoded light background that breaks dark mode.
|
|
369
|
+
|
|
370
|
+
### Complete Create/Edit Form, Recovery and Close Lifecycle
|
|
371
|
+
|
|
372
|
+
The component below consumes the three owners defined in section VI. It includes a real query-driven list, create/edit entry, typed validation, mutation submission, post-save refresh and failure recovery. All types/functions it imports are defined above or exported by the installed framework. Nuxt UI's `validate` callback avoids adding an uninstalled schema library to this template.
|
|
373
|
+
|
|
374
|
+
**Consumer — `app/components/ItemEditor.vue`:**
|
|
375
|
+
|
|
376
|
+
```vue
|
|
377
|
+
<script setup lang="ts">
|
|
378
|
+
import type { FormError, FormSubmitEvent } from "@nuxt/ui";
|
|
379
|
+
import type { Item, ItemDraft, ItemService } from "~/api/items";
|
|
380
|
+
import { onScopeDispose, reactive, ref, watch } from "vue";
|
|
381
|
+
import { useItemList, useSaveItem } from "~/composables/useItems";
|
|
382
|
+
import { useItemScopeReset } from "~/composables/useItemScopeReset";
|
|
383
|
+
import { useItemFiltersStore } from "~/stores/item-filters";
|
|
384
|
+
|
|
385
|
+
const props = defineProps<{ scope: string; service: ItemService }>();
|
|
386
|
+
const filters = useItemFiltersStore();
|
|
387
|
+
const retireScope = useItemScopeReset();
|
|
388
|
+
const {
|
|
389
|
+
data: items,
|
|
390
|
+
error: listError,
|
|
391
|
+
isLoading: listLoading,
|
|
392
|
+
refetch,
|
|
393
|
+
} = useItemList(
|
|
394
|
+
props.service,
|
|
395
|
+
() => props.scope,
|
|
396
|
+
() => ({ keyword: filters.keyword }),
|
|
397
|
+
);
|
|
398
|
+
const {
|
|
399
|
+
mutateAsync,
|
|
400
|
+
isLoading: saving,
|
|
401
|
+
reset: resetMutation,
|
|
402
|
+
refreshSavedScope,
|
|
403
|
+
} = useSaveItem(props.service);
|
|
404
|
+
const open = ref(false);
|
|
405
|
+
const editingId = ref<string | null>(null);
|
|
406
|
+
const draft = reactive<ItemDraft>({ name: "" });
|
|
407
|
+
const saveError = ref("");
|
|
408
|
+
const resultMessage = ref("");
|
|
409
|
+
let revision = 0;
|
|
410
|
+
let saveController: AbortController | undefined;
|
|
411
|
+
|
|
412
|
+
function validate(values: ItemDraft): FormError[] {
|
|
413
|
+
const name = values.name.trim();
|
|
414
|
+
if (name.length === 0) return [{ name: "name", message: "Enter a name." }];
|
|
415
|
+
if (name.length > 120) return [{ name: "name", message: "Use at most 120 characters." }];
|
|
416
|
+
return [];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function resetDraft() {
|
|
420
|
+
editingId.value = null;
|
|
421
|
+
draft.name = "";
|
|
422
|
+
saveError.value = "";
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function beginEdit(item?: Item) {
|
|
426
|
+
revision += 1;
|
|
427
|
+
resetDraft();
|
|
428
|
+
resetMutation();
|
|
429
|
+
editingId.value = item?.id ?? null;
|
|
430
|
+
draft.name = item?.name ?? "";
|
|
431
|
+
resultMessage.value = "";
|
|
432
|
+
open.value = true;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
function afterClose() {
|
|
436
|
+
// 离场后清理,避免关闭动画中闪现空表单。
|
|
437
|
+
if (!open.value) resetDraft();
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
async function submit(event: FormSubmitEvent<ItemDraft>) {
|
|
441
|
+
const submittedRevision = revision;
|
|
442
|
+
const submittedScope = props.scope;
|
|
443
|
+
const controller = new AbortController();
|
|
444
|
+
saveController = controller;
|
|
445
|
+
saveError.value = "";
|
|
446
|
+
try {
|
|
447
|
+
await mutateAsync({
|
|
448
|
+
scope: submittedScope,
|
|
449
|
+
id: editingId.value,
|
|
450
|
+
draft: { name: event.data.name.trim() },
|
|
451
|
+
signal: controller.signal,
|
|
452
|
+
});
|
|
453
|
+
} catch {
|
|
454
|
+
if (revision === submittedRevision && !controller.signal.aborted) {
|
|
455
|
+
saveError.value = "Unable to save. Your input is preserved; try again.";
|
|
456
|
+
}
|
|
457
|
+
return;
|
|
458
|
+
} finally {
|
|
459
|
+
if (saveController === controller) saveController = undefined;
|
|
460
|
+
}
|
|
461
|
+
if (revision !== submittedRevision || controller.signal.aborted) return;
|
|
462
|
+
open.value = false;
|
|
463
|
+
resultMessage.value = "Saved.";
|
|
464
|
+
try {
|
|
465
|
+
await refreshSavedScope(submittedScope);
|
|
466
|
+
} catch {
|
|
467
|
+
if (revision === submittedRevision) {
|
|
468
|
+
resultMessage.value =
|
|
469
|
+
"Saved, but the list could not refresh. Refresh the list; do not submit again.";
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
watch(
|
|
475
|
+
() => props.scope,
|
|
476
|
+
(_current, previous) => {
|
|
477
|
+
revision += 1;
|
|
478
|
+
saveController?.abort();
|
|
479
|
+
open.value = false;
|
|
480
|
+
resetDraft();
|
|
481
|
+
resultMessage.value = "";
|
|
482
|
+
retireScope(previous);
|
|
483
|
+
},
|
|
484
|
+
{ flush: "sync" },
|
|
485
|
+
);
|
|
486
|
+
|
|
487
|
+
onScopeDispose(() => {
|
|
488
|
+
revision += 1;
|
|
489
|
+
saveController?.abort();
|
|
490
|
+
});
|
|
491
|
+
</script>
|
|
492
|
+
|
|
493
|
+
<template>
|
|
494
|
+
<section class="space-y-4">
|
|
495
|
+
<UFormField label="Search" name="keyword">
|
|
496
|
+
<UInput v-model="filters.keyword" class="w-full" />
|
|
497
|
+
</UFormField>
|
|
498
|
+
<UButton :disabled="saving" @click="beginEdit()">Create</UButton>
|
|
499
|
+
<p v-if="resultMessage" role="status" v-text="resultMessage" />
|
|
500
|
+
<p v-if="listLoading" role="status">Loading…</p>
|
|
501
|
+
<div v-if="listError" role="alert">
|
|
502
|
+
<p>Unable to refresh the list. Previously loaded items remain available.</p>
|
|
503
|
+
<UButton :loading="listLoading" @click="refetch()">Refresh list</UButton>
|
|
504
|
+
</div>
|
|
505
|
+
<p v-if="items && items.length === 0 && !listError">No matching items.</p>
|
|
506
|
+
<ul v-if="items" class="space-y-2">
|
|
507
|
+
<li v-for="item in items" :key="item.id" class="flex items-center gap-3">
|
|
508
|
+
<span class="min-w-0 break-words" v-text="item.name" />
|
|
509
|
+
<UButton :disabled="saving" @click="beginEdit(item)">Edit</UButton>
|
|
510
|
+
</li>
|
|
511
|
+
</ul>
|
|
512
|
+
<UModal
|
|
513
|
+
v-model:open="open"
|
|
514
|
+
:title="editingId ? 'Edit item' : 'Create item'"
|
|
515
|
+
:dismissible="!saving"
|
|
516
|
+
:close="!saving"
|
|
517
|
+
@after:leave="afterClose"
|
|
518
|
+
>
|
|
519
|
+
<template #body>
|
|
520
|
+
<UForm
|
|
521
|
+
:state="draft"
|
|
522
|
+
:validate="validate"
|
|
523
|
+
:disabled="saving"
|
|
524
|
+
class="space-y-4"
|
|
525
|
+
@submit="submit"
|
|
526
|
+
>
|
|
527
|
+
<UFormField label="Name" name="name" required>
|
|
528
|
+
<UInput v-model="draft.name" class="w-full" />
|
|
529
|
+
</UFormField>
|
|
530
|
+
<p v-if="saveError" role="alert" v-text="saveError" />
|
|
531
|
+
<div class="flex justify-end gap-2">
|
|
532
|
+
<UButton color="neutral" variant="outline" :disabled="saving" @click="open = false"
|
|
533
|
+
>Cancel</UButton
|
|
534
|
+
>
|
|
535
|
+
<UButton type="submit" :loading="saving" :disabled="saving">Save</UButton>
|
|
536
|
+
</div>
|
|
537
|
+
</UForm>
|
|
538
|
+
</template>
|
|
539
|
+
</UModal>
|
|
540
|
+
</section>
|
|
541
|
+
</template>
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
The component's `scope` is a validated identity/resource-context key supplied by its parent. The service instance must be request/application-scoped and perform actual authorization. In an application with a global identity coordinator, move `retireScope(previous)` to that single owner rather than repeating account-retirement effects in every editor.
|
|
545
|
+
|
|
546
|
+
The submitting editor blocks normal close/duplicate submit while the write is pending. Account changes and disposal abort local waiting and invalidate the revision, so old errors/results cannot update the new scope. This does not claim that an accepted remote write was rolled back. The API adapter must expose ambiguous acceptance safely instead of automatically replaying a mutation.
|
|
547
|
+
|
|
548
|
+
✅ A failed save leaves the modal open and the draft intact. A successful save closes it, resets draft after the leave transition and refreshes the submitted scope. A refresh failure is reported as **saved but not refreshed**, with a read-only retry; it never invites another create.
|
|
549
|
+
|
|
550
|
+
❌ Do not place write and refresh in one catch that reports both as “save failed”. Do not call `resetDraft()` in a write `finally`, close before awaiting `mutateAsync`, destroy old data on a refresh error, or use `Object.assign(state, {})` as reset.
|
|
551
|
+
|
|
552
|
+
**Acceptance cases for these examples**: change filter while the first query is pending; switch identity while saving; fail validation without invoking the service; fail save and retain typed input; succeed save but fail list refresh; close/reopen and verify cleared errors; dispose while pending; verify another active consumer keeps its shared query cache. Query loading and stale-data states come from Colada, not a second ad-hoc fetch lifecycle.
|
|
553
|
+
|
|
554
|
+
For the late-detail-read case, hold a detail read pending, complete a save, then resolve the older read with stale data even though its signal was aborted. Assert that `cache.getQueryData(itemKeys.detail(submittedScope, saved.id))` still equals `saved`; also assert that a different scope's detail request was not aborted. This proves that saved data survives out-of-order completion without cancelling unrelated consumers.
|
|
555
|
+
|
|
556
|
+
## VIII. Layout and Interaction Rules
|
|
557
|
+
|
|
558
|
+
Each rule applies to the matching UI surface; administrative density and Vben-specific APIs are not imposed on consumer/marketing routes.
|
|
559
|
+
|
|
560
|
+
| ID | Required behavior |
|
|
561
|
+
| ------ | ----------------------------------------------------------------------------------------------------- |
|
|
562
|
+
| NX-U1 | Variable-length columns share width; deterministic values retain appropriate bounds. |
|
|
563
|
+
| NX-U2 | Read component defaults before alignment or sizing overrides. |
|
|
564
|
+
| NX-U3 | Keep alignment coherent with content; numeric and prose semantics differ. |
|
|
565
|
+
| NX-U4 | Preserve required information when fixing width; use responsive layout or scroll. |
|
|
566
|
+
| NX-U5 | Long names, URLs and descriptions must wrap/truncate with usable detail access. |
|
|
567
|
+
| NX-U6 | Fixed-size controls and dates must not consume arbitrary flex space. |
|
|
568
|
+
| NX-U7 | Row actions must not accidentally trigger parent selection/navigation. |
|
|
569
|
+
| NX-U8 | Details use real layout regions, not overlapping absolute panels. |
|
|
570
|
+
| NX-U9 | Equivalent pages reuse the established layout and interaction shape. |
|
|
571
|
+
| NX-U10 | Theme adjustments belong to the token/component owner. |
|
|
572
|
+
| NX-U11 | Primary, secondary and tertiary actions have clear visual hierarchy. |
|
|
573
|
+
| NX-U12 | Labels remain visually closer to their own control than adjacent fields. |
|
|
574
|
+
| NX-U13 | Density follows the user task; consumer pages do not inherit admin compactness blindly. |
|
|
575
|
+
| NX-U14 | Date ranges and multi-field controls keep usable width on narrow screens. |
|
|
576
|
+
| NX-U15 | Choose sheet/modal/drawer by interaction semantics and the accepted design. |
|
|
577
|
+
| NX-U16 | Form controls fill the usable field width and preserve validation space. |
|
|
578
|
+
| NX-U17 | Entity references use searchable real options instead of raw foreign-key entry. |
|
|
579
|
+
| NX-U18 | Ordinary lists load their valid default state before optional refinement. |
|
|
580
|
+
| NX-U19 | Media selection/upload uses the existing unified asset control when available. |
|
|
581
|
+
| NX-U20 | List row density and secondary text follow the accepted consumer design. |
|
|
582
|
+
| NX-U21 | Workbench pane width follows information density, not equal thirds. |
|
|
583
|
+
| NX-U22 | Parent context survives related steps; do not split one workflow into disconnected pages. |
|
|
584
|
+
| NX-U23 | Page chrome communicates actual object/context, not implementation instructions. |
|
|
585
|
+
| NX-U24 | Field help and actionable error states replace decorative warning banners. |
|
|
586
|
+
| NX-U25 | Metrics and badges must inform a real user decision. |
|
|
587
|
+
| NX-U26 | Structured business values use typed controls, not raw JSON as the primary editor. |
|
|
588
|
+
| NX-U27 | Loading states are component state, not fake selectable values. |
|
|
589
|
+
| NX-U28 | References display meaningful identity and real navigation/copy affordances. |
|
|
590
|
+
| NX-U29 | Server-generated identifiers are not mandatory manual form fields. |
|
|
591
|
+
| NX-U30 | Frequent simple edits use the accepted inline interaction; full edits retain their form. |
|
|
592
|
+
| NX-U31 | Table alignment belongs to the actual Nuxt component/theme; no copied Vben center mandate. |
|
|
593
|
+
| NX-U32 | Real identifiers/long values have reusable copy behavior where useful. |
|
|
594
|
+
| NX-U33 | User-facing names use human labels; machine codes remain available for diagnostics. |
|
|
595
|
+
| NX-U34 | Bounded details, history and steps use semantic components rather than forced tables. |
|
|
596
|
+
| NX-U35 | Detail navigation and child section chrome match the accepted design. |
|
|
597
|
+
| NX-U36 | Design verification accounts for every visible region and resolves in-scope gaps. |
|
|
598
|
+
| NX-U37 | Empty values explain the field's absence; absent values are not copyable controls. |
|
|
599
|
+
| NX-U38 | Navigation follows related analytical layers versus heterogeneous sections. |
|
|
600
|
+
| NX-U39 | Prose and long detail values retain natural readable alignment. |
|
|
601
|
+
| NX-U40 | Long pickers/history support their actual paginated or infinite-loading contract. |
|
|
602
|
+
| NX-U41 | Large machine collections offer bounded previews and search, not default tag walls. |
|
|
603
|
+
| NX-U42 | Custom icon/tag content aligns through component layout, not arbitrary offsets. |
|
|
604
|
+
| NX-U43 | Denied writes do not blank readable evidence or unrelated detail sections. |
|
|
605
|
+
| NX-U44 | Parent sections own outer spacing; children own internal gaps. |
|
|
606
|
+
| NX-U45 | Read-only rows retain safe navigation and omit meaningless destructive controls. |
|
|
607
|
+
| NX-U46 | Embedded lists adapt to content/viewport without blank action columns or magic heights. |
|
|
608
|
+
| NX-U47 | Repeated title/action rows use the shared component owner. |
|
|
609
|
+
| NX-U48 | Wide lists keep important actions reachable without deleting data to fit. |
|
|
610
|
+
| NX-U49 | Runtime inventory includes children, slots, teleports and overlays. |
|
|
611
|
+
| NX-U50 | Repeated row actions use one reusable action owner and actual permission state. |
|
|
612
|
+
| NX-U51 | Preserve meaningful accepted steps; do not collapse security/review/relationship decisions. |
|
|
613
|
+
| NX-U52 | Every step owns real state, validation, payload, failure and refresh behavior. |
|
|
614
|
+
| NX-U53 | Remote relationship selection preserves selected summary, unavailable rows and explicit confirmation. |
|
|
615
|
+
| NX-U54 | Equivalent details reuse navigation, field, reference, picker and history primitives. |
|
|
616
|
+
| NX-U55 | History comes from a real event source and updates after relevant mutations. |
|
|
617
|
+
| NX-U56 | Scope/permission explanation uses semantic labels and real references. |
|
|
618
|
+
| NX-U57 | Credential operations need actual backend APIs and one-time-secret handling; no fake buttons. |
|
|
619
|
+
| NX-U58 | Browser evidence covers changed and adjacent states, console and network results. |
|
|
620
|
+
| NX-U59 | Each filter dimension has one primary control owner, not duplicate chips and form inputs. |
|
|
621
|
+
|
|
622
|
+
## IX. Filters, Pagination and Complex Flows
|
|
623
|
+
|
|
624
|
+
A search control must map to a supported API field. Use one keyword control when the producer supports combined search; do not invent server search semantics. Date ranges declare inclusive/exclusive boundaries and timezone. Pagination must use the producer's actual cursor/page contract and preserve total/next information.
|
|
625
|
+
|
|
626
|
+
Remote selection debounces where appropriate, cancels stale work and preserves labels for selected IDs. “Select loaded” means loaded selectable rows; never claim all matching records unless the backend provides that contract.
|
|
627
|
+
|
|
628
|
+
For complex pages, complete these steps before coding:
|
|
629
|
+
|
|
630
|
+
1. State the user's real decision in one sentence.
|
|
631
|
+
2. Draw the resource/dependency chain.
|
|
632
|
+
3. Select list, scoped child, orchestration or layered-detail shape.
|
|
633
|
+
4. Identify parent/child context and propagation.
|
|
634
|
+
5. Allocate width by density and responsive behavior.
|
|
635
|
+
6. Define each region's data contract, permissions and errors.
|
|
636
|
+
7. For computed results such as prices, identify base inputs, overrides and authoritative result.
|
|
637
|
+
8. Verify that every action has a real source, payload, result and refresh target.
|
|
638
|
+
|
|
639
|
+
Draw the layout as boxes before styling; compare it to the accepted design. Do not replace meaningful user steps with an implementation shortcut.
|
|
640
|
+
|
|
641
|
+
## X. Internationalization, Accessibility and Content
|
|
642
|
+
|
|
643
|
+
Use the installed i18n owner for locale lists, fallback and route generation. API locale keys and browser language tags may differ; normalize at the boundary without rewriting backend identifiers. Do not duplicate locale option arrays in pages.
|
|
644
|
+
|
|
645
|
+
Every interactive control needs an accessible name, keyboard operation and visible focus. Dialog close restores focus; error text links to its field. Test both themes and narrow/long-text states.
|
|
646
|
+
|
|
647
|
+
SEO metadata uses the real canonical URL and actual content. Sitemap configuration cannot prove indexability; preview configuration cannot prove authenticated CMS integration. Assets need correct dimensions, alt semantics and legal ownership.
|
|
648
|
+
|
|
649
|
+
## XI. Delivery and References
|
|
650
|
+
|
|
651
|
+
Code comments explain why in Chinese. Exported APIs/composables document non-obvious contracts, lifetime and errors. Delete dead imports and commented code; do not introduce deferred production actions.
|
|
652
|
+
|
|
653
|
+
Read [Architecture](architecture.md), [Security and Lifecycle](security-lifecycle.md), [Verification](verification.md) and the complete [Design Template](architecture-template.md).
|
|
654
|
+
|
|
655
|
+
### Pre-commit Checklist
|
|
656
|
+
|
|
657
|
+
- [ ] Real package versions, aliases and layer exports are used.
|
|
658
|
+
- [ ] API and server-state owners remain separate from presentation.
|
|
659
|
+
- [ ] SSR identity, hydration and disposal behavior are verified.
|
|
660
|
+
- [ ] Private configuration never enters public payloads.
|
|
661
|
+
- [ ] Every visible action maps to a real implementation and error path.
|
|
662
|
+
- [ ] All applicable NX-S/A/T/C/H/E/M/P/U rules are checked.
|
|
663
|
+
- [ ] Design coverage includes children, overlays and loading/empty/error/forbidden states.
|
|
664
|
+
- [ ] `pnpm typecheck` and `pnpm build` pass for code/contract changes.
|
|
665
|
+
- [ ] Browser and network evidence proves the touched interactions.
|
|
666
|
+
- [ ] No uninstalled lint/test/authorization capability is claimed.
|