@stackonward/cli 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +16 -12
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# Payment Gateway Onboarding Playbook
|
|
2
|
+
|
|
3
|
+
> **Upstream scope**: this complete OneX provider playbook applies to work in the upstream payment module. A product backend consumes that platform capability through its authenticated contract; these source paths and provider credentials do not belong to the product repository. Verify the current upstream module and provider contract before executing the playbook.
|
|
4
|
+
|
|
5
|
+
> **目的**:新接入一个支付 provider(card rail 类,非 IAP)从 0 到 production 的完整流程。目标是让 **新 engineer / AI agent 首周独立接第 7 个 provider**,不问现任。
|
|
6
|
+
>
|
|
7
|
+
> **范围**:card-rail HTTP provider(Stripe / PayPal / Airwallex / Payssion / Adyen / Checkout.com / 2Checkout 等)。**不**覆盖 Apple IAP / Google Play(客户端驱动,单独设计)。
|
|
8
|
+
>
|
|
9
|
+
> **最后更新**:2026-08-06(ProviderOperation 命令与资源生命周期契约)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
1. [前置:ops-side 申请 sandbox](#1-前置ops-side-申请-sandbox)
|
|
16
|
+
2. [实现 Go Gateway Builder](#2-实现-go-gateway-builder)
|
|
17
|
+
3. [配置 DB:`p_config_payment_configs` 新增 row](#3-配置-dbp_config_payment_configs-新增-row)
|
|
18
|
+
4. [配置 DB:`p_config_payment_decline_rules` seed](#4-配置-dbp_config_payment_decline_rules-seed)
|
|
19
|
+
5. [Wire DI 注册 Builder](#5-wire-di-注册-builder)
|
|
20
|
+
6. [契约测试 `contract_test.go` 加 provider 分支](#6-契约测试-contract_testgo-加-provider-分支)
|
|
21
|
+
7. [Staging 部署 + 真实小额测试](#7-staging-部署--真实小额测试)
|
|
22
|
+
8. [上线检查清单](#8-上线检查清单)
|
|
23
|
+
9. [已知陷阱](#9-已知陷阱)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 1. 前置:ops-side 申请 sandbox
|
|
28
|
+
|
|
29
|
+
> 本步骤为 **ops 工作**,不计入"30 分钟 code leap"目标。部分 provider 需数天到数周 KYC。
|
|
30
|
+
|
|
31
|
+
| Provider | Sandbox 类型 | 获取路径 | 预计时间 |
|
|
32
|
+
|---------|------------|---------|---------|
|
|
33
|
+
| Stripe | Test Mode(自服务)| dashboard.stripe.com → Developers → API keys → 测试模式 | 5 分钟 |
|
|
34
|
+
| PayPal | Sandbox 账户 | developer.paypal.com → Apps & Credentials → Sandbox | 30 分钟 |
|
|
35
|
+
| Airwallex | 商户申请 | 联系商务 → KYC → Sandbox credential | 1-2 周 |
|
|
36
|
+
| Payssion | 商户申请 | payssion.com → contact | 1 周 |
|
|
37
|
+
| Checkout.com | 自服务 | checkout.com → Signup → Sandbox | 30 分钟 |
|
|
38
|
+
| Adyen | 商户申请 | adyen.com → Get Started → 企业 KYC | 2 周+ |
|
|
39
|
+
|
|
40
|
+
获取到 sandbox 后:
|
|
41
|
+
- 将 secret 加密后插入 `p_config_payment_configs`(见 §3)
|
|
42
|
+
- 将 test key 放入 `.env.dev`(本地)+ CI secret(若启用 live sandbox CI)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 2. 实现 Go Gateway Builder
|
|
47
|
+
|
|
48
|
+
目标目录:`backend/internal/platform/trade/payment/infrastructure/gateway/{provider}/`
|
|
49
|
+
|
|
50
|
+
参考 `stripe/` 的文件结构:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
{provider}/
|
|
54
|
+
gateway.go — provider 私有 HTTP 客户端、Webhook 与查询实现
|
|
55
|
+
provider_operation.go — 实现真实支持的 ProviderOperation capability
|
|
56
|
+
auth.go — provider 鉴权(OAuth token 刷新 / API key 签名)
|
|
57
|
+
api.go — provider REST client(http.Client 封装)
|
|
58
|
+
gateway_test.go — 单点 smoke test(独立于 contract matrix)
|
|
59
|
+
test_clock.go — 若 provider 支持 time-travel(Stripe 独有),实现 SandboxClockGateway
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 2.1 实现基础 `domain.PaymentGateway`
|
|
63
|
+
|
|
64
|
+
```go
|
|
65
|
+
package {provider}
|
|
66
|
+
|
|
67
|
+
import (
|
|
68
|
+
"github.com/onex-platform/backend/internal/platform/trade/payment/domain"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
type Gateway struct {
|
|
72
|
+
logger *zap.Logger
|
|
73
|
+
client *Client
|
|
74
|
+
config domain.GatewayConfig
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Builder 构造 Gateway 实例(registered into ProvideGatewayBuilders map)
|
|
78
|
+
func Builder(deps domain.GatewayBuilderDeps) (domain.PaymentGateway, error) {
|
|
79
|
+
// 解码 config.Secrets → provider-specific credential 结构
|
|
80
|
+
// 构造 Client + Gateway
|
|
81
|
+
// return &Gateway{...}, nil
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
func (g *Gateway) Provider() string { return "{provider}" }
|
|
85
|
+
|
|
86
|
+
func (g *Gateway) VerifyWebhookSignature(rawBody []byte, headers map[string]string) error { ... }
|
|
87
|
+
|
|
88
|
+
func (g *Gateway) ParseWebhookEvent(payload []byte) (*domain.PaymentEvent, error) { ... }
|
|
89
|
+
|
|
90
|
+
func (g *Gateway) CreateRefund(ctx context.Context, req *domain.CreateRefundGatewayRequest) (*domain.RefundGatewayResult, error) { ... }
|
|
91
|
+
|
|
92
|
+
func (g *Gateway) GetPaymentStatus(ctx context.Context, providerPaymentID string) (*domain.PaymentGatewayStatus, error) { ... }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`PaymentGateway` 不表示“可以发起客户在场支付”。每个远端操作都必须通过真实支持的 operation capability 暴露,不得在基础接口中留下返回“不支持”的占位方法。
|
|
96
|
+
|
|
97
|
+
### 2.2 实现 ProviderOperation capability
|
|
98
|
+
|
|
99
|
+
客户在场支付至少实现 `PaymentCreationGateway`;只有 provider 真实存在服务端二阶段确认时才实现 `PaymentConfirmationGateway`:
|
|
100
|
+
|
|
101
|
+
```go
|
|
102
|
+
var _ domain.PaymentCreationGateway = (*Gateway)(nil)
|
|
103
|
+
|
|
104
|
+
func (g *Gateway) CreatePayment(
|
|
105
|
+
ctx context.Context,
|
|
106
|
+
request *domain.ProviderOperationRequest,
|
|
107
|
+
) (*domain.ProviderOperationResult, error) {
|
|
108
|
+
// provider 私有请求映射、幂等键透传和返回事实归一化
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
成功结果必须在 `ProviderOperationResult.Resources` 返回全部真实 `ProviderOperationResource`,并把用户交互所需的短期上下文放入版本化 `ProviderOperationPresentation`。PSP 名词(Stripe Checkout Session、PayPal Order、Airwallex PaymentIntent)只能出现在 adapter 内部与对应的 `ProviderResourceKind` 中。
|
|
113
|
+
|
|
114
|
+
### 2.3 按真实能力实现其他 sub-interface
|
|
115
|
+
|
|
116
|
+
按 provider 实际能力实现:
|
|
117
|
+
|
|
118
|
+
- `CustomerGateway` — 有 customer vault 能力(Stripe Customers / Airwallex Customers)
|
|
119
|
+
- `MerchantInitiatedPaymentGateway` — 支持基于已建立授权的商户发起扣款
|
|
120
|
+
- `HostedSubscriptionGateway` — provider 自己托管 recurring
|
|
121
|
+
- `ProviderResourceQueryGateway` — 能查询已知 PSP 资源
|
|
122
|
+
- `ProviderResourceDiscoveryGateway` — 能按不变商户引用发现创建效果
|
|
123
|
+
- `ProviderResourceLifecycleGateway` — 能取消或撤销已知 PSP 资源
|
|
124
|
+
- `RefundExecutionGateway` — 能对类型化收款资源发起退款
|
|
125
|
+
- `SandboxClockGateway` — provider 支持时钟推进(**仅 Stripe**)
|
|
126
|
+
|
|
127
|
+
> **原则**:不能可靠实现的能力**不要实现**。Resolver 返回 `ok=false`,命令执行器返回类型化的 capability 错误;禁止返回 `nil, nil`。
|
|
128
|
+
|
|
129
|
+
### 2.4 Webhook 解析
|
|
130
|
+
|
|
131
|
+
- `ParseWebhookEvent` 必须返回统一的 `*domain.PaymentEvent` 结构
|
|
132
|
+
- 事件 type 映射参考 `stripe/gateway.go` 的 `mapWebhookEventType()`
|
|
133
|
+
- adapter 必须把每个参与运行时关联的 PSP 对象写入
|
|
134
|
+
`PaymentEvent.ProviderResources`;application 不会从 raw provider ID 或 ID 前缀
|
|
135
|
+
推断资源类型
|
|
136
|
+
- `payment_intent`、`payment_attempt`、`provider_order` 始终归 Payment 所有;只有
|
|
137
|
+
`charge`、`capture` 在写入对应 PaymentTransaction 时转移 owner。Airwallex
|
|
138
|
+
`int_*` 必须声明为 `payment_intent`、`att_*` 声明为 `payment_attempt`;PayPal
|
|
139
|
+
captured payment 必须声明为 `capture`
|
|
140
|
+
- 未知/不处理的事件类型返回 `domain.NewWebhookEventSkippedError(domain.WebhookSkipReasonUnsupportedEventType)`
|
|
141
|
+
|
|
142
|
+
### 2.5 Idempotency Key
|
|
143
|
+
|
|
144
|
+
- 每个 provider mutation 必须使用 `request.ProviderIdempotencyKey`
|
|
145
|
+
- provider 各自的 idempotency 头规范:
|
|
146
|
+
- Stripe: `Idempotency-Key` header
|
|
147
|
+
- PayPal: `PayPal-Request-Id` header
|
|
148
|
+
- Airwallex: `request_id` 请求体字段
|
|
149
|
+
- Payssion: query param `pm_orderid`
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 3. 配置 DB:`p_config_payment_configs` 新增 row
|
|
154
|
+
|
|
155
|
+
通过 migration 或 admin UI(`/commerce/payments/gateways/`)插入:
|
|
156
|
+
|
|
157
|
+
```sql
|
|
158
|
+
INSERT INTO p_config_payment_configs (
|
|
159
|
+
product_code, provider, is_active, is_default,
|
|
160
|
+
secrets_encrypted, metadata
|
|
161
|
+
) VALUES (
|
|
162
|
+
'product_beta', '{provider}', true, false,
|
|
163
|
+
'<ENCRYPTED_JSON>', -- 调 crypto.Encryptor 加密
|
|
164
|
+
'{"environment": "sandbox"}'::jsonb
|
|
165
|
+
);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
- **每个产品** 独立配置(`productCode:provider` 为 cache key)
|
|
169
|
+
- `is_default=true` 至多 1 条/产品,Factory 调 `GetDefaultGateway(productCode)` 时返回它
|
|
170
|
+
- `secrets_encrypted` 通过 `internal/core/crypto.Encryptor.Encrypt(plaintext)` 生成;解密由 Factory 自动完成
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## 4. 配置 DB:`p_config_payment_decline_rules` seed
|
|
175
|
+
|
|
176
|
+
通过新 migration(或运营 admin 的 workflow)seed 该 provider 的 decline 规则:
|
|
177
|
+
|
|
178
|
+
```sql
|
|
179
|
+
INSERT INTO p_config_payment_decline_rules (product_code, provider, raw_code, decline_type, reason_text) VALUES
|
|
180
|
+
('default', '{provider}', '{raw_code_1}', 'hard', 'Friendly message 1'),
|
|
181
|
+
('default', '{provider}', '{raw_code_2}', 'soft', 'Friendly message 2'),
|
|
182
|
+
...
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- `product_code='default'` 是无差异基线;产品差异化按需插入 `product_code=<productCode>` 行(FindRule 会优先匹配精确 product,再 fallback 到 default)
|
|
186
|
+
- `decline_type` 仅 `hard` / `soft`;运营后续可改 `reason_text` 但改不了 `decline_type`
|
|
187
|
+
- 未 seed 的 raw_code 在运行时会触发 `ErrDeclineRuleNotConfigured` → 上层 fail-loud 为 Hard decline 并 alert 运营
|
|
188
|
+
|
|
189
|
+
**最小 seed 集合**:从 provider 官方 decline code 文档提取 **最常见的 20-30 条**(full list 可能有 100+,但头部 20 覆盖 95% 流量)。
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 5. Wire DI 注册 Builder
|
|
194
|
+
|
|
195
|
+
编辑 `backend/internal/platform/trade/payment/provider.go`:
|
|
196
|
+
|
|
197
|
+
```go
|
|
198
|
+
func ProvideGatewayBuilders() map[string]domain.GatewayBuilder {
|
|
199
|
+
return map[string]domain.GatewayBuilder{
|
|
200
|
+
"stripe": stripe.Builder,
|
|
201
|
+
"paypal": paypal.Builder,
|
|
202
|
+
"airwallex": airwallex.Builder,
|
|
203
|
+
"apple_iap": appleiap.Builder,
|
|
204
|
+
"google_play": googleplay.Builder,
|
|
205
|
+
"payssion": payssion.Builder,
|
|
206
|
+
"{provider}": {provider}.Builder, // ← 新增一行
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
然后:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
cd backend
|
|
215
|
+
make wire # 重新生成 wire_gen.go
|
|
216
|
+
go build ./...
|
|
217
|
+
go vet ./...
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 6. 契约测试 `contract_test.go` 加 provider 分支
|
|
223
|
+
|
|
224
|
+
在 `CapabilityMatrix` 中声明该 provider 真实支持的 operation 与可选能力,并增加 builder runner。矩阵会同时验证:
|
|
225
|
+
|
|
226
|
+
- adapter 可由最小合法配置构造;
|
|
227
|
+
- `PaymentCreationGateway` / `PaymentConfirmationGateway` 与真实 PSP 流程一致;
|
|
228
|
+
- 熔断装饰器不会丢失或伪造 capability;
|
|
229
|
+
- IAP 类 provider 不会被误声明为服务端支付创建能力。
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
go test -tags contract -run TestContract ./internal/platform/trade/payment/infrastructure/gateway/...
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## 7. Staging 部署 + 真实小额测试
|
|
238
|
+
|
|
239
|
+
1. 部署到 staging:`make docker-dev` 或既有 CI pipeline
|
|
240
|
+
2. admin 登入 → `/commerce/payments/gateways/` → 确认新 provider row 展示
|
|
241
|
+
3. 通过平台 CheckoutSession API 用 sandbox 支付方式发起真实 checkout:
|
|
242
|
+
- `ProviderCommand` 以 `create_payment` 执行且持久化唯一 PSP resource;
|
|
243
|
+
- PayKit 只消费版本化 `ProviderOperationPresentation`,不探测 provider 字段;
|
|
244
|
+
- 跳转或嵌入式 provider 流程使用 test card 成功;
|
|
245
|
+
- webhook 回调命中 `ParseWebhookEvent` 并与同一 PSP resource 收敛;
|
|
246
|
+
- DB 中 Payment、ProviderResource、ProviderCommand 与资金流水所有者一致。
|
|
247
|
+
4. 测试 refund:调 admin 或 API 发 refund → provider 返回 success → DB 出现 refund row
|
|
248
|
+
5. 测试 decline:用 `4000000000000002`(Stripe 测试 decline card)→ `ClassifyDecline` 命中 seeded rule → 记录 `expired_card` 或 `generic_decline` 决议
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 8. 上线检查清单
|
|
253
|
+
|
|
254
|
+
- [ ] go build ./... 通过
|
|
255
|
+
- [ ] go vet ./... 通过
|
|
256
|
+
- [ ] make wire 重新生成无冲突
|
|
257
|
+
- [ ] migration (`000XXX_payment_config_{provider}.up.sql`) 在 staging 执行成功
|
|
258
|
+
- [ ] decline rules seed 覆盖该 provider 常见 code(最少 20 条)
|
|
259
|
+
- [ ] admin UI 能看到并切换默认 gateway(若需要)
|
|
260
|
+
- [ ] staging 完整 E2E:checkout → pay → webhook → DB truth → refund
|
|
261
|
+
- [ ] `stripe/paypal/airwallex/payssion` 既有 provider 的 E2E 仍绿(零 regression)
|
|
262
|
+
- [ ] Sentry / log 无新错误类型
|
|
263
|
+
- [ ] decline rule 触发 `ErrDeclineRuleNotConfigured` 时告警链路可观测
|
|
264
|
+
- [ ] 本 playbook 结尾的"已知陷阱"对新 provider 无遗漏
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## 9. 已知陷阱
|
|
269
|
+
|
|
270
|
+
| 陷阱 | 避免方式 |
|
|
271
|
+
|------|---------|
|
|
272
|
+
| Provider 返回的 webhook payload schema 升级 | `ParseWebhookEvent` 对未知字段宽容(json.RawMessage),失败时返回 `WebhookEventSkippedError` 而非 panic |
|
|
273
|
+
| Idempotency key 长度超限 | 部分 provider 限制 40/64/255 字符,统一用 `internal/common/idempotency` helper 截断 |
|
|
274
|
+
| Webhook 签名验证的 secret 和 checkout 用的 API key 不同 | provider config 分字段存储 `api_key` vs `webhook_secret` |
|
|
275
|
+
| `decline_type` 分类错误导致金融事故 | 工程锁定字段只能 migration 改;admin UI 对 `decline_type` readonly(enforce in frontend + backend DTO) |
|
|
276
|
+
| Stripe test-mode 有 100 req/s rate limit | 契约测试每 provider 加 `resilience.RateLimiter`(onex 已有),避免 CI 误触发限流 |
|
|
277
|
+
| `productCode:provider` cache 未失效 | admin 改配置后必须调 `Factory.InvalidateCache(productCode)`;见 `p_config_payment_configs` 更新流 |
|
|
278
|
+
| 新 provider decline_type 假设成"soft" fallback | 本 playbook 明确:未 seed 的 raw_code 进入 fail-loud Hard decline,不 fallback,避免过度重试 chargeback |
|
|
279
|
+
| 新 provider 只实现基础 `PaymentGateway` | 客户在场支付必须额外实现 `PaymentCreationGateway`;否则产品政策启动校验失败 |
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
**维护**:本文档随新 provider 接入时追加陷阱;每次 breaking change(如 PaymentGateway 接口新增方法)必须同步更新 §2.1。
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Platform Boundary Standards
|
|
2
|
+
|
|
3
|
+
This document defines the binding responsibility split between OneX platform services, external product BFFs, APISIX, and product frontends.
|
|
4
|
+
|
|
5
|
+
It is a current-state rules document, not a migration guide.
|
|
6
|
+
|
|
7
|
+
## Final Boundary
|
|
8
|
+
|
|
9
|
+
- Identity issuance and session lifecycle belong to `platform-api`.
|
|
10
|
+
- The authenticated viewer projection belongs to `platform-api`.
|
|
11
|
+
- Product business orchestration belongs to the product-owned BFF outside this repository.
|
|
12
|
+
- APISIX performs routing and policy enforcement only.
|
|
13
|
+
- Product-specific naming and presentation mapping belong to the product BFF or frontend, never to OneX platform modules.
|
|
14
|
+
- OneX does not contain product BFF routes, product projections, or product frontend adapters.
|
|
15
|
+
|
|
16
|
+
## Industry Alignment
|
|
17
|
+
|
|
18
|
+
| Decision Point | Industry Pattern | Used By | OneX Choice | Rationale |
|
|
19
|
+
| --- | --- | --- | --- | --- |
|
|
20
|
+
| Login, registration, OAuth, refresh | Centralized identity service | OIDC providers, Auth0, Cognito, Keycloak | `platform-api` owns `/api/v1/auth/*` | Token issuance, revocation, credential linking, and OAuth state machines have one owner. |
|
|
21
|
+
| Post-login bootstrap | Separate authenticated-user read model | OIDC UserInfo, GitHub authenticated-user bootstrap | `GET /api/v1/viewer` | Authentication responses remain security-focused while viewer carries post-auth state. |
|
|
22
|
+
| Subscription identifiers | Raw billing identifiers, presentation mapped outside the billing control plane | Stripe subscriptions and prices | Viewer returns raw `tier_code`, `plan_code`, and `plan_name` | The platform cannot infer product marketing tiers. |
|
|
23
|
+
| Frontend subscription status | Business-facing access state derived from provider lifecycle | Stripe-style access projection | Viewer exposes `active`, `canceled`, or `expired` | Product clients do not couple bootstrap to provider-specific lifecycle detail. |
|
|
24
|
+
| Gateway responsibility | Routing, authentication, rate limiting, and header policy | AWS API Gateway, Kong, APISIX | APISIX routes and enforces edge policy only | Response composition belongs to the application owner. |
|
|
25
|
+
|
|
26
|
+
## Binding Rules
|
|
27
|
+
|
|
28
|
+
### 1. Auth Responses Return Credentials Only
|
|
29
|
+
|
|
30
|
+
Allowed:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"access_token": "...",
|
|
35
|
+
"refresh_token": "...",
|
|
36
|
+
"expires_in": 3600,
|
|
37
|
+
"token_type": "Bearer",
|
|
38
|
+
"is_new_user": false
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Auth responses must not contain credits, subscriptions, product pricing, feature flags, or a second response envelope.
|
|
43
|
+
|
|
44
|
+
Clients authenticate first and then fetch viewer state. Anything beyond credentials belongs outside the authentication VO.
|
|
45
|
+
|
|
46
|
+
### 2. Viewer Is the Authenticated Bootstrap Read Model
|
|
47
|
+
|
|
48
|
+
Route:
|
|
49
|
+
|
|
50
|
+
- `GET /api/v1/viewer?product_code=sample_product`
|
|
51
|
+
|
|
52
|
+
Responsibilities:
|
|
53
|
+
|
|
54
|
+
- return the current user identity projection;
|
|
55
|
+
- return the product-context subscription projection;
|
|
56
|
+
- return the product-context credit summary and buckets;
|
|
57
|
+
- provide one stable bootstrap contract for authenticated product sessions.
|
|
58
|
+
|
|
59
|
+
Forbidden:
|
|
60
|
+
|
|
61
|
+
- client fan-out across user, credit, and subscription endpoints during bootstrap;
|
|
62
|
+
- duplicate viewer aggregation in a product BFF;
|
|
63
|
+
- gateway-side viewer response composition.
|
|
64
|
+
|
|
65
|
+
An external product BFF may proxy this contract through its single public product origin, but it must not redefine or persist the platform projection.
|
|
66
|
+
|
|
67
|
+
### 3. Viewer Subscription Contract Uses Raw Identifiers and Business Status
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"subscription": {
|
|
72
|
+
"tier_code": "premium",
|
|
73
|
+
"plan_id": 301,
|
|
74
|
+
"plan_code": "sample_product_pro_monthly",
|
|
75
|
+
"plan_name": "Sample Product Pro Monthly",
|
|
76
|
+
"status": "canceled",
|
|
77
|
+
"subscription_id": 101,
|
|
78
|
+
"current_period_end": "2026-04-30T10:00:00.000Z",
|
|
79
|
+
"next_renewal_at": "2026-05-01T10:00:00.000Z",
|
|
80
|
+
"cancel_at_period_end": true
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Rules:
|
|
86
|
+
|
|
87
|
+
- `tier_code`, `plan_code`, and `plan_name` are raw platform identifiers.
|
|
88
|
+
- `status` is one of `active`, `canceled`, or `expired`.
|
|
89
|
+
- Raw provider status remains in the subscription domain and subscription APIs.
|
|
90
|
+
- Detailed `system_status` remains in subscription-owned admin and internal contracts.
|
|
91
|
+
- A user without an active paid subscription may have `tier_code="free"` and `status="expired"`.
|
|
92
|
+
|
|
93
|
+
Mapping:
|
|
94
|
+
|
|
95
|
+
- `system_status=active` and `cancel_at_period_end=false` => `active`
|
|
96
|
+
- `system_status=active` and `cancel_at_period_end=true` => `canceled`
|
|
97
|
+
- `system_status=grace_period` => `active`
|
|
98
|
+
- `system_status=suspended` => `canceled`
|
|
99
|
+
- `system_status=expired` => `expired`
|
|
100
|
+
|
|
101
|
+
### 4. Viewer Credit Contract Uses Summary and Buckets
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"credits": {
|
|
106
|
+
"total_available": 1800,
|
|
107
|
+
"total_frozen": 200,
|
|
108
|
+
"unit": "credits",
|
|
109
|
+
"buckets": [
|
|
110
|
+
{
|
|
111
|
+
"grant_type_code": "subscription",
|
|
112
|
+
"available": 1200,
|
|
113
|
+
"unit": "credits"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"grant_type_code": "top_up",
|
|
117
|
+
"available": 500,
|
|
118
|
+
"unit": "credits"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"grant_type_code": "bonus",
|
|
122
|
+
"available": 100,
|
|
123
|
+
"unit": "credits"
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Rules:
|
|
131
|
+
|
|
132
|
+
- totals and buckets are scoped by the requested product context;
|
|
133
|
+
- grant type codes are platform identifiers, not product marketing labels;
|
|
134
|
+
- product clients may localize labels but must preserve the codes.
|
|
135
|
+
|
|
136
|
+
### 5. Contracts Use Platform-Native Semantics
|
|
137
|
+
|
|
138
|
+
Canonical names include:
|
|
139
|
+
|
|
140
|
+
- `display_name`
|
|
141
|
+
- `subscription.tier_code`
|
|
142
|
+
- `subscription.plan_code`
|
|
143
|
+
- `subscription.plan_name`
|
|
144
|
+
- `subscription.status`
|
|
145
|
+
- `credits.total_available`
|
|
146
|
+
- `credits.total_frozen`
|
|
147
|
+
- `credits.buckets[].grant_type_code`
|
|
148
|
+
- `current_period_end`
|
|
149
|
+
- `next_renewal_at`
|
|
150
|
+
|
|
151
|
+
Product-facing copy may map these fields at the product boundary. OneX contracts must not introduce product-specific aliases or legacy response envelopes.
|
|
152
|
+
|
|
153
|
+
### 6. Product BFFs Own Product Workflows, Not Platform Identity
|
|
154
|
+
|
|
155
|
+
External product BFFs may own product workflows, product projections, product feed aggregation, and product-only operational views.
|
|
156
|
+
|
|
157
|
+
They must not own token issuance, credential lifecycle, OAuth state, session revocation, or the canonical viewer projection.
|
|
158
|
+
|
|
159
|
+
| Contract | Owner | Purpose |
|
|
160
|
+
| --- | --- | --- |
|
|
161
|
+
| `/api/v1/auth/*` | `platform-api` | Identity and session lifecycle |
|
|
162
|
+
| `/api/v1/viewer` | `platform-api` | Authenticated bootstrap projection |
|
|
163
|
+
| `/api/v1/users/me` | `platform-api` | Platform user profile |
|
|
164
|
+
| Product business routes | External product BFF | Product workflow and presentation contracts |
|
|
165
|
+
| OneX internal platform routes | Owning OneX platform module | BFF-to-platform capability calls |
|
|
166
|
+
|
|
167
|
+
### 7. Product Frontends Use One Public Product Origin
|
|
168
|
+
|
|
169
|
+
A product frontend configures one product API origin. APISIX may route platform-owned and BFF-owned paths behind that origin, but the frontend must not select infrastructure services by feature.
|
|
170
|
+
|
|
171
|
+
Forbidden:
|
|
172
|
+
|
|
173
|
+
- multiple public base URLs selected by feature;
|
|
174
|
+
- direct coupling to OneX internal routes;
|
|
175
|
+
- client-side re-wrapping of platform responses into legacy envelopes;
|
|
176
|
+
- product label heuristics inside OneX control-plane contracts.
|
|
177
|
+
|
|
178
|
+
### 8. Gateway Does Not Shape Response Objects
|
|
179
|
+
|
|
180
|
+
APISIX owns host and path routing, authentication enforcement, rate limiting, CORS, and header policy.
|
|
181
|
+
|
|
182
|
+
APISIX does not own viewer composition, authentication payload shaping, response envelopes, or product naming translation.
|
|
183
|
+
|
|
184
|
+
## Review Checklist
|
|
185
|
+
|
|
186
|
+
- Does an authentication endpoint return credentials only?
|
|
187
|
+
- Does authenticated bootstrap reuse viewer instead of client fan-out?
|
|
188
|
+
- Does every product workflow remain outside OneX product-neutral modules?
|
|
189
|
+
- Does a new field use platform-native semantics?
|
|
190
|
+
- Does the product frontend use one public product origin?
|
|
191
|
+
- Does the gateway avoid response composition?
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Quality Gate Standard
|
|
2
|
+
|
|
3
|
+
> **Owner scope**: the OneX branch protection, platform governance audit, Admin checks and hook commands below describe the upstream platform gates. Product backend gates are the concrete targets in its own `Makefile`. This full reference does not assert that OneX CI jobs or Admin sources exist in a generated backend.
|
|
4
|
+
|
|
5
|
+
> Mandatory engineering gates for local commits, pull requests, and main-branch protection.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Industry Alignment
|
|
10
|
+
|
|
11
|
+
| Decision Point | Industry Pattern | Used By | Our Choice | Rationale |
|
|
12
|
+
| --- | --- | --- | --- | --- |
|
|
13
|
+
| Main branch protection | Required status checks before merge | GitHub protected branches | Required CI jobs on `main` pull requests | Local hooks can be bypassed; CI is the authoritative merge gate. |
|
|
14
|
+
| Local developer feedback | Git hooks for pre-commit and pre-push checks | Git client hooks | Versioned `.githooks` adapters | Fail fast before code leaves the workstation. |
|
|
15
|
+
| Existing quality debt | Ratcheting baseline | SRE error-budget practice | Block new governance findings against the target branch baseline | Current debt can be burned down incrementally without allowing regressions. |
|
|
16
|
+
| Cross-layer architecture | Dependency direction and package-boundary checks | OpenSSF Scorecard, golangci-lint | `platform-audit` architecture analyzer | Architecture rules must be executable, not only documented. |
|
|
17
|
+
| Database index approval | Query-path-backed index review | PostgreSQL production tuning practice | Every new index must cite owning query path and index rationale | Indexes are write-amplifying storage contracts, not field-existence checkboxes. |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Required Main-Branch Gates
|
|
22
|
+
|
|
23
|
+
Pull requests targeting `main` must pass these required checks:
|
|
24
|
+
|
|
25
|
+
- `Lint`
|
|
26
|
+
- `Backend Governance Gate`
|
|
27
|
+
- `Admin Typecheck`
|
|
28
|
+
- `Build`
|
|
29
|
+
- `Test`
|
|
30
|
+
|
|
31
|
+
Repository branch protection must require the checks above before merge. Direct pushes to `main` are forbidden except for repository administrators performing incident recovery.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Local Hook Gates
|
|
36
|
+
|
|
37
|
+
Versioned hooks live under `.githooks`.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
scripts/install-git-hooks.sh
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The hook contract is:
|
|
44
|
+
|
|
45
|
+
| Hook | Command | Purpose |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| `pre-commit` | `cd backend && make pre-commit` | Static contract checks, migration sequence check, index evidence check, platform governance audit. |
|
|
48
|
+
| `pre-push` | `cd backend && make pre-push` | All pre-commit gates plus `go test ./...`. |
|
|
49
|
+
|
|
50
|
+
Local hooks are advisory acceleration. The CI checks above are the authoritative merge gate.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Governance Ratchet
|
|
55
|
+
|
|
56
|
+
`backend/scripts/governance-gate.sh` compares the generated platform audit report with the target branch report.
|
|
57
|
+
|
|
58
|
+
Rules:
|
|
59
|
+
|
|
60
|
+
1. A pull request may reduce findings.
|
|
61
|
+
2. A pull request may keep the same finding count while changing unrelated code.
|
|
62
|
+
3. A pull request must not increase findings by severity and code.
|
|
63
|
+
4. `backend/internal/platform/datagovernance/auditdata/platform-audit.json` must match the generated report counts.
|
|
64
|
+
5. Once a finding class reaches zero, it must remain zero.
|
|
65
|
+
|
|
66
|
+
The embedded report includes schema, API, write-audit, and architecture findings. Architecture findings cover backend import direction and admin API/query/view ownership boundaries.
|
|
67
|
+
|
|
68
|
+
When all existing findings are eliminated, CI must set:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
GOVERNANCE_STRICT_ZERO=1
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Strict mode rejects any governance finding.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Index Evidence Gate
|
|
79
|
+
|
|
80
|
+
Every new `CREATE INDEX` in migration `000683` and later must carry both comments immediately above the statement:
|
|
81
|
+
|
|
82
|
+
```sql
|
|
83
|
+
-- 查询路径:<owning repository/service path and operation>
|
|
84
|
+
-- 索引理由:<equality filters, range/sort column, uniqueness or investigation path>
|
|
85
|
+
CREATE INDEX ...
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The evidence must name a real business query path. It is invalid to justify an index only because a table contains `product_code`, `deleted_at`, `status`, or another common column.
|
|
89
|
+
|
|
90
|
+
Reviewer checklist:
|
|
91
|
+
|
|
92
|
+
1. Verify the named repository or service actually executes the query.
|
|
93
|
+
2. Verify left-prefix order matches equality filters before range or sort fields.
|
|
94
|
+
3. Verify partial-index predicates match the query predicate exactly.
|
|
95
|
+
4. Verify write amplification is acceptable for the table write volume.
|
|
96
|
+
5. Verify an exact-match runtime dedupe lookup has a matching unique index.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Required Commands
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
cd backend
|
|
104
|
+
make pre-commit
|
|
105
|
+
make pre-push
|
|
106
|
+
make governance-audit
|
|
107
|
+
|
|
108
|
+
cd ../admin
|
|
109
|
+
pnpm run check:type
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
CI runs `bash scripts/governance-gate.sh --mode ci` and must use full git history so the target branch baseline is available.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
APP_ENV=local
|
|
2
|
+
APP_NAME={{projectName}}-api
|
|
3
|
+
APP_HOST=127.0.0.1
|
|
4
|
+
APP_PORT=3100
|
|
5
|
+
DATABASE_HOST=localhost
|
|
6
|
+
DATABASE_PORT=5432
|
|
7
|
+
DATABASE_USERNAME={{projectName}}
|
|
8
|
+
DATABASE_NAME={{projectName}}
|
|
9
|
+
DATABASE_PASSWORD=
|
|
10
|
+
REDIS_HOST=localhost
|
|
11
|
+
REDIS_PORT=6379
|
|
12
|
+
REDIS_PASSWORD=
|
|
13
|
+
DATABASE_URL=
|