@wazir-dev/cli 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.
Files changed (629) hide show
  1. package/AGENTS.md +111 -0
  2. package/CHANGELOG.md +14 -0
  3. package/CONTRIBUTING.md +101 -0
  4. package/LICENSE +21 -0
  5. package/README.md +314 -0
  6. package/assets/composition-engine.mmd +34 -0
  7. package/assets/demo-script.sh +17 -0
  8. package/assets/logo-dark.svg +14 -0
  9. package/assets/logo.svg +14 -0
  10. package/assets/pipeline.mmd +39 -0
  11. package/assets/record-demo.sh +51 -0
  12. package/docs/README.md +51 -0
  13. package/docs/adapters/context-mode.md +60 -0
  14. package/docs/concepts/architecture.md +87 -0
  15. package/docs/concepts/artifact-model.md +60 -0
  16. package/docs/concepts/composition-engine.md +36 -0
  17. package/docs/concepts/indexing-and-recall.md +160 -0
  18. package/docs/concepts/observability.md +41 -0
  19. package/docs/concepts/roles-and-workflows.md +59 -0
  20. package/docs/concepts/terminology-policy.md +27 -0
  21. package/docs/getting-started/01-installation.md +78 -0
  22. package/docs/getting-started/02-first-run.md +102 -0
  23. package/docs/getting-started/03-adding-to-project.md +15 -0
  24. package/docs/getting-started/04-host-setup.md +15 -0
  25. package/docs/guides/ci-integration.md +15 -0
  26. package/docs/guides/creating-skills.md +15 -0
  27. package/docs/guides/expertise-module-authoring.md +15 -0
  28. package/docs/guides/hook-development.md +15 -0
  29. package/docs/guides/memory-and-learnings.md +34 -0
  30. package/docs/guides/multi-host-export.md +15 -0
  31. package/docs/guides/troubleshooting.md +101 -0
  32. package/docs/guides/writing-custom-roles.md +15 -0
  33. package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
  34. package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
  35. package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
  36. package/docs/readmes/INDEX.md +99 -0
  37. package/docs/readmes/features/expertise/README.md +171 -0
  38. package/docs/readmes/features/exports/README.md +222 -0
  39. package/docs/readmes/features/hooks/README.md +103 -0
  40. package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
  41. package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
  42. package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
  43. package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
  44. package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
  45. package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
  46. package/docs/readmes/features/hooks/session-start.md +119 -0
  47. package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
  48. package/docs/readmes/features/roles/README.md +157 -0
  49. package/docs/readmes/features/roles/clarifier.md +152 -0
  50. package/docs/readmes/features/roles/content-author.md +190 -0
  51. package/docs/readmes/features/roles/designer.md +193 -0
  52. package/docs/readmes/features/roles/executor.md +184 -0
  53. package/docs/readmes/features/roles/learner.md +210 -0
  54. package/docs/readmes/features/roles/planner.md +182 -0
  55. package/docs/readmes/features/roles/researcher.md +164 -0
  56. package/docs/readmes/features/roles/reviewer.md +184 -0
  57. package/docs/readmes/features/roles/specifier.md +162 -0
  58. package/docs/readmes/features/roles/verifier.md +215 -0
  59. package/docs/readmes/features/schemas/README.md +178 -0
  60. package/docs/readmes/features/skills/README.md +63 -0
  61. package/docs/readmes/features/skills/brainstorming.md +96 -0
  62. package/docs/readmes/features/skills/debugging.md +148 -0
  63. package/docs/readmes/features/skills/design.md +120 -0
  64. package/docs/readmes/features/skills/prepare-next.md +109 -0
  65. package/docs/readmes/features/skills/run-audit.md +159 -0
  66. package/docs/readmes/features/skills/scan-project.md +109 -0
  67. package/docs/readmes/features/skills/self-audit.md +176 -0
  68. package/docs/readmes/features/skills/tdd.md +137 -0
  69. package/docs/readmes/features/skills/using-skills.md +92 -0
  70. package/docs/readmes/features/skills/verification.md +120 -0
  71. package/docs/readmes/features/skills/writing-plans.md +104 -0
  72. package/docs/readmes/features/tooling/README.md +320 -0
  73. package/docs/readmes/features/workflows/README.md +186 -0
  74. package/docs/readmes/features/workflows/author.md +181 -0
  75. package/docs/readmes/features/workflows/clarify.md +154 -0
  76. package/docs/readmes/features/workflows/design-review.md +171 -0
  77. package/docs/readmes/features/workflows/design.md +169 -0
  78. package/docs/readmes/features/workflows/discover.md +162 -0
  79. package/docs/readmes/features/workflows/execute.md +173 -0
  80. package/docs/readmes/features/workflows/learn.md +167 -0
  81. package/docs/readmes/features/workflows/plan-review.md +165 -0
  82. package/docs/readmes/features/workflows/plan.md +170 -0
  83. package/docs/readmes/features/workflows/prepare-next.md +167 -0
  84. package/docs/readmes/features/workflows/review.md +169 -0
  85. package/docs/readmes/features/workflows/run-audit.md +191 -0
  86. package/docs/readmes/features/workflows/spec-challenge.md +159 -0
  87. package/docs/readmes/features/workflows/specify.md +160 -0
  88. package/docs/readmes/features/workflows/verify.md +177 -0
  89. package/docs/readmes/packages/README.md +50 -0
  90. package/docs/readmes/packages/ajv.md +117 -0
  91. package/docs/readmes/packages/context-mode.md +118 -0
  92. package/docs/readmes/packages/gray-matter.md +116 -0
  93. package/docs/readmes/packages/node-test.md +137 -0
  94. package/docs/readmes/packages/yaml.md +112 -0
  95. package/docs/reference/configuration-reference.md +159 -0
  96. package/docs/reference/expertise-index.md +52 -0
  97. package/docs/reference/git-flow.md +43 -0
  98. package/docs/reference/hooks.md +87 -0
  99. package/docs/reference/host-exports.md +50 -0
  100. package/docs/reference/launch-checklist.md +172 -0
  101. package/docs/reference/marketplace-listings.md +76 -0
  102. package/docs/reference/release-process.md +34 -0
  103. package/docs/reference/roles-reference.md +77 -0
  104. package/docs/reference/skills.md +33 -0
  105. package/docs/reference/templates.md +29 -0
  106. package/docs/reference/tooling-cli.md +94 -0
  107. package/docs/truth-claims.yaml +222 -0
  108. package/expertise/PROGRESS.md +63 -0
  109. package/expertise/README.md +18 -0
  110. package/expertise/antipatterns/PROGRESS.md +56 -0
  111. package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
  112. package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
  113. package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
  114. package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
  115. package/expertise/antipatterns/backend/index.md +24 -0
  116. package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
  117. package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
  118. package/expertise/antipatterns/code/async-antipatterns.md +622 -0
  119. package/expertise/antipatterns/code/code-smells.md +1186 -0
  120. package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
  121. package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
  122. package/expertise/antipatterns/code/index.md +27 -0
  123. package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
  124. package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
  125. package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
  126. package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
  127. package/expertise/antipatterns/design/dark-patterns.md +1121 -0
  128. package/expertise/antipatterns/design/index.md +22 -0
  129. package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
  130. package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
  131. package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
  132. package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
  133. package/expertise/antipatterns/frontend/index.md +23 -0
  134. package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
  135. package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
  136. package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
  137. package/expertise/antipatterns/index.md +31 -0
  138. package/expertise/antipatterns/performance/index.md +20 -0
  139. package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
  140. package/expertise/antipatterns/performance/premature-optimization.md +623 -0
  141. package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
  142. package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
  143. package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
  144. package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
  145. package/expertise/antipatterns/process/index.md +23 -0
  146. package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
  147. package/expertise/antipatterns/security/index.md +20 -0
  148. package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
  149. package/expertise/antipatterns/security/security-theater.md +843 -0
  150. package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
  151. package/expertise/architecture/PROGRESS.md +70 -0
  152. package/expertise/architecture/data/caching-architecture.md +671 -0
  153. package/expertise/architecture/data/data-consistency.md +574 -0
  154. package/expertise/architecture/data/data-modeling.md +536 -0
  155. package/expertise/architecture/data/event-streams-and-queues.md +634 -0
  156. package/expertise/architecture/data/index.md +25 -0
  157. package/expertise/architecture/data/search-architecture.md +663 -0
  158. package/expertise/architecture/data/sql-vs-nosql.md +708 -0
  159. package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
  160. package/expertise/architecture/decisions/build-vs-buy.md +616 -0
  161. package/expertise/architecture/decisions/index.md +23 -0
  162. package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
  163. package/expertise/architecture/decisions/technology-selection.md +616 -0
  164. package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
  165. package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
  166. package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
  167. package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
  168. package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
  169. package/expertise/architecture/distributed/index.md +25 -0
  170. package/expertise/architecture/distributed/saga-pattern.md +797 -0
  171. package/expertise/architecture/foundations/architectural-thinking.md +460 -0
  172. package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
  173. package/expertise/architecture/foundations/design-principles-solid.md +649 -0
  174. package/expertise/architecture/foundations/domain-driven-design.md +719 -0
  175. package/expertise/architecture/foundations/index.md +25 -0
  176. package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
  177. package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
  178. package/expertise/architecture/index.md +34 -0
  179. package/expertise/architecture/integration/api-design-graphql.md +638 -0
  180. package/expertise/architecture/integration/api-design-grpc.md +804 -0
  181. package/expertise/architecture/integration/api-design-rest.md +892 -0
  182. package/expertise/architecture/integration/index.md +25 -0
  183. package/expertise/architecture/integration/third-party-integration.md +795 -0
  184. package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
  185. package/expertise/architecture/integration/websockets-realtime.md +791 -0
  186. package/expertise/architecture/mobile-architecture/index.md +22 -0
  187. package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
  188. package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
  189. package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
  190. package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
  191. package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
  192. package/expertise/architecture/patterns/event-driven.md +797 -0
  193. package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
  194. package/expertise/architecture/patterns/index.md +27 -0
  195. package/expertise/architecture/patterns/layered-architecture.md +736 -0
  196. package/expertise/architecture/patterns/microservices.md +753 -0
  197. package/expertise/architecture/patterns/modular-monolith.md +692 -0
  198. package/expertise/architecture/patterns/monolith.md +626 -0
  199. package/expertise/architecture/patterns/plugin-architecture.md +735 -0
  200. package/expertise/architecture/patterns/serverless.md +780 -0
  201. package/expertise/architecture/scaling/database-scaling.md +615 -0
  202. package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
  203. package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
  204. package/expertise/architecture/scaling/index.md +24 -0
  205. package/expertise/architecture/scaling/multi-tenancy.md +800 -0
  206. package/expertise/architecture/scaling/stateless-design.md +787 -0
  207. package/expertise/backend/embedded-firmware.md +625 -0
  208. package/expertise/backend/go.md +853 -0
  209. package/expertise/backend/index.md +24 -0
  210. package/expertise/backend/java-spring.md +448 -0
  211. package/expertise/backend/node-typescript.md +625 -0
  212. package/expertise/backend/python-fastapi.md +724 -0
  213. package/expertise/backend/rust.md +458 -0
  214. package/expertise/backend/solidity.md +711 -0
  215. package/expertise/composition-map.yaml +443 -0
  216. package/expertise/content/foundations/content-modeling.md +395 -0
  217. package/expertise/content/foundations/editorial-standards.md +449 -0
  218. package/expertise/content/foundations/index.md +24 -0
  219. package/expertise/content/foundations/microcopy.md +455 -0
  220. package/expertise/content/foundations/terminology-governance.md +509 -0
  221. package/expertise/content/index.md +34 -0
  222. package/expertise/content/patterns/accessibility-copy.md +518 -0
  223. package/expertise/content/patterns/index.md +24 -0
  224. package/expertise/content/patterns/notification-content.md +433 -0
  225. package/expertise/content/patterns/sample-content.md +486 -0
  226. package/expertise/content/patterns/state-copy.md +439 -0
  227. package/expertise/design/PROGRESS.md +58 -0
  228. package/expertise/design/disciplines/dark-mode-theming.md +577 -0
  229. package/expertise/design/disciplines/design-systems.md +595 -0
  230. package/expertise/design/disciplines/index.md +25 -0
  231. package/expertise/design/disciplines/information-architecture.md +800 -0
  232. package/expertise/design/disciplines/interaction-design.md +788 -0
  233. package/expertise/design/disciplines/responsive-design.md +552 -0
  234. package/expertise/design/disciplines/usability-testing.md +516 -0
  235. package/expertise/design/disciplines/user-research.md +792 -0
  236. package/expertise/design/foundations/accessibility-design.md +796 -0
  237. package/expertise/design/foundations/color-theory.md +797 -0
  238. package/expertise/design/foundations/iconography.md +795 -0
  239. package/expertise/design/foundations/index.md +26 -0
  240. package/expertise/design/foundations/motion-and-animation.md +653 -0
  241. package/expertise/design/foundations/rtl-design.md +585 -0
  242. package/expertise/design/foundations/spacing-and-layout.md +607 -0
  243. package/expertise/design/foundations/typography.md +800 -0
  244. package/expertise/design/foundations/visual-hierarchy.md +761 -0
  245. package/expertise/design/index.md +32 -0
  246. package/expertise/design/patterns/authentication-flows.md +474 -0
  247. package/expertise/design/patterns/content-consumption.md +789 -0
  248. package/expertise/design/patterns/data-display.md +618 -0
  249. package/expertise/design/patterns/e-commerce.md +1494 -0
  250. package/expertise/design/patterns/feedback-and-states.md +642 -0
  251. package/expertise/design/patterns/forms-and-input.md +819 -0
  252. package/expertise/design/patterns/gamification.md +801 -0
  253. package/expertise/design/patterns/index.md +31 -0
  254. package/expertise/design/patterns/microinteractions.md +449 -0
  255. package/expertise/design/patterns/navigation.md +800 -0
  256. package/expertise/design/patterns/notifications.md +705 -0
  257. package/expertise/design/patterns/onboarding.md +700 -0
  258. package/expertise/design/patterns/search-and-filter.md +601 -0
  259. package/expertise/design/patterns/settings-and-preferences.md +768 -0
  260. package/expertise/design/patterns/social-and-community.md +748 -0
  261. package/expertise/design/platforms/desktop-native.md +612 -0
  262. package/expertise/design/platforms/index.md +25 -0
  263. package/expertise/design/platforms/mobile-android.md +825 -0
  264. package/expertise/design/platforms/mobile-cross-platform.md +983 -0
  265. package/expertise/design/platforms/mobile-ios.md +699 -0
  266. package/expertise/design/platforms/tablet.md +794 -0
  267. package/expertise/design/platforms/web-dashboard.md +790 -0
  268. package/expertise/design/platforms/web-responsive.md +550 -0
  269. package/expertise/design/psychology/behavioral-nudges.md +449 -0
  270. package/expertise/design/psychology/cognitive-load.md +1191 -0
  271. package/expertise/design/psychology/error-psychology.md +778 -0
  272. package/expertise/design/psychology/index.md +22 -0
  273. package/expertise/design/psychology/persuasive-design.md +736 -0
  274. package/expertise/design/psychology/user-mental-models.md +623 -0
  275. package/expertise/design/tooling/open-pencil.md +266 -0
  276. package/expertise/frontend/angular.md +1073 -0
  277. package/expertise/frontend/desktop-electron.md +546 -0
  278. package/expertise/frontend/flutter.md +782 -0
  279. package/expertise/frontend/index.md +27 -0
  280. package/expertise/frontend/native-android.md +409 -0
  281. package/expertise/frontend/native-ios.md +490 -0
  282. package/expertise/frontend/react-native.md +1160 -0
  283. package/expertise/frontend/react.md +808 -0
  284. package/expertise/frontend/vue.md +1089 -0
  285. package/expertise/humanize/domain-rules-code.md +79 -0
  286. package/expertise/humanize/domain-rules-content.md +67 -0
  287. package/expertise/humanize/domain-rules-technical-docs.md +56 -0
  288. package/expertise/humanize/index.md +35 -0
  289. package/expertise/humanize/self-audit-checklist.md +87 -0
  290. package/expertise/humanize/sentence-patterns.md +218 -0
  291. package/expertise/humanize/vocabulary-blacklist.md +105 -0
  292. package/expertise/i18n/PROGRESS.md +65 -0
  293. package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
  294. package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
  295. package/expertise/i18n/advanced/complex-scripts.md +30 -0
  296. package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
  297. package/expertise/i18n/advanced/testing-i18n.md +28 -0
  298. package/expertise/i18n/content/content-adaptation.md +23 -0
  299. package/expertise/i18n/content/locale-specific-formatting.md +23 -0
  300. package/expertise/i18n/content/machine-translation-integration.md +28 -0
  301. package/expertise/i18n/content/translation-management.md +29 -0
  302. package/expertise/i18n/foundations/date-time-calendars.md +67 -0
  303. package/expertise/i18n/foundations/i18n-architecture.md +272 -0
  304. package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
  305. package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
  306. package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
  307. package/expertise/i18n/foundations/string-externalization.md +236 -0
  308. package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
  309. package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
  310. package/expertise/i18n/index.md +38 -0
  311. package/expertise/i18n/platform/backend-i18n.md +31 -0
  312. package/expertise/i18n/platform/flutter-i18n.md +148 -0
  313. package/expertise/i18n/platform/native-android-i18n.md +36 -0
  314. package/expertise/i18n/platform/native-ios-i18n.md +36 -0
  315. package/expertise/i18n/platform/react-i18n.md +103 -0
  316. package/expertise/i18n/platform/web-css-i18n.md +81 -0
  317. package/expertise/i18n/rtl/arabic-specific.md +175 -0
  318. package/expertise/i18n/rtl/hebrew-specific.md +149 -0
  319. package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
  320. package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
  321. package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
  322. package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
  323. package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
  324. package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
  325. package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
  326. package/expertise/i18n/rtl/rtl-typography.md +160 -0
  327. package/expertise/index.md +113 -0
  328. package/expertise/index.yaml +216 -0
  329. package/expertise/infrastructure/cloud-aws.md +597 -0
  330. package/expertise/infrastructure/cloud-gcp.md +599 -0
  331. package/expertise/infrastructure/cybersecurity.md +816 -0
  332. package/expertise/infrastructure/database-mongodb.md +447 -0
  333. package/expertise/infrastructure/database-postgres.md +400 -0
  334. package/expertise/infrastructure/devops-cicd.md +787 -0
  335. package/expertise/infrastructure/index.md +27 -0
  336. package/expertise/performance/PROGRESS.md +50 -0
  337. package/expertise/performance/backend/api-latency.md +1204 -0
  338. package/expertise/performance/backend/background-jobs.md +506 -0
  339. package/expertise/performance/backend/connection-pooling.md +1209 -0
  340. package/expertise/performance/backend/database-query-optimization.md +515 -0
  341. package/expertise/performance/backend/index.md +23 -0
  342. package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
  343. package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
  344. package/expertise/performance/foundations/caching-strategies.md +489 -0
  345. package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
  346. package/expertise/performance/foundations/index.md +24 -0
  347. package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
  348. package/expertise/performance/foundations/memory-management.md +964 -0
  349. package/expertise/performance/foundations/performance-budgets.md +1314 -0
  350. package/expertise/performance/index.md +31 -0
  351. package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
  352. package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
  353. package/expertise/performance/infrastructure/index.md +22 -0
  354. package/expertise/performance/infrastructure/load-balancing.md +1081 -0
  355. package/expertise/performance/infrastructure/observability.md +1079 -0
  356. package/expertise/performance/mobile/index.md +23 -0
  357. package/expertise/performance/mobile/mobile-animations.md +544 -0
  358. package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
  359. package/expertise/performance/mobile/mobile-network.md +452 -0
  360. package/expertise/performance/mobile/mobile-rendering.md +599 -0
  361. package/expertise/performance/mobile/mobile-startup-time.md +505 -0
  362. package/expertise/performance/platform-specific/flutter-performance.md +647 -0
  363. package/expertise/performance/platform-specific/index.md +22 -0
  364. package/expertise/performance/platform-specific/node-performance.md +1307 -0
  365. package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
  366. package/expertise/performance/platform-specific/react-performance.md +1403 -0
  367. package/expertise/performance/web/bundle-optimization.md +1239 -0
  368. package/expertise/performance/web/image-and-media.md +636 -0
  369. package/expertise/performance/web/index.md +24 -0
  370. package/expertise/performance/web/network-optimization.md +1133 -0
  371. package/expertise/performance/web/rendering-performance.md +1098 -0
  372. package/expertise/performance/web/ssr-and-hydration.md +918 -0
  373. package/expertise/performance/web/web-vitals.md +1374 -0
  374. package/expertise/quality/accessibility.md +985 -0
  375. package/expertise/quality/evidence-based-verification.md +499 -0
  376. package/expertise/quality/index.md +24 -0
  377. package/expertise/quality/ml-model-audit.md +614 -0
  378. package/expertise/quality/performance.md +600 -0
  379. package/expertise/quality/testing-api.md +891 -0
  380. package/expertise/quality/testing-mobile.md +496 -0
  381. package/expertise/quality/testing-web.md +849 -0
  382. package/expertise/security/PROGRESS.md +54 -0
  383. package/expertise/security/agentic-identity.md +540 -0
  384. package/expertise/security/compliance-frameworks.md +601 -0
  385. package/expertise/security/data/data-encryption.md +364 -0
  386. package/expertise/security/data/data-privacy-gdpr.md +692 -0
  387. package/expertise/security/data/database-security.md +1171 -0
  388. package/expertise/security/data/index.md +22 -0
  389. package/expertise/security/data/pii-handling.md +531 -0
  390. package/expertise/security/foundations/authentication.md +1041 -0
  391. package/expertise/security/foundations/authorization.md +603 -0
  392. package/expertise/security/foundations/cryptography.md +1001 -0
  393. package/expertise/security/foundations/index.md +25 -0
  394. package/expertise/security/foundations/owasp-top-10.md +1354 -0
  395. package/expertise/security/foundations/secrets-management.md +1217 -0
  396. package/expertise/security/foundations/secure-sdlc.md +700 -0
  397. package/expertise/security/foundations/supply-chain-security.md +698 -0
  398. package/expertise/security/index.md +31 -0
  399. package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
  400. package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
  401. package/expertise/security/infrastructure/container-security.md +721 -0
  402. package/expertise/security/infrastructure/incident-response.md +1295 -0
  403. package/expertise/security/infrastructure/index.md +24 -0
  404. package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
  405. package/expertise/security/infrastructure/network-security.md +1337 -0
  406. package/expertise/security/mobile/index.md +23 -0
  407. package/expertise/security/mobile/mobile-android-security.md +1218 -0
  408. package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
  409. package/expertise/security/mobile/mobile-data-storage.md +1265 -0
  410. package/expertise/security/mobile/mobile-ios-security.md +1401 -0
  411. package/expertise/security/mobile/mobile-network-security.md +1520 -0
  412. package/expertise/security/smart-contract-security.md +594 -0
  413. package/expertise/security/testing/index.md +22 -0
  414. package/expertise/security/testing/penetration-testing.md +1258 -0
  415. package/expertise/security/testing/security-code-review.md +1765 -0
  416. package/expertise/security/testing/threat-modeling.md +1074 -0
  417. package/expertise/security/testing/vulnerability-scanning.md +1062 -0
  418. package/expertise/security/web/api-security.md +586 -0
  419. package/expertise/security/web/cors-and-headers.md +433 -0
  420. package/expertise/security/web/csrf.md +562 -0
  421. package/expertise/security/web/file-upload.md +1477 -0
  422. package/expertise/security/web/index.md +25 -0
  423. package/expertise/security/web/injection.md +1375 -0
  424. package/expertise/security/web/session-management.md +1101 -0
  425. package/expertise/security/web/xss.md +1158 -0
  426. package/exports/README.md +17 -0
  427. package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
  428. package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
  429. package/exports/hosts/claude/.claude/agents/designer.md +55 -0
  430. package/exports/hosts/claude/.claude/agents/executor.md +55 -0
  431. package/exports/hosts/claude/.claude/agents/learner.md +51 -0
  432. package/exports/hosts/claude/.claude/agents/planner.md +53 -0
  433. package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
  434. package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
  435. package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
  436. package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
  437. package/exports/hosts/claude/.claude/commands/author.md +42 -0
  438. package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
  439. package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
  440. package/exports/hosts/claude/.claude/commands/design.md +44 -0
  441. package/exports/hosts/claude/.claude/commands/discover.md +37 -0
  442. package/exports/hosts/claude/.claude/commands/execute.md +48 -0
  443. package/exports/hosts/claude/.claude/commands/learn.md +38 -0
  444. package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
  445. package/exports/hosts/claude/.claude/commands/plan.md +39 -0
  446. package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
  447. package/exports/hosts/claude/.claude/commands/review.md +40 -0
  448. package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
  449. package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
  450. package/exports/hosts/claude/.claude/commands/specify.md +38 -0
  451. package/exports/hosts/claude/.claude/commands/verify.md +37 -0
  452. package/exports/hosts/claude/.claude/settings.json +34 -0
  453. package/exports/hosts/claude/CLAUDE.md +19 -0
  454. package/exports/hosts/claude/export.manifest.json +38 -0
  455. package/exports/hosts/claude/host-package.json +67 -0
  456. package/exports/hosts/codex/AGENTS.md +19 -0
  457. package/exports/hosts/codex/export.manifest.json +38 -0
  458. package/exports/hosts/codex/host-package.json +41 -0
  459. package/exports/hosts/cursor/.cursor/hooks.json +16 -0
  460. package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
  461. package/exports/hosts/cursor/export.manifest.json +38 -0
  462. package/exports/hosts/cursor/host-package.json +42 -0
  463. package/exports/hosts/gemini/GEMINI.md +19 -0
  464. package/exports/hosts/gemini/export.manifest.json +38 -0
  465. package/exports/hosts/gemini/host-package.json +41 -0
  466. package/hooks/README.md +18 -0
  467. package/hooks/definitions/loop_cap_guard.yaml +21 -0
  468. package/hooks/definitions/post_tool_capture.yaml +24 -0
  469. package/hooks/definitions/pre_compact_summary.yaml +19 -0
  470. package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
  471. package/hooks/definitions/protected_path_write_guard.yaml +19 -0
  472. package/hooks/definitions/session_start.yaml +19 -0
  473. package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
  474. package/hooks/loop-cap-guard +17 -0
  475. package/hooks/post-tool-lint +36 -0
  476. package/hooks/protected-path-write-guard +17 -0
  477. package/hooks/session-start +41 -0
  478. package/llms-full.txt +2355 -0
  479. package/llms.txt +43 -0
  480. package/package.json +79 -0
  481. package/roles/README.md +20 -0
  482. package/roles/clarifier.md +42 -0
  483. package/roles/content-author.md +63 -0
  484. package/roles/designer.md +55 -0
  485. package/roles/executor.md +55 -0
  486. package/roles/learner.md +51 -0
  487. package/roles/planner.md +53 -0
  488. package/roles/researcher.md +43 -0
  489. package/roles/reviewer.md +54 -0
  490. package/roles/specifier.md +47 -0
  491. package/roles/verifier.md +71 -0
  492. package/schemas/README.md +24 -0
  493. package/schemas/accepted-learning.schema.json +20 -0
  494. package/schemas/author-artifact.schema.json +156 -0
  495. package/schemas/clarification.schema.json +19 -0
  496. package/schemas/design-artifact.schema.json +80 -0
  497. package/schemas/docs-claim.schema.json +18 -0
  498. package/schemas/export-manifest.schema.json +20 -0
  499. package/schemas/hook.schema.json +67 -0
  500. package/schemas/host-export-package.schema.json +18 -0
  501. package/schemas/implementation-plan.schema.json +19 -0
  502. package/schemas/proposed-learning.schema.json +19 -0
  503. package/schemas/research.schema.json +18 -0
  504. package/schemas/review.schema.json +29 -0
  505. package/schemas/run-manifest.schema.json +18 -0
  506. package/schemas/spec-challenge.schema.json +18 -0
  507. package/schemas/spec.schema.json +20 -0
  508. package/schemas/usage.schema.json +102 -0
  509. package/schemas/verification-proof.schema.json +29 -0
  510. package/schemas/wazir-manifest.schema.json +173 -0
  511. package/skills/README.md +40 -0
  512. package/skills/brainstorming/SKILL.md +77 -0
  513. package/skills/debugging/SKILL.md +50 -0
  514. package/skills/design/SKILL.md +61 -0
  515. package/skills/dispatching-parallel-agents/SKILL.md +128 -0
  516. package/skills/executing-plans/SKILL.md +70 -0
  517. package/skills/finishing-a-development-branch/SKILL.md +169 -0
  518. package/skills/humanize/SKILL.md +123 -0
  519. package/skills/init-pipeline/SKILL.md +124 -0
  520. package/skills/prepare-next/SKILL.md +20 -0
  521. package/skills/receiving-code-review/SKILL.md +123 -0
  522. package/skills/requesting-code-review/SKILL.md +105 -0
  523. package/skills/requesting-code-review/code-reviewer.md +108 -0
  524. package/skills/run-audit/SKILL.md +197 -0
  525. package/skills/scan-project/SKILL.md +41 -0
  526. package/skills/self-audit/SKILL.md +153 -0
  527. package/skills/subagent-driven-development/SKILL.md +154 -0
  528. package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
  529. package/skills/subagent-driven-development/implementer-prompt.md +102 -0
  530. package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
  531. package/skills/tdd/SKILL.md +23 -0
  532. package/skills/using-git-worktrees/SKILL.md +163 -0
  533. package/skills/using-skills/SKILL.md +95 -0
  534. package/skills/verification/SKILL.md +22 -0
  535. package/skills/wazir/SKILL.md +463 -0
  536. package/skills/writing-plans/SKILL.md +30 -0
  537. package/skills/writing-skills/SKILL.md +157 -0
  538. package/skills/writing-skills/anthropic-best-practices.md +122 -0
  539. package/skills/writing-skills/persuasion-principles.md +50 -0
  540. package/templates/README.md +20 -0
  541. package/templates/artifacts/README.md +10 -0
  542. package/templates/artifacts/accepted-learning.md +19 -0
  543. package/templates/artifacts/accepted-learning.template.json +12 -0
  544. package/templates/artifacts/author.md +74 -0
  545. package/templates/artifacts/author.template.json +19 -0
  546. package/templates/artifacts/clarification.md +21 -0
  547. package/templates/artifacts/clarification.template.json +12 -0
  548. package/templates/artifacts/execute-notes.md +19 -0
  549. package/templates/artifacts/implementation-plan.md +21 -0
  550. package/templates/artifacts/implementation-plan.template.json +11 -0
  551. package/templates/artifacts/learning-proposal.md +19 -0
  552. package/templates/artifacts/next-run-handoff.md +21 -0
  553. package/templates/artifacts/plan-review.md +19 -0
  554. package/templates/artifacts/proposed-learning.template.json +12 -0
  555. package/templates/artifacts/research.md +21 -0
  556. package/templates/artifacts/research.template.json +12 -0
  557. package/templates/artifacts/review-findings.md +19 -0
  558. package/templates/artifacts/review.template.json +11 -0
  559. package/templates/artifacts/run-manifest.template.json +8 -0
  560. package/templates/artifacts/spec-challenge.md +19 -0
  561. package/templates/artifacts/spec-challenge.template.json +11 -0
  562. package/templates/artifacts/spec.md +21 -0
  563. package/templates/artifacts/spec.template.json +12 -0
  564. package/templates/artifacts/verification-proof.md +19 -0
  565. package/templates/artifacts/verification-proof.template.json +11 -0
  566. package/templates/examples/accepted-learning.example.json +14 -0
  567. package/templates/examples/author.example.json +152 -0
  568. package/templates/examples/clarification.example.json +15 -0
  569. package/templates/examples/docs-claim.example.json +8 -0
  570. package/templates/examples/export-manifest.example.json +7 -0
  571. package/templates/examples/host-export-package.example.json +11 -0
  572. package/templates/examples/implementation-plan.example.json +17 -0
  573. package/templates/examples/proposed-learning.example.json +13 -0
  574. package/templates/examples/research.example.json +15 -0
  575. package/templates/examples/research.example.md +6 -0
  576. package/templates/examples/review.example.json +17 -0
  577. package/templates/examples/run-manifest.example.json +9 -0
  578. package/templates/examples/spec-challenge.example.json +14 -0
  579. package/templates/examples/spec.example.json +21 -0
  580. package/templates/examples/verification-proof.example.json +21 -0
  581. package/templates/examples/wazir-manifest.example.yaml +65 -0
  582. package/templates/task-definition-schema.md +99 -0
  583. package/tooling/README.md +20 -0
  584. package/tooling/src/adapters/context-mode.js +50 -0
  585. package/tooling/src/capture/command.js +376 -0
  586. package/tooling/src/capture/store.js +99 -0
  587. package/tooling/src/capture/usage.js +270 -0
  588. package/tooling/src/checks/branches.js +50 -0
  589. package/tooling/src/checks/brand-truth.js +110 -0
  590. package/tooling/src/checks/changelog.js +231 -0
  591. package/tooling/src/checks/command-registry.js +36 -0
  592. package/tooling/src/checks/commits.js +102 -0
  593. package/tooling/src/checks/docs-drift.js +103 -0
  594. package/tooling/src/checks/docs-truth.js +201 -0
  595. package/tooling/src/checks/runtime-surface.js +156 -0
  596. package/tooling/src/cli.js +116 -0
  597. package/tooling/src/command-options.js +56 -0
  598. package/tooling/src/commands/validate.js +320 -0
  599. package/tooling/src/doctor/command.js +91 -0
  600. package/tooling/src/export/command.js +77 -0
  601. package/tooling/src/export/compiler.js +498 -0
  602. package/tooling/src/guards/loop-cap-guard.js +52 -0
  603. package/tooling/src/guards/protected-path-write-guard.js +67 -0
  604. package/tooling/src/index/command.js +152 -0
  605. package/tooling/src/index/storage.js +1061 -0
  606. package/tooling/src/index/summarizers.js +261 -0
  607. package/tooling/src/loaders.js +18 -0
  608. package/tooling/src/project-root.js +22 -0
  609. package/tooling/src/recall/command.js +225 -0
  610. package/tooling/src/schema-validator.js +30 -0
  611. package/tooling/src/state-root.js +40 -0
  612. package/tooling/src/status/command.js +71 -0
  613. package/wazir.manifest.yaml +135 -0
  614. package/workflows/README.md +19 -0
  615. package/workflows/author.md +42 -0
  616. package/workflows/clarify.md +38 -0
  617. package/workflows/design-review.md +46 -0
  618. package/workflows/design.md +44 -0
  619. package/workflows/discover.md +37 -0
  620. package/workflows/execute.md +48 -0
  621. package/workflows/learn.md +38 -0
  622. package/workflows/plan-review.md +42 -0
  623. package/workflows/plan.md +39 -0
  624. package/workflows/prepare-next.md +37 -0
  625. package/workflows/review.md +40 -0
  626. package/workflows/run-audit.md +41 -0
  627. package/workflows/spec-challenge.md +41 -0
  628. package/workflows/specify.md +38 -0
  629. package/workflows/verify.md +37 -0
@@ -0,0 +1,795 @@
1
+ # Third-Party Integration -- Architecture Expertise Module
2
+
3
+ > Third-party integration covers the architecture of connecting your system to external services
4
+ > (payment processors, email providers, cloud APIs, SaaS platforms). The key principle: never let
5
+ > a third-party API shape your domain model. Use adapter/anti-corruption layers to isolate external
6
+ > dependencies so that vendor changes, outages, and API deprecations remain contained at the boundary.
7
+
8
+ > **Category:** Integration
9
+ > **Complexity:** Moderate
10
+ > **Applies when:** Integrating with any external service -- payment processing, email/SMS, cloud storage, analytics, authentication providers, AI/ML APIs, or any vendor whose availability and API surface you do not control.
11
+
12
+ ---
13
+
14
+ ## What This Is (and What It Isn't)
15
+
16
+ ### Core Concepts
17
+
18
+ **Adapter Pattern for External Services.** An adapter wraps a third-party API behind an interface
19
+ that your domain defines. Your domain declares what it needs (a port): "I need to charge a
20
+ customer." The adapter translates that into Stripe's `PaymentIntent.create()` call, or Braintree's
21
+ `Transaction.sale()`, or Adyen's `/payments` endpoint. The domain never imports the vendor SDK.
22
+ The adapter lives in the infrastructure layer and implements the domain's port.
23
+
24
+ **Anti-Corruption Layer (ACL).** Coined by Eric Evans in *Domain-Driven Design* (2003), the ACL
25
+ is a boundary that prevents an external system's model from leaking into your domain. The external
26
+ system has its own language, its own entity shapes, its own invariants. The ACL translates between
27
+ the two models. Without it, your domain objects accumulate fields like `stripe_customer_id`,
28
+ `twilio_message_sid`, `sendgrid_template_id` -- vendor concepts that have no place in your
29
+ business logic. The ACL is more than an adapter: it actively reshapes data, maps foreign concepts
30
+ to domain concepts, and may aggregate or decompose entities to maintain domain integrity.
31
+
32
+ **Facade for External APIs.** When an external service exposes a sprawling API surface (AWS S3
33
+ has 100+ operations, Stripe has 300+ endpoints), a facade narrows the interface to only the
34
+ operations your system actually uses. This reduces the blast radius of API changes and makes the
35
+ integration testable. If you use 4 of Stripe's 300 endpoints, your facade exposes 4 methods.
36
+
37
+ **Vendor Abstraction.** A generalized interface that lets you swap between vendors without
38
+ touching application code. Your system defines a `NotificationSender` interface; one adapter
39
+ sends via Twilio SMS, another via AWS SNS, another via Firebase Cloud Messaging. The application
40
+ code calls `notificationSender.send(recipient, message)` and does not know or care which vendor
41
+ fulfills it. This is the Dependency Inversion Principle applied to external service boundaries.
42
+
43
+ ### What It Is NOT
44
+
45
+ **Not about wrapping every HTTP call.** If your system makes a one-off call to a public REST API
46
+ to fetch weather data for a display widget, you do not need a port, adapter, ACL, and factory.
47
+ A simple HTTP client call with error handling is sufficient. Architecture is about protecting
48
+ the parts of your system that matter, not about ceremony for its own sake.
49
+
50
+ **Not about eliminating all vendor awareness.** Some vendor-specific concerns are legitimate at
51
+ the infrastructure level. A Stripe webhook handler needs to verify Stripe's signature format.
52
+ An AWS S3 adapter needs to handle multipart uploads. The goal is not to pretend vendors don't
53
+ exist -- it is to confine vendor awareness to a specific architectural layer.
54
+
55
+ **Not a guarantee against vendor lock-in.** An adapter interface reduces switching cost, but it
56
+ does not eliminate it. If you depend on Stripe's dispute resolution workflow, subscription
57
+ lifecycle events, and billing portal, switching to Braintree means rebuilding all of those
58
+ adapter implementations. The abstraction makes the switch *possible* without domain changes;
59
+ it does not make the switch *cheap*.
60
+
61
+ **Not always the right investment.** Abstraction has a cost: indirection, maintenance burden,
62
+ and the risk of a leaky or lowest-common-denominator interface. The decision to abstract must
63
+ be justified by the likelihood and cost of change.
64
+
65
+ ---
66
+
67
+ ## When to Use Abstraction Layers
68
+
69
+ ### The Qualifying Conditions
70
+
71
+ **Multiple vendors are realistic.** Your system may need to support Stripe in the US, Adyen
72
+ in Europe, and Razorpay in India. You genuinely need a `PaymentGateway` interface with multiple
73
+ implementations. This is the strongest justification for adapter/ACL investment.
74
+
75
+ **Vendor switching is a real business risk.** The vendor may raise prices, deprecate a critical
76
+ feature, suffer reliability issues, or lose compliance certifications. Shopify's architecture
77
+ decouples core commerce logic from payment gateways specifically because merchants routinely
78
+ switch between Stripe, PayPal, and local processors. The switching cost needs to be contained.
79
+
80
+ **The vendor's model conflicts with your domain model.** Stripe models payments as
81
+ `PaymentIntent` -> `Charge` -> `BalanceTransaction`. Your domain might model payments as
82
+ `Order` -> `Payment` -> `Settlement`. These are fundamentally different entity graphs. Without
83
+ an ACL, your domain classes inherit Stripe's terminology and lifecycle, making it impossible
84
+ to reason about your business in your own terms.
85
+
86
+ **The vendor API is unstable or rapidly evolving.** Stripe ships breaking changes in new API
87
+ versions roughly annually. OpenAI's API evolved from completions to chat completions to
88
+ assistants within two years. If the vendor moves fast, an adapter layer absorbs those changes
89
+ in one place rather than scattering updates across your codebase.
90
+
91
+ **You need to test business logic without the vendor.** Your checkout flow has 47 business
92
+ rules about discounts, taxes, shipping calculations, and inventory checks. If the payment
93
+ call is embedded directly in the checkout service, testing those 47 rules requires mocking
94
+ Stripe at the HTTP level. With an adapter, you inject a `FakePaymentGateway` that returns
95
+ success/failure deterministically.
96
+
97
+ **Regulatory or compliance boundaries.** PCI DSS requires that cardholder data handling is
98
+ isolated and auditable. GDPR requires that data sent to third parties is tracked. An adapter
99
+ layer provides a natural audit boundary: all data flowing to the vendor passes through a
100
+ single, reviewable chokepoint.
101
+
102
+ ---
103
+
104
+ ## When NOT to Use Abstraction Layers
105
+
106
+ This section is as important as the previous one. Over-abstraction of third-party integrations
107
+ is one of the most common architectural mistakes, producing interfaces that serve no purpose
108
+ except to satisfy a pattern fetish.
109
+
110
+ ### The Disqualifying Conditions
111
+
112
+ **You will only ever use one vendor, and that is a deliberate strategic choice.** If your
113
+ entire business model is built on Shopify's platform, you are not going to switch to
114
+ WooCommerce. If you are an AWS shop that has committed to a three-year Reserved Instance
115
+ contract with enterprise support, abstracting S3 behind a `FileStorage` interface "in case
116
+ you switch to GCP" is a fantasy. The abstraction will rot because it is never exercised by
117
+ a second implementation.
118
+
119
+ A fintech startup spent four months building a vendor-agnostic payment abstraction layer
120
+ supporting Stripe, Braintree, and Adyen. They launched with Stripe. Three years later, they
121
+ still only use Stripe. The abstraction layer has been maintained across 14 Stripe API version
122
+ upgrades, each requiring changes to the "vendor-agnostic" interface because the interface was
123
+ unknowingly shaped by Stripe's model. The second and third adapters were never written.
124
+
125
+ **The abstraction costs more than switching would.** If switching vendors is a one-time,
126
+ two-week project that happens at most once in the system's lifetime, spending four months
127
+ building and maintaining an abstraction layer to make that switch take one week instead of
128
+ two is a net loss. Calculate: (cost of maintaining abstraction x system lifetime) vs.
129
+ (one-time cost of switching without abstraction). If the latter is smaller, skip the layer.
130
+
131
+ **Thin abstractions that just proxy calls.** An interface `EmailSender` with one method
132
+ `send(to, subject, body)` that has exactly one implementation `SendGridEmailSender` which
133
+ calls `sendGrid.send(to, subject, body)` is not an abstraction -- it is a forwarding layer.
134
+ It adds a file, an interface, and a binding without providing any value. If the interface
135
+ method signature is a 1:1 mirror of the vendor method, you have not abstracted anything.
136
+ You have added indirection.
137
+
138
+ **The vendor IS the product.** If you are building a Stripe dashboard, a Twilio call center,
139
+ or an AWS management console, the vendor API is not an external dependency -- it is your
140
+ domain. Abstracting it away means abstracting away your core business logic. A Stripe
141
+ analytics tool that hides Stripe's data model behind a "vendor-agnostic payment" interface
142
+ loses the ability to surface Stripe-specific insights that are the tool's entire value.
143
+
144
+ **Prototypes and MVPs.** You are validating whether customers want the feature at all. Do not
145
+ build adapter layers for a feature that might be deleted in six weeks. Call Stripe directly.
146
+ If the feature survives and the system grows, introduce the abstraction then. This is not
147
+ technical debt -- it is appropriate engineering for the stage of the product.
148
+
149
+ **The lowest-common-denominator problem.** If Stripe supports subscriptions with metered
150
+ billing, proration, and usage-based pricing, but Braintree only supports flat-rate
151
+ subscriptions, your "vendor-agnostic" subscription interface can only expose the intersection
152
+ of their capabilities: flat-rate subscriptions. You lose access to Stripe features that your
153
+ customers need, or you add vendor-specific escape hatches that defeat the purpose of the
154
+ abstraction. The richer vendor's unique capabilities leak through the interface or are
155
+ abandoned.
156
+
157
+ **Real example of over-abstraction.** A SaaS company built a `CloudProvider` interface
158
+ abstracting AWS, GCP, and Azure behind unified `compute()`, `store()`, and `queue()` methods.
159
+ The interface could not express AWS Lambda's cold start characteristics, GCP's BigQuery
160
+ integration, or Azure's Active Directory hooks. Every meaningful feature required
161
+ vendor-specific code paths. The abstraction became a lie -- callers needed to know which
162
+ vendor was behind the interface to use it correctly. The team eventually deleted the
163
+ abstraction and used vendor SDKs directly with thin, vendor-specific adapters per service.
164
+
165
+ ---
166
+
167
+ ## How It Works
168
+
169
+ ### 1. Adapter Pattern Implementation
170
+
171
+ The adapter pattern for third-party services follows a structure:
172
+
173
+ ```
174
+ Domain Layer (your code):
175
+ defines PaymentGateway port (interface)
176
+ defines domain types: Money, PaymentResult, PaymentMethod
177
+
178
+ Infrastructure Layer (your code):
179
+ StripePaymentGateway implements PaymentGateway
180
+ - imports Stripe SDK
181
+ - translates domain types to/from Stripe types
182
+ - handles Stripe-specific errors, retries, idempotency keys
183
+
184
+ BraintreePaymentGateway implements PaymentGateway
185
+ - imports Braintree SDK
186
+ - translates domain types to/from Braintree types
187
+ - handles Braintree-specific error codes
188
+
189
+ Application Layer (your code):
190
+ CheckoutService depends on PaymentGateway (the interface)
191
+ - never imports Stripe or Braintree
192
+ - testable with FakePaymentGateway
193
+ ```
194
+
195
+ The critical discipline: the interface is defined in terms of your domain, not the vendor's.
196
+ `PaymentGateway.charge(Money amount, PaymentMethod method)` -- not
197
+ `PaymentGateway.createPaymentIntent(int amountInCents, String currency, String paymentMethodId)`.
198
+ The former is your language. The latter is Stripe's language wearing your interface's clothes.
199
+
200
+ ### 2. Anti-Corruption Layer Translation
201
+
202
+ The ACL does more than route calls. It translates between two conceptual models.
203
+
204
+ **Example -- CRM Integration:**
205
+
206
+ Your domain has `Customer` with `loyaltyTier`, `lifetimeValue`, and `preferredContactMethod`.
207
+ Salesforce has `Contact` with `Account`, `Opportunity`, and 200 custom fields. The ACL:
208
+
209
+ - Maps `Customer` to a Salesforce `Contact` + `Account` (one domain entity becomes two Salesforce
210
+ entities).
211
+ - Translates `loyaltyTier` (an enum: BRONZE, SILVER, GOLD) to Salesforce's custom field
212
+ `Loyalty_Level__c` (a string: "B", "S", "G").
213
+ - Ignores the 180 Salesforce fields your system does not use.
214
+ - Handles Salesforce's governor limits (API calls per 24-hour window) internally.
215
+ - Converts Salesforce's `SystemModstamp` (ISO 8601 with timezone) to your domain's `updatedAt`
216
+ (UTC epoch milliseconds).
217
+
218
+ Without the ACL, Salesforce's model colonizes your codebase. With the ACL, your domain stays
219
+ clean and the Salesforce translation logic is contained in one package.
220
+
221
+ ### 3. Circuit Breaker for External Calls
222
+
223
+ Third-party services fail. They fail more often than your own services because you do not
224
+ control their infrastructure, deployment schedule, or capacity planning. The circuit breaker
225
+ pattern prevents a failing third-party from cascading into your system.
226
+
227
+ **Three states:**
228
+
229
+ - **Closed (normal):** Requests flow to the third party. The breaker tracks failure rates.
230
+ - **Open (tripped):** After the failure threshold is exceeded (e.g., 50% of requests failed
231
+ in the last 30 seconds), the breaker opens. All requests are immediately rejected with a
232
+ fallback response. No calls reach the third party. This protects your system from hanging
233
+ on timeouts and protects the third party from retry storms.
234
+ - **Half-open (probing):** After a cooldown period (e.g., 60 seconds), the breaker allows
235
+ one probe request. If it succeeds, the breaker closes. If it fails, the breaker reopens.
236
+
237
+ **Real-world example -- Stripe latency outage (2022):** Increased traffic combined with an
238
+ unbalanced connection pool saturated a database cluster. Downstream clients without circuit
239
+ breakers continued retrying, amplifying the load. Services with circuit breakers detected
240
+ the elevated latency, opened their breakers, and served cached or fallback responses.
241
+ Services without breakers queued requests until their own thread pools exhausted, causing
242
+ cascading failures in their own systems.
243
+
244
+ ### 4. Retry with Exponential Backoff
245
+
246
+ Not every failure is permanent. Network blips, rate limits, and transient 503 errors are
247
+ common with third-party APIs. Retry logic handles these, but naive retries cause more harm
248
+ than good.
249
+
250
+ **Rules for retry:**
251
+
252
+ - **Retry only idempotent operations** or operations with idempotency keys. Retrying a
253
+ non-idempotent `POST /charges` without an idempotency key risks double-charging.
254
+ - **Exponential backoff:** Wait 1s, 2s, 4s, 8s, 16s. Not 1s, 1s, 1s, 1s (which becomes
255
+ a retry storm under load).
256
+ - **Jitter:** Add random variation (0-500ms) to the backoff interval. Without jitter, when
257
+ a third-party recovers from an outage, all clients retry simultaneously at the same
258
+ exponential intervals, creating a thundering herd.
259
+ - **Maximum retries:** Cap at 3-5 attempts. Beyond that, the failure is not transient.
260
+ - **Retry only retriable errors:** Retry on 429, 503, 504, connection timeout. Do not retry
261
+ on 400 (bad request), 401 (auth failure), 404 (not found), or 422 (validation error).
262
+ These will never succeed on retry.
263
+
264
+ **Combine with circuit breaker:** Retries happen inside the circuit breaker. If the breaker
265
+ is open, retries are skipped entirely. This prevents retry storms from preventing the
266
+ breaker from recovering.
267
+
268
+ ### 5. Timeout Configuration
269
+
270
+ Every external call must have a timeout. Without one, a hanging connection holds a thread
271
+ and potentially a database transaction open indefinitely.
272
+
273
+ - **Connection timeout (1-5s):** Time to establish TCP connection. Fail fast if unreachable.
274
+ - **Read timeout (5-30s):** Time to receive a response. Varies by operation (Stripe charge:
275
+ 2-5s; AI inference: up to 30s).
276
+ - **Overall timeout (10-60s):** Total budget including retries.
277
+
278
+ **Do not use vendor SDK defaults.** Stripe's Ruby SDK defaulted to 80 seconds for years. One
279
+ slow call holding a thread for 80 seconds under load can exhaust your entire thread pool.
280
+
281
+ ### 6. Credential Management
282
+
283
+ - **Never store credentials in code.** Use environment variables for simple deployments;
284
+ secrets managers (Vault, AWS Secrets Manager) for production.
285
+ - **Rotate on a schedule.** Create new key, deploy, verify, then revoke old key. Automate.
286
+ - **Scope minimally.** If you only create charges and read customers, use a restricted key.
287
+ - **Separate per environment.** Staging using production Stripe keys is a billing incident.
288
+
289
+ **Real incident -- Uber (2016):** AWS credentials committed to GitHub. Attackers accessed
290
+ 57 million user records. Root cause: credential management, not an AWS vulnerability.
291
+
292
+ ### 7. Webhook Handling
293
+
294
+ Webhooks are how third-party services notify you of events (payment completed, subscription
295
+ cancelled, email bounced). They invert the communication direction: instead of polling,
296
+ the vendor pushes to you.
297
+
298
+ **Architectural requirements:**
299
+
300
+ - **Verify signatures on every webhook.** Stripe signs payloads with HMAC-SHA256 using
301
+ your webhook signing secret. Verify the signature using the raw request body and a
302
+ timing-safe comparison. Without verification, anyone can POST fake events to your
303
+ webhook endpoint.
304
+ - **Enforce timestamp windows.** Reject webhooks with timestamps older than 5-10 minutes
305
+ to prevent replay attacks.
306
+ - **Implement idempotency.** Webhooks are delivered at least once, not exactly once.
307
+ Store processed event IDs (e.g., Stripe's `evt_xxxxx`) in your database or Redis with
308
+ a TTL of 7-30 days. Before processing, check if the event ID exists. If it does, return
309
+ 200 and skip processing. This prevents duplicate order fulfillment, duplicate emails,
310
+ and duplicate inventory decrements.
311
+ - **Respond fast, process asynchronously.** Return HTTP 200 within 1-3 seconds. Enqueue
312
+ the event for background processing. If your webhook handler takes 30 seconds to process
313
+ an event synchronously, the vendor will time out and retry, causing duplicate delivery.
314
+ Treat webhook receivers as verify-enqueue-acknowledge services.
315
+ - **Handle out-of-order delivery.** Webhooks may arrive out of order. A `payment.succeeded`
316
+ event might arrive before the `payment.created` event. Design your handler to be
317
+ order-independent, or implement ordering logic using event timestamps and sequence numbers.
318
+ - **Set up a dead-letter queue.** Events that fail processing after all retries should be
319
+ stored in a DLQ for manual inspection and replay, not silently dropped.
320
+
321
+ ### 8. Rate Limit Handling
322
+
323
+ Third-party APIs enforce rate limits (Stripe: 100 reads/s live, 25 test; Twilio:
324
+ per-account concurrency; SendGrid: plan-tier based).
325
+
326
+ - **Read rate limit headers.** Track `X-RateLimit-Remaining` and `Retry-After` to throttle
327
+ proactively before hitting the limit.
328
+ - **Client-side rate limiting.** Token bucket or leaky bucket in your adapter prevents
329
+ bursts from triggering 429 responses.
330
+ - **Queue and batch.** SendGrid supports 1,000 recipients per call. Batch where possible.
331
+ - **Degrade gracefully on 429.** Surface as delays ("processing, ready in a few minutes"),
332
+ not errors ("service unavailable"). Back off using `Retry-After`.
333
+
334
+ ### 9. SDK vs. Direct HTTP
335
+
336
+ **Use the SDK when:** it handles authentication, pagination, webhook verification, and
337
+ versioning correctly; it provides type safety; your adapter wraps it so the rest of your
338
+ system never sees SDK types.
339
+
340
+ **Use direct HTTP when:** the SDK is unmaintained, pulls heavy transitive dependencies,
341
+ you only use 2-3 endpoints, or cold start time matters in serverless environments.
342
+
343
+ **The hybrid approach:** Use the SDK inside your adapter, but define the adapter interface
344
+ in domain terms. `charge(amount: Money): PaymentResult` calls `stripe.paymentIntents.create()`
345
+ internally. If you switch to direct HTTP, only the adapter body changes.
346
+
347
+ ### 10. Error Mapping
348
+
349
+ Third-party error responses must be translated into your domain's error model. Do not let
350
+ vendor error codes propagate into your application layer.
351
+
352
+ - **Map vendor errors to domain errors.** Stripe's `card_declined` becomes your
353
+ `PaymentDeclined`. Your application catches domain exceptions, not Stripe exceptions.
354
+ - **Log vendor diagnostics, never expose them.** The adapter logs `Stripe: card_declined
355
+ (req_xxx)` and throws `PaymentDeclined` with a user-safe message.
356
+ - **Distinguish retriable from terminal.** `rate_limit` is retriable (retry may succeed).
357
+ `card_declined` is terminal (do not retry). Your error model must express this.
358
+
359
+ ### 11. Health Checks for External Dependencies
360
+
361
+ - **Shallow check:** Verify reachability (DNS, TCP, TLS). Catches network-level failures.
362
+ - **Deep check:** Lightweight read-only API call (Stripe: `GET /v1/balance`). Catches auth
363
+ failures and account suspension.
364
+ - **Never block your primary health check on third-party health.** Stripe down means
365
+ degraded, not dead. Report vendor status on a dependency endpoint. If your liveness probe
366
+ fails because Stripe is down, Kubernetes restarts healthy pods unnecessarily.
367
+
368
+ ---
369
+
370
+ ## Trade-Offs Matrix
371
+
372
+ | Decision | Benefit | Cost | When to Accept the Cost |
373
+ |----------|---------|------|------------------------|
374
+ | Full adapter + ACL layer | Vendor-independent domain; clean testability | More code, more indirection; risk of lowest-common-denominator interface | Multiple vendors realistic; domain model is valuable and long-lived |
375
+ | Direct vendor SDK usage | Fastest integration; access to all vendor features | Domain polluted with vendor types; switching cost is high | Single vendor commitment; prototype/MVP; vendor IS the domain |
376
+ | Circuit breaker | Prevents cascading failure from vendor outage | Added complexity; risk of opening too aggressively (false positives) | Any vendor where downtime causes user-facing impact |
377
+ | Retry with backoff | Handles transient failures transparently | Increased latency on failure paths; retry storms if misconfigured | All integrations, but only for idempotent or idempotency-keyed operations |
378
+ | Webhook-based integration | Real-time updates; no polling overhead | Must handle at-least-once delivery, out-of-order events, signature verification | Vendor supports webhooks and you need real-time event processing |
379
+ | Polling-based integration | Simpler implementation; you control the schedule | Higher latency; wasted API calls on no-change polls; rate limit consumption | Vendor does not support webhooks; event freshness requirements are relaxed |
380
+ | SDK usage | Faster development; handles auth, pagination, versioning | Dependency on vendor's SDK quality and maintenance; transitive dependency risk | SDK is well-maintained, actively versioned, and does not conflict with your stack |
381
+ | Direct HTTP calls | Full control; minimal dependencies; smaller bundle | Must implement auth, pagination, error handling, versioning manually | SDK is unavailable, unmaintained, or adds excessive dependency weight |
382
+ | Client-side rate limiting | Prevents 429 errors; smoother request distribution | Adds state management (token bucket); may under-utilize available quota | High-volume integrations where hitting rate limits causes user-facing degradation |
383
+ | Multi-vendor fallback | Resilience against single vendor outage | Maintaining two vendor integrations; data consistency between vendors | The integration is mission-critical and single-vendor outage is unacceptable |
384
+
385
+ ---
386
+
387
+ ## Evolution Path
388
+
389
+ ### Stage 1: Direct Integration (Day 1 - MVP)
390
+
391
+ Call the vendor SDK directly from your service layer. No adapter, no interface, no ACL.
392
+ Ship the feature and validate that customers want it. Vendor types may appear in your
393
+ service signatures. This is acceptable at this stage.
394
+
395
+ ```
396
+ CheckoutService -> stripe.paymentIntents.create(...)
397
+ ```
398
+
399
+ **Cost of staying here too long:** Vendor concepts spread throughout the codebase. Tests
400
+ require mocking the vendor at the HTTP level. Switching vendors means touching every file
401
+ that imports the SDK.
402
+
403
+ ### Stage 2: Extract Adapter (Month 3-6)
404
+
405
+ When the integration stabilizes and the feature is validated, extract the vendor calls into
406
+ a dedicated adapter class. Define an interface in your domain layer. Inject the adapter.
407
+ Write tests against a fake implementation.
408
+
409
+ ```
410
+ CheckoutService -> PaymentGateway (interface) -> StripePaymentGateway (adapter)
411
+ ```
412
+
413
+ **Trigger:** You need to write tests for checkout logic without calling Stripe. Or you
414
+ receive the first request to support a second payment provider.
415
+
416
+ ### Stage 3: Add Resilience (Month 6-12)
417
+
418
+ Wrap the adapter with circuit breaker, retry, and timeout logic. Implement health checks.
419
+ Add monitoring for vendor API latency and error rates. Implement webhook handling with
420
+ idempotency and signature verification.
421
+
422
+ **Trigger:** The first vendor outage that causes user-facing impact. Or your system reaches
423
+ scale where transient errors are no longer rare edge cases.
424
+
425
+ ### Stage 4: Multi-Vendor Support (Year 1-2)
426
+
427
+ If a second vendor is genuinely needed, implement a second adapter behind the same interface.
428
+ Add a routing layer that selects the vendor based on geography, feature requirements, or
429
+ failover rules. Refine the interface to accommodate both vendors without becoming a
430
+ lowest-common-denominator contract.
431
+
432
+ **Trigger:** Business expansion to a region where the current vendor does not operate. Or
433
+ contract negotiation where having a second vendor provides leverage.
434
+
435
+ ### Stage 5: Platform Abstraction (Year 2+)
436
+
437
+ For systems with many integrations (10+ vendors), extract the integration infrastructure
438
+ into a shared platform: circuit breaker configuration, credential management, rate limiting,
439
+ health checking, and monitoring. Individual adapters focus only on translation logic.
440
+
441
+ **Trigger:** You are maintaining 10+ integrations and each one reimplements retry, timeout,
442
+ and error mapping logic independently.
443
+
444
+ ---
445
+
446
+ ## Failure Modes
447
+
448
+ ### 1. Vendor Outage Cascading to Your System
449
+
450
+ **What happens:** Stripe goes down. Your checkout service calls Stripe with a 60-second
451
+ timeout. All checkout requests hang for 60 seconds. Your web server's thread pool is
452
+ exhausted. Your health check times out. Kubernetes restarts the pod. The new pod immediately
453
+ fills its thread pool with hanging Stripe calls. Your entire system is down because one
454
+ vendor is down.
455
+
456
+ **Real incident -- Slack (2020):** A massive user disconnection-reconnection event exceeded
457
+ database capacity, causing cascading connection failures. 5% of users could not connect for
458
+ over 2 hours. Services that depended on Slack's API for notifications experienced silent
459
+ failures.
460
+
461
+ **Real incident -- Cloudflare (November 2025):** A Cloudflare outage took down Resend's
462
+ email delivery service from 11:30 UTC to 14:31 UTC. Every service that depended on Resend
463
+ for transactional email lost email delivery capability for three hours.
464
+
465
+ **Prevention:** Circuit breakers with aggressive timeouts (5s, not 60s). Fallback responses
466
+ for non-critical paths. Graceful degradation: if Stripe is down, show "Payment processing
467
+ is temporarily delayed" instead of a 500 error. Queue the payment attempt for retry.
468
+
469
+ ### 2. Rate Limiting Causing User-Facing Errors
470
+
471
+ **What happens:** A batch job runs during peak hours and consumes your entire Stripe rate
472
+ limit. Real-time checkout requests receive 429 responses. Users see "Payment failed."
473
+
474
+ **Prevention:** Separate API keys for batch and real-time operations (most vendors support
475
+ this). Client-side rate limiting with priority queues: real-time operations get priority
476
+ over batch operations. Schedule batch jobs during off-peak hours.
477
+
478
+ ### 3. Credential Rotation Failures
479
+
480
+ **What happens:** Your API key rotation script creates a new key, deploys it to staging,
481
+ but fails to deploy to production. The old key is revoked. Production loses access to the
482
+ vendor API.
483
+
484
+ **Real incident -- Redocly (January 2026):** A background job queue error triggered a
485
+ cascading failure that, among other things, exhausted the secrets engine. With the secrets
486
+ engine rejecting requests, the orchestration layer could not start new API allocations,
487
+ leaving the API in a flapping state.
488
+
489
+ **Prevention:** Blue-green credential rotation: deploy the new credential, verify it
490
+ works in production with a health check, then revoke the old credential. Never revoke
491
+ before verifying. Keep the old credential valid for a grace period (24-48 hours).
492
+
493
+ ### 4. API Version Deprecation Surprises
494
+
495
+ **What happens:** Stripe deprecates API version `2022-11-15` with 12 months notice. Your
496
+ team misses the deprecation email. Twelve months later, API calls start returning errors
497
+ with unknown fields or changed response shapes.
498
+
499
+ **Prevention:** Pin your API version explicitly (in the SDK configuration, not implicitly).
500
+ Monitor vendor changelogs and deprecation notices. Subscribe to vendor status pages and
501
+ engineering blogs. Include API version in your health check response so monitoring can
502
+ alert on upcoming deprecations.
503
+
504
+ ### 5. Webhook Delivery Failures
505
+
506
+ **What happens:** Your webhook endpoint is down for 4 hours. The vendor retries with
507
+ exponential backoff. When your endpoint comes back, you receive 4 hours of webhooks in
508
+ rapid succession. Your processing pipeline is overwhelmed. Some events are processed out
509
+ of order. A subscription cancellation event arrives before the subscription creation event.
510
+
511
+ **Prevention:** Asynchronous processing with a queue between the webhook receiver and the
512
+ processor. Idempotency checks on event IDs. Order-independent event handling or explicit
513
+ ordering logic using event timestamps. Auto-scaling the processor based on queue depth.
514
+
515
+ ### 6. Silent Data Corruption from API Changes
516
+
517
+ **What happens:** A vendor changes a field from string to integer, or adds a required field,
518
+ or changes the semantics of an existing field. Your deserialization succeeds (the SDK handles
519
+ the type change) but your business logic makes incorrect decisions based on the changed
520
+ semantics.
521
+
522
+ **Real example:** A vendor changed a `status` field from `"active"` to `"enabled"`. The
523
+ adapter checked `status === "active"`, which now always returned false. All users appeared
524
+ inactive. No error was thrown. The issue was discovered three days later by a customer
525
+ support ticket.
526
+
527
+ **Prevention:** Contract testing. Use tools like Pact or vendor-provided contract test
528
+ suites. Assert on the shape and semantics of vendor responses in your integration tests.
529
+ Monitor business metrics (conversion rates, active user counts) for anomalies that may
530
+ indicate silent API changes.
531
+
532
+ ---
533
+
534
+ ## Technology Landscape
535
+
536
+ ### Common Integrations and Their Characteristics
537
+
538
+ | Service | Category | SDK Quality | Rate Limits | Webhook Support | API Stability |
539
+ |---------|----------|-------------|-------------|-----------------|---------------|
540
+ | **Stripe** | Payments | Excellent SDKs in 7+ languages; strongly typed | 100 reads/s live, 25 test | Comprehensive; signed; retries with backoff | Annual versions; 12-month deprecation |
541
+ | **Twilio** | SMS/Voice | Good SDKs; well-documented | Per-account concurrency | Webhook-first design; status callbacks | Stable; long deprecation cycles |
542
+ | **SendGrid** | Email | Good SDKs; supports batch | Plan-tier based | Event webhooks for delivery, opens, clicks | Stable |
543
+ | **AWS (S3/SQS/SNS)** | Cloud infra | Official SDKs; auto-retry built in | Service-specific; generous | SNS for notifications; EventBridge for events | Backwards-compatible; never removes APIs |
544
+ | **Auth0** | Authentication | Good SDKs; Management + Auth APIs | Rate limits by plan and endpoint | Hooks and Actions (server-side); Log Streams | Stable |
545
+ | **OpenAI** | AI/ML | SDKs in Python/Node; evolving rapidly | Tokens/min + requests/min by model | No webhooks; polling for async jobs | Rapidly evolving; frequent breaking changes |
546
+ | **Salesforce** | CRM | Heavy SDK; SOAP and REST APIs | API call limits per 24-hour window | Outbound Messages; Platform Events | Versioned; long support cycles |
547
+
548
+ ### SDK vs. REST Decision by Vendor
549
+
550
+ **Use the SDK:** Stripe (handles idempotency keys, pagination, webhook verification),
551
+ AWS (handles SigV4 signing, retry, pagination), Auth0 (handles token management, JWKS caching).
552
+
553
+ **Consider direct HTTP:** Simple REST APIs with API key auth (SendGrid for basic sends),
554
+ vendors with outdated/unmaintained SDKs, serverless functions where cold start matters,
555
+ GraphQL APIs where the SDK adds no value over a generic GraphQL client.
556
+
557
+ ### API Gateway for External Calls
558
+
559
+ Some architectures route all outbound third-party calls through an API gateway or proxy:
560
+
561
+ - **Benefits:** Centralized logging, rate limiting, circuit breaking, credential injection,
562
+ and audit trail. Single place to enforce timeout policies.
563
+ - **Costs:** Additional network hop (latency), single point of failure, operational complexity.
564
+ - **When it makes sense:** Regulated industries (finance, healthcare) where all external
565
+ data flow must be audited. Systems with 10+ integrations where per-adapter resilience
566
+ configuration is unsustainable.
567
+
568
+ ---
569
+
570
+ ## Decision Tree
571
+
572
+ ```
573
+ START: You need to integrate with a third-party service.
574
+
575
+ Q1: Is this a prototype/MVP or a production system?
576
+ -> Prototype/MVP: Call the vendor SDK/API directly. No adapter.
577
+ Skip to: "Add error handling and timeouts."
578
+ -> Production: Continue.
579
+
580
+ Q2: Will you realistically use more than one vendor for this capability?
581
+ -> Yes (e.g., payment in multiple regions): Build adapter + ACL.
582
+ -> No, but switching is possible in 2+ years: Build a thin adapter.
583
+ Interface matches your domain. One implementation. Easy to add a second later.
584
+ -> No, and the vendor IS the product: Call the vendor SDK directly.
585
+ No adapter. Vendor types in your service layer are acceptable.
586
+
587
+ Q3: Does the vendor's data model conflict with your domain model?
588
+ -> Yes (different entity shapes, terminology, lifecycle): Build an ACL.
589
+ Translate at the boundary. Domain never sees vendor types.
590
+ -> No (vendor model aligns with your domain): Adapter is sufficient.
591
+ Translation is minimal (type conversion, error mapping).
592
+
593
+ Q4: Is the vendor call in a critical user-facing path?
594
+ -> Yes (checkout, login, real-time messaging):
595
+ Add circuit breaker + retry with backoff + aggressive timeout.
596
+ Add fallback behavior (cached response, graceful degradation).
597
+ -> No (batch processing, async analytics):
598
+ Add retry with backoff + timeout. Circuit breaker optional.
599
+
600
+ Q5: Does the vendor push events to you (webhooks)?
601
+ -> Yes: Implement signature verification + idempotency + async processing.
602
+ -> No, but you need real-time updates: Implement polling with backoff.
603
+ -> No, and batch freshness is fine: Scheduled sync job.
604
+
605
+ Q6: SDK or direct HTTP?
606
+ -> SDK if: well-maintained, handles auth/pagination/versioning, your adapter wraps it.
607
+ -> HTTP if: SDK unavailable/bloated, you use <5 endpoints, cold start matters.
608
+ ```
609
+
610
+ ---
611
+
612
+ ## Implementation Sketch
613
+
614
+ ### Adapter Interface (Domain Layer)
615
+
616
+ ```typescript
617
+ // domain/ports/PaymentGateway.ts
618
+ // This interface is defined by YOUR domain, not by Stripe.
619
+
620
+ interface PaymentGateway {
621
+ charge(params: ChargeParams): Promise<ChargeResult>;
622
+ refund(paymentId: PaymentId, amount: Money): Promise<RefundResult>;
623
+ getPaymentStatus(paymentId: PaymentId): Promise<PaymentStatus>;
624
+ }
625
+
626
+ interface ChargeParams {
627
+ orderId: OrderId; // YOUR domain's order identifier
628
+ amount: Money; // YOUR domain's money type (amount + currency)
629
+ method: PaymentMethodRef; // YOUR domain's reference to a stored payment method
630
+ idempotencyKey: string; // Caller-generated, prevents double charges
631
+ metadata?: Record<string, string>;
632
+ }
633
+
634
+ interface ChargeResult {
635
+ paymentId: PaymentId; // YOUR domain's payment identifier
636
+ status: PaymentStatus; // YOUR enum: SUCCEEDED | PENDING | FAILED
637
+ failureReason?: PaymentFailureReason; // YOUR enum: DECLINED | INSUFFICIENT_FUNDS | ...
638
+ }
639
+
640
+ // Note: no Stripe types, no stripe-specific fields, no vendor terminology.
641
+ ```
642
+
643
+ ### Concrete Stripe Adapter (Infrastructure Layer)
644
+
645
+ ```typescript
646
+ // infrastructure/payment/StripePaymentGateway.ts
647
+
648
+ class StripePaymentGateway implements PaymentGateway {
649
+ private stripe: Stripe;
650
+
651
+ constructor(apiKey: string, apiVersion: string = '2024-11-20') {
652
+ this.stripe = new Stripe(apiKey, { apiVersion, timeout: 10_000 });
653
+ }
654
+
655
+ async charge(params: ChargeParams): Promise<ChargeResult> {
656
+ try {
657
+ const intent = await this.stripe.paymentIntents.create(
658
+ {
659
+ amount: params.amount.toSmallestUnit(), // $10.50 -> 1050 cents
660
+ currency: params.amount.currency.toLowerCase(),
661
+ payment_method: params.method.vendorRef,
662
+ confirm: true,
663
+ metadata: { order_id: params.orderId.toString(), ...params.metadata },
664
+ },
665
+ { idempotencyKey: params.idempotencyKey }
666
+ );
667
+ return {
668
+ paymentId: PaymentId.from(intent.id),
669
+ status: this.mapStatus(intent.status),
670
+ };
671
+ } catch (error) {
672
+ if (error instanceof Stripe.errors.StripeCardError) {
673
+ return {
674
+ paymentId: PaymentId.generate(),
675
+ status: PaymentStatus.FAILED,
676
+ failureReason: this.mapDeclineCode(error.decline_code),
677
+ };
678
+ }
679
+ if (error instanceof Stripe.errors.StripeRateLimitError) {
680
+ throw new ServiceTemporarilyUnavailable('Payment service rate limited');
681
+ }
682
+ throw new PaymentServiceError('Unexpected payment error', { cause: error });
683
+ }
684
+ }
685
+
686
+ // Maps Stripe status strings to domain PaymentStatus enum
687
+ private mapStatus(s: string): PaymentStatus {
688
+ if (s === 'succeeded') return PaymentStatus.SUCCEEDED;
689
+ if (s === 'processing' || s === 'requires_action') return PaymentStatus.PENDING;
690
+ return PaymentStatus.FAILED;
691
+ }
692
+
693
+ // Maps Stripe decline codes to domain PaymentFailureReason enum
694
+ private mapDeclineCode(code?: string): PaymentFailureReason {
695
+ if (code === 'insufficient_funds') return PaymentFailureReason.INSUFFICIENT_FUNDS;
696
+ if (code === 'lost_card' || code === 'stolen_card') return PaymentFailureReason.CARD_INVALID;
697
+ if (code === 'expired_card') return PaymentFailureReason.CARD_EXPIRED;
698
+ return PaymentFailureReason.DECLINED;
699
+ }
700
+ }
701
+ ```
702
+
703
+ ### Fallback Provider Pattern
704
+
705
+ ```typescript
706
+ // infrastructure/payment/FallbackPaymentGateway.ts
707
+
708
+ class FallbackPaymentGateway implements PaymentGateway {
709
+ constructor(
710
+ private primary: PaymentGateway,
711
+ private fallback: PaymentGateway,
712
+ private circuitBreaker: CircuitBreaker,
713
+ private logger: Logger
714
+ ) {}
715
+
716
+ async charge(params: ChargeParams): Promise<ChargeResult> {
717
+ try {
718
+ return await this.circuitBreaker.execute(() => this.primary.charge(params));
719
+ } catch (error) {
720
+ if (error instanceof ServiceTemporarilyUnavailable ||
721
+ error instanceof CircuitBreakerOpen ||
722
+ error instanceof TimeoutError) {
723
+ this.logger.warn('Primary gateway failed, falling back', { orderId: params.orderId });
724
+ return this.fallback.charge(params);
725
+ }
726
+ throw error; // Terminal errors (card declined) are not retried on fallback
727
+ }
728
+ }
729
+ }
730
+
731
+ // Composition at bootstrap -- CheckoutService has no idea which vendor is behind the interface
732
+ const paymentGateway = new FallbackPaymentGateway(
733
+ new StripePaymentGateway(config.stripeKey),
734
+ new BraintreePaymentGateway(config.braintreeKey),
735
+ new CircuitBreaker({ failureThreshold: 5, resetTimeout: 30_000 }),
736
+ logger
737
+ );
738
+ const checkoutService = new CheckoutService(paymentGateway, orderRepo);
739
+ ```
740
+
741
+ ### Webhook Handler with Idempotency
742
+
743
+ ```typescript
744
+ // infrastructure/webhooks/StripeWebhookHandler.ts
745
+
746
+ class StripeWebhookHandler {
747
+ constructor(
748
+ private webhookSecret: string,
749
+ private eventStore: ProcessedEventStore, // Redis or DB
750
+ private eventQueue: EventQueue, // SQS, RabbitMQ, etc.
751
+ ) {}
752
+
753
+ async handle(rawBody: Buffer, signatureHeader: string): Promise<void> {
754
+ // 1. Verify signature (timing-safe comparison via Stripe SDK)
755
+ const event = stripe.webhooks.constructEvent(rawBody, signatureHeader, this.webhookSecret);
756
+
757
+ // 2. Idempotency check -- skip already-processed events
758
+ if (await this.eventStore.hasBeenProcessed(event.id)) return;
759
+
760
+ // 3. Enqueue for async processing, ACK fast to Stripe
761
+ await this.eventQueue.enqueue({ eventId: event.id, type: event.type, data: event.data.object });
762
+ await this.eventStore.markReceived(event.id);
763
+ }
764
+ }
765
+ ```
766
+
767
+ ---
768
+
769
+ ## Cross-References
770
+
771
+ - **[hexagonal-clean-architecture](../patterns/hexagonal-clean-architecture.md)** --
772
+ Third-party adapters are the canonical example of driven adapters (secondary ports) in
773
+ hexagonal architecture. The payment gateway port is a driven port; the Stripe adapter is
774
+ a driven adapter. If you are building a system with hexagonal architecture, third-party
775
+ integrations are where the pattern pays its biggest dividends.
776
+
777
+ - **[coupling-and-cohesion](../foundations/coupling-and-cohesion.md)** -- Third-party
778
+ integrations without adapter layers create stamp coupling (your domain shares data
779
+ structures with the vendor) and content coupling (your domain depends on the vendor's
780
+ internal model). The adapter pattern converts this to data coupling (your domain
781
+ communicates with the adapter through well-defined domain parameters).
782
+
783
+ - **circuit-breaker-bulkhead** -- The circuit breaker and bulkhead patterns are essential
784
+ for any third-party integration in a critical path. Circuit breakers prevent vendor
785
+ outages from cascading. Bulkheads isolate vendor failures so that a Stripe outage does
786
+ not consume the thread pool needed for serving cached content.
787
+
788
+ - **api-design-rest** -- When your system itself exposes APIs that wrap third-party
789
+ capabilities (e.g., a unified payments API), the API design principles for REST apply.
790
+ Your API should expose your domain model, not the vendor's model.
791
+
792
+ - **webhooks-and-callbacks** -- Webhook handling is a deep topic on its own: signature
793
+ verification, idempotency, ordering, dead-letter queues, and replay mechanisms. The
794
+ webhook section in this module covers the third-party integration perspective; the
795
+ dedicated module covers the full architectural pattern.