@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.
Files changed (638) hide show
  1. package/dist/index.js +4588 -205
  2. package/dist/index.js.map +1 -1
  3. package/dist/resources/apple/.claude/docs/architecture-template.md +54 -0
  4. package/dist/resources/apple/.claude/docs/architecture.md +52 -0
  5. package/dist/resources/apple/.claude/docs/index.md +13 -0
  6. package/dist/resources/apple/.claude/docs/security-lifecycle.md +57 -0
  7. package/dist/resources/apple/.claude/docs/stack.md +93 -0
  8. package/dist/resources/apple/.claude/docs/verification.md +63 -0
  9. package/dist/resources/apple/AGENTS.md +397 -0
  10. package/dist/resources/apple/CLAUDE.md +397 -0
  11. package/dist/resources/apple/Gemfile +2 -0
  12. package/dist/resources/apple/Gemfile.lock +365 -0
  13. package/dist/resources/apple/_gitignore +14 -0
  14. package/dist/resources/apple/fastlane/Fastfile +123 -0
  15. package/dist/resources/components/nuxt/site-source/app/app.vue +42 -0
  16. package/dist/resources/components/nuxt/site-source/app/assets/css/site-shell.css +1035 -0
  17. package/dist/resources/components/nuxt/site-source/app/assets/icons/brand/.gitkeep +0 -0
  18. package/dist/resources/components/nuxt/site-source/app/assets/icons/common/.gitkeep +0 -0
  19. package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationHeader.vue +35 -0
  20. package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationShell.vue +56 -0
  21. package/dist/resources/components/nuxt/site-source/app/components/site/ApplicationSidebar.vue +40 -0
  22. package/dist/resources/components/nuxt/site-source/app/components/site/BackToTop.vue +42 -0
  23. package/dist/resources/components/nuxt/site-source/app/components/site/ContentArticlePage.vue +40 -0
  24. package/dist/resources/components/nuxt/site-source/app/components/site/ContentListPage.vue +30 -0
  25. package/dist/resources/components/nuxt/site-source/app/components/site/CookieConsent.vue +18 -0
  26. package/dist/resources/components/nuxt/site-source/app/components/site/MarketingFooter.vue +52 -0
  27. package/dist/resources/components/nuxt/site-source/app/components/site/MarketingHeader.vue +106 -0
  28. package/dist/resources/components/nuxt/site-source/app/components/site/MarketingShell.vue +35 -0
  29. package/dist/resources/components/nuxt/site-source/app/components/site/SiteBrand.vue +10 -0
  30. package/dist/resources/components/nuxt/site-source/app/components/site/StaticPage.vue +21 -0
  31. package/dist/resources/components/nuxt/site-source/app/components/site/ToastViewport.vue +25 -0
  32. package/dist/resources/components/nuxt/site-source/app/components/ui/BaseButton.vue +86 -0
  33. package/dist/resources/components/nuxt/site-source/app/components/ui/BaseGradientBorder.vue +59 -0
  34. package/dist/resources/components/nuxt/site-source/app/components/ui/BaseModal.vue +131 -0
  35. package/dist/resources/components/nuxt/site-source/app/components/ui/BasePopover.vue +150 -0
  36. package/dist/resources/components/nuxt/site-source/app/components/ui/BaseText.vue +138 -0
  37. package/dist/resources/components/nuxt/site-source/app/components/ui/CheckoutStatus.vue +112 -0
  38. package/dist/resources/components/nuxt/site-source/app/components/ui/CheckoutSummary.vue +172 -0
  39. package/dist/resources/components/nuxt/site-source/app/components/ui/GoogleSignInButton.vue +113 -0
  40. package/dist/resources/components/nuxt/site-source/app/components/ui/InfiniteScroll.vue +123 -0
  41. package/dist/resources/components/nuxt/site-source/app/components/ui/YoutubeEmbed.vue +126 -0
  42. package/dist/resources/components/nuxt/site-source/app/composables/useAnalytics.ts +24 -0
  43. package/dist/resources/components/nuxt/site-source/app/composables/useCheckout.ts +121 -0
  44. package/dist/resources/components/nuxt/site-source/app/composables/useConsent.ts +31 -0
  45. package/dist/resources/components/nuxt/site-source/app/composables/useGoogleIdentity.ts +163 -0
  46. package/dist/resources/components/nuxt/site-source/app/composables/useNavigation.ts +11 -0
  47. package/dist/resources/components/nuxt/site-source/app/composables/useSeo.ts +33 -0
  48. package/dist/resources/components/nuxt/site-source/app/composables/useSiteShell.ts +58 -0
  49. package/dist/resources/components/nuxt/site-source/app/composables/useToasts.ts +48 -0
  50. package/dist/resources/components/nuxt/site-source/app/layouts/app.vue +5 -0
  51. package/dist/resources/components/nuxt/site-source/app/layouts/default.vue +5 -0
  52. package/dist/resources/components/nuxt/site-source/app/plugins/analytics.client.ts +121 -0
  53. package/dist/resources/components/nuxt/site-source/app/plugins/google-identity.client.ts +24 -0
  54. package/dist/resources/components/nuxt/site-source/app/theme/accordion.ts +9 -0
  55. package/dist/resources/components/nuxt/site-source/app/theme/breadcrumb.ts +8 -0
  56. package/dist/resources/components/nuxt/site-source/app/theme/button.ts +92 -0
  57. package/dist/resources/components/nuxt/site-source/app/theme/carousel.ts +11 -0
  58. package/dist/resources/components/nuxt/site-source/app/theme/checkbox.ts +12 -0
  59. package/dist/resources/components/nuxt/site-source/app/theme/index.ts +30 -0
  60. package/dist/resources/components/nuxt/site-source/app/theme/input.ts +47 -0
  61. package/dist/resources/components/nuxt/site-source/app/theme/modal.ts +9 -0
  62. package/dist/resources/components/nuxt/site-source/app/theme/pagination.ts +6 -0
  63. package/dist/resources/components/nuxt/site-source/app/theme/select.ts +23 -0
  64. package/dist/resources/components/nuxt/site-source/app/theme/stepper.ts +10 -0
  65. package/dist/resources/components/nuxt/site-source/app/theme/toast.ts +8 -0
  66. package/dist/resources/components/nuxt/site-source/app/theme/tooltip.ts +6 -0
  67. package/dist/resources/components/nuxt/site-source/app/types/site-shell.ts +85 -0
  68. package/dist/resources/components/react/ui/Button.tsx +73 -0
  69. package/dist/resources/components/react/ui/Input.tsx +44 -0
  70. package/dist/resources/components/registry.json +355 -0
  71. package/dist/resources/components/vue/feedback/Toast.vue +120 -0
  72. package/dist/resources/components/vue/feedback/useToast.ts +70 -0
  73. package/dist/resources/components/vue/media/FileUpload.vue +229 -0
  74. package/dist/resources/components/vue/media/VideoPlayer.vue +157 -0
  75. package/dist/resources/components/vue/ui/AppImage.vue +147 -0
  76. package/dist/resources/components/vue/ui/BottomSheet.vue +217 -0
  77. package/dist/resources/components/vue/ui/Button.vue +154 -0
  78. package/dist/resources/components/vue/ui/Card.vue +111 -0
  79. package/dist/resources/components/vue/ui/Input.vue +113 -0
  80. package/dist/resources/components/vue/ui/Modal.vue +193 -0
  81. package/dist/resources/components/vue/ui/ScrollArea.vue +163 -0
  82. package/dist/resources/components/vue/ui/Tooltip.vue +115 -0
  83. package/dist/resources/registry.json +158 -0
  84. package/dist/resources/snippets/node/cache.ts +116 -0
  85. package/dist/resources/snippets/node/date.ts +126 -0
  86. package/dist/resources/snippets/node/logger.ts +104 -0
  87. package/dist/resources/snippets/node/validation.ts +132 -0
  88. package/dist/resources/snippets/react/useDebounce.ts +90 -0
  89. package/dist/resources/snippets/registry.json +65 -0
  90. package/dist/resources/snippets/vue/useAsync.ts +96 -0
  91. package/dist/resources/snippets/vue/usePagination.ts +102 -0
  92. package/dist/resources/templates/base/.claude/docs/architecture-template.md +459 -0
  93. package/dist/resources/templates/base/.claude/docs/architecture.md +137 -0
  94. package/dist/resources/templates/base/.claude/docs/index.md +42 -0
  95. package/dist/resources/templates/base/.claude/docs/security-lifecycle.md +129 -0
  96. package/dist/resources/templates/base/.claude/docs/verification.md +121 -0
  97. package/dist/resources/templates/base/AGENTS.md +415 -0
  98. package/dist/resources/templates/base/CLAUDE.md +415 -0
  99. package/dist/resources/templates/go-backend/.claude/docs/api-design.md +486 -0
  100. package/dist/resources/templates/go-backend/.claude/docs/architecture-template.md +449 -0
  101. package/dist/resources/templates/go-backend/.claude/docs/check-list.md +155 -0
  102. package/dist/resources/templates/go-backend/.claude/docs/database.md +369 -0
  103. package/dist/resources/templates/go-backend/.claude/docs/e2e-standards.md +161 -0
  104. package/dist/resources/templates/go-backend/.claude/docs/error-handling.md +558 -0
  105. package/dist/resources/templates/go-backend/.claude/docs/event-runtime-boundary.md +124 -0
  106. package/dist/resources/templates/go-backend/.claude/docs/identifier-contract.md +195 -0
  107. package/dist/resources/templates/go-backend/.claude/docs/index.md +22 -0
  108. package/dist/resources/templates/go-backend/.claude/docs/logging.md +314 -0
  109. package/dist/resources/templates/go-backend/.claude/docs/mediagen-provider-onboarding-sop.md +917 -0
  110. package/dist/resources/templates/go-backend/.claude/docs/mediagen-provider-quick-reference.md +195 -0
  111. package/dist/resources/templates/go-backend/.claude/docs/module-standards.md +309 -0
  112. package/dist/resources/templates/go-backend/.claude/docs/openapi-contract.md +141 -0
  113. package/dist/resources/templates/go-backend/.claude/docs/payment-gateway-onboarding.md +283 -0
  114. package/dist/resources/templates/go-backend/.claude/docs/platform-boundary.md +191 -0
  115. package/dist/resources/templates/go-backend/.claude/docs/quality-gates.md +112 -0
  116. package/dist/resources/templates/go-backend/.dockerignore +6 -0
  117. package/dist/resources/templates/go-backend/.env.example +13 -0
  118. package/dist/resources/templates/go-backend/.gitattributes +2 -0
  119. package/dist/resources/templates/go-backend/AGENTS.md +1139 -0
  120. package/dist/resources/templates/go-backend/CLAUDE.md +1139 -0
  121. package/dist/resources/templates/go-backend/Dockerfile +14 -0
  122. package/dist/resources/templates/go-backend/Makefile +71 -0
  123. package/dist/resources/templates/go-backend/README.md +66 -0
  124. package/dist/resources/templates/go-backend/_gitignore +10 -0
  125. package/dist/resources/templates/go-backend/api/openapi/README.md +29 -0
  126. package/dist/resources/templates/go-backend/api/openapi/dist/artifact-manifest.json +19 -0
  127. package/dist/resources/templates/go-backend/api/openapi/dist/conformance-matrix.json +276 -0
  128. package/dist/resources/templates/go-backend/api/openapi/document.go +30 -0
  129. package/dist/resources/templates/go-backend/api/openapi/package.json +28 -0
  130. package/dist/resources/templates/go-backend/api/openapi/pnpm-lock.yaml +3052 -0
  131. package/dist/resources/templates/go-backend/api/openapi/redocly-source.yaml +18 -0
  132. package/dist/resources/templates/go-backend/api/openapi/redocly.yaml +8 -0
  133. package/dist/resources/templates/go-backend/api/openapi/sdk-generators.json +16 -0
  134. package/dist/resources/templates/go-backend/api/openapi/service-registry.json +39 -0
  135. package/dist/resources/templates/go-backend/api/openapi/services/product-api/conformance/runtime.arazzo.yaml +65 -0
  136. package/dist/resources/templates/go-backend/api/openapi/services/product-api/dist/internal.openapi.json +327 -0
  137. package/dist/resources/templates/go-backend/api/openapi/services/product-api/dist/runtime-contract.json +56 -0
  138. package/dist/resources/templates/go-backend/api/openapi/services/product-api/openapi.yaml +222 -0
  139. package/dist/resources/templates/go-backend/api/openapi/services/worker/conformance/runtime.arazzo.yaml +65 -0
  140. package/dist/resources/templates/go-backend/api/openapi/services/worker/dist/internal.openapi.json +327 -0
  141. package/dist/resources/templates/go-backend/api/openapi/services/worker/dist/runtime-contract.json +56 -0
  142. package/dist/resources/templates/go-backend/api/openapi/services/worker/openapi.yaml +222 -0
  143. package/dist/resources/templates/go-backend/api/openapi/tooling/breaking.mjs +416 -0
  144. package/dist/resources/templates/go-backend/api/openapi/tooling/build.mjs +103 -0
  145. package/dist/resources/templates/go-backend/api/openapi/tooling/conformance_coverage.mjs +111 -0
  146. package/dist/resources/templates/go-backend/api/openapi/tooling/contract_compiler.mjs +62 -0
  147. package/dist/resources/templates/go-backend/api/openapi/tooling/contract_policy.mjs +208 -0
  148. package/dist/resources/templates/go-backend/api/openapi/tooling/delegated_contract.mjs +302 -0
  149. package/dist/resources/templates/go-backend/api/openapi/tooling/deterministic_archive.mjs +69 -0
  150. package/dist/resources/templates/go-backend/api/openapi/tooling/documentation_example_privacy.mjs +93 -0
  151. package/dist/resources/templates/go-backend/api/openapi/tooling/documentation_projection.mjs +498 -0
  152. package/dist/resources/templates/go-backend/api/openapi/tooling/documentation_quality.mjs +346 -0
  153. package/dist/resources/templates/go-backend/api/openapi/tooling/git_artifact_history.mjs +188 -0
  154. package/dist/resources/templates/go-backend/api/openapi/tooling/manifest.mjs +170 -0
  155. package/dist/resources/templates/go-backend/api/openapi/tooling/overlay.mjs +98 -0
  156. package/dist/resources/templates/go-backend/api/openapi/tooling/project.mjs +549 -0
  157. package/dist/resources/templates/go-backend/api/openapi/tooling/route_contract.mjs +156 -0
  158. package/dist/resources/templates/go-backend/api/openapi/tooling/runtime_conformance.mjs +193 -0
  159. package/dist/resources/templates/go-backend/api/openapi/tooling/scalar_asset_localization.mjs +164 -0
  160. package/dist/resources/templates/go-backend/api/openapi/tooling/sdk_generator.mjs +229 -0
  161. package/dist/resources/templates/go-backend/api/openapi/tooling/semantic_version.mjs +64 -0
  162. package/dist/resources/templates/go-backend/api/openapi/tooling/service_contract_inputs.mjs +16 -0
  163. package/dist/resources/templates/go-backend/api/openapi/tooling/test/breaking.test.mjs +365 -0
  164. package/dist/resources/templates/go-backend/api/openapi/tooling/test/build.test.mjs +42 -0
  165. package/dist/resources/templates/go-backend/api/openapi/tooling/test/conformance_coverage.test.mjs +88 -0
  166. package/dist/resources/templates/go-backend/api/openapi/tooling/test/contract_policy.test.mjs +257 -0
  167. package/dist/resources/templates/go-backend/api/openapi/tooling/test/delegated_contract.test.mjs +205 -0
  168. package/dist/resources/templates/go-backend/api/openapi/tooling/test/documentation_example_privacy.test.mjs +51 -0
  169. package/dist/resources/templates/go-backend/api/openapi/tooling/test/documentation_projection.test.mjs +368 -0
  170. package/dist/resources/templates/go-backend/api/openapi/tooling/test/documentation_quality.test.mjs +151 -0
  171. package/dist/resources/templates/go-backend/api/openapi/tooling/test/git_artifact_history.test.mjs +60 -0
  172. package/dist/resources/templates/go-backend/api/openapi/tooling/test/head_policy.test.mjs +8 -0
  173. package/dist/resources/templates/go-backend/api/openapi/tooling/test/overlay.test.mjs +44 -0
  174. package/dist/resources/templates/go-backend/api/openapi/tooling/test/projection.test.mjs +270 -0
  175. package/dist/resources/templates/go-backend/api/openapi/tooling/test/redocly_documentation_rules.test.mjs +146 -0
  176. package/dist/resources/templates/go-backend/api/openapi/tooling/test/release_manifest.test.mjs +76 -0
  177. package/dist/resources/templates/go-backend/api/openapi/tooling/test/route_contract.test.mjs +119 -0
  178. package/dist/resources/templates/go-backend/api/openapi/tooling/test/runtime_conformance.test.mjs +75 -0
  179. package/dist/resources/templates/go-backend/api/openapi/tooling/test/scalar_asset_localization.test.mjs +50 -0
  180. package/dist/resources/templates/go-backend/api/openapi/tooling/test/sdk_generator.test.mjs +31 -0
  181. package/dist/resources/templates/go-backend/api/openapi/tooling/test/semantic_version.test.mjs +60 -0
  182. package/dist/resources/templates/go-backend/api/openapi/tooling/test/service_contract_inputs.test.mjs +27 -0
  183. package/dist/resources/templates/go-backend/cmd/internal/runtime/resources.go +125 -0
  184. package/dist/resources/templates/go-backend/cmd/internal/runtime/runtime.go +102 -0
  185. package/dist/resources/templates/go-backend/cmd/internal/runtime/runtime_test.go +70 -0
  186. package/dist/resources/templates/go-backend/cmd/product-api/lifecycle_test.go +58 -0
  187. package/dist/resources/templates/go-backend/cmd/product-api/main.go +32 -0
  188. package/dist/resources/templates/go-backend/cmd/product-api/wire.go +13 -0
  189. package/dist/resources/templates/go-backend/cmd/product-api/wire_gen.go +94 -0
  190. package/dist/resources/templates/go-backend/cmd/worker/main.go +47 -0
  191. package/dist/resources/templates/go-backend/cmd/worker/wire.go +14 -0
  192. package/dist/resources/templates/go-backend/cmd/worker/wire_gen.go +111 -0
  193. package/dist/resources/templates/go-backend/configs/config.yaml +37 -0
  194. package/dist/resources/templates/go-backend/deployments/compose.yaml +71 -0
  195. package/dist/resources/templates/go-backend/docs/openapi-provenance.json +489 -0
  196. package/dist/resources/templates/go-backend/docs/runtime-provenance.json +175 -0
  197. package/dist/resources/templates/go-backend/docs/source-provenance.json +3568 -0
  198. package/dist/resources/templates/go-backend/docs/standards-provenance.json +1624 -0
  199. package/dist/resources/templates/go-backend/go.mod +256 -0
  200. package/dist/resources/templates/go-backend/go.sum +805 -0
  201. package/dist/resources/templates/go-backend/internal/common/canonicaljson/canonical.go +370 -0
  202. package/dist/resources/templates/go-backend/internal/common/canonicaljson/canonical_test.go +223 -0
  203. package/dist/resources/templates/go-backend/internal/common/checkoutbff/contracts.go +125 -0
  204. package/dist/resources/templates/go-backend/internal/common/checkoutbff/platform_client.go +212 -0
  205. package/dist/resources/templates/go-backend/internal/common/checkoutbff/platform_client_test.go +319 -0
  206. package/dist/resources/templates/go-backend/internal/common/contentaccess/contentaccess.go +50 -0
  207. package/dist/resources/templates/go-backend/internal/common/contracts/contact.go +85 -0
  208. package/dist/resources/templates/go-backend/internal/common/ctxutil/identity.go +20 -0
  209. package/dist/resources/templates/go-backend/internal/common/ctxutil/product.go +53 -0
  210. package/dist/resources/templates/go-backend/internal/common/enumdomain/payment.go +12 -0
  211. package/dist/resources/templates/go-backend/internal/common/enums/dto_admin.go +9 -0
  212. package/dist/resources/templates/go-backend/internal/common/enums/enum.go +1247 -0
  213. package/dist/resources/templates/go-backend/internal/common/enums/handler_admin.go +66 -0
  214. package/dist/resources/templates/go-backend/internal/common/enums/module.go +46 -0
  215. package/dist/resources/templates/go-backend/internal/common/enums/provider.go +10 -0
  216. package/dist/resources/templates/go-backend/internal/common/enums/register.go +11 -0
  217. package/dist/resources/templates/go-backend/internal/common/enums/register_audit.go +274 -0
  218. package/dist/resources/templates/go-backend/internal/common/enums/register_command_replay.go +12 -0
  219. package/dist/resources/templates/go-backend/internal/common/enums/register_config.go +27 -0
  220. package/dist/resources/templates/go-backend/internal/common/enums/register_locale.go +37 -0
  221. package/dist/resources/templates/go-backend/internal/common/enums/register_ops.go +14 -0
  222. package/dist/resources/templates/go-backend/internal/common/enums/register_outbox.go +15 -0
  223. package/dist/resources/templates/go-backend/internal/common/enums/register_rule_expression.go +63 -0
  224. package/dist/resources/templates/go-backend/internal/common/enums/registry.go +77 -0
  225. package/dist/resources/templates/go-backend/internal/common/httporigin/origin.go +62 -0
  226. package/dist/resources/templates/go-backend/internal/common/httporigin/origin_test.go +38 -0
  227. package/dist/resources/templates/go-backend/internal/common/iamcredential/plaintext.go +35 -0
  228. package/dist/resources/templates/go-backend/internal/common/iamcredential/plaintext_test.go +29 -0
  229. package/dist/resources/templates/go-backend/internal/common/iamscope/scope.go +212 -0
  230. package/dist/resources/templates/go-backend/internal/common/iamscope/scope_binding.go +26 -0
  231. package/dist/resources/templates/go-backend/internal/common/iamscope/scope_filter.go +173 -0
  232. package/dist/resources/templates/go-backend/internal/common/iamscope/scope_filter_test.go +279 -0
  233. package/dist/resources/templates/go-backend/internal/common/internalapi/authorization_details.go +10 -0
  234. package/dist/resources/templates/go-backend/internal/common/internalapi/route_permission_policies.go +660 -0
  235. package/dist/resources/templates/go-backend/internal/common/internalapi/route_permission_policies_test.go +331 -0
  236. package/dist/resources/templates/go-backend/internal/common/internalservice/audience_token_source.go +166 -0
  237. package/dist/resources/templates/go-backend/internal/common/internalservice/bootstrap_token_exchanger.go +183 -0
  238. package/dist/resources/templates/go-backend/internal/common/internalservice/bound_service_token_signer.go +52 -0
  239. package/dist/resources/templates/go-backend/internal/common/internalservice/delegated_access_token_exchanger.go +189 -0
  240. package/dist/resources/templates/go-backend/internal/common/internalservice/delegated_access_token_exchanger_test.go +159 -0
  241. package/dist/resources/templates/go-backend/internal/common/internalservice/product_scoped_service_token_signer.go +92 -0
  242. package/dist/resources/templates/go-backend/internal/common/internalservice/provider.go +25 -0
  243. package/dist/resources/templates/go-backend/internal/common/internalservice/request_signer.go +86 -0
  244. package/dist/resources/templates/go-backend/internal/common/internalservice/resolver.go +69 -0
  245. package/dist/resources/templates/go-backend/internal/common/internalservice/resolver_test.go +42 -0
  246. package/dist/resources/templates/go-backend/internal/common/internalservice/route_scope.go +95 -0
  247. package/dist/resources/templates/go-backend/internal/common/internalservice/route_scope_test.go +78 -0
  248. package/dist/resources/templates/go-backend/internal/common/internalservice/service_identity_test.go +387 -0
  249. package/dist/resources/templates/go-backend/internal/common/jsonschema/compiler.go +100 -0
  250. package/dist/resources/templates/go-backend/internal/common/jsonschema/compiler_test.go +41 -0
  251. package/dist/resources/templates/go-backend/internal/common/jwksapi/handler.go +83 -0
  252. package/dist/resources/templates/go-backend/internal/common/jwksapi/handler_test.go +104 -0
  253. package/dist/resources/templates/go-backend/internal/common/locale/locale.go +145 -0
  254. package/dist/resources/templates/go-backend/internal/common/locale/locale_test.go +75 -0
  255. package/dist/resources/templates/go-backend/internal/common/mediaref/mediaref.go +54 -0
  256. package/dist/resources/templates/go-backend/internal/common/mediaref/mediaref_test.go +77 -0
  257. package/dist/resources/templates/go-backend/internal/common/middleware/apikey_auth.go +320 -0
  258. package/dist/resources/templates/go-backend/internal/common/middleware/apikey_throttle.go +158 -0
  259. package/dist/resources/templates/go-backend/internal/common/middleware/auth.go +40 -0
  260. package/dist/resources/templates/go-backend/internal/common/middleware/auth_test.go +50 -0
  261. package/dist/resources/templates/go-backend/internal/common/middleware/client_context.go +86 -0
  262. package/dist/resources/templates/go-backend/internal/common/middleware/cors.go +68 -0
  263. package/dist/resources/templates/go-backend/internal/common/middleware/event_context.go +18 -0
  264. package/dist/resources/templates/go-backend/internal/common/middleware/gateway_identity.go +279 -0
  265. package/dist/resources/templates/go-backend/internal/common/middleware/helpers.go +159 -0
  266. package/dist/resources/templates/go-backend/internal/common/middleware/iam_delegated_route_permission.go +171 -0
  267. package/dist/resources/templates/go-backend/internal/common/middleware/iam_delegated_token_auth.go +151 -0
  268. package/dist/resources/templates/go-backend/internal/common/middleware/iam_delegated_token_auth_test.go +99 -0
  269. package/dist/resources/templates/go-backend/internal/common/middleware/iam_service_identity.go +138 -0
  270. package/dist/resources/templates/go-backend/internal/common/middleware/iam_service_token_auth.go +74 -0
  271. package/dist/resources/templates/go-backend/internal/common/middleware/idempotent.go +273 -0
  272. package/dist/resources/templates/go-backend/internal/common/middleware/idempotent_test.go +83 -0
  273. package/dist/resources/templates/go-backend/internal/common/middleware/internal_route_permission.go +45 -0
  274. package/dist/resources/templates/go-backend/internal/common/middleware/internal_route_permission_test.go +186 -0
  275. package/dist/resources/templates/go-backend/internal/common/middleware/logging.go +191 -0
  276. package/dist/resources/templates/go-backend/internal/common/middleware/metrics.go +45 -0
  277. package/dist/resources/templates/go-backend/internal/common/middleware/middleware_test.go +1516 -0
  278. package/dist/resources/templates/go-backend/internal/common/middleware/principal_context.go +160 -0
  279. package/dist/resources/templates/go-backend/internal/common/middleware/principal_context_test.go +355 -0
  280. package/dist/resources/templates/go-backend/internal/common/middleware/product_context.go +100 -0
  281. package/dist/resources/templates/go-backend/internal/common/middleware/recovery.go +40 -0
  282. package/dist/resources/templates/go-backend/internal/common/middleware/referral_attribution.go +178 -0
  283. package/dist/resources/templates/go-backend/internal/common/middleware/requestid.go +48 -0
  284. package/dist/resources/templates/go-backend/internal/common/middleware/resource_permission.go +790 -0
  285. package/dist/resources/templates/go-backend/internal/common/middleware/resource_permission_test.go +440 -0
  286. package/dist/resources/templates/go-backend/internal/common/middleware/service_credential_auth.go +67 -0
  287. package/dist/resources/templates/go-backend/internal/common/middleware/tenant.go +148 -0
  288. package/dist/resources/templates/go-backend/internal/common/middleware/throttle.go +310 -0
  289. package/dist/resources/templates/go-backend/internal/common/middleware/trusted_client_ip.go +23 -0
  290. package/dist/resources/templates/go-backend/internal/common/middleware/trusted_client_ip_test.go +60 -0
  291. package/dist/resources/templates/go-backend/internal/common/money/currency.go +25 -0
  292. package/dist/resources/templates/go-backend/internal/common/money/errors.go +23 -0
  293. package/dist/resources/templates/go-backend/internal/common/money/format.go +123 -0
  294. package/dist/resources/templates/go-backend/internal/common/money/format_test.go +204 -0
  295. package/dist/resources/templates/go-backend/internal/common/money/gateway.go +144 -0
  296. package/dist/resources/templates/go-backend/internal/common/money/gateway_test.go +165 -0
  297. package/dist/resources/templates/go-backend/internal/common/money/rounding.go +56 -0
  298. package/dist/resources/templates/go-backend/internal/common/money/rounding_test.go +51 -0
  299. package/dist/resources/templates/go-backend/internal/common/principal/context.go +56 -0
  300. package/dist/resources/templates/go-backend/internal/common/principal/principal.go +49 -0
  301. package/dist/resources/templates/go-backend/internal/common/productcode/code.go +24 -0
  302. package/dist/resources/templates/go-backend/internal/common/productcode/code_test.go +35 -0
  303. package/dist/resources/templates/go-backend/internal/common/providerconfig/schema.go +577 -0
  304. package/dist/resources/templates/go-backend/internal/common/providerconfig/schema_test.go +47 -0
  305. package/dist/resources/templates/go-backend/internal/common/requestprivacy/request.go +246 -0
  306. package/dist/resources/templates/go-backend/internal/common/requestprivacy/request_test.go +170 -0
  307. package/dist/resources/templates/go-backend/internal/common/response/pagination.go +60 -0
  308. package/dist/resources/templates/go-backend/internal/common/response/response.go +110 -0
  309. package/dist/resources/templates/go-backend/internal/common/response/response_test.go +463 -0
  310. package/dist/resources/templates/go-backend/internal/common/ruleexpression/ast.go +141 -0
  311. package/dist/resources/templates/go-backend/internal/common/ruleexpression/ast_test.go +81 -0
  312. package/dist/resources/templates/go-backend/internal/common/ruleexpression/canonical.go +184 -0
  313. package/dist/resources/templates/go-backend/internal/common/ruleexpression/canonical_test.go +319 -0
  314. package/dist/resources/templates/go-backend/internal/common/ruleexpression/decoder.go +555 -0
  315. package/dist/resources/templates/go-backend/internal/common/ruleexpression/decoder_test.go +260 -0
  316. package/dist/resources/templates/go-backend/internal/common/ruleexpression/errors.go +55 -0
  317. package/dist/resources/templates/go-backend/internal/common/ruleexpression/evaluator.go +96 -0
  318. package/dist/resources/templates/go-backend/internal/common/ruleexpression/evaluator_test.go +220 -0
  319. package/dist/resources/templates/go-backend/internal/common/ruleexpression/fuzz_test.go +116 -0
  320. package/dist/resources/templates/go-backend/internal/common/ruleexpression/limits.go +331 -0
  321. package/dist/resources/templates/go-backend/internal/common/ruleexpression/schema.go +412 -0
  322. package/dist/resources/templates/go-backend/internal/common/ruleexpression/schema_test.go +164 -0
  323. package/dist/resources/templates/go-backend/internal/common/runtimeinput/runtime_input.go +627 -0
  324. package/dist/resources/templates/go-backend/internal/common/runtimeinput/runtime_input_test.go +245 -0
  325. package/dist/resources/templates/go-backend/internal/common/semver/errors.go +6 -0
  326. package/dist/resources/templates/go-backend/internal/common/semver/semver.go +125 -0
  327. package/dist/resources/templates/go-backend/internal/common/semver/semver_test.go +205 -0
  328. package/dist/resources/templates/go-backend/internal/common/serviceidentity/audience.go +48 -0
  329. package/dist/resources/templates/go-backend/internal/common/serviceidentity/audience_test.go +35 -0
  330. package/dist/resources/templates/go-backend/internal/common/serviceidentity/resource_identifier.go +33 -0
  331. package/dist/resources/templates/go-backend/internal/common/serviceidentity/resource_identifier_test.go +32 -0
  332. package/dist/resources/templates/go-backend/internal/common/tradeno/generator.go +99 -0
  333. package/dist/resources/templates/go-backend/internal/common/tradeno/generator_test.go +396 -0
  334. package/dist/resources/templates/go-backend/internal/common/tradeno/prefix.go +247 -0
  335. package/dist/resources/templates/go-backend/internal/common/types/asset_url.go +11 -0
  336. package/dist/resources/templates/go-backend/internal/common/types/billing.go +89 -0
  337. package/dist/resources/templates/go-backend/internal/common/types/billing_test.go +77 -0
  338. package/dist/resources/templates/go-backend/internal/common/types/country.go +74 -0
  339. package/dist/resources/templates/go-backend/internal/common/types/country_test.go +28 -0
  340. package/dist/resources/templates/go-backend/internal/common/types/currency.go +60 -0
  341. package/dist/resources/templates/go-backend/internal/common/types/identifiers.go +41 -0
  342. package/dist/resources/templates/go-backend/internal/common/types/operator.go +28 -0
  343. package/dist/resources/templates/go-backend/internal/common/types/subscription_entitlement.go +24 -0
  344. package/dist/resources/templates/go-backend/internal/common/types/subscription_entitlement_test.go +35 -0
  345. package/dist/resources/templates/go-backend/internal/common/types/tier.go +72 -0
  346. package/dist/resources/templates/go-backend/internal/common/types/types.go +411 -0
  347. package/dist/resources/templates/go-backend/internal/common/types/types_test.go +295 -0
  348. package/dist/resources/templates/go-backend/internal/common/utils/constants.go +100 -0
  349. package/dist/resources/templates/go-backend/internal/common/utils/crypto.go +158 -0
  350. package/dist/resources/templates/go-backend/internal/common/utils/crypto_test.go +345 -0
  351. package/dist/resources/templates/go-backend/internal/common/utils/duration.go +25 -0
  352. package/dist/resources/templates/go-backend/internal/common/utils/helpers.go +18 -0
  353. package/dist/resources/templates/go-backend/internal/common/utils/json.go +62 -0
  354. package/dist/resources/templates/go-backend/internal/common/utils/json_test.go +76 -0
  355. package/dist/resources/templates/go-backend/internal/common/utils/pagination.go +51 -0
  356. package/dist/resources/templates/go-backend/internal/common/utils/pagination_test.go +45 -0
  357. package/dist/resources/templates/go-backend/internal/common/utils/pointer.go +107 -0
  358. package/dist/resources/templates/go-backend/internal/common/utils/pointer_test.go +15 -0
  359. package/dist/resources/templates/go-backend/internal/common/utils/slice.go +24 -0
  360. package/dist/resources/templates/go-backend/internal/common/utils/snowflake.go +110 -0
  361. package/dist/resources/templates/go-backend/internal/common/utils/snowflake_test.go +316 -0
  362. package/dist/resources/templates/go-backend/internal/common/utils/string.go +16 -0
  363. package/dist/resources/templates/go-backend/internal/common/utils/timefmt.go +42 -0
  364. package/dist/resources/templates/go-backend/internal/common/validator/validator.go +136 -0
  365. package/dist/resources/templates/go-backend/internal/common/validator/validator_test.go +240 -0
  366. package/dist/resources/templates/go-backend/internal/common/youtubeapi/client.go +224 -0
  367. package/dist/resources/templates/go-backend/internal/core/apicontract/document.go +269 -0
  368. package/dist/resources/templates/go-backend/internal/core/apicontract/document_test.go +104 -0
  369. package/dist/resources/templates/go-backend/internal/core/apicontract/route_validator.go +78 -0
  370. package/dist/resources/templates/go-backend/internal/core/apicontract/route_validator_test.go +108 -0
  371. package/dist/resources/templates/go-backend/internal/core/apidocs/assets/scalar-api-reference.js +2385 -0
  372. package/dist/resources/templates/go-backend/internal/core/apidocs/assets/scalar-api-reference.metadata.json +10 -0
  373. package/dist/resources/templates/go-backend/internal/core/apidocs/route.go +107 -0
  374. package/dist/resources/templates/go-backend/internal/core/apidocs/route_test.go +200 -0
  375. package/dist/resources/templates/go-backend/internal/core/apidocs/scalar.go +117 -0
  376. package/dist/resources/templates/go-backend/internal/core/apidocs/scalar_test.go +99 -0
  377. package/dist/resources/templates/go-backend/internal/core/audit/access_log_policy.go +91 -0
  378. package/dist/resources/templates/go-backend/internal/core/audit/access_log_policy_test.go +51 -0
  379. package/dist/resources/templates/go-backend/internal/core/audit/actor_resolver.go +36 -0
  380. package/dist/resources/templates/go-backend/internal/core/audit/constants.go +30 -0
  381. package/dist/resources/templates/go-backend/internal/core/audit/context.go +119 -0
  382. package/dist/resources/templates/go-backend/internal/core/audit/context_test.go +310 -0
  383. package/dist/resources/templates/go-backend/internal/core/audit/dto.go +468 -0
  384. package/dist/resources/templates/go-backend/internal/core/audit/dto_admin.go +172 -0
  385. package/dist/resources/templates/go-backend/internal/core/audit/enum.go +460 -0
  386. package/dist/resources/templates/go-backend/internal/core/audit/enum_test.go +314 -0
  387. package/dist/resources/templates/go-backend/internal/core/audit/errors.go +9 -0
  388. package/dist/resources/templates/go-backend/internal/core/audit/handler.go +568 -0
  389. package/dist/resources/templates/go-backend/internal/core/audit/listener.go +319 -0
  390. package/dist/resources/templates/go-backend/internal/core/audit/listener_test.go +98 -0
  391. package/dist/resources/templates/go-backend/internal/core/audit/middleware.go +669 -0
  392. package/dist/resources/templates/go-backend/internal/core/audit/middleware_test.go +268 -0
  393. package/dist/resources/templates/go-backend/internal/core/audit/model.go +306 -0
  394. package/dist/resources/templates/go-backend/internal/core/audit/partition_job.go +316 -0
  395. package/dist/resources/templates/go-backend/internal/core/audit/ports.go +9 -0
  396. package/dist/resources/templates/go-backend/internal/core/audit/provider.go +30 -0
  397. package/dist/resources/templates/go-backend/internal/core/audit/repository.go +1007 -0
  398. package/dist/resources/templates/go-backend/internal/core/audit/repository_test.go +934 -0
  399. package/dist/resources/templates/go-backend/internal/core/audit/router.go +85 -0
  400. package/dist/resources/templates/go-backend/internal/core/audit/service.go +770 -0
  401. package/dist/resources/templates/go-backend/internal/core/audit/service_test.go +331 -0
  402. package/dist/resources/templates/go-backend/internal/core/audit/vo_admin.go +475 -0
  403. package/dist/resources/templates/go-backend/internal/core/cache/config.go +30 -0
  404. package/dist/resources/templates/go-backend/internal/core/cache/key.go +41 -0
  405. package/dist/resources/templates/go-backend/internal/core/cache/key_test.go +62 -0
  406. package/dist/resources/templates/go-backend/internal/core/cache/l1.go +153 -0
  407. package/dist/resources/templates/go-backend/internal/core/cache/l1_test.go +212 -0
  408. package/dist/resources/templates/go-backend/internal/core/cache/manager.go +278 -0
  409. package/dist/resources/templates/go-backend/internal/core/cache/manager_provider.go +24 -0
  410. package/dist/resources/templates/go-backend/internal/core/cache/metrics.go +126 -0
  411. package/dist/resources/templates/go-backend/internal/core/cache/namespace.go +46 -0
  412. package/dist/resources/templates/go-backend/internal/core/cache/namespace_test.go +90 -0
  413. package/dist/resources/templates/go-backend/internal/core/cache/options.go +39 -0
  414. package/dist/resources/templates/go-backend/internal/core/cache/options_test.go +96 -0
  415. package/dist/resources/templates/go-backend/internal/core/cache/redis.go +311 -0
  416. package/dist/resources/templates/go-backend/internal/core/cache/redis_test.go +51 -0
  417. package/dist/resources/templates/go-backend/internal/core/cache/serializer.go +31 -0
  418. package/dist/resources/templates/go-backend/internal/core/cache/serializer_test.go +139 -0
  419. package/dist/resources/templates/go-backend/internal/core/cache/singleflight.go +53 -0
  420. package/dist/resources/templates/go-backend/internal/core/cache/singleflight_test.go +211 -0
  421. package/dist/resources/templates/go-backend/internal/core/cache/warming.go +86 -0
  422. package/dist/resources/templates/go-backend/internal/core/clock/clock.go +66 -0
  423. package/dist/resources/templates/go-backend/internal/core/clock/clock_test.go +26 -0
  424. package/dist/resources/templates/go-backend/internal/core/clock/runtime_clock.go +283 -0
  425. package/dist/resources/templates/go-backend/internal/core/clock/runtime_clock_test.go +98 -0
  426. package/dist/resources/templates/go-backend/internal/core/commandreplay/errors.go +6 -0
  427. package/dist/resources/templates/go-backend/internal/core/commandreplay/model.go +90 -0
  428. package/dist/resources/templates/go-backend/internal/core/commandreplay/model_test.go +79 -0
  429. package/dist/resources/templates/go-backend/internal/core/commandreplay/namespace.go +7 -0
  430. package/dist/resources/templates/go-backend/internal/core/commandreplay/persistence.go +269 -0
  431. package/dist/resources/templates/go-backend/internal/core/commandreplay/persistence_test.go +185 -0
  432. package/dist/resources/templates/go-backend/internal/core/commandreplay/provider.go +9 -0
  433. package/dist/resources/templates/go-backend/internal/core/commandreplay/repository.go +22 -0
  434. package/dist/resources/templates/go-backend/internal/core/commandreplay/service.go +853 -0
  435. package/dist/resources/templates/go-backend/internal/core/commandreplay/service_persistence_test.go +432 -0
  436. package/dist/resources/templates/go-backend/internal/core/commandreplay/service_test.go +891 -0
  437. package/dist/resources/templates/go-backend/internal/core/commandreplay/types.go +121 -0
  438. package/dist/resources/templates/go-backend/internal/core/config/config.go +2069 -0
  439. package/dist/resources/templates/go-backend/internal/core/config/config_test.go +1122 -0
  440. package/dist/resources/templates/go-backend/internal/core/config/contract/contract_test.go +388 -0
  441. package/dist/resources/templates/go-backend/internal/core/config/contract/docs.go +198 -0
  442. package/dist/resources/templates/go-backend/internal/core/config/contract/verify.go +424 -0
  443. package/dist/resources/templates/go-backend/internal/core/config/enum.go +46 -0
  444. package/dist/resources/templates/go-backend/internal/core/config/metadata.go +717 -0
  445. package/dist/resources/templates/go-backend/internal/core/config/metadata_test.go +228 -0
  446. package/dist/resources/templates/go-backend/internal/core/config/product_admin_config_test.go +210 -0
  447. package/dist/resources/templates/go-backend/internal/core/crypto/aes_gcm.go +111 -0
  448. package/dist/resources/templates/go-backend/internal/core/crypto/aes_gcm_test.go +364 -0
  449. package/dist/resources/templates/go-backend/internal/core/crypto/encryptor.go +12 -0
  450. package/dist/resources/templates/go-backend/internal/core/crypto/envelope_encryptor.go +134 -0
  451. package/dist/resources/templates/go-backend/internal/core/crypto/envelope_encryptor_test.go +118 -0
  452. package/dist/resources/templates/go-backend/internal/core/crypto/pem.go +112 -0
  453. package/dist/resources/templates/go-backend/internal/core/crypto/pem_test.go +44 -0
  454. package/dist/resources/templates/go-backend/internal/core/crypto/provider.go +130 -0
  455. package/dist/resources/templates/go-backend/internal/core/crypto/provider_test.go +92 -0
  456. package/dist/resources/templates/go-backend/internal/core/database/base_model.go +24 -0
  457. package/dist/resources/templates/go-backend/internal/core/database/clickhouse.go +121 -0
  458. package/dist/resources/templates/go-backend/internal/core/database/database.go +112 -0
  459. package/dist/resources/templates/go-backend/internal/core/database/database_logger_test.go +95 -0
  460. package/dist/resources/templates/go-backend/internal/core/database/errors.go +25 -0
  461. package/dist/resources/templates/go-backend/internal/core/database/metrics_plugin.go +105 -0
  462. package/dist/resources/templates/go-backend/internal/core/database/pool_collector.go +71 -0
  463. package/dist/resources/templates/go-backend/internal/core/database/read_replica.go +520 -0
  464. package/dist/resources/templates/go-backend/internal/core/database/transaction.go +170 -0
  465. package/dist/resources/templates/go-backend/internal/core/database/transaction_test.go +282 -0
  466. package/dist/resources/templates/go-backend/internal/core/distlock/lock.go +353 -0
  467. package/dist/resources/templates/go-backend/internal/core/distlock/lock_test.go +106 -0
  468. package/dist/resources/templates/go-backend/internal/core/errors/handler.go +189 -0
  469. package/dist/resources/templates/go-backend/internal/core/errors/handler_test.go +515 -0
  470. package/dist/resources/templates/go-backend/internal/core/eventbus/eventbus.go +667 -0
  471. package/dist/resources/templates/go-backend/internal/core/eventbus/eventbus_test.go +792 -0
  472. package/dist/resources/templates/go-backend/internal/core/eventstream/noop.go +22 -0
  473. package/dist/resources/templates/go-backend/internal/core/eventstream/provider.go +20 -0
  474. package/dist/resources/templates/go-backend/internal/core/eventstream/publisher.go +38 -0
  475. package/dist/resources/templates/go-backend/internal/core/eventstream/redis.go +109 -0
  476. package/dist/resources/templates/go-backend/internal/core/eventstream/routing.go +104 -0
  477. package/dist/resources/templates/go-backend/internal/core/eventstream/routing_test.go +71 -0
  478. package/dist/resources/templates/go-backend/internal/core/geoip/model.go +19 -0
  479. package/dist/resources/templates/go-backend/internal/core/geoip/service.go +88 -0
  480. package/dist/resources/templates/go-backend/internal/core/health/health.go +333 -0
  481. package/dist/resources/templates/go-backend/internal/core/health/health_test.go +27 -0
  482. package/dist/resources/templates/go-backend/internal/core/httpclient/client.go +772 -0
  483. package/dist/resources/templates/go-backend/internal/core/httpclient/client_test.go +287 -0
  484. package/dist/resources/templates/go-backend/internal/core/httpclient/download.go +578 -0
  485. package/dist/resources/templates/go-backend/internal/core/httpclient/download_test.go +374 -0
  486. package/dist/resources/templates/go-backend/internal/core/jwtkeyring/jwk.go +38 -0
  487. package/dist/resources/templates/go-backend/internal/core/jwtkeyring/keyring.go +144 -0
  488. package/dist/resources/templates/go-backend/internal/core/jwtkeyring/keyring_test.go +128 -0
  489. package/dist/resources/templates/go-backend/internal/core/jwtkeyring/registry.go +60 -0
  490. package/dist/resources/templates/go-backend/internal/core/logger/logger.go +53 -0
  491. package/dist/resources/templates/go-backend/internal/core/logger/logger_test.go +194 -0
  492. package/dist/resources/templates/go-backend/internal/core/observability/metrics.go +358 -0
  493. package/dist/resources/templates/go-backend/internal/core/observability/sentry.go +445 -0
  494. package/dist/resources/templates/go-backend/internal/core/observability/sentry_privacy_test.go +175 -0
  495. package/dist/resources/templates/go-backend/internal/core/observability/tracing.go +187 -0
  496. package/dist/resources/templates/go-backend/internal/core/outbox/model.go +314 -0
  497. package/dist/resources/templates/go-backend/internal/core/outbox/model_test.go +77 -0
  498. package/dist/resources/templates/go-backend/internal/core/outbox/persistence.go +51 -0
  499. package/dist/resources/templates/go-backend/internal/core/outbox/provider.go +23 -0
  500. package/dist/resources/templates/go-backend/internal/core/outbox/relay.go +1138 -0
  501. package/dist/resources/templates/go-backend/internal/core/outbox/relay_postgres_test.go +257 -0
  502. package/dist/resources/templates/go-backend/internal/core/outbox/relay_test.go +690 -0
  503. package/dist/resources/templates/go-backend/internal/core/outbox/rescheduler.go +164 -0
  504. package/dist/resources/templates/go-backend/internal/core/outbox/rescheduler_test.go +209 -0
  505. package/dist/resources/templates/go-backend/internal/core/outbox/writer.go +249 -0
  506. package/dist/resources/templates/go-backend/internal/core/outbox/writer_postgres_test.go +170 -0
  507. package/dist/resources/templates/go-backend/internal/core/outbox/writer_test.go +123 -0
  508. package/dist/resources/templates/go-backend/internal/core/provider.go +198 -0
  509. package/dist/resources/templates/go-backend/internal/core/queue/metrics_middleware.go +38 -0
  510. package/dist/resources/templates/go-backend/internal/core/queue/metrics_middleware_test.go +12 -0
  511. package/dist/resources/templates/go-backend/internal/core/queue/queue.go +288 -0
  512. package/dist/resources/templates/go-backend/internal/core/queue/queue_test.go +159 -0
  513. package/dist/resources/templates/go-backend/internal/core/resilience/bulkhead.go +514 -0
  514. package/dist/resources/templates/go-backend/internal/core/resilience/bulkhead_test.go +984 -0
  515. package/dist/resources/templates/go-backend/internal/core/resilience/circuitbreaker.go +358 -0
  516. package/dist/resources/templates/go-backend/internal/core/resilience/circuitbreaker_test.go +788 -0
  517. package/dist/resources/templates/go-backend/internal/core/resilience/retry.go +318 -0
  518. package/dist/resources/templates/go-backend/internal/core/resilience/retry_test.go +735 -0
  519. package/dist/resources/templates/go-backend/internal/core/schedule/recorder.go +305 -0
  520. package/dist/resources/templates/go-backend/internal/core/schedule/run_context.go +124 -0
  521. package/dist/resources/templates/go-backend/internal/core/schedule/run_context_test.go +85 -0
  522. package/dist/resources/templates/go-backend/internal/core/schedule/scheduler.go +1589 -0
  523. package/dist/resources/templates/go-backend/internal/core/schedule/scheduler_control_test.go +808 -0
  524. package/dist/resources/templates/go-backend/internal/core/storage/oss_provider.go +398 -0
  525. package/dist/resources/templates/go-backend/internal/core/storage/oss_provider_test.go +89 -0
  526. package/dist/resources/templates/go-backend/internal/core/storage/path.go +110 -0
  527. package/dist/resources/templates/go-backend/internal/core/storage/path_test.go +301 -0
  528. package/dist/resources/templates/go-backend/internal/core/storage/s3_provider.go +489 -0
  529. package/dist/resources/templates/go-backend/internal/core/storage/s3_provider_test.go +60 -0
  530. package/dist/resources/templates/go-backend/internal/core/storage/storage.go +268 -0
  531. package/dist/resources/templates/go-backend/internal/core/storage/validation.go +225 -0
  532. package/dist/resources/templates/go-backend/internal/core/storage/validation_test.go +495 -0
  533. package/dist/resources/templates/go-backend/internal/core/temporal/logger.go +38 -0
  534. package/dist/resources/templates/go-backend/internal/core/temporal/provider.go +126 -0
  535. package/dist/resources/templates/go-backend/internal/core/temporal/provider_test.go +67 -0
  536. package/dist/resources/templates/go-backend/internal/core/websocket/client.go +282 -0
  537. package/dist/resources/templates/go-backend/internal/core/websocket/client_test.go +81 -0
  538. package/dist/resources/templates/go-backend/internal/core/websocket/config.go +58 -0
  539. package/dist/resources/templates/go-backend/internal/core/websocket/handler.go +53 -0
  540. package/dist/resources/templates/go-backend/internal/core/websocket/hub.go +269 -0
  541. package/dist/resources/templates/go-backend/internal/core/websocket/message.go +273 -0
  542. package/dist/resources/templates/go-backend/internal/core/websocket/notifier.go +92 -0
  543. package/dist/resources/templates/go-backend/internal/core/websocket/provider.go +33 -0
  544. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/action.go +77 -0
  545. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/action_test.go +238 -0
  546. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/condition.go +107 -0
  547. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/decision.go +256 -0
  548. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/enum.go +643 -0
  549. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/errors.go +102 -0
  550. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/principal_record.go +21 -0
  551. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/product_context.go +486 -0
  552. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/resource.go +215 -0
  553. package/dist/resources/templates/go-backend/internal/integrations/onex/iam/resource_test.go +242 -0
  554. package/dist/resources/templates/go-backend/internal/products/README.md +5 -0
  555. package/dist/resources/templates/go-backend/internal/sharedevents/README.md +5 -0
  556. package/dist/resources/templates/go-backend/migrations/000001_infrastructure.down.sql +13 -0
  557. package/dist/resources/templates/go-backend/migrations/000001_infrastructure.up.sql +886 -0
  558. package/dist/resources/templates/go-backend/pkg/apierror/error.go +327 -0
  559. package/dist/resources/templates/go-backend/pkg/apierror/error_code.go +65 -0
  560. package/dist/resources/templates/go-backend/pkg/apierror/error_test.go +41 -0
  561. package/dist/resources/templates/go-backend/pkg/apierror/error_type.go +14 -0
  562. package/dist/resources/templates/go-backend/pkg/apierror/http_response.go +216 -0
  563. package/dist/resources/templates/go-backend/pkg/apierror/http_response_test.go +216 -0
  564. package/dist/resources/templates/go-backend/scripts/check-openapi-clean-deletion.sh +54 -0
  565. package/dist/resources/templates/go-backend/scripts/test-migrations.sh +32 -0
  566. package/dist/resources/templates/go-backend/tests/infrastructure.sql +69 -0
  567. package/dist/resources/templates/mcp-server/.claude/docs/stack.md +338 -0
  568. package/dist/resources/templates/mcp-server/.editorconfig +13 -0
  569. package/dist/resources/templates/mcp-server/.env.example +8 -0
  570. package/dist/resources/templates/mcp-server/.github/ISSUE_TEMPLATE/bug_report.yml +104 -0
  571. package/dist/resources/templates/mcp-server/.github/ISSUE_TEMPLATE/feature_request.yml +54 -0
  572. package/dist/resources/templates/mcp-server/.github/PULL_REQUEST_TEMPLATE.md +36 -0
  573. package/dist/resources/templates/mcp-server/.github/workflows/ci.yml +78 -0
  574. package/dist/resources/templates/mcp-server/.husky/commit-msg +1 -0
  575. package/dist/resources/templates/mcp-server/.husky/pre-commit +1 -0
  576. package/dist/resources/templates/mcp-server/.lintstagedrc.json +4 -0
  577. package/dist/resources/templates/mcp-server/.nvmrc +1 -0
  578. package/dist/resources/templates/mcp-server/.prettierrc +8 -0
  579. package/dist/resources/templates/mcp-server/CONTRIBUTING.md +184 -0
  580. package/dist/resources/templates/mcp-server/Dockerfile +23 -0
  581. package/dist/resources/templates/mcp-server/LICENSE +21 -0
  582. package/dist/resources/templates/mcp-server/README.md +123 -0
  583. package/dist/resources/templates/mcp-server/_gitignore +26 -0
  584. package/dist/resources/templates/mcp-server/commitlint.config.js +24 -0
  585. package/dist/resources/templates/mcp-server/eslint.config.js +30 -0
  586. package/dist/resources/templates/mcp-server/package.json +72 -0
  587. package/dist/resources/templates/mcp-server/src/index.ts +27 -0
  588. package/dist/resources/templates/mcp-server/src/resources.ts +33 -0
  589. package/dist/resources/templates/mcp-server/src/services/.gitkeep +0 -0
  590. package/dist/resources/templates/mcp-server/src/tools.ts +43 -0
  591. package/dist/resources/templates/mcp-server/src/types/index.ts +19 -0
  592. package/dist/resources/templates/mcp-server/src/utils/index.ts +31 -0
  593. package/dist/resources/templates/mcp-server/tsconfig.json +22 -0
  594. package/dist/resources/templates/mcp-server/tsup.config.ts +14 -0
  595. package/dist/resources/templates/mcp-server/vitest.config.ts +15 -0
  596. package/dist/resources/templates/nuxt/.claude/docs/stack.md +666 -0
  597. package/dist/resources/templates/nuxt/.editorconfig +15 -0
  598. package/dist/resources/templates/nuxt/.env.example +22 -0
  599. package/dist/resources/templates/nuxt/.github/workflows/ci.yml +34 -0
  600. package/dist/resources/templates/nuxt/.husky/commit-msg +1 -0
  601. package/dist/resources/templates/nuxt/.husky/pre-commit +1 -0
  602. package/dist/resources/templates/nuxt/.nvmrc +1 -0
  603. package/dist/resources/templates/nuxt/.prettierignore +9 -0
  604. package/dist/resources/templates/nuxt/.prettierrc +1 -0
  605. package/dist/resources/templates/nuxt/README.md +23 -0
  606. package/dist/resources/templates/nuxt/_gitignore +7 -0
  607. package/dist/resources/templates/nuxt/app/app.config.ts +105 -0
  608. package/dist/resources/templates/nuxt/app/i18n/locales/en.json +5 -0
  609. package/dist/resources/templates/nuxt/app/pages/app/index.vue +224 -0
  610. package/dist/resources/templates/nuxt/app/pages/authors/[slug].vue +37 -0
  611. package/dist/resources/templates/nuxt/app/pages/blog/[slug].vue +55 -0
  612. package/dist/resources/templates/nuxt/app/pages/blog/category/[category].vue +38 -0
  613. package/dist/resources/templates/nuxt/app/pages/blog/index.vue +46 -0
  614. package/dist/resources/templates/nuxt/app/pages/index.vue +626 -0
  615. package/dist/resources/templates/nuxt/app/pages/legal/privacy.vue +21 -0
  616. package/dist/resources/templates/nuxt/app/pages/legal/terms.vue +21 -0
  617. package/dist/resources/templates/nuxt/app/pages/ui/index.vue +397 -0
  618. package/dist/resources/templates/nuxt/commitlint.config.mjs +1 -0
  619. package/dist/resources/templates/nuxt/eslint.config.mjs +4 -0
  620. package/dist/resources/templates/nuxt/lint-staged.config.mjs +8 -0
  621. package/dist/resources/templates/nuxt/nuxt.config.ts +71 -0
  622. package/dist/resources/templates/nuxt/package.json +67 -0
  623. package/dist/resources/templates/nuxt/public/apple-touch-icon.png +0 -0
  624. package/dist/resources/templates/nuxt/public/favicon.ico +0 -0
  625. package/dist/resources/templates/nuxt/public/favicon.svg +5 -0
  626. package/dist/resources/templates/nuxt/public/icon-16x16.png +0 -0
  627. package/dist/resources/templates/nuxt/public/icon-192x192.png +0 -0
  628. package/dist/resources/templates/nuxt/public/icon-32x32.png +0 -0
  629. package/dist/resources/templates/nuxt/public/icon-512x512.png +0 -0
  630. package/dist/resources/templates/nuxt/public/logo.svg +6 -0
  631. package/dist/resources/templates/nuxt/public/media/hero-product-gallery.png +0 -0
  632. package/dist/resources/templates/nuxt/server/api/content/sitemap-urls.get.ts +12 -0
  633. package/dist/resources/templates/nuxt/server/api/preview.get.ts +9 -0
  634. package/dist/resources/templates/nuxt/stylelint.config.mjs +3 -0
  635. package/dist/resources/templates/nuxt/test/e2e/rendering.test.ts +13 -0
  636. package/dist/resources/templates/nuxt/tsconfig.json +3 -0
  637. package/dist/resources/templates/nuxt/vitest.config.ts +8 -0
  638. package/package.json +8 -5
@@ -0,0 +1,558 @@
1
+ # Error Handling Templates
2
+
3
+ > Implementation code for errors and middleware. Rules are in `CLAUDE.md`.
4
+
5
+ ---
6
+
7
+ ## ErrorType Constants
8
+
9
+ ```go
10
+ package apierror
11
+
12
+ // 错误类型
13
+ const (
14
+ TypeValidation = "validation_error"
15
+ TypeAuthentication = "authentication_error"
16
+ TypeAuthorization = "authorization_error"
17
+ TypeInvalidRequest = "invalid_request_error"
18
+ TypeRateLimit = "rate_limit_error"
19
+ TypeAPI = "api_error"
20
+ TypeNotFound = "not_found_error"
21
+ // TypeGone 资源已永久移除
22
+ TypeGone = "gone_error"
23
+ )
24
+ ```
25
+
26
+ ## ErrorCode Constants
27
+
28
+ ```go
29
+ package apierror
30
+
31
+ // 错误码
32
+ const (
33
+ // 通用
34
+ CodeInternalError = "internal_error"
35
+ CodeResourceNotFound = "resource_not_found"
36
+ CodeResourceExists = "resource_already_exists"
37
+ CodeInvalidOperation = "invalid_operation"
38
+ CodeValidationFailed = "invalid_parameters"
39
+ CodeTooManyRequests = "rate_limit_exceeded"
40
+ CodeServiceUnavailable = "service_unavailable"
41
+ CodeNotImplemented = "not_implemented"
42
+ CodeIdempotencyKeyConflict = "idempotency_key_conflict"
43
+ CodeIdempotencyRequestInProgress = "idempotency_request_in_progress"
44
+
45
+ // 认证/授权
46
+ CodeUnauthorized = "unauthorized"
47
+ CodeAccessDenied = "access_denied"
48
+ CodeInvalidCredentials = "invalid_credentials" //nolint:gosec // G101: 错误码常量,非凭据
49
+ CodeTokenExpired = "token_expired"
50
+ CodeTokenInvalid = "token_invalid"
51
+ CodeRefreshTokenExpired = "refresh_token_expired" //nolint:gosec // G101: 错误码常量,非凭据
52
+ CodeAccountDisabled = "account_disabled"
53
+ CodeAccountNotVerified = "account_not_verified"
54
+ CodeAccountPendingDeletion = "account_pending_deletion"
55
+
56
+ // 用户
57
+ CodeUserNotFound = "user_not_found"
58
+ CodeUserExists = "user_already_exists"
59
+ CodeEmailRegistered = "email_already_registered"
60
+ CodeInvalidPassword = "invalid_password"
61
+ CodePasswordTooWeak = "password_too_weak"
62
+
63
+ // AI 服务
64
+ CodeAIUnavailable = "ai_service_unavailable"
65
+ CodeAIQuotaExceeded = "ai_quota_exceeded"
66
+ CodeAIInvalidRequest = "ai_invalid_request"
67
+ CodeAIContentFiltered = "ai_content_filtered"
68
+ CodeAIContextTooLong = "ai_context_too_long"
69
+
70
+ // 支付
71
+ CodePaymentFailed = "payment_failed"
72
+ CodePaymentCancelled = "payment_cancelled"
73
+ CodePaymentExpired = "payment_expired"
74
+ CodeInsufficientBalance = "insufficient_balance"
75
+
76
+ // 资源状态
77
+ // CodeResourceGone 资源已永久下线
78
+ CodeResourceGone = "resource_gone"
79
+
80
+ // 订阅
81
+ CodeSubscriptionNotFound = "subscription_not_found"
82
+ CodeSubscriptionExpired = "subscription_expired"
83
+ CodeSubscriptionActive = "subscription_already_active"
84
+ CodePlanNotAvailable = "plan_not_available"
85
+
86
+ // 工单(Helpdesk)— 入参非法值(domain enum 校验失败)
87
+ CodeInvalidSourceChannel = "invalid_source_channel"
88
+ CodeInvalidSourceType = "invalid_source_type"
89
+ CodeInvalidPriority = "invalid_priority"
90
+ CodeInvalidTicketType = "invalid_ticket_type"
91
+ CodeInvalidTicketCategory = "invalid_ticket_category"
92
+ CodeInvalidConversationType = "invalid_conversation_type"
93
+ )
94
+ ```
95
+
96
+ ## APIError Type
97
+
98
+ ```go
99
+ package apierror
100
+
101
+ import (
102
+ "fmt"
103
+ "net/http"
104
+ )
105
+
106
+ // ErrorResponse API 统一错误响应
107
+ type ErrorResponse struct {
108
+ Error ErrorDetail `json:"error"`
109
+ }
110
+
111
+ // ErrorDetail 错误详情
112
+ type ErrorDetail struct {
113
+ Type string `json:"type"`
114
+ Code string `json:"code"`
115
+ Message string `json:"message"`
116
+ Param string `json:"param,omitempty"`
117
+ Errors []FieldError `json:"errors,omitempty"`
118
+ }
119
+
120
+ // FieldError 字段校验错误
121
+ type FieldError struct {
122
+ Field string `json:"field"`
123
+ Message string `json:"message"`
124
+ }
125
+
126
+ // HTTPResponseMetadata 描述允许投影到 HTTP 响应的受控错误元数据。
127
+ type HTTPResponseMetadata struct {
128
+ retryAfter string
129
+ }
130
+
131
+ // RetryAfter 返回经过校验的重试时间提示。
132
+ func (m HTTPResponseMetadata) RetryAfter() string {
133
+ return m.retryAfter
134
+ }
135
+
136
+ // HTTPError 统一可由 HTTP writer 输出的类型化错误契约。
137
+ type HTTPError interface {
138
+ error
139
+ HTTPStatus() int
140
+ ToResponse() ErrorResponse
141
+ HTTPResponseMetadata() HTTPResponseMetadata
142
+ }
143
+
144
+ // APIError 业务错误
145
+ type APIError struct {
146
+ Status int
147
+ Detail ErrorDetail
148
+
149
+ responseMetadata HTTPResponseMetadata
150
+ }
151
+
152
+ func (e *APIError) Error() string {
153
+ return e.Detail.Message
154
+ }
155
+
156
+ // HTTPStatus 返回错误对应的 HTTP 状态码。
157
+ func (e *APIError) HTTPStatus() int {
158
+ return e.Status
159
+ }
160
+
161
+ // HTTPResponseMetadata 返回经过边界校验的响应元数据。
162
+ func (e *APIError) HTTPResponseMetadata() HTTPResponseMetadata {
163
+ return e.responseMetadata
164
+ }
165
+
166
+ // WithParam 为业务错误补充字段定位信息,供前端做字段级展示。
167
+ func (e *APIError) WithParam(param string) *APIError {
168
+ e.Detail.Param = param
169
+ return e
170
+ }
171
+
172
+ // WithErrors 为业务错误补充结构化字段错误列表,供前端做字段级展示。
173
+ func (e *APIError) WithErrors(errors []FieldError) *APIError {
174
+ e.Detail.Errors = errors
175
+ return e
176
+ }
177
+
178
+ // ToResponse 转换为标准错误响应
179
+ func (e *APIError) ToResponse() ErrorResponse {
180
+ return ErrorResponse{Error: e.Detail}
181
+ }
182
+
183
+ // ErrorTypeFromStatus 根据 HTTP 状态码推导错误类型
184
+ func ErrorTypeFromStatus(status int) string {
185
+ switch status {
186
+ case http.StatusBadRequest:
187
+ return TypeInvalidRequest
188
+ case http.StatusUnauthorized:
189
+ return TypeAuthentication
190
+ case http.StatusForbidden:
191
+ return TypeAuthorization
192
+ case http.StatusNotFound:
193
+ return TypeNotFound
194
+ case http.StatusTooManyRequests:
195
+ return TypeRateLimit
196
+ case http.StatusGone:
197
+ return TypeGone
198
+ default:
199
+ return TypeAPI
200
+ }
201
+ }
202
+
203
+ // ═══════════════════════════════════════════════════════════════
204
+ // 通用业务错误
205
+ // ═══════════════════════════════════════════════════════════════
206
+
207
+ // NotFound 资源未找到
208
+ func NotFound(resource string, id ...any) *APIError {
209
+ var msg, param string
210
+ if len(id) > 0 {
211
+ msg = fmt.Sprintf("%s with id %v was not found", resource, id[0])
212
+ param = "id"
213
+ } else {
214
+ msg = fmt.Sprintf("%s was not found", resource)
215
+ }
216
+ return &APIError{
217
+ Status: http.StatusNotFound,
218
+ Detail: ErrorDetail{Type: TypeNotFound, Code: CodeResourceNotFound, Message: msg, Param: param},
219
+ }
220
+ }
221
+
222
+ // NotFoundWithCode 返回保留业务错误码的资源不存在错误。
223
+ func NotFoundWithCode(code, message string) *APIError {
224
+ return &APIError{
225
+ Status: http.StatusNotFound,
226
+ Detail: ErrorDetail{Type: TypeNotFound, Code: code, Message: message},
227
+ }
228
+ }
229
+
230
+ // Gone 资源已永久移除(HTTP 410)
231
+ func Gone(resource string) *APIError {
232
+ return &APIError{
233
+ Status: http.StatusGone,
234
+ Detail: ErrorDetail{Type: TypeGone, Code: CodeResourceGone, Message: fmt.Sprintf("%s has been permanently removed", resource)},
235
+ }
236
+ }
237
+
238
+ // AlreadyExists 资源已存在
239
+ func AlreadyExists(resource string, field ...string) *APIError {
240
+ var msg, param string
241
+ if len(field) > 0 {
242
+ msg = fmt.Sprintf("%s with this %s already exists", resource, field[0])
243
+ param = field[0]
244
+ } else {
245
+ msg = fmt.Sprintf("%s already exists", resource)
246
+ }
247
+ return &APIError{
248
+ Status: http.StatusConflict,
249
+ Detail: ErrorDetail{Type: TypeInvalidRequest, Code: CodeResourceExists, Message: msg, Param: param},
250
+ }
251
+ }
252
+
253
+ // InvalidOperation 无效操作
254
+ func InvalidOperation(message string, param ...string) *APIError {
255
+ e := &APIError{
256
+ Status: http.StatusBadRequest,
257
+ Detail: ErrorDetail{Type: TypeInvalidRequest, Code: CodeInvalidOperation, Message: message},
258
+ }
259
+ if len(param) > 0 {
260
+ e.Detail.Param = param[0]
261
+ }
262
+ return e
263
+ }
264
+
265
+ // Forbidden 禁止访问
266
+ func Forbidden(message ...string) *APIError {
267
+ msg := "Access denied"
268
+ if len(message) > 0 {
269
+ msg = message[0]
270
+ }
271
+ return &APIError{
272
+ Status: http.StatusForbidden,
273
+ Detail: ErrorDetail{Type: TypeAuthorization, Code: CodeAccessDenied, Message: msg},
274
+ }
275
+ }
276
+
277
+ // ═══════════════════════════════════════════════════════════════
278
+ // 认证相关错误
279
+ // ═══════════════════════════════════════════════════════════════
280
+
281
+ // Unauthorized 未授权
282
+ func Unauthorized(message ...string) *APIError {
283
+ msg := "Unauthorized"
284
+ if len(message) > 0 {
285
+ msg = message[0]
286
+ }
287
+ return &APIError{
288
+ Status: http.StatusUnauthorized,
289
+ Detail: ErrorDetail{Type: TypeAuthentication, Code: CodeUnauthorized, Message: msg},
290
+ }
291
+ }
292
+
293
+ // InvalidCredentials 凭证错误
294
+ func InvalidCredentials() *APIError {
295
+ return &APIError{
296
+ Status: http.StatusUnauthorized,
297
+ Detail: ErrorDetail{Type: TypeAuthentication, Code: CodeInvalidCredentials, Message: "Invalid email or password"},
298
+ }
299
+ }
300
+
301
+ // TokenExpired Token 过期
302
+ func TokenExpired() *APIError {
303
+ return &APIError{
304
+ Status: http.StatusUnauthorized,
305
+ Detail: ErrorDetail{Type: TypeAuthentication, Code: CodeTokenExpired, Message: "Token has expired"},
306
+ }
307
+ }
308
+
309
+ // TokenInvalid Token 无效
310
+ func TokenInvalid() *APIError {
311
+ return &APIError{
312
+ Status: http.StatusUnauthorized,
313
+ Detail: ErrorDetail{Type: TypeAuthentication, Code: CodeTokenInvalid, Message: "Invalid token"},
314
+ }
315
+ }
316
+
317
+ // ═══════════════════════════════════════════════════════════════
318
+ // 校验相关错误
319
+ // ═══════════════════════════════════════════════════════════════
320
+
321
+ // ValidationFailed 校验失败
322
+ func ValidationFailed(errors []FieldError) *APIError {
323
+ return &APIError{
324
+ Status: http.StatusBadRequest,
325
+ Detail: ErrorDetail{Type: TypeValidation, Code: CodeValidationFailed, Message: "Request validation failed", Errors: errors},
326
+ }
327
+ }
328
+
329
+ // ═══════════════════════════════════════════════════════════════
330
+ // 限流相关错误
331
+ // ═══════════════════════════════════════════════════════════════
332
+
333
+ // TooManyRequests 请求过多
334
+ func TooManyRequests() *APIError {
335
+ return &APIError{
336
+ Status: http.StatusTooManyRequests,
337
+ Detail: ErrorDetail{Type: TypeRateLimit, Code: CodeTooManyRequests, Message: "Too many requests, please try again later"},
338
+ }
339
+ }
340
+
341
+ // ═══════════════════════════════════════════════════════════════
342
+ // AI 服务相关错误
343
+ // ═══════════════════════════════════════════════════════════════
344
+
345
+ // AIServiceUnavailable AI 服务不可用
346
+ func AIServiceUnavailable(provider string) *APIError {
347
+ return &APIError{
348
+ Status: http.StatusServiceUnavailable,
349
+ Detail: ErrorDetail{Type: TypeAPI, Code: CodeAIUnavailable, Message: fmt.Sprintf("AI service (%s) is temporarily unavailable", provider)},
350
+ }
351
+ }
352
+
353
+ // AIQuotaExceeded AI 配额用尽
354
+ func AIQuotaExceeded() *APIError {
355
+ return &APIError{
356
+ Status: http.StatusTooManyRequests,
357
+ Detail: ErrorDetail{Type: TypeRateLimit, Code: CodeAIQuotaExceeded, Message: "AI usage quota exceeded"},
358
+ }
359
+ }
360
+
361
+ // ═══════════════════════════════════════════════════════════════
362
+ // 通用构造
363
+ // ═══════════════════════════════════════════════════════════════
364
+
365
+ // New 创建自定义 APIError
366
+ func New(status int, errorType, code, message string) *APIError {
367
+ return &APIError{
368
+ Status: status,
369
+ Detail: ErrorDetail{Type: errorType, Code: code, Message: message},
370
+ }
371
+ }
372
+
373
+ // Internal 内部服务错误
374
+ func Internal(message ...string) *APIError {
375
+ msg := "Internal server error"
376
+ if len(message) > 0 {
377
+ msg = message[0]
378
+ }
379
+ return &APIError{
380
+ Status: http.StatusInternalServerError,
381
+ Detail: ErrorDetail{Type: TypeAPI, Code: CodeInternalError, Message: msg},
382
+ }
383
+ }
384
+
385
+ // BadRequest 请求错误
386
+ func BadRequest(code, message string) *APIError {
387
+ return &APIError{
388
+ Status: http.StatusBadRequest,
389
+ Detail: ErrorDetail{Type: TypeInvalidRequest, Code: code, Message: message},
390
+ }
391
+ }
392
+
393
+ // Business 业务规则冲突(422 Unprocessable Entity)
394
+ func Business(code, message string) *APIError {
395
+ return &APIError{
396
+ Status: http.StatusUnprocessableEntity,
397
+ Detail: ErrorDetail{Type: TypeInvalidRequest, Code: code, Message: message},
398
+ }
399
+ }
400
+
401
+ // Conflict 资源冲突(409 Conflict)
402
+ func Conflict(code, message string) *APIError {
403
+ return &APIError{
404
+ Status: http.StatusConflict,
405
+ Detail: ErrorDetail{Type: TypeInvalidRequest, Code: code, Message: message},
406
+ }
407
+ }
408
+
409
+ // NotImplemented 未实现的功能(501 Not Implemented)。
410
+ //
411
+ // 用于路由已暴露但子模块尚未上线的场景(如 PDF 生成、第三方 webhook 验签):
412
+ // 客户端可以提前约定 URL 形态,服务端必须 fail-loud 拒绝调用,避免静默
413
+ // 返回伪数据(D5/D6 合规)。
414
+ //
415
+ // 行业对照:HTTP RFC 9110 §15.6.2 — 501 表示"服务器不支持该方法语义",
416
+ // 与 GitHub `Not Implemented`、Stripe 早期 API beta endpoint 同义。
417
+ func NotImplemented(message string) *APIError {
418
+ if message == "" {
419
+ message = "Not implemented"
420
+ }
421
+ return &APIError{
422
+ Status: http.StatusNotImplemented,
423
+ Detail: ErrorDetail{Type: TypeAPI, Code: CodeNotImplemented, Message: message},
424
+ }
425
+ }
426
+ ```
427
+
428
+ ## Error Response Helper
429
+
430
+ ```go
431
+ // Error 根据 error 类型自动选择状态码和响应格式
432
+ func Error(c *gin.Context, err error) {
433
+ var httpErr apierror.HTTPError
434
+ if errors.As(err, &httpErr) {
435
+ status := httpErr.HTTPStatus()
436
+ // 410 Gone 响应附加 noindex 头,通知搜索引擎不再索引
437
+ if status == http.StatusGone {
438
+ c.Header("X-Robots-Tag", "noindex, nofollow")
439
+ }
440
+ if status == http.StatusTooManyRequests || status == http.StatusServiceUnavailable {
441
+ if retryAfter := httpErr.HTTPResponseMetadata().RetryAfter(); retryAfter != "" {
442
+ c.Header(types.HeaderRetryAfter, retryAfter)
443
+ }
444
+ }
445
+ c.JSON(status, httpErr.ToResponse())
446
+ return
447
+ }
448
+
449
+ // 未知错误:注入 Gin context 供 logging middleware 输出错误详情,返回通用 500
450
+ _ = c.Error(err)
451
+ internal := apierror.Internal("Internal server error")
452
+ c.JSON(internal.Status, internal.ToResponse())
453
+ }
454
+
455
+ ```
456
+
457
+ ## Recovery Middleware
458
+
459
+ ```go
460
+ package middleware
461
+
462
+ import (
463
+ "fmt"
464
+ "net/http"
465
+ "runtime/debug"
466
+
467
+ "github.com/gin-gonic/gin"
468
+ "go.uber.org/zap"
469
+
470
+ "{{module}}/internal/common/requestprivacy"
471
+ "{{module}}/pkg/apierror"
472
+ )
473
+
474
+ // Recovery 捕获 panic 并返回 500 APIError 响应
475
+ func Recovery(logger *zap.Logger) gin.HandlerFunc {
476
+ return func(c *gin.Context) {
477
+ defer func() {
478
+ if r := recover(); r != nil {
479
+ stack := string(debug.Stack())
480
+
481
+ logger.Error("panic recovered",
482
+ zap.String("panic_type", fmt.Sprintf("%T", r)),
483
+ zap.String("stack", stack),
484
+ zap.String("method", c.Request.Method),
485
+ zap.String("path", requestprivacy.SanitizeRequestTarget(
486
+ c.Request.URL,
487
+ requestprivacy.RouteTemplateOrUnmatched(c.FullPath()),
488
+ requestprivacy.RedactSensitiveQueryValues,
489
+ )),
490
+ zap.String("clientIP", c.ClientIP()),
491
+ )
492
+
493
+ apiErr := apierror.Internal("Internal server error")
494
+ c.AbortWithStatusJSON(http.StatusInternalServerError, apiErr.ToResponse())
495
+ }
496
+ }()
497
+ c.Next()
498
+ }
499
+ }
500
+ ```
501
+
502
+ ## Validation Error Formatting
503
+
504
+ ```go
505
+ // ValidationError 格式化 go-playground/validator 的校验错误
506
+ func ValidationError(c *gin.Context, err error) {
507
+ var ve validator.ValidationErrors
508
+ if !errors.As(err, &ve) {
509
+ // 非 validator 校验错误,按普通错误处理
510
+ apiErr := apierror.BadRequest(apierror.CodeValidationFailed, err.Error())
511
+ c.JSON(apiErr.Status, apiErr.ToResponse())
512
+ return
513
+ }
514
+
515
+ fieldErrors := make([]apierror.FieldError, 0, len(ve))
516
+ for _, fe := range ve {
517
+ fieldErrors = append(fieldErrors, apierror.FieldError{
518
+ Field: fe.Field(),
519
+ Message: formatValidationMessage(fe),
520
+ })
521
+ }
522
+
523
+ apiErr := apierror.ValidationFailed(fieldErrors)
524
+ c.JSON(apiErr.Status, apiErr.ToResponse())
525
+ }
526
+
527
+ // formatValidationMessage 将 validator tag 转换为可读的错误消息
528
+ func formatValidationMessage(fe validator.FieldError) string {
529
+ switch fe.Tag() {
530
+ case "required":
531
+ return "is required"
532
+ case "email":
533
+ return "must be a valid email"
534
+ case "min":
535
+ return "must be at least " + fe.Param()
536
+ case "max":
537
+ return "must be at most " + fe.Param()
538
+ case "len":
539
+ return "must have length " + fe.Param()
540
+ case "oneof":
541
+ return "must be one of: " + fe.Param()
542
+ case "uuid":
543
+ return "must be a valid UUID"
544
+ case "url":
545
+ return "must be a valid URL"
546
+ case "gte":
547
+ return "must be greater than or equal to " + fe.Param()
548
+ case "lte":
549
+ return "must be less than or equal to " + fe.Param()
550
+ case "gt":
551
+ return "must be greater than " + fe.Param()
552
+ case "lt":
553
+ return "must be less than " + fe.Param()
554
+ default:
555
+ return "failed on " + fe.Tag() + " validation"
556
+ }
557
+ }
558
+ ```
@@ -0,0 +1,124 @@
1
+ # Event Runtime Boundary Standards
2
+
3
+ This document defines the binding runtime split between `platform-api`, `admin-api`, `worker`, and the transactional outbox relay.
4
+
5
+ It is a rules document, not a sample implementation guide.
6
+
7
+ ## Final Boundary
8
+
9
+ - Aggregate-owner projections run in the runtime that owns the source aggregate state machine.
10
+ - Cross-process side effects run only from durable outbox events.
11
+ - `worker` consumes downstream public events only; it does not rebuild source projections.
12
+ - Partial aggregate families must use explicit event-name whitelists, not broad wildcards.
13
+ - Every irreversible cross-process workflow must have one E2E contract test plus one relay whitelist regression test.
14
+
15
+ ## Industry Alignment
16
+
17
+ | Decision Point | Industry Pattern | Used By | Our Choice | Rationale |
18
+ | --- | --- | --- | --- | --- |
19
+ | State change + async publish | Transactional Outbox | AWS Prescriptive Guidance, Shopify, Stripe-style event platforms | Transactional outbox | Prevents committed state without downstream delivery and removes dual-write races. |
20
+ | Public event contract | Explicit event type contract | Stripe Events, GitHub Webhooks | Explicit cross-process event whitelist | Downstream consumers must depend on stable named events, not accidental aggregate-wide fan-out. |
21
+ | Projection ownership | Source service owns source projections | Stripe-style service ownership, AWS service boundaries | `platform-api` owns identity/user projection listeners | Source truth and projection repair must stay in the runtime that owns the lifecycle. |
22
+ | Background processing | Worker consumes durable side effects only | AWS async workers, Shopify job workers | `worker` handles downstream cleanup and notifications only | Prevents duplicate projection work, duplicate bootstrap side effects, and split-brain lifecycle handling. |
23
+ | Account closure orchestration | Immediate access revocation + async cleanup saga | Auth0, AWS account closure, GitHub account deletion | Identity-led closure saga | Authentication truth closes first; cleanup follows via durable events. |
24
+
25
+ ## Binding Rules
26
+
27
+ ### 1. Source Aggregate Listeners Stay with the Source Runtime
28
+
29
+ Rules:
30
+
31
+ - `identity.*` source lifecycle listeners run in `platform-api`.
32
+ - User projection listeners that materialize `p_user_users` and `p_user_product_users` from identity events run in `platform-api`.
33
+ - `worker` must not register source listeners that create or repair identity/user projections.
34
+ - `admin-api` may write its own outbox events when it owns a write path, but it must not subscribe to source aggregate events just to recreate platform projections.
35
+
36
+ Forbidden:
37
+
38
+ - Registering `IdentityEventListener` in `worker`
39
+ - Registering `UserEventListener` in `worker`
40
+ - Replaying identity bootstrap side effects from both `platform-api` and `worker`
41
+
42
+ ### 2. Cross-Process Delivery Must Use Public Durable Events
43
+
44
+ Rules:
45
+
46
+ - Any event needed by another runtime must be written to `sys_outbox_events`.
47
+ - Cross-process subscriptions consume `internal/sharedevents` public contracts only.
48
+ - The relay whitelist in `ProvideRelayConfig()` is a public API surface and must be reviewed like an external contract.
49
+
50
+ Forbidden:
51
+
52
+ - Depending on in-process `eventbus.PublishAsync()` for worker-visible side effects
53
+ - Publishing private domain payloads directly to another runtime
54
+ - Treating relay config as an implementation detail
55
+
56
+ ### 3. Wildcards Are Allowed Only for Full Public Families
57
+
58
+ Rules:
59
+
60
+ - Use aggregate wildcards only when every event in that family is intentionally public and schema-stable across runtimes.
61
+ - Use exact event names when only one or a few events in the family are public.
62
+ - `user.deleted` must stay explicit because `user.created` and `user.updated` are local projection concerns, not worker-wide side effects.
63
+
64
+ Examples:
65
+
66
+ - Allowed: `payment.*`, `order.*`, `subscription.*`
67
+ - Required exact match: `user.deleted`
68
+
69
+ Forbidden:
70
+
71
+ - `user.*` in relay config
72
+ - Adding a wildcard because it is “easier”
73
+ - Reusing a human-readable reason string as a machine routing key
74
+
75
+ ### 4. Worker Owns Side Effects, Not Source Truth
76
+
77
+ Worker responsibilities:
78
+
79
+ - notifications
80
+ - API key revocation
81
+ - subscription cleanup
82
+ - quota / entitlement / credit side effects
83
+ - product data cleanup
84
+
85
+ Worker must not own:
86
+
87
+ - identity status projection
88
+ - user bootstrap projection
89
+ - default profile creation
90
+ - product-user bootstrap reconciliation
91
+
92
+ ### 5. Account Closure Event Flow
93
+
94
+ Canonical flow:
95
+
96
+ 1. `POST /api/v1/deletion/request`
97
+ 2. Identity service revokes sessions and updates identity lifecycle
98
+ 3. Identity service writes durable identity outbox event
99
+ 4. `platform-api` local listeners project user and product-user lifecycle changes
100
+ 5. User service writes durable `user.deleted`
101
+ 6. Relay publishes `user.deleted` to cross-process consumers
102
+ 7. `worker` executes cleanup side effects
103
+
104
+ Key guarantee:
105
+
106
+ - Access revocation must complete before asynchronous cleanup is considered successful.
107
+
108
+ ### 6. Required Regression Coverage
109
+
110
+ For every new cross-process workflow:
111
+
112
+ - add one unit test that asserts the exact `ProvideRelayConfig()` whitelist
113
+ - add one E2E test that proves the externally observable terminal state
114
+
115
+ The unit test protects configuration drift.
116
+ The E2E test protects runtime orchestration drift.
117
+
118
+ ## Review Checklist
119
+
120
+ - Does this new listener belong to the source runtime or the side-effect runtime?
121
+ - Is the event public enough to cross process, or is it only a local projection event?
122
+ - Is the relay whitelist exact where the aggregate family is only partially public?
123
+ - Does `worker` consume durable public events only?
124
+ - Does the E2E test assert state rows, access contract, and downstream cleanup?