@k2works/claude-code-booster 6.1.0 → 6.3.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 (622) hide show
  1. package/lib/assets/.claude/skills/practicing-getting-start-tdd/SKILL.md +3 -7
  2. package/lib/assets/docs/article/index.md +16 -41
  3. package/lib/assets/docs/assets/js/extra.js +5 -1
  4. package/lib/assets/docs/assets/js/mathjax.js +27 -0
  5. package/lib/assets/docs/index.md +1 -1
  6. package/lib/assets/mkdocs.yml +6 -7
  7. package/lib/assets/ops/docker/mkdoc/Dockerfile +19 -19
  8. package/lib/assets/package.json +1 -1
  9. package/package.json +1 -1
  10. package/lib/assets/docs/article/functional-desgin-ppp/all/01-immutability-and-data-transformation.md +0 -484
  11. package/lib/assets/docs/article/functional-desgin-ppp/all/02-function-composition.md +0 -528
  12. package/lib/assets/docs/article/functional-desgin-ppp/all/03-polymorphism.md +0 -546
  13. package/lib/assets/docs/article/functional-desgin-ppp/all/04-data-validation.md +0 -309
  14. package/lib/assets/docs/article/functional-desgin-ppp/all/05-property-based-testing.md +0 -329
  15. package/lib/assets/docs/article/functional-desgin-ppp/all/06-tdd-and-functional.md +0 -507
  16. package/lib/assets/docs/article/functional-desgin-ppp/all/07-composite-pattern.md +0 -307
  17. package/lib/assets/docs/article/functional-desgin-ppp/all/08-decorator-pattern.md +0 -300
  18. package/lib/assets/docs/article/functional-desgin-ppp/all/09-adapter-pattern.md +0 -345
  19. package/lib/assets/docs/article/functional-desgin-ppp/all/10-strategy-pattern.md +0 -312
  20. package/lib/assets/docs/article/functional-desgin-ppp/all/11-command-pattern.md +0 -295
  21. package/lib/assets/docs/article/functional-desgin-ppp/all/12-visitor-pattern.md +0 -331
  22. package/lib/assets/docs/article/functional-desgin-ppp/all/13-abstract-factory-pattern.md +0 -328
  23. package/lib/assets/docs/article/functional-desgin-ppp/all/14-abstract-server-pattern.md +0 -374
  24. package/lib/assets/docs/article/functional-desgin-ppp/all/15-gossiping-bus-drivers.md +0 -165
  25. package/lib/assets/docs/article/functional-desgin-ppp/all/16-payroll-system.md +0 -187
  26. package/lib/assets/docs/article/functional-desgin-ppp/all/17-video-rental-system.md +0 -321
  27. package/lib/assets/docs/article/functional-desgin-ppp/all/18-concurrency-system.md +0 -296
  28. package/lib/assets/docs/article/functional-desgin-ppp/all/19-wa-tor-simulation.md +0 -295
  29. package/lib/assets/docs/article/functional-desgin-ppp/all/20-pattern-interactions.md +0 -283
  30. package/lib/assets/docs/article/functional-desgin-ppp/all/21-best-practices.md +0 -303
  31. package/lib/assets/docs/article/functional-desgin-ppp/all/22-oo-to-fp-migration.md +0 -346
  32. package/lib/assets/docs/article/functional-desgin-ppp/all/index.md +0 -388
  33. package/lib/assets/docs/article/functional-desgin-ppp/clojure/01-immutability-and-data-transformation.md +0 -282
  34. package/lib/assets/docs/article/functional-desgin-ppp/clojure/02-function-composition.md +0 -389
  35. package/lib/assets/docs/article/functional-desgin-ppp/clojure/03-polymorphism.md +0 -393
  36. package/lib/assets/docs/article/functional-desgin-ppp/clojure/04-clojure-spec.md +0 -359
  37. package/lib/assets/docs/article/functional-desgin-ppp/clojure/05-property-based-testing.md +0 -361
  38. package/lib/assets/docs/article/functional-desgin-ppp/clojure/06-tdd-in-functional.md +0 -392
  39. package/lib/assets/docs/article/functional-desgin-ppp/clojure/07-composite-pattern.md +0 -538
  40. package/lib/assets/docs/article/functional-desgin-ppp/clojure/08-decorator-pattern.md +0 -404
  41. package/lib/assets/docs/article/functional-desgin-ppp/clojure/09-adapter-pattern.md +0 -408
  42. package/lib/assets/docs/article/functional-desgin-ppp/clojure/10-strategy-pattern.md +0 -494
  43. package/lib/assets/docs/article/functional-desgin-ppp/clojure/11-command-pattern.md +0 -575
  44. package/lib/assets/docs/article/functional-desgin-ppp/clojure/12-visitor-pattern.md +0 -576
  45. package/lib/assets/docs/article/functional-desgin-ppp/clojure/13-abstract-factory-pattern.md +0 -484
  46. package/lib/assets/docs/article/functional-desgin-ppp/clojure/14-abstract-server-pattern.md +0 -471
  47. package/lib/assets/docs/article/functional-desgin-ppp/clojure/15-gossiping-bus-drivers.md +0 -334
  48. package/lib/assets/docs/article/functional-desgin-ppp/clojure/16-payroll-system.md +0 -410
  49. package/lib/assets/docs/article/functional-desgin-ppp/clojure/17-video-rental-system.md +0 -459
  50. package/lib/assets/docs/article/functional-desgin-ppp/clojure/18-concurrency-system.md +0 -484
  51. package/lib/assets/docs/article/functional-desgin-ppp/clojure/19-wator-simulation.md +0 -748
  52. package/lib/assets/docs/article/functional-desgin-ppp/clojure/20-pattern-interactions.md +0 -576
  53. package/lib/assets/docs/article/functional-desgin-ppp/clojure/21-best-practices.md +0 -527
  54. package/lib/assets/docs/article/functional-desgin-ppp/clojure/22-oo-to-fp-migration.md +0 -541
  55. package/lib/assets/docs/article/functional-desgin-ppp/clojure/index.md +0 -241
  56. package/lib/assets/docs/article/functional-desgin-ppp/elixir/01-immutability-and-data-transformation.md +0 -392
  57. package/lib/assets/docs/article/functional-desgin-ppp/elixir/02-function-composition.md +0 -383
  58. package/lib/assets/docs/article/functional-desgin-ppp/elixir/03-polymorphism.md +0 -384
  59. package/lib/assets/docs/article/functional-desgin-ppp/elixir/04-data-validation.md +0 -204
  60. package/lib/assets/docs/article/functional-desgin-ppp/elixir/05-property-based-testing.md +0 -277
  61. package/lib/assets/docs/article/functional-desgin-ppp/elixir/06-tdd-and-fp.md +0 -303
  62. package/lib/assets/docs/article/functional-desgin-ppp/elixir/07-effects-and-pure-functions.md +0 -173
  63. package/lib/assets/docs/article/functional-desgin-ppp/elixir/08-error-handling-strategies.md +0 -177
  64. package/lib/assets/docs/article/functional-desgin-ppp/elixir/09-io-and-external-systems.md +0 -263
  65. package/lib/assets/docs/article/functional-desgin-ppp/elixir/10-concurrency-patterns.md +0 -278
  66. package/lib/assets/docs/article/functional-desgin-ppp/elixir/11-command-pattern.md +0 -157
  67. package/lib/assets/docs/article/functional-desgin-ppp/elixir/12-visitor-pattern.md +0 -185
  68. package/lib/assets/docs/article/functional-desgin-ppp/elixir/13-abstract-factory-pattern.md +0 -613
  69. package/lib/assets/docs/article/functional-desgin-ppp/elixir/14-abstract-server-pattern.md +0 -738
  70. package/lib/assets/docs/article/functional-desgin-ppp/elixir/15-gossiping-bus-drivers.md +0 -300
  71. package/lib/assets/docs/article/functional-desgin-ppp/elixir/16-payroll-system.md +0 -429
  72. package/lib/assets/docs/article/functional-desgin-ppp/elixir/17-video-rental-system.md +0 -328
  73. package/lib/assets/docs/article/functional-desgin-ppp/elixir/18-concurrency-system.md +0 -475
  74. package/lib/assets/docs/article/functional-desgin-ppp/elixir/19-wator-simulation.md +0 -532
  75. package/lib/assets/docs/article/functional-desgin-ppp/elixir/20-pattern-interactions.md +0 -296
  76. package/lib/assets/docs/article/functional-desgin-ppp/elixir/21-best-practices.md +0 -349
  77. package/lib/assets/docs/article/functional-desgin-ppp/elixir/22-oo-to-fp-migration.md +0 -404
  78. package/lib/assets/docs/article/functional-desgin-ppp/elixir/index.md +0 -248
  79. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/01-immutability-and-data-transformation.md +0 -393
  80. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/02-function-composition.md +0 -461
  81. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/03-polymorphism.md +0 -504
  82. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/04-data-validation.md +0 -425
  83. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/05-property-based-testing.md +0 -391
  84. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/06-tdd-functional.md +0 -696
  85. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/07-composite-pattern.md +0 -451
  86. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/08-decorator-pattern.md +0 -488
  87. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/09-adapter-pattern.md +0 -488
  88. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/10-strategy-pattern.md +0 -436
  89. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/11-command-pattern.md +0 -437
  90. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/12-visitor-pattern.md +0 -348
  91. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/13-abstract-factory-pattern.md +0 -318
  92. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/14-abstract-server-pattern.md +0 -605
  93. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/15-gossiping-bus-drivers.md +0 -364
  94. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/16-payroll-system.md +0 -359
  95. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/17-video-rental-system.md +0 -423
  96. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/18-concurrency-system.md +0 -376
  97. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/19-wator-simulation.md +0 -412
  98. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/20-pattern-interactions.md +0 -300
  99. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/21-best-practices.md +0 -333
  100. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/22-oo-to-fp-migration.md +0 -341
  101. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/index.md +0 -274
  102. package/lib/assets/docs/article/functional-desgin-ppp/haskell/01-immutability-and-data-transformation.md +0 -307
  103. package/lib/assets/docs/article/functional-desgin-ppp/haskell/02-function-composition.md +0 -313
  104. package/lib/assets/docs/article/functional-desgin-ppp/haskell/03-polymorphism.md +0 -371
  105. package/lib/assets/docs/article/functional-desgin-ppp/haskell/04-data-validation.md +0 -266
  106. package/lib/assets/docs/article/functional-desgin-ppp/haskell/05-property-based-testing.md +0 -263
  107. package/lib/assets/docs/article/functional-desgin-ppp/haskell/06-tdd-functional.md +0 -292
  108. package/lib/assets/docs/article/functional-desgin-ppp/haskell/07-composite-pattern.md +0 -404
  109. package/lib/assets/docs/article/functional-desgin-ppp/haskell/08-decorator-pattern.md +0 -328
  110. package/lib/assets/docs/article/functional-desgin-ppp/haskell/09-adapter-pattern.md +0 -391
  111. package/lib/assets/docs/article/functional-desgin-ppp/haskell/10-strategy-pattern.md +0 -296
  112. package/lib/assets/docs/article/functional-desgin-ppp/haskell/11-command-pattern.md +0 -312
  113. package/lib/assets/docs/article/functional-desgin-ppp/haskell/12-visitor-pattern.md +0 -335
  114. package/lib/assets/docs/article/functional-desgin-ppp/haskell/13-abstract-factory-pattern.md +0 -341
  115. package/lib/assets/docs/article/functional-desgin-ppp/haskell/14-abstract-server-pattern.md +0 -388
  116. package/lib/assets/docs/article/functional-desgin-ppp/haskell/15-gossiping-bus-drivers.md +0 -186
  117. package/lib/assets/docs/article/functional-desgin-ppp/haskell/16-payroll-system.md +0 -228
  118. package/lib/assets/docs/article/functional-desgin-ppp/haskell/17-video-rental-system.md +0 -253
  119. package/lib/assets/docs/article/functional-desgin-ppp/haskell/18-concurrency-system.md +0 -372
  120. package/lib/assets/docs/article/functional-desgin-ppp/haskell/19-wator-simulation.md +0 -447
  121. package/lib/assets/docs/article/functional-desgin-ppp/haskell/20-pattern-interactions.md +0 -334
  122. package/lib/assets/docs/article/functional-desgin-ppp/haskell/21-best-practices.md +0 -412
  123. package/lib/assets/docs/article/functional-desgin-ppp/haskell/22-oo-to-fp-migration.md +0 -478
  124. package/lib/assets/docs/article/functional-desgin-ppp/haskell/index.md +0 -174
  125. package/lib/assets/docs/article/functional-desgin-ppp/index.md +0 -90
  126. package/lib/assets/docs/article/functional-desgin-ppp/rust/01-immutability-and-data-transformation.md +0 -459
  127. package/lib/assets/docs/article/functional-desgin-ppp/rust/02-function-composition.md +0 -472
  128. package/lib/assets/docs/article/functional-desgin-ppp/rust/03-polymorphism.md +0 -434
  129. package/lib/assets/docs/article/functional-desgin-ppp/rust/04-data-validation.md +0 -282
  130. package/lib/assets/docs/article/functional-desgin-ppp/rust/05-property-based-testing.md +0 -256
  131. package/lib/assets/docs/article/functional-desgin-ppp/rust/06-tdd-and-functional.md +0 -850
  132. package/lib/assets/docs/article/functional-desgin-ppp/rust/07-composite-pattern.md +0 -393
  133. package/lib/assets/docs/article/functional-desgin-ppp/rust/08-decorator-pattern.md +0 -392
  134. package/lib/assets/docs/article/functional-desgin-ppp/rust/09-adapter-pattern.md +0 -348
  135. package/lib/assets/docs/article/functional-desgin-ppp/rust/10-strategy-pattern.md +0 -340
  136. package/lib/assets/docs/article/functional-desgin-ppp/rust/11-command-pattern.md +0 -365
  137. package/lib/assets/docs/article/functional-desgin-ppp/rust/12-visitor-pattern.md +0 -388
  138. package/lib/assets/docs/article/functional-desgin-ppp/rust/13-abstract-factory-pattern.md +0 -370
  139. package/lib/assets/docs/article/functional-desgin-ppp/rust/14-abstract-server-pattern.md +0 -401
  140. package/lib/assets/docs/article/functional-desgin-ppp/rust/15-gossiping-bus-drivers.md +0 -309
  141. package/lib/assets/docs/article/functional-desgin-ppp/rust/16-payroll-system.md +0 -306
  142. package/lib/assets/docs/article/functional-desgin-ppp/rust/17-video-rental-system.md +0 -313
  143. package/lib/assets/docs/article/functional-desgin-ppp/rust/18-concurrency-system.md +0 -324
  144. package/lib/assets/docs/article/functional-desgin-ppp/rust/19-wator-simulation.md +0 -320
  145. package/lib/assets/docs/article/functional-desgin-ppp/rust/20-pattern-interactions.md +0 -313
  146. package/lib/assets/docs/article/functional-desgin-ppp/rust/21-best-practices.md +0 -345
  147. package/lib/assets/docs/article/functional-desgin-ppp/rust/22-oo-to-fp-migration.md +0 -358
  148. package/lib/assets/docs/article/functional-desgin-ppp/rust/index.md +0 -243
  149. package/lib/assets/docs/article/functional-desgin-ppp/scala/01-immutability-and-data-transformation.md +0 -337
  150. package/lib/assets/docs/article/functional-desgin-ppp/scala/02-function-composition.md +0 -357
  151. package/lib/assets/docs/article/functional-desgin-ppp/scala/03-polymorphism.md +0 -366
  152. package/lib/assets/docs/article/functional-desgin-ppp/scala/04-data-validation.md +0 -373
  153. package/lib/assets/docs/article/functional-desgin-ppp/scala/05-property-based-testing.md +0 -524
  154. package/lib/assets/docs/article/functional-desgin-ppp/scala/06-tdd-functional.md +0 -566
  155. package/lib/assets/docs/article/functional-desgin-ppp/scala/07-composite-pattern.md +0 -372
  156. package/lib/assets/docs/article/functional-desgin-ppp/scala/08-decorator-pattern.md +0 -336
  157. package/lib/assets/docs/article/functional-desgin-ppp/scala/09-adapter-pattern.md +0 -526
  158. package/lib/assets/docs/article/functional-desgin-ppp/scala/10-strategy-pattern.md +0 -450
  159. package/lib/assets/docs/article/functional-desgin-ppp/scala/11-command-pattern.md +0 -416
  160. package/lib/assets/docs/article/functional-desgin-ppp/scala/12-visitor-pattern.md +0 -388
  161. package/lib/assets/docs/article/functional-desgin-ppp/scala/13-abstract-factory-pattern.md +0 -407
  162. package/lib/assets/docs/article/functional-desgin-ppp/scala/14-abstract-server-pattern.md +0 -485
  163. package/lib/assets/docs/article/functional-desgin-ppp/scala/15-gossiping-bus-drivers.md +0 -400
  164. package/lib/assets/docs/article/functional-desgin-ppp/scala/16-payroll-system.md +0 -351
  165. package/lib/assets/docs/article/functional-desgin-ppp/scala/17-video-rental-system.md +0 -333
  166. package/lib/assets/docs/article/functional-desgin-ppp/scala/18-concurrency-system.md +0 -739
  167. package/lib/assets/docs/article/functional-desgin-ppp/scala/19-wator-simulation.md +0 -633
  168. package/lib/assets/docs/article/functional-desgin-ppp/scala/20-pattern-interactions.md +0 -521
  169. package/lib/assets/docs/article/functional-desgin-ppp/scala/21-best-practices.md +0 -442
  170. package/lib/assets/docs/article/functional-desgin-ppp/scala/22-oo-to-fp-migration.md +0 -697
  171. package/lib/assets/docs/article/functional-desgin-ppp/scala/index.md +0 -243
  172. package/lib/assets/docs/article/getting-start-docker-kubernetes/01-container-and-docker-basics.md +0 -341
  173. package/lib/assets/docs/article/getting-start-docker-kubernetes/02-container-deployment.md +0 -785
  174. package/lib/assets/docs/article/getting-start-docker-kubernetes/03-practical-container-build-deploy.md +0 -466
  175. package/lib/assets/docs/article/getting-start-docker-kubernetes/04-multi-container-application.md +0 -878
  176. package/lib/assets/docs/article/getting-start-docker-kubernetes/05-kubernetes-introduction.md +0 -585
  177. package/lib/assets/docs/article/getting-start-docker-kubernetes/06-kubernetes-deploy-cluster.md +0 -620
  178. package/lib/assets/docs/article/getting-start-docker-kubernetes/07-kubernetes-advanced.md +0 -621
  179. package/lib/assets/docs/article/getting-start-docker-kubernetes/08-kubernetes-packaging.md +0 -518
  180. package/lib/assets/docs/article/getting-start-docker-kubernetes/09-container-operations.md +0 -546
  181. package/lib/assets/docs/article/getting-start-docker-kubernetes/10-optimal-container-image.md +0 -640
  182. package/lib/assets/docs/article/getting-start-docker-kubernetes/11-continuous-delivery.md +0 -607
  183. package/lib/assets/docs/article/getting-start-docker-kubernetes/12-container-use-cases.md +0 -463
  184. package/lib/assets/docs/article/getting-start-docker-kubernetes/13-case-monolith-compose-vs-kustomize.md +0 -346
  185. package/lib/assets/docs/article/getting-start-docker-kubernetes/14-case-event-driven-kustomize-vs-helm.md +0 -324
  186. package/lib/assets/docs/article/getting-start-docker-kubernetes/15-case-escqrs-axon-kustomize-vs-helm.md +0 -297
  187. package/lib/assets/docs/article/getting-start-docker-kubernetes/16-case-escqrs-kafka-kustomize-vs-helm.md +0 -256
  188. package/lib/assets/docs/article/getting-start-docker-kubernetes/17-case-comparison-summary.md +0 -141
  189. package/lib/assets/docs/article/getting-start-docker-kubernetes/18-case-load-testing.md +0 -303
  190. package/lib/assets/docs/article/getting-start-docker-kubernetes/appendix-a-dev-tools-setup.md +0 -274
  191. package/lib/assets/docs/article/getting-start-docker-kubernetes/appendix-b-orchestration-environments.md +0 -530
  192. package/lib/assets/docs/article/getting-start-docker-kubernetes/appendix-c-tips.md +0 -519
  193. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-01-comic.png +0 -0
  194. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-02-comic.png +0 -0
  195. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-03-comic.png +0 -0
  196. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-04-comic.png +0 -0
  197. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-05-comic.png +0 -0
  198. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-06-comic.png +0 -0
  199. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-07-comic.png +0 -0
  200. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-08-comic.png +0 -0
  201. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-09-comic.png +0 -0
  202. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-10-comic.png +0 -0
  203. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-11-comic.png +0 -0
  204. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/chapter-12-comic.png +0 -0
  205. package/lib/assets/docs/article/getting-start-docker-kubernetes/images/overview-comic.png +0 -0
  206. package/lib/assets/docs/article/getting-start-docker-kubernetes/index.md +0 -82
  207. package/lib/assets/docs/article/getting-start-docker-kubernetes/outline.md +0 -220
  208. package/lib/assets/docs/article/getting-start-tdd/clojure/01-todo-list-and-first-test.md +0 -175
  209. package/lib/assets/docs/article/getting-start-tdd/clojure/02-fake-it-and-triangulation.md +0 -171
  210. package/lib/assets/docs/article/getting-start-tdd/clojure/03-obvious-implementation-and-refactoring.md +0 -144
  211. package/lib/assets/docs/article/getting-start-tdd/clojure/04-version-control-and-conventional-commits.md +0 -97
  212. package/lib/assets/docs/article/getting-start-tdd/clojure/05-package-management-and-static-analysis.md +0 -308
  213. package/lib/assets/docs/article/getting-start-tdd/clojure/06-task-runner-and-ci-cd.md +0 -250
  214. package/lib/assets/docs/article/getting-start-tdd/clojure/07-protocols-and-records.md +0 -140
  215. package/lib/assets/docs/article/getting-start-tdd/clojure/08-multimethods-and-design-patterns.md +0 -139
  216. package/lib/assets/docs/article/getting-start-tdd/clojure/09-namespaces-and-module-design.md +0 -136
  217. package/lib/assets/docs/article/getting-start-tdd/clojure/10-higher-order-functions-and-composition.md +0 -123
  218. package/lib/assets/docs/article/getting-start-tdd/clojure/11-persistent-data-and-pipeline.md +0 -147
  219. package/lib/assets/docs/article/getting-start-tdd/clojure/12-error-handling-and-spec.md +0 -170
  220. package/lib/assets/docs/article/getting-start-tdd/clojure/index.md +0 -65
  221. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter01.md +0 -241
  222. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter02.md +0 -253
  223. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter03.md +0 -211
  224. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter04.md +0 -101
  225. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter05.md +0 -265
  226. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter06.md +0 -204
  227. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter07.md +0 -223
  228. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter08.md +0 -258
  229. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter09.md +0 -183
  230. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter10.md +0 -175
  231. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter11.md +0 -201
  232. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter12.md +0 -220
  233. package/lib/assets/docs/article/getting-start-tdd/csharp/index.md +0 -83
  234. package/lib/assets/docs/article/getting-start-tdd/elixir/01-todo-list-and-first-test.md +0 -96
  235. package/lib/assets/docs/article/getting-start-tdd/elixir/02-fake-it-and-triangulation.md +0 -104
  236. package/lib/assets/docs/article/getting-start-tdd/elixir/03-obvious-implementation-and-refactoring.md +0 -118
  237. package/lib/assets/docs/article/getting-start-tdd/elixir/04-version-control-and-conventional-commits.md +0 -105
  238. package/lib/assets/docs/article/getting-start-tdd/elixir/05-package-management-and-static-analysis.md +0 -97
  239. package/lib/assets/docs/article/getting-start-tdd/elixir/06-task-runner-and-ci-cd.md +0 -80
  240. package/lib/assets/docs/article/getting-start-tdd/elixir/07-structs-and-protocols.md +0 -119
  241. package/lib/assets/docs/article/getting-start-tdd/elixir/08-pattern-matching-and-guards.md +0 -117
  242. package/lib/assets/docs/article/getting-start-tdd/elixir/09-module-design-and-behaviours.md +0 -113
  243. package/lib/assets/docs/article/getting-start-tdd/elixir/10-higher-order-functions-and-pipeline.md +0 -187
  244. package/lib/assets/docs/article/getting-start-tdd/elixir/11-stream-and-lazy-evaluation.md +0 -151
  245. package/lib/assets/docs/article/getting-start-tdd/elixir/12-error-handling-and-with.md +0 -154
  246. package/lib/assets/docs/article/getting-start-tdd/elixir/index.md +0 -35
  247. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter01.md +0 -211
  248. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter02.md +0 -255
  249. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter03.md +0 -227
  250. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter04.md +0 -188
  251. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter05.md +0 -276
  252. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter06.md +0 -199
  253. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter07.md +0 -170
  254. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter08.md +0 -184
  255. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter09.md +0 -231
  256. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter10.md +0 -198
  257. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter11.md +0 -221
  258. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter12.md +0 -224
  259. package/lib/assets/docs/article/getting-start-tdd/fsharp/index.md +0 -71
  260. package/lib/assets/docs/article/getting-start-tdd/go/01-todo-list-and-first-test.md +0 -222
  261. package/lib/assets/docs/article/getting-start-tdd/go/02-fake-it-and-triangulation.md +0 -311
  262. package/lib/assets/docs/article/getting-start-tdd/go/03-obvious-implementation-and-refactoring.md +0 -348
  263. package/lib/assets/docs/article/getting-start-tdd/go/04-version-control-and-conventional-commits.md +0 -121
  264. package/lib/assets/docs/article/getting-start-tdd/go/05-package-management-and-static-analysis.md +0 -281
  265. package/lib/assets/docs/article/getting-start-tdd/go/06-task-runner-and-ci-cd.md +0 -242
  266. package/lib/assets/docs/article/getting-start-tdd/go/07-encapsulation-and-polymorphism.md +0 -402
  267. package/lib/assets/docs/article/getting-start-tdd/go/08-design-patterns.md +0 -430
  268. package/lib/assets/docs/article/getting-start-tdd/go/09-solid-principles-and-module-design.md +0 -408
  269. package/lib/assets/docs/article/getting-start-tdd/go/10-higher-order-functions-and-composition.md +0 -234
  270. package/lib/assets/docs/article/getting-start-tdd/go/11-immutable-data-and-pipeline.md +0 -304
  271. package/lib/assets/docs/article/getting-start-tdd/go/12-error-handling-and-type-safety.md +0 -419
  272. package/lib/assets/docs/article/getting-start-tdd/go/index.md +0 -83
  273. package/lib/assets/docs/article/getting-start-tdd/haskell/01-todo-list-and-first-test.md +0 -288
  274. package/lib/assets/docs/article/getting-start-tdd/haskell/02-fake-it-and-triangulation.md +0 -346
  275. package/lib/assets/docs/article/getting-start-tdd/haskell/03-obvious-implementation-and-refactoring.md +0 -266
  276. package/lib/assets/docs/article/getting-start-tdd/haskell/04-version-control-and-conventional-commits.md +0 -191
  277. package/lib/assets/docs/article/getting-start-tdd/haskell/05-package-management-and-static-analysis.md +0 -322
  278. package/lib/assets/docs/article/getting-start-tdd/haskell/06-task-runner-and-ci-cd.md +0 -318
  279. package/lib/assets/docs/article/getting-start-tdd/haskell/07-algebraic-data-types-and-type-classes.md +0 -421
  280. package/lib/assets/docs/article/getting-start-tdd/haskell/08-pattern-matching-and-guards.md +0 -399
  281. package/lib/assets/docs/article/getting-start-tdd/haskell/09-module-design-and-smart-constructors.md +0 -470
  282. package/lib/assets/docs/article/getting-start-tdd/haskell/10-higher-order-functions-and-currying.md +0 -443
  283. package/lib/assets/docs/article/getting-start-tdd/haskell/11-function-composition-and-point-free.md +0 -401
  284. package/lib/assets/docs/article/getting-start-tdd/haskell/12-monad-and-error-handling.md +0 -640
  285. package/lib/assets/docs/article/getting-start-tdd/haskell/index.md +0 -49
  286. package/lib/assets/docs/article/getting-start-tdd/index.md +0 -93
  287. package/lib/assets/docs/article/getting-start-tdd/integration/01-language-overview.md +0 -384
  288. package/lib/assets/docs/article/getting-start-tdd/integration/02-test-framework-comparison.md +0 -358
  289. package/lib/assets/docs/article/getting-start-tdd/integration/03-tdd-pattern-comparison.md +0 -454
  290. package/lib/assets/docs/article/getting-start-tdd/integration/04-type-system-comparison.md +0 -418
  291. package/lib/assets/docs/article/getting-start-tdd/integration/05-dev-environment-comparison.md +0 -339
  292. package/lib/assets/docs/article/getting-start-tdd/integration/06-learning-roadmap.md +0 -299
  293. package/lib/assets/docs/article/getting-start-tdd/integration/index.md +0 -69
  294. package/lib/assets/docs/article/getting-start-tdd/java/01-todo-list-and-first-test.md +0 -243
  295. package/lib/assets/docs/article/getting-start-tdd/java/02-fake-it-and-triangulation.md +0 -270
  296. package/lib/assets/docs/article/getting-start-tdd/java/03-obvious-implementation-and-refactoring.md +0 -194
  297. package/lib/assets/docs/article/getting-start-tdd/java/04-version-control-and-conventional-commits.md +0 -124
  298. package/lib/assets/docs/article/getting-start-tdd/java/05-package-management-and-static-analysis.md +0 -391
  299. package/lib/assets/docs/article/getting-start-tdd/java/06-task-runner-and-ci-cd.md +0 -281
  300. package/lib/assets/docs/article/getting-start-tdd/java/07-encapsulation-and-polymorphism.md +0 -635
  301. package/lib/assets/docs/article/getting-start-tdd/java/08-design-patterns.md +0 -402
  302. package/lib/assets/docs/article/getting-start-tdd/java/09-solid-principles-and-module-design.md +0 -319
  303. package/lib/assets/docs/article/getting-start-tdd/java/10-higher-order-functions-and-composition.md +0 -197
  304. package/lib/assets/docs/article/getting-start-tdd/java/11-immutable-data-and-pipeline.md +0 -176
  305. package/lib/assets/docs/article/getting-start-tdd/java/12-error-handling-and-type-safety.md +0 -214
  306. package/lib/assets/docs/article/getting-start-tdd/java/index.md +0 -61
  307. package/lib/assets/docs/article/getting-start-tdd/node/01-todo-list-and-first-test.md +0 -253
  308. package/lib/assets/docs/article/getting-start-tdd/node/02-fake-it-and-triangulation.md +0 -271
  309. package/lib/assets/docs/article/getting-start-tdd/node/03-obvious-implementation-and-refactoring.md +0 -178
  310. package/lib/assets/docs/article/getting-start-tdd/node/04-version-control-and-conventional-commits.md +0 -121
  311. package/lib/assets/docs/article/getting-start-tdd/node/05-package-management-and-static-analysis.md +0 -323
  312. package/lib/assets/docs/article/getting-start-tdd/node/06-task-runner-and-ci-cd.md +0 -244
  313. package/lib/assets/docs/article/getting-start-tdd/node/07-encapsulation-and-polymorphism.md +0 -336
  314. package/lib/assets/docs/article/getting-start-tdd/node/08-design-patterns.md +0 -331
  315. package/lib/assets/docs/article/getting-start-tdd/node/09-solid-principles-and-module-design.md +0 -294
  316. package/lib/assets/docs/article/getting-start-tdd/node/10-higher-order-functions-and-composition.md +0 -208
  317. package/lib/assets/docs/article/getting-start-tdd/node/11-immutable-data-and-pipeline.md +0 -216
  318. package/lib/assets/docs/article/getting-start-tdd/node/12-error-handling-and-type-safety.md +0 -304
  319. package/lib/assets/docs/article/getting-start-tdd/node/index.md +0 -56
  320. package/lib/assets/docs/article/getting-start-tdd/php/01-todo-list-and-first-test.md +0 -268
  321. package/lib/assets/docs/article/getting-start-tdd/php/02-fake-it-and-triangulation.md +0 -209
  322. package/lib/assets/docs/article/getting-start-tdd/php/03-obvious-implementation-and-refactoring.md +0 -257
  323. package/lib/assets/docs/article/getting-start-tdd/php/04-version-control-and-conventional-commits.md +0 -150
  324. package/lib/assets/docs/article/getting-start-tdd/php/05-package-management-and-static-analysis.md +0 -419
  325. package/lib/assets/docs/article/getting-start-tdd/php/06-task-runner-and-ci-cd.md +0 -330
  326. package/lib/assets/docs/article/getting-start-tdd/php/07-encapsulation-and-polymorphism.md +0 -380
  327. package/lib/assets/docs/article/getting-start-tdd/php/08-design-patterns.md +0 -461
  328. package/lib/assets/docs/article/getting-start-tdd/php/09-solid-principles-and-module-design.md +0 -468
  329. package/lib/assets/docs/article/getting-start-tdd/php/10-higher-order-functions-and-composition.md +0 -190
  330. package/lib/assets/docs/article/getting-start-tdd/php/11-immutable-data-and-pipeline.md +0 -274
  331. package/lib/assets/docs/article/getting-start-tdd/php/12-error-handling-and-type-safety.md +0 -316
  332. package/lib/assets/docs/article/getting-start-tdd/php/index.md +0 -84
  333. package/lib/assets/docs/article/getting-start-tdd/python/01-todo-list-and-first-test.md +0 -210
  334. package/lib/assets/docs/article/getting-start-tdd/python/02-fake-it-and-triangulation.md +0 -256
  335. package/lib/assets/docs/article/getting-start-tdd/python/03-obvious-implementation-and-refactoring.md +0 -208
  336. package/lib/assets/docs/article/getting-start-tdd/python/04-version-control-and-conventional-commits.md +0 -96
  337. package/lib/assets/docs/article/getting-start-tdd/python/05-package-management-and-static-analysis.md +0 -283
  338. package/lib/assets/docs/article/getting-start-tdd/python/06-task-runner-and-ci-cd.md +0 -199
  339. package/lib/assets/docs/article/getting-start-tdd/python/07-encapsulation-and-polymorphism.md +0 -217
  340. package/lib/assets/docs/article/getting-start-tdd/python/08-design-patterns.md +0 -181
  341. package/lib/assets/docs/article/getting-start-tdd/python/09-solid-principles-and-module-design.md +0 -139
  342. package/lib/assets/docs/article/getting-start-tdd/python/10-higher-order-functions-and-composition.md +0 -131
  343. package/lib/assets/docs/article/getting-start-tdd/python/11-immutable-data-and-pipeline.md +0 -125
  344. package/lib/assets/docs/article/getting-start-tdd/python/12-error-handling-and-type-safety.md +0 -135
  345. package/lib/assets/docs/article/getting-start-tdd/python/index.md +0 -55
  346. package/lib/assets/docs/article/getting-start-tdd/ruby/01-todo-list-and-first-test.md +0 -240
  347. package/lib/assets/docs/article/getting-start-tdd/ruby/02-fake-it-and-triangulation.md +0 -247
  348. package/lib/assets/docs/article/getting-start-tdd/ruby/03-obvious-implementation-and-refactoring.md +0 -237
  349. package/lib/assets/docs/article/getting-start-tdd/ruby/04-version-control-and-conventional-commits.md +0 -121
  350. package/lib/assets/docs/article/getting-start-tdd/ruby/05-package-management-and-static-analysis.md +0 -296
  351. package/lib/assets/docs/article/getting-start-tdd/ruby/06-task-runner-and-ci-cd.md +0 -257
  352. package/lib/assets/docs/article/getting-start-tdd/ruby/07-encapsulation-and-polymorphism.md +0 -288
  353. package/lib/assets/docs/article/getting-start-tdd/ruby/08-design-patterns.md +0 -338
  354. package/lib/assets/docs/article/getting-start-tdd/ruby/09-solid-principles-and-module-design.md +0 -205
  355. package/lib/assets/docs/article/getting-start-tdd/ruby/10-higher-order-functions-and-composition.md +0 -184
  356. package/lib/assets/docs/article/getting-start-tdd/ruby/11-immutable-data-and-pipeline.md +0 -246
  357. package/lib/assets/docs/article/getting-start-tdd/ruby/12-error-handling-and-type-safety.md +0 -407
  358. package/lib/assets/docs/article/getting-start-tdd/ruby/index.md +0 -83
  359. package/lib/assets/docs/article/getting-start-tdd/rust/01-todo-list-and-first-test.md +0 -220
  360. package/lib/assets/docs/article/getting-start-tdd/rust/02-fake-it-and-triangulation.md +0 -273
  361. package/lib/assets/docs/article/getting-start-tdd/rust/03-obvious-implementation-and-refactoring.md +0 -242
  362. package/lib/assets/docs/article/getting-start-tdd/rust/04-version-control-and-conventional-commits.md +0 -101
  363. package/lib/assets/docs/article/getting-start-tdd/rust/05-package-management-and-static-analysis.md +0 -221
  364. package/lib/assets/docs/article/getting-start-tdd/rust/06-task-runner-and-ci-cd.md +0 -173
  365. package/lib/assets/docs/article/getting-start-tdd/rust/07-encapsulation-and-polymorphism.md +0 -151
  366. package/lib/assets/docs/article/getting-start-tdd/rust/08-design-patterns.md +0 -154
  367. package/lib/assets/docs/article/getting-start-tdd/rust/09-solid-principles-and-module-design.md +0 -119
  368. package/lib/assets/docs/article/getting-start-tdd/rust/10-higher-order-functions-and-composition.md +0 -103
  369. package/lib/assets/docs/article/getting-start-tdd/rust/11-immutable-data-and-pipeline.md +0 -114
  370. package/lib/assets/docs/article/getting-start-tdd/rust/12-error-handling-and-type-safety.md +0 -121
  371. package/lib/assets/docs/article/getting-start-tdd/rust/index.md +0 -83
  372. package/lib/assets/docs/article/getting-start-tdd/scala/01-todo-list-and-first-test.md +0 -120
  373. package/lib/assets/docs/article/getting-start-tdd/scala/02-fake-it-and-triangulation.md +0 -116
  374. package/lib/assets/docs/article/getting-start-tdd/scala/03-obvious-implementation-and-refactoring.md +0 -108
  375. package/lib/assets/docs/article/getting-start-tdd/scala/04-version-control-and-conventional-commits.md +0 -132
  376. package/lib/assets/docs/article/getting-start-tdd/scala/05-package-management-and-static-analysis.md +0 -205
  377. package/lib/assets/docs/article/getting-start-tdd/scala/06-task-runner-and-ci-cd.md +0 -195
  378. package/lib/assets/docs/article/getting-start-tdd/scala/07-case-classes-and-traits.md +0 -148
  379. package/lib/assets/docs/article/getting-start-tdd/scala/08-pattern-matching-and-sealed-traits.md +0 -115
  380. package/lib/assets/docs/article/getting-start-tdd/scala/09-packages-and-module-design.md +0 -84
  381. package/lib/assets/docs/article/getting-start-tdd/scala/10-higher-order-functions-and-composition.md +0 -113
  382. package/lib/assets/docs/article/getting-start-tdd/scala/11-collections-and-lazy-evaluation.md +0 -103
  383. package/lib/assets/docs/article/getting-start-tdd/scala/12-error-handling-and-type-safety.md +0 -101
  384. package/lib/assets/docs/article/getting-start-tdd/scala/index.md +0 -65
  385. package/lib/assets/docs/article/grokking-concurrency/all/index.md +0 -403
  386. package/lib/assets/docs/article/grokking-concurrency/all/part-1-ch02-sequential.md +0 -563
  387. package/lib/assets/docs/article/grokking-concurrency/all/part-2-ch04-05-threads.md +0 -478
  388. package/lib/assets/docs/article/grokking-concurrency/all/part-3-ch06-multitasking.md +0 -529
  389. package/lib/assets/docs/article/grokking-concurrency/all/part-4-ch07-parallel-patterns.md +0 -429
  390. package/lib/assets/docs/article/grokking-concurrency/all/part-5-ch08-09-synchronization.md +0 -519
  391. package/lib/assets/docs/article/grokking-concurrency/all/part-6-ch10-11-nonblocking-io.md +0 -444
  392. package/lib/assets/docs/article/grokking-concurrency/all/part-7-ch12-async.md +0 -474
  393. package/lib/assets/docs/article/grokking-concurrency/all/part-8-ch13-mapreduce.md +0 -386
  394. package/lib/assets/docs/article/grokking-concurrency/clojure/index.md +0 -106
  395. package/lib/assets/docs/article/grokking-concurrency/clojure/part-1.md +0 -107
  396. package/lib/assets/docs/article/grokking-concurrency/clojure/part-2.md +0 -100
  397. package/lib/assets/docs/article/grokking-concurrency/clojure/part-3.md +0 -121
  398. package/lib/assets/docs/article/grokking-concurrency/clojure/part-4.md +0 -122
  399. package/lib/assets/docs/article/grokking-concurrency/clojure/part-5.md +0 -117
  400. package/lib/assets/docs/article/grokking-concurrency/clojure/part-6.md +0 -88
  401. package/lib/assets/docs/article/grokking-concurrency/clojure/part-7.md +0 -99
  402. package/lib/assets/docs/article/grokking-concurrency/clojure/part-8.md +0 -119
  403. package/lib/assets/docs/article/grokking-concurrency/csharp/index.md +0 -91
  404. package/lib/assets/docs/article/grokking-concurrency/csharp/part-1.md +0 -96
  405. package/lib/assets/docs/article/grokking-concurrency/csharp/part-2.md +0 -122
  406. package/lib/assets/docs/article/grokking-concurrency/csharp/part-3.md +0 -100
  407. package/lib/assets/docs/article/grokking-concurrency/csharp/part-4.md +0 -111
  408. package/lib/assets/docs/article/grokking-concurrency/csharp/part-5.md +0 -98
  409. package/lib/assets/docs/article/grokking-concurrency/csharp/part-6.md +0 -60
  410. package/lib/assets/docs/article/grokking-concurrency/csharp/part-7.md +0 -83
  411. package/lib/assets/docs/article/grokking-concurrency/csharp/part-8.md +0 -91
  412. package/lib/assets/docs/article/grokking-concurrency/fsharp/index.md +0 -55
  413. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-1.md +0 -79
  414. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-2.md +0 -102
  415. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-3.md +0 -93
  416. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-4.md +0 -109
  417. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-5.md +0 -103
  418. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-6.md +0 -92
  419. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-7.md +0 -120
  420. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-8.md +0 -106
  421. package/lib/assets/docs/article/grokking-concurrency/haskell/index.md +0 -238
  422. package/lib/assets/docs/article/grokking-concurrency/haskell/part-1.md +0 -95
  423. package/lib/assets/docs/article/grokking-concurrency/haskell/part-2.md +0 -95
  424. package/lib/assets/docs/article/grokking-concurrency/haskell/part-3.md +0 -90
  425. package/lib/assets/docs/article/grokking-concurrency/haskell/part-4.md +0 -105
  426. package/lib/assets/docs/article/grokking-concurrency/haskell/part-5.md +0 -98
  427. package/lib/assets/docs/article/grokking-concurrency/haskell/part-6.md +0 -94
  428. package/lib/assets/docs/article/grokking-concurrency/haskell/part-7.md +0 -110
  429. package/lib/assets/docs/article/grokking-concurrency/haskell/part-8.md +0 -117
  430. package/lib/assets/docs/article/grokking-concurrency/index.md +0 -66
  431. package/lib/assets/docs/article/grokking-concurrency/java/index.md +0 -92
  432. package/lib/assets/docs/article/grokking-concurrency/java/part-1.md +0 -307
  433. package/lib/assets/docs/article/grokking-concurrency/java/part-2.md +0 -333
  434. package/lib/assets/docs/article/grokking-concurrency/java/part-3.md +0 -220
  435. package/lib/assets/docs/article/grokking-concurrency/java/part-4.md +0 -212
  436. package/lib/assets/docs/article/grokking-concurrency/java/part-5.md +0 -111
  437. package/lib/assets/docs/article/grokking-concurrency/java/part-6.md +0 -68
  438. package/lib/assets/docs/article/grokking-concurrency/java/part-7.md +0 -100
  439. package/lib/assets/docs/article/grokking-concurrency/java/part-8.md +0 -100
  440. package/lib/assets/docs/article/grokking-concurrency/python/index.md +0 -303
  441. package/lib/assets/docs/article/grokking-concurrency/python/part-1.md +0 -238
  442. package/lib/assets/docs/article/grokking-concurrency/python/part-2.md +0 -417
  443. package/lib/assets/docs/article/grokking-concurrency/python/part-3.md +0 -226
  444. package/lib/assets/docs/article/grokking-concurrency/python/part-4.md +0 -298
  445. package/lib/assets/docs/article/grokking-concurrency/python/part-5.md +0 -314
  446. package/lib/assets/docs/article/grokking-concurrency/python/part-6.md +0 -296
  447. package/lib/assets/docs/article/grokking-concurrency/python/part-7.md +0 -313
  448. package/lib/assets/docs/article/grokking-concurrency/python/part-8.md +0 -359
  449. package/lib/assets/docs/article/grokking-concurrency/rust/index.md +0 -260
  450. package/lib/assets/docs/article/grokking-concurrency/rust/part-1.md +0 -107
  451. package/lib/assets/docs/article/grokking-concurrency/rust/part-2.md +0 -119
  452. package/lib/assets/docs/article/grokking-concurrency/rust/part-3.md +0 -125
  453. package/lib/assets/docs/article/grokking-concurrency/rust/part-4.md +0 -174
  454. package/lib/assets/docs/article/grokking-concurrency/rust/part-5.md +0 -157
  455. package/lib/assets/docs/article/grokking-concurrency/rust/part-6.md +0 -93
  456. package/lib/assets/docs/article/grokking-concurrency/rust/part-7.md +0 -132
  457. package/lib/assets/docs/article/grokking-concurrency/rust/part-8.md +0 -154
  458. package/lib/assets/docs/article/grokking-concurrency/scala/index.md +0 -59
  459. package/lib/assets/docs/article/grokking-concurrency/scala/part-1.md +0 -77
  460. package/lib/assets/docs/article/grokking-concurrency/scala/part-2.md +0 -111
  461. package/lib/assets/docs/article/grokking-concurrency/scala/part-3.md +0 -92
  462. package/lib/assets/docs/article/grokking-concurrency/scala/part-4.md +0 -109
  463. package/lib/assets/docs/article/grokking-concurrency/scala/part-5.md +0 -118
  464. package/lib/assets/docs/article/grokking-concurrency/scala/part-6.md +0 -82
  465. package/lib/assets/docs/article/grokking-concurrency/scala/part-7.md +0 -130
  466. package/lib/assets/docs/article/grokking-concurrency/scala/part-8.md +0 -128
  467. package/lib/assets/docs/article/grokkingfp/all/index.md +0 -368
  468. package/lib/assets/docs/article/grokkingfp/all/part-1-ch01-fp-introduction.md +0 -539
  469. package/lib/assets/docs/article/grokkingfp/all/part-1-ch02-pure-functions.md +0 -932
  470. package/lib/assets/docs/article/grokkingfp/all/part-2-ch03-immutable-data.md +0 -1137
  471. package/lib/assets/docs/article/grokkingfp/all/part-2-ch04-higher-order-functions.md +0 -1113
  472. package/lib/assets/docs/article/grokkingfp/all/part-2-ch05-flatmap.md +0 -1035
  473. package/lib/assets/docs/article/grokkingfp/all/part-3-ch06-option.md +0 -794
  474. package/lib/assets/docs/article/grokkingfp/all/part-3-ch07-either-adt.md +0 -880
  475. package/lib/assets/docs/article/grokkingfp/all/part-4-ch08-io-monad.md +0 -981
  476. package/lib/assets/docs/article/grokkingfp/all/part-4-ch09-streams.md +0 -935
  477. package/lib/assets/docs/article/grokkingfp/all/part-5-ch10-concurrency.md +0 -879
  478. package/lib/assets/docs/article/grokkingfp/all/part-6-ch11-application.md +0 -724
  479. package/lib/assets/docs/article/grokkingfp/all/part-6-ch12-testing.md +0 -635
  480. package/lib/assets/docs/article/grokkingfp/all/writing-plan.md +0 -721
  481. package/lib/assets/docs/article/grokkingfp/clojure/index.md +0 -276
  482. package/lib/assets/docs/article/grokkingfp/clojure/part-1.md +0 -676
  483. package/lib/assets/docs/article/grokkingfp/clojure/part-2.md +0 -652
  484. package/lib/assets/docs/article/grokkingfp/clojure/part-3.md +0 -629
  485. package/lib/assets/docs/article/grokkingfp/clojure/part-4.md +0 -706
  486. package/lib/assets/docs/article/grokkingfp/clojure/part-5.md +0 -760
  487. package/lib/assets/docs/article/grokkingfp/clojure/part-6.md +0 -730
  488. package/lib/assets/docs/article/grokkingfp/csharp/index.md +0 -246
  489. package/lib/assets/docs/article/grokkingfp/csharp/part-1.md +0 -820
  490. package/lib/assets/docs/article/grokkingfp/csharp/part-2.md +0 -980
  491. package/lib/assets/docs/article/grokkingfp/csharp/part-3.md +0 -990
  492. package/lib/assets/docs/article/grokkingfp/csharp/part-4.md +0 -958
  493. package/lib/assets/docs/article/grokkingfp/csharp/part-5.md +0 -956
  494. package/lib/assets/docs/article/grokkingfp/csharp/part-6.md +0 -748
  495. package/lib/assets/docs/article/grokkingfp/elixir/index.md +0 -203
  496. package/lib/assets/docs/article/grokkingfp/elixir/part-1.md +0 -721
  497. package/lib/assets/docs/article/grokkingfp/elixir/part-2.md +0 -847
  498. package/lib/assets/docs/article/grokkingfp/elixir/part-3.md +0 -994
  499. package/lib/assets/docs/article/grokkingfp/elixir/part-4.md +0 -983
  500. package/lib/assets/docs/article/grokkingfp/elixir/part-5.md +0 -1295
  501. package/lib/assets/docs/article/grokkingfp/elixir/part-6.md +0 -1058
  502. package/lib/assets/docs/article/grokkingfp/fsharp/index.md +0 -210
  503. package/lib/assets/docs/article/grokkingfp/fsharp/part-1.md +0 -723
  504. package/lib/assets/docs/article/grokkingfp/fsharp/part-2.md +0 -970
  505. package/lib/assets/docs/article/grokkingfp/fsharp/part-3.md +0 -981
  506. package/lib/assets/docs/article/grokkingfp/fsharp/part-4.md +0 -841
  507. package/lib/assets/docs/article/grokkingfp/fsharp/part-5.md +0 -920
  508. package/lib/assets/docs/article/grokkingfp/fsharp/part-6.md +0 -931
  509. package/lib/assets/docs/article/grokkingfp/haskell/index.md +0 -234
  510. package/lib/assets/docs/article/grokkingfp/haskell/part-1.md +0 -600
  511. package/lib/assets/docs/article/grokkingfp/haskell/part-2.md +0 -875
  512. package/lib/assets/docs/article/grokkingfp/haskell/part-3.md +0 -924
  513. package/lib/assets/docs/article/grokkingfp/haskell/part-4.md +0 -887
  514. package/lib/assets/docs/article/grokkingfp/haskell/part-5.md +0 -854
  515. package/lib/assets/docs/article/grokkingfp/haskell/part-6.md +0 -853
  516. package/lib/assets/docs/article/grokkingfp/index.md +0 -143
  517. package/lib/assets/docs/article/grokkingfp/java/index.md +0 -211
  518. package/lib/assets/docs/article/grokkingfp/java/part-1.md +0 -657
  519. package/lib/assets/docs/article/grokkingfp/java/part-2.md +0 -684
  520. package/lib/assets/docs/article/grokkingfp/java/part-3.md +0 -681
  521. package/lib/assets/docs/article/grokkingfp/java/part-4.md +0 -780
  522. package/lib/assets/docs/article/grokkingfp/java/part-5.md +0 -968
  523. package/lib/assets/docs/article/grokkingfp/java/part-6.md +0 -1337
  524. package/lib/assets/docs/article/grokkingfp/python/index.md +0 -258
  525. package/lib/assets/docs/article/grokkingfp/python/part-1.md +0 -452
  526. package/lib/assets/docs/article/grokkingfp/python/part-2.md +0 -967
  527. package/lib/assets/docs/article/grokkingfp/python/part-3.md +0 -1013
  528. package/lib/assets/docs/article/grokkingfp/python/part-4.md +0 -774
  529. package/lib/assets/docs/article/grokkingfp/python/part-5.md +0 -756
  530. package/lib/assets/docs/article/grokkingfp/python/part-6.md +0 -870
  531. package/lib/assets/docs/article/grokkingfp/ruby/index.md +0 -330
  532. package/lib/assets/docs/article/grokkingfp/ruby/part-1.md +0 -764
  533. package/lib/assets/docs/article/grokkingfp/ruby/part-2.md +0 -947
  534. package/lib/assets/docs/article/grokkingfp/ruby/part-3.md +0 -955
  535. package/lib/assets/docs/article/grokkingfp/ruby/part-4.md +0 -930
  536. package/lib/assets/docs/article/grokkingfp/ruby/part-5.md +0 -917
  537. package/lib/assets/docs/article/grokkingfp/ruby/part-6.md +0 -1421
  538. package/lib/assets/docs/article/grokkingfp/rust/index.md +0 -242
  539. package/lib/assets/docs/article/grokkingfp/rust/part-1.md +0 -643
  540. package/lib/assets/docs/article/grokkingfp/rust/part-2.md +0 -1069
  541. package/lib/assets/docs/article/grokkingfp/rust/part-3.md +0 -1003
  542. package/lib/assets/docs/article/grokkingfp/rust/part-4.md +0 -582
  543. package/lib/assets/docs/article/grokkingfp/rust/part-5.md +0 -714
  544. package/lib/assets/docs/article/grokkingfp/rust/part-6.md +0 -517
  545. package/lib/assets/docs/article/grokkingfp/scala/index.md +0 -171
  546. package/lib/assets/docs/article/grokkingfp/scala/part-1.md +0 -552
  547. package/lib/assets/docs/article/grokkingfp/scala/part-2.md +0 -955
  548. package/lib/assets/docs/article/grokkingfp/scala/part-3.md +0 -928
  549. package/lib/assets/docs/article/grokkingfp/scala/part-4.md +0 -751
  550. package/lib/assets/docs/article/grokkingfp/scala/part-5.md +0 -731
  551. package/lib/assets/docs/article/grokkingfp/scala/part-6.md +0 -876
  552. package/lib/assets/docs/article/grokkingfp/typescript/index.md +0 -273
  553. package/lib/assets/docs/article/grokkingfp/typescript/part-1.md +0 -570
  554. package/lib/assets/docs/article/grokkingfp/typescript/part-2.md +0 -1138
  555. package/lib/assets/docs/article/grokkingfp/typescript/part-3.md +0 -851
  556. package/lib/assets/docs/article/grokkingfp/typescript/part-4.md +0 -1096
  557. package/lib/assets/docs/article/grokkingfp/typescript/part-5.md +0 -726
  558. package/lib/assets/docs/article/grokkingfp/typescript/part-6.md +0 -991
  559. package/lib/assets/docs/article/practical-database-design/index.md +0 -121
  560. package/lib/assets/docs/article/practical-database-design/part1/chapter01.md +0 -297
  561. package/lib/assets/docs/article/practical-database-design/part1/chapter02.md +0 -527
  562. package/lib/assets/docs/article/practical-database-design/part1/chapter03.md +0 -566
  563. package/lib/assets/docs/article/practical-database-design/part2/chapter04.md +0 -933
  564. package/lib/assets/docs/article/practical-database-design/part2/chapter05.md +0 -1636
  565. package/lib/assets/docs/article/practical-database-design/part2/chapter06.md +0 -2725
  566. package/lib/assets/docs/article/practical-database-design/part2/chapter07.md +0 -2091
  567. package/lib/assets/docs/article/practical-database-design/part2/chapter08.md +0 -2114
  568. package/lib/assets/docs/article/practical-database-design/part2/chapter09.md +0 -2040
  569. package/lib/assets/docs/article/practical-database-design/part2/chapter10.md +0 -1396
  570. package/lib/assets/docs/article/practical-database-design/part2/chapter11.md +0 -1686
  571. package/lib/assets/docs/article/practical-database-design/part2/chapter12.md +0 -1426
  572. package/lib/assets/docs/article/practical-database-design/part2/chapter13.md +0 -1443
  573. package/lib/assets/docs/article/practical-database-design/part3/chapter14.md +0 -676
  574. package/lib/assets/docs/article/practical-database-design/part3/chapter15.md +0 -1634
  575. package/lib/assets/docs/article/practical-database-design/part3/chapter16.md +0 -1924
  576. package/lib/assets/docs/article/practical-database-design/part3/chapter17.md +0 -1717
  577. package/lib/assets/docs/article/practical-database-design/part3/chapter18.md +0 -2104
  578. package/lib/assets/docs/article/practical-database-design/part3/chapter19.md +0 -1132
  579. package/lib/assets/docs/article/practical-database-design/part3/chapter20.md +0 -1040
  580. package/lib/assets/docs/article/practical-database-design/part3/chapter21.md +0 -1391
  581. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter14-orm.md +0 -1000
  582. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter15-orm.md +0 -1309
  583. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter16-orm.md +0 -1175
  584. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter17-orm.md +0 -1593
  585. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter18-orm.md +0 -1192
  586. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter19-orm.md +0 -1025
  587. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter20-orm.md +0 -1762
  588. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter21-orm.md +0 -1456
  589. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter22-orm.md +0 -1887
  590. package/lib/assets/docs/article/practical-database-design/part4/chapter22.md +0 -974
  591. package/lib/assets/docs/article/practical-database-design/part4/chapter23.md +0 -2078
  592. package/lib/assets/docs/article/practical-database-design/part4/chapter24.md +0 -2448
  593. package/lib/assets/docs/article/practical-database-design/part4/chapter25.md +0 -3670
  594. package/lib/assets/docs/article/practical-database-design/part4/chapter26.md +0 -2925
  595. package/lib/assets/docs/article/practical-database-design/part4/chapter27.md +0 -3114
  596. package/lib/assets/docs/article/practical-database-design/part4/chapter28.md +0 -2706
  597. package/lib/assets/docs/article/practical-database-design/part4/chapter29.md +0 -2552
  598. package/lib/assets/docs/article/practical-database-design/part4/chapter30.md +0 -2188
  599. package/lib/assets/docs/article/practical-database-design/part4/chapter31.md +0 -1200
  600. package/lib/assets/docs/article/practical-database-design/part4/chapter32.md +0 -2109
  601. package/lib/assets/docs/article/practical-database-design/part5/chapter33.md +0 -1041
  602. package/lib/assets/docs/article/practical-database-design/part5/chapter34.md +0 -1618
  603. package/lib/assets/docs/article/practical-database-design/part5/chapter35.md +0 -1462
  604. package/lib/assets/docs/article/practical-database-design/part5/chapter36.md +0 -1301
  605. package/lib/assets/docs/article/practical-database-design/part5/chapter37.md +0 -1479
  606. package/lib/assets/docs/article/practical-database-design/part5/chapter38.md +0 -1707
  607. package/lib/assets/docs/article/practical-database-design/part5/chapter39.md +0 -2343
  608. package/lib/assets/docs/article/practical-database-design/study/study2-1.md +0 -1702
  609. package/lib/assets/docs/article/practical-database-design/study/study2-2.md +0 -1356
  610. package/lib/assets/docs/article/practical-database-design/study/study2-3.md +0 -2053
  611. package/lib/assets/docs/article/practical-database-design/study/study2-4.md +0 -2238
  612. package/lib/assets/docs/article/practical-database-design/study/study2-5.md +0 -2427
  613. package/lib/assets/docs/article/practical-database-design/study/study3-1.md +0 -2214
  614. package/lib/assets/docs/article/practical-database-design/study/study3-2.md +0 -2230
  615. package/lib/assets/docs/article/practical-database-design/study/study3-3.md +0 -2262
  616. package/lib/assets/docs/article/practical-database-design/study/study3-4.md +0 -2115
  617. package/lib/assets/docs/article/practical-database-design/study/study3-5.md +0 -2516
  618. package/lib/assets/docs/article/practical-database-design/study/study4-1.md +0 -2596
  619. package/lib/assets/docs/article/practical-database-design/study/study4-2.md +0 -2084
  620. package/lib/assets/docs/article/practical-database-design/study/study4-3.md +0 -1814
  621. package/lib/assets/docs/article/practical-database-design/study/study4-4.md +0 -1904
  622. package/lib/assets/docs/article/practical-database-design/study/study4-5.md +0 -2887
@@ -1,1618 +0,0 @@
1
- ---
2
- type: Article
3
- title: "第34章:メッセージングパターン"
4
- description: "本章では、エンタープライズインテグレーションの基盤となるメッセージングパターンについて解説します。"
5
- tags: [article, practical-database-design, part5]
6
- status: stable
7
- generated: { by: human:kakimomokuri, at: 2026-03-30T08:34:28Z }
8
- ---
9
-
10
- # 第34章:メッセージングパターン
11
-
12
- 本章では、エンタープライズインテグレーションの基盤となるメッセージングパターンについて解説します。Gregor Hohpe と Bobby Woolf による「Enterprise Integration Patterns」で体系化されたパターンを、基幹業務システムの文脈で理解していきます。
13
-
14
- ---
15
-
16
- ## 34.1 メッセージングの基礎
17
-
18
- ### メッセージングシステムの全体像
19
-
20
- メッセージングシステムは、分散システム間の非同期通信を実現するための基盤です。送信側と受信側が直接接続する必要がなく、疎結合なシステム統合を可能にします。
21
-
22
- ```plantuml
23
- @startuml
24
- title メッセージングシステムの基本構造
25
-
26
- rectangle "送信側アプリケーション" as sender {
27
- rectangle "ビジネスロジック" as sender_logic
28
- rectangle "メッセージ\nエンドポイント" as sender_endpoint
29
- }
30
-
31
- rectangle "メッセージングシステム" as messaging {
32
- queue "メッセージ\nチャネル" as channel
33
- rectangle "メッセージ\nルーター" as router
34
- rectangle "メッセージ\n変換" as transformer
35
- }
36
-
37
- rectangle "受信側アプリケーション" as receiver {
38
- rectangle "メッセージ\nエンドポイント" as receiver_endpoint
39
- rectangle "ビジネスロジック" as receiver_logic
40
- }
41
-
42
- sender_logic --> sender_endpoint
43
- sender_endpoint --> channel
44
- channel --> router
45
- router --> transformer
46
- transformer --> receiver_endpoint
47
- receiver_endpoint --> receiver_logic
48
-
49
- note bottom of messaging
50
- ・非同期通信
51
- ・疎結合
52
- ・信頼性のある配信
53
- ・スケーラビリティ
54
- end note
55
-
56
- @enduml
57
- ```
58
-
59
- ### メッセージチャネル(Message Channel)
60
-
61
- メッセージチャネルは、送信側と受信側をつなぐ論理的なパイプです。チャネルの種類によって、メッセージの配信方法が異なります。
62
-
63
- ```plantuml
64
- @startuml
65
- title メッセージチャネルの種類
66
-
67
- rectangle "Point-to-Point Channel" as p2p {
68
- rectangle "送信者A" as senderA
69
- queue "キュー" as queue1
70
- rectangle "受信者A" as receiverA
71
-
72
- senderA --> queue1
73
- queue1 --> receiverA
74
- }
75
-
76
- note right of p2p
77
- ・1対1の通信
78
- ・メッセージは1つの受信者のみが受信
79
- ・負荷分散に適用可能
80
-
81
- 例:受注処理キュー
82
- end note
83
-
84
- rectangle "Publish-Subscribe Channel" as pubsub {
85
- rectangle "発行者" as publisher
86
- collections "トピック" as topic
87
- rectangle "購読者A" as subA
88
- rectangle "購読者B" as subB
89
- rectangle "購読者C" as subC
90
-
91
- publisher --> topic
92
- topic --> subA
93
- topic --> subB
94
- topic --> subC
95
- }
96
-
97
- note right of pubsub
98
- ・1対多の通信
99
- ・すべての購読者がメッセージを受信
100
- ・イベント通知に最適
101
-
102
- 例:売上イベントの通知
103
- end note
104
-
105
- @enduml
106
- ```
107
-
108
- #### 基幹業務システムにおけるチャネル設計
109
-
110
- ```plantuml
111
- @startuml
112
- title 基幹業務システムのメッセージチャネル設計
113
-
114
- package "販売管理" as sales {
115
- rectangle "受注サービス" as order_svc
116
- rectangle "出荷サービス" as ship_svc
117
- rectangle "売上サービス" as sales_svc
118
- }
119
-
120
- package "メッセージチャネル" as channels {
121
- queue "受注確定キュー" as order_queue
122
- collections "売上イベント\nトピック" as sales_topic
123
- queue "仕訳生成キュー" as journal_queue
124
- }
125
-
126
- package "会計" as accounting {
127
- rectangle "自動仕訳\nサービス" as auto_journal
128
- }
129
-
130
- package "生産管理" as production {
131
- rectangle "生産計画\nサービス" as prod_plan
132
- }
133
-
134
- package "分析" as analytics {
135
- rectangle "売上分析\nサービス" as sales_analytics
136
- }
137
-
138
- order_svc --> order_queue : 受注確定
139
- order_queue --> ship_svc : 出荷指示作成
140
- sales_svc --> sales_topic : 売上計上イベント
141
- sales_topic --> auto_journal : 仕訳生成
142
- sales_topic --> prod_plan : 需要情報更新
143
- sales_topic --> sales_analytics : 分析データ収集
144
-
145
- @enduml
146
- ```
147
-
148
- ### メッセージ(Message)の構造
149
-
150
- メッセージは、ヘッダーとボディで構成されます。ヘッダーにはルーティングや処理に必要なメタデータを、ボディにはビジネスデータを含めます。
151
-
152
- ```plantuml
153
- @startuml
154
- title メッセージの構造
155
-
156
- class "Message" as msg {
157
- +Header header
158
- +Body body
159
- }
160
-
161
- class "Header" as header {
162
- +String messageId
163
- +String correlationId
164
- +String replyTo
165
- +Date timestamp
166
- +String messageType
167
- +Map<String, Object> properties
168
- }
169
-
170
- class "Body" as body {
171
- +Object payload
172
- +String contentType
173
- +String encoding
174
- }
175
-
176
- msg --> header
177
- msg --> body
178
-
179
- note right of header
180
- 【メタデータ】
181
- ・messageId: 一意識別子
182
- ・correlationId: 関連メッセージの追跡
183
- ・replyTo: 返信先チャネル
184
- ・timestamp: 送信日時
185
- ・messageType: メッセージ種別
186
- end note
187
-
188
- note right of body
189
- 【ビジネスデータ】
190
- ・payload: 実際のデータ
191
- ・contentType: JSON/XML等
192
- ・encoding: UTF-8等
193
- end note
194
-
195
- @enduml
196
- ```
197
-
198
- #### 売上イベントメッセージの例
199
-
200
- ```plantuml
201
- @startuml
202
- title 売上イベントメッセージの例
203
-
204
- object "売上イベントメッセージ" as sales_event {
205
- <b>Header</b>
206
- messageId = "MSG-20240115-001"
207
- correlationId = "ORD-2024-00123"
208
- messageType = "SalesCompleted"
209
- timestamp = "2024-01-15T10:30:00Z"
210
- source = "sales-service"
211
- --
212
- <b>Body</b>
213
- eventType = "売上計上"
214
- salesId = "SLS-2024-00456"
215
- orderNumber = "ORD-2024-00123"
216
- customerId = "CUS-001"
217
- salesDate = "2024-01-15"
218
- totalAmount = 108000
219
- taxAmount = 8000
220
- lines = [...]
221
- }
222
-
223
- @enduml
224
- ```
225
-
226
- <details>
227
- <summary>Java 実装例</summary>
228
-
229
- ```java
230
- // メッセージヘッダー
231
- public record MessageHeader(
232
- String messageId,
233
- String correlationId,
234
- String replyTo,
235
- Instant timestamp,
236
- String messageType,
237
- String source,
238
- Map<String, Object> properties
239
- ) {
240
- public static MessageHeader create(String messageType, String source) {
241
- return new MessageHeader(
242
- UUID.randomUUID().toString(),
243
- null,
244
- null,
245
- Instant.now(),
246
- messageType,
247
- source,
248
- new HashMap<>()
249
- );
250
- }
251
-
252
- public MessageHeader withCorrelationId(String correlationId) {
253
- return new MessageHeader(
254
- messageId, correlationId, replyTo, timestamp,
255
- messageType, source, properties
256
- );
257
- }
258
- }
259
-
260
- // メッセージ本体
261
- public record Message<T>(
262
- MessageHeader header,
263
- T payload
264
- ) {
265
- public static <T> Message<T> of(String messageType, String source, T payload) {
266
- return new Message<>(
267
- MessageHeader.create(messageType, source),
268
- payload
269
- );
270
- }
271
- }
272
-
273
- // 売上イベント
274
- public record SalesCompletedEvent(
275
- String salesId,
276
- String orderNumber,
277
- String customerId,
278
- LocalDate salesDate,
279
- BigDecimal totalAmount,
280
- BigDecimal taxAmount,
281
- List<SalesLineEvent> lines
282
- ) {}
283
-
284
- // 使用例
285
- Message<SalesCompletedEvent> message = Message.of(
286
- "SalesCompleted",
287
- "sales-service",
288
- new SalesCompletedEvent(
289
- "SLS-2024-00456",
290
- "ORD-2024-00123",
291
- "CUS-001",
292
- LocalDate.of(2024, 1, 15),
293
- new BigDecimal("108000"),
294
- new BigDecimal("8000"),
295
- lines
296
- )
297
- ).header().withCorrelationId("ORD-2024-00123");
298
- ```
299
-
300
- </details>
301
-
302
- ### パイプとフィルター(Pipes and Filters)
303
-
304
- パイプとフィルターパターンは、複雑な処理を小さな独立したステップ(フィルター)に分解し、パイプでつなげて処理する方式です。
305
-
306
- ```plantuml
307
- @startuml
308
- title パイプとフィルターパターン
309
-
310
- rectangle "入力" as input
311
- rectangle "フィルターA\n(検証)" as filterA
312
- rectangle "フィルターB\n(変換)" as filterB
313
- rectangle "フィルターC\n(エンリッチ)" as filterC
314
- rectangle "フィルターD\n(ルーティング)" as filterD
315
- rectangle "出力" as output
316
-
317
- input --> filterA : パイプ
318
- filterA --> filterB : パイプ
319
- filterB --> filterC : パイプ
320
- filterC --> filterD : パイプ
321
- filterD --> output : パイプ
322
-
323
- note bottom of filterA
324
- 各フィルターは
325
- ・独立して動作
326
- ・単一責任
327
- ・再利用可能
328
- ・テスト容易
329
- end note
330
-
331
- @enduml
332
- ```
333
-
334
- #### 売上仕訳生成パイプライン
335
-
336
- ```plantuml
337
- @startuml
338
- title 売上から仕訳生成へのパイプライン
339
-
340
- rectangle "売上\nイベント" as input
341
-
342
- rectangle "バリデーション\nフィルター" as validate {
343
- note right
344
- ・必須項目チェック
345
- ・金額整合性確認
346
- end note
347
- }
348
-
349
- rectangle "仕訳パターン\n判定フィルター" as pattern {
350
- note right
351
- ・商品グループ判定
352
- ・顧客グループ判定
353
- ・科目決定
354
- end note
355
- }
356
-
357
- rectangle "仕訳明細\n生成フィルター" as generate {
358
- note right
359
- ・借方明細生成
360
- ・貸方明細生成
361
- ・消費税計算
362
- end note
363
- }
364
-
365
- rectangle "貸借一致\n検証フィルター" as balance {
366
- note right
367
- ・借方合計 = 貸方合計
368
- ・検証エラー処理
369
- end note
370
- }
371
-
372
- rectangle "仕訳\nイベント" as output
373
-
374
- input --> validate
375
- validate --> pattern
376
- pattern --> generate
377
- generate --> balance
378
- balance --> output
379
-
380
- @enduml
381
- ```
382
-
383
- <details>
384
- <summary>Java 実装例</summary>
385
-
386
- ```java
387
- // フィルターインターフェース
388
- @FunctionalInterface
389
- public interface Filter<T> {
390
- T process(T input) throws FilterException;
391
-
392
- default Filter<T> andThen(Filter<T> next) {
393
- return input -> next.process(this.process(input));
394
- }
395
- }
396
-
397
- // パイプラインビルダー
398
- public class Pipeline<T> {
399
- private final List<Filter<T>> filters = new ArrayList<>();
400
-
401
- public Pipeline<T> addFilter(Filter<T> filter) {
402
- filters.add(filter);
403
- return this;
404
- }
405
-
406
- public T execute(T input) throws FilterException {
407
- T result = input;
408
- for (Filter<T> filter : filters) {
409
- result = filter.process(result);
410
- }
411
- return result;
412
- }
413
- }
414
-
415
- // 売上仕訳変換コンテキスト
416
- public class SalesJournalContext {
417
- private SalesCompletedEvent salesEvent;
418
- private JournalPattern pattern;
419
- private List<JournalLine> journalLines;
420
- private JournalEntry journalEntry;
421
- private List<String> errors = new ArrayList<>();
422
-
423
- // getter/setter
424
- }
425
-
426
- // バリデーションフィルター
427
- public class ValidationFilter implements Filter<SalesJournalContext> {
428
- @Override
429
- public SalesJournalContext process(SalesJournalContext ctx) {
430
- SalesCompletedEvent event = ctx.getSalesEvent();
431
-
432
- if (event.salesId() == null || event.salesId().isBlank()) {
433
- ctx.getErrors().add("売上IDは必須です");
434
- }
435
- if (event.totalAmount().compareTo(BigDecimal.ZERO) <= 0) {
436
- ctx.getErrors().add("売上金額は正の値である必要があります");
437
- }
438
-
439
- if (!ctx.getErrors().isEmpty()) {
440
- throw new ValidationException(ctx.getErrors());
441
- }
442
- return ctx;
443
- }
444
- }
445
-
446
- // 仕訳パターン判定フィルター
447
- public class PatternDeterminationFilter implements Filter<SalesJournalContext> {
448
- private final JournalPatternRepository patternRepository;
449
-
450
- @Override
451
- public SalesJournalContext process(SalesJournalContext ctx) {
452
- JournalPattern pattern = patternRepository.findByProductAndCustomerGroup(
453
- ctx.getSalesEvent().productGroup(),
454
- ctx.getSalesEvent().customerGroup()
455
- ).orElseThrow(() -> new PatternNotFoundException("仕訳パターンが見つかりません"));
456
-
457
- ctx.setPattern(pattern);
458
- return ctx;
459
- }
460
- }
461
-
462
- // パイプラインの構築と実行
463
- public class SalesJournalPipeline {
464
- private final Pipeline<SalesJournalContext> pipeline;
465
-
466
- public SalesJournalPipeline(
467
- ValidationFilter validationFilter,
468
- PatternDeterminationFilter patternFilter,
469
- JournalLineGenerationFilter generationFilter,
470
- BalanceValidationFilter balanceFilter) {
471
-
472
- this.pipeline = new Pipeline<SalesJournalContext>()
473
- .addFilter(validationFilter)
474
- .addFilter(patternFilter)
475
- .addFilter(generationFilter)
476
- .addFilter(balanceFilter);
477
- }
478
-
479
- public JournalEntry process(SalesCompletedEvent event) {
480
- SalesJournalContext ctx = new SalesJournalContext();
481
- ctx.setSalesEvent(event);
482
-
483
- SalesJournalContext result = pipeline.execute(ctx);
484
- return result.getJournalEntry();
485
- }
486
- }
487
- ```
488
-
489
- </details>
490
-
491
- ---
492
-
493
- ## 34.2 メッセージルーティング
494
-
495
- メッセージルーティングは、メッセージの内容や属性に基づいて、適切な宛先にメッセージを振り分ける機能です。
496
-
497
- ### Content-Based Router(内容ベースルーター)
498
-
499
- メッセージの内容を検査し、条件に基づいて異なるチャネルにルーティングします。
500
-
501
- ```plantuml
502
- @startuml
503
- title Content-Based Router パターン
504
-
505
- rectangle "入力\nチャネル" as input
506
-
507
- rectangle "Content-Based\nRouter" as router
508
-
509
- queue "売上仕訳\nチャネル" as sales_channel
510
- queue "仕入仕訳\nチャネル" as purchase_channel
511
- queue "経費仕訳\nチャネル" as expense_channel
512
-
513
- input --> router
514
-
515
- router --> sales_channel : 伝票区分 = "売上"
516
- router --> purchase_channel : 伝票区分 = "仕入"
517
- router --> expense_channel : 伝票区分 = "経費"
518
-
519
- note right of router
520
- メッセージ内容を検査し
521
- 条件に基づいて
522
- 適切なチャネルへ振り分け
523
- end note
524
-
525
- @enduml
526
- ```
527
-
528
- #### 基幹業務システムでの適用例
529
-
530
- ```plantuml
531
- @startuml
532
- title 取引イベントのルーティング
533
-
534
- rectangle "取引イベント" as input
535
-
536
- rectangle "取引種別\nルーター" as router
537
-
538
- package "販売系処理" as sales_pkg {
539
- queue "受注処理" as order_q
540
- queue "出荷処理" as ship_q
541
- queue "売上処理" as sales_q
542
- }
543
-
544
- package "調達系処理" as purchase_pkg {
545
- queue "発注処理" as po_q
546
- queue "入荷処理" as receipt_q
547
- queue "仕入処理" as purchase_q
548
- }
549
-
550
- package "在庫系処理" as inv_pkg {
551
- queue "入庫処理" as stock_in_q
552
- queue "出庫処理" as stock_out_q
553
- queue "棚卸処理" as inventory_q
554
- }
555
-
556
- input --> router
557
-
558
- router --> order_q : type = ORDER
559
- router --> ship_q : type = SHIPMENT
560
- router --> sales_q : type = SALES
561
- router --> po_q : type = PURCHASE_ORDER
562
- router --> receipt_q : type = RECEIPT
563
- router --> purchase_q : type = PURCHASE
564
- router --> stock_in_q : type = STOCK_IN
565
- router --> stock_out_q : type = STOCK_OUT
566
- router --> inventory_q : type = INVENTORY
567
-
568
- @enduml
569
- ```
570
-
571
- <details>
572
- <summary>Java 実装例</summary>
573
-
574
- ```java
575
- // ルーティング条件
576
- public interface RoutingCondition<T> {
577
- boolean matches(T message);
578
- String getDestination();
579
- }
580
-
581
- // Content-Based Router
582
- public class ContentBasedRouter<T> {
583
- private final List<RoutingCondition<T>> conditions = new ArrayList<>();
584
- private String defaultDestination;
585
-
586
- public ContentBasedRouter<T> when(Predicate<T> predicate, String destination) {
587
- conditions.add(new RoutingCondition<>() {
588
- @Override
589
- public boolean matches(T message) {
590
- return predicate.test(message);
591
- }
592
- @Override
593
- public String getDestination() {
594
- return destination;
595
- }
596
- });
597
- return this;
598
- }
599
-
600
- public ContentBasedRouter<T> otherwise(String destination) {
601
- this.defaultDestination = destination;
602
- return this;
603
- }
604
-
605
- public String route(T message) {
606
- return conditions.stream()
607
- .filter(c -> c.matches(message))
608
- .findFirst()
609
- .map(RoutingCondition::getDestination)
610
- .orElse(defaultDestination);
611
- }
612
- }
613
-
614
- // 取引イベントルーター
615
- public class TransactionEventRouter {
616
- private final ContentBasedRouter<TransactionEvent> router;
617
- private final MessageSender messageSender;
618
-
619
- public TransactionEventRouter(MessageSender messageSender) {
620
- this.messageSender = messageSender;
621
- this.router = new ContentBasedRouter<TransactionEvent>()
622
- .when(e -> e.type() == TransactionType.ORDER, "order-queue")
623
- .when(e -> e.type() == TransactionType.SHIPMENT, "shipment-queue")
624
- .when(e -> e.type() == TransactionType.SALES, "sales-queue")
625
- .when(e -> e.type() == TransactionType.PURCHASE_ORDER, "po-queue")
626
- .when(e -> e.type() == TransactionType.RECEIPT, "receipt-queue")
627
- .when(e -> e.type() == TransactionType.PURCHASE, "purchase-queue")
628
- .otherwise("dead-letter-queue");
629
- }
630
-
631
- public void route(TransactionEvent event) {
632
- String destination = router.route(event);
633
- messageSender.send(destination, event);
634
- }
635
- }
636
- ```
637
-
638
- </details>
639
-
640
- ### Message Filter(メッセージフィルター)
641
-
642
- 条件に合致するメッセージのみを通過させ、それ以外は破棄または別のチャネルに送ります。
643
-
644
- ```plantuml
645
- @startuml
646
- title Message Filter パターン
647
-
648
- rectangle "入力\nチャネル" as input
649
-
650
- rectangle "Message\nFilter" as filter
651
-
652
- rectangle "出力\nチャネル" as output
653
-
654
- rectangle "破棄/DLQ" as discard
655
-
656
- input --> filter
657
- filter --> output : 条件に合致
658
- filter --> discard : 条件に不合致
659
-
660
- note right of filter
661
- 【フィルター条件の例】
662
- ・金額が閾値以上
663
- ・特定の顧客のみ
664
- ・特定期間のデータのみ
665
- ・重複メッセージの排除
666
- end note
667
-
668
- @enduml
669
- ```
670
-
671
- #### 高額取引フィルターの例
672
-
673
- ```plantuml
674
- @startuml
675
- title 高額取引アラートフィルター
676
-
677
- rectangle "売上イベント" as input
678
-
679
- rectangle "高額取引\nフィルター" as filter {
680
- note right
681
- 条件:金額 >= 100万円
682
- end note
683
- }
684
-
685
- rectangle "通常処理\nチャネル" as normal
686
- rectangle "高額取引\nアラートチャネル" as alert
687
-
688
- input --> filter
689
- filter --> normal : 金額 < 100万円
690
- filter --> alert : 金額 >= 100万円
691
-
692
- @enduml
693
- ```
694
-
695
- ### Splitter / Aggregator(分割 / 集約)
696
-
697
- 大きなメッセージを複数の小さなメッセージに分割し、処理後に再び集約するパターンです。
698
-
699
- ```plantuml
700
- @startuml
701
- title Splitter / Aggregator パターン
702
-
703
- rectangle "受注\nメッセージ" as input
704
- note right of input
705
- 受注ヘッダー
706
- + 明細10件
707
- end note
708
-
709
- rectangle "Splitter\n(分割)" as splitter
710
-
711
- rectangle "明細1" as line1
712
- rectangle "明細2" as line2
713
- rectangle "..." as dots
714
- rectangle "明細10" as line10
715
-
716
- rectangle "在庫引当\n処理" as process
717
-
718
- rectangle "Aggregator\n(集約)" as aggregator
719
-
720
- rectangle "引当結果\nメッセージ" as output
721
- note right of output
722
- 受注ヘッダー
723
- + 引当結果10件
724
- end note
725
-
726
- input --> splitter
727
- splitter --> line1
728
- splitter --> line2
729
- splitter --> dots
730
- splitter --> line10
731
-
732
- line1 --> process
733
- line2 --> process
734
- dots --> process
735
- line10 --> process
736
-
737
- process --> aggregator
738
- aggregator --> output
739
-
740
- note bottom of splitter
741
- 【Splitter】
742
- 複合メッセージを
743
- 個別メッセージに分割
744
- end note
745
-
746
- note bottom of aggregator
747
- 【Aggregator】
748
- 関連メッセージを
749
- 1つに集約
750
- ・correlationIdで関連付け
751
- ・完了条件の判定
752
- end note
753
-
754
- @enduml
755
- ```
756
-
757
- #### 基幹業務システムでの適用例
758
-
759
- ```plantuml
760
- @startuml
761
- title 一括仕訳処理のSplitter/Aggregator
762
-
763
- rectangle "月次締め\nリクエスト" as input
764
-
765
- rectangle "売上データ\n取得" as fetch
766
-
767
- rectangle "Splitter" as splitter
768
-
769
- rectangle "仕訳変換\n処理" as transform
770
-
771
- rectangle "Aggregator" as aggregator
772
-
773
- rectangle "仕訳バッチ\n登録" as register
774
-
775
- rectangle "月次締め\n完了" as output
776
-
777
- input --> fetch : 期間指定
778
- fetch --> splitter : 売上リスト
779
-
780
- splitter --> transform : 売上1
781
- splitter --> transform : 売上2
782
- splitter --> transform : 売上N
783
-
784
- transform --> aggregator : 仕訳1
785
- transform --> aggregator : 仕訳2
786
- transform --> aggregator : 仕訳N
787
-
788
- aggregator --> register : 仕訳リスト
789
- register --> output
790
-
791
- note right of aggregator
792
- 【集約条件】
793
- ・すべての売上が処理完了
794
- ・タイムアウト時は部分集約
795
- ・エラー時は補償処理
796
- end note
797
-
798
- @enduml
799
- ```
800
-
801
- <details>
802
- <summary>Java 実装例</summary>
803
-
804
- ```java
805
- // Splitter
806
- public class OrderLineSplitter {
807
- public List<Message<OrderLineEvent>> split(Message<OrderEvent> orderMessage) {
808
- OrderEvent order = orderMessage.payload();
809
- return order.lines().stream()
810
- .map(line -> {
811
- OrderLineEvent lineEvent = new OrderLineEvent(
812
- order.orderId(),
813
- line.lineNumber(),
814
- line.productId(),
815
- line.quantity(),
816
- line.unitPrice()
817
- );
818
- return Message.of("OrderLine", "splitter", lineEvent)
819
- .withCorrelationId(order.orderId());
820
- })
821
- .toList();
822
- }
823
- }
824
-
825
- // Aggregator
826
- public class AllocationResultAggregator {
827
- private final Map<String, AggregationState> states = new ConcurrentHashMap<>();
828
-
829
- public record AggregationState(
830
- String correlationId,
831
- int expectedCount,
832
- List<AllocationResult> results,
833
- Instant startTime
834
- ) {}
835
-
836
- public void aggregate(Message<AllocationResult> message) {
837
- String correlationId = message.header().correlationId();
838
- AllocationResult result = message.payload();
839
-
840
- states.compute(correlationId, (id, state) -> {
841
- if (state == null) {
842
- // 初期状態
843
- state = new AggregationState(
844
- id,
845
- getExpectedCount(id),
846
- new ArrayList<>(),
847
- Instant.now()
848
- );
849
- }
850
- state.results().add(result);
851
- return state;
852
- });
853
-
854
- checkCompletion(correlationId);
855
- }
856
-
857
- private void checkCompletion(String correlationId) {
858
- AggregationState state = states.get(correlationId);
859
- if (state == null) return;
860
-
861
- // 完了条件:すべての結果が揃った
862
- if (state.results().size() >= state.expectedCount()) {
863
- AggregatedAllocationResult aggregated = new AggregatedAllocationResult(
864
- correlationId,
865
- state.results()
866
- );
867
- publishAggregatedResult(aggregated);
868
- states.remove(correlationId);
869
- }
870
- // タイムアウトチェック
871
- else if (Duration.between(state.startTime(), Instant.now()).toMinutes() > 5) {
872
- handleTimeout(state);
873
- }
874
- }
875
- }
876
- ```
877
-
878
- </details>
879
-
880
- ### Resequencer(再順序付け)
881
-
882
- 順序が乱れて到着したメッセージを、正しい順序に並べ替えてから処理します。
883
-
884
- ```plantuml
885
- @startuml
886
- title Resequencer パターン
887
-
888
- rectangle "入力チャネル" as input
889
-
890
- rectangle "Resequencer" as reseq {
891
- rectangle "バッファ" as buffer
892
- rectangle "順序判定" as order
893
- }
894
-
895
- rectangle "出力チャネル" as output
896
-
897
- input --> reseq : メッセージ(3)
898
- input --> reseq : メッセージ(1)
899
- input --> reseq : メッセージ(5)
900
- input --> reseq : メッセージ(2)
901
- input --> reseq : メッセージ(4)
902
-
903
- reseq --> output : メッセージ(1)
904
- reseq --> output : メッセージ(2)
905
- reseq --> output : メッセージ(3)
906
- reseq --> output : メッセージ(4)
907
- reseq --> output : メッセージ(5)
908
-
909
- note right of reseq
910
- 【Resequencer の動作】
911
- ・シーケンス番号でバッファリング
912
- ・欠番の待機
913
- ・タイムアウト処理
914
-
915
- 【適用例】
916
- ・在庫移動の順序保証
917
- ・仕訳の時系列順序
918
- end note
919
-
920
- @enduml
921
- ```
922
-
923
- ---
924
-
925
- ## 34.3 メッセージ変換
926
-
927
- 異なるシステム間でデータをやり取りする際、データ形式やスキーマの変換が必要になります。
928
-
929
- ### Message Translator(メッセージ変換)
930
-
931
- あるシステムのメッセージ形式を、別のシステムが理解できる形式に変換します。
932
-
933
- ```plantuml
934
- @startuml
935
- title Message Translator パターン
936
-
937
- rectangle "送信側\nシステム" as sender
938
-
939
- rectangle "Message\nTranslator" as translator
940
-
941
- rectangle "受信側\nシステム" as receiver
942
-
943
- sender --> translator : フォーマットA
944
- translator --> receiver : フォーマットB
945
-
946
- note bottom of translator
947
- 【変換内容】
948
- ・データ形式(JSON ↔ XML)
949
- ・スキーマ変換
950
- ・フィールド名マッピング
951
- ・値の変換(コード変換等)
952
- ・データ型変換
953
- end note
954
-
955
- @enduml
956
- ```
957
-
958
- #### 売上から仕訳への変換例
959
-
960
- ```plantuml
961
- @startuml
962
- title 売上イベントから仕訳への変換
963
-
964
- class "売上イベント" as sales {
965
- +salesId: String
966
- +salesDate: Date
967
- +customerId: String
968
- +totalAmount: Decimal
969
- +taxAmount: Decimal
970
- +lines: List<SalesLine>
971
- }
972
-
973
- class "SalesLine" as sales_line {
974
- +productId: String
975
- +quantity: int
976
- +unitPrice: Decimal
977
- +amount: Decimal
978
- }
979
-
980
- class "仕訳伝票" as journal {
981
- +journalId: String
982
- +journalDate: Date
983
- +journalType: String
984
- +entries: List<JournalEntry>
985
- }
986
-
987
- class "仕訳明細" as journal_entry {
988
- +debitCredit: String
989
- +accountCode: String
990
- +amount: Decimal
991
- +description: String
992
- }
993
-
994
- class "SalesJournalTranslator" as translator {
995
- +translate(SalesEvent): JournalEntry
996
- -determineAccounts()
997
- -calculateTax()
998
- -createDebitEntries()
999
- -createCreditEntries()
1000
- }
1001
-
1002
- sales "1" -- "*" sales_line
1003
- journal "1" -- "*" journal_entry
1004
- translator ..> sales : 入力
1005
- translator ..> journal : 出力
1006
-
1007
- @enduml
1008
- ```
1009
-
1010
- <details>
1011
- <summary>Java 実装例</summary>
1012
-
1013
- ```java
1014
- // メッセージ変換インターフェース
1015
- public interface MessageTranslator<S, T> {
1016
- T translate(S source);
1017
- }
1018
-
1019
- // 売上から仕訳への変換
1020
- @Component
1021
- public class SalesJournalTranslator
1022
- implements MessageTranslator<SalesCompletedEvent, JournalEntryCommand> {
1023
-
1024
- private final JournalPatternRepository patternRepository;
1025
- private final AccountRepository accountRepository;
1026
-
1027
- @Override
1028
- public JournalEntryCommand translate(SalesCompletedEvent sales) {
1029
- // 仕訳パターン取得
1030
- JournalPattern pattern = patternRepository.findBySalesType(
1031
- sales.salesType()
1032
- ).orElseThrow();
1033
-
1034
- // 借方明細(売掛金)
1035
- List<JournalLineCommand> debitLines = List.of(
1036
- new JournalLineCommand(
1037
- DebitCredit.DEBIT,
1038
- pattern.debitAccountCode(),
1039
- sales.totalAmount(),
1040
- "売掛金計上 " + sales.customerName()
1041
- )
1042
- );
1043
-
1044
- // 貸方明細(売上 + 仮受消費税)
1045
- List<JournalLineCommand> creditLines = new ArrayList<>();
1046
- creditLines.add(new JournalLineCommand(
1047
- DebitCredit.CREDIT,
1048
- pattern.creditAccountCode(),
1049
- sales.totalAmount().subtract(sales.taxAmount()),
1050
- "売上計上 " + sales.salesId()
1051
- ));
1052
- creditLines.add(new JournalLineCommand(
1053
- DebitCredit.CREDIT,
1054
- pattern.taxAccountCode(),
1055
- sales.taxAmount(),
1056
- "仮受消費税"
1057
- ));
1058
-
1059
- // 仕訳伝票作成
1060
- return new JournalEntryCommand(
1061
- generateJournalId(),
1062
- sales.salesDate(),
1063
- JournalType.SALES,
1064
- sales.salesId(),
1065
- Stream.concat(debitLines.stream(), creditLines.stream()).toList()
1066
- );
1067
- }
1068
- }
1069
- ```
1070
-
1071
- </details>
1072
-
1073
- ### Envelope Wrapper(エンベロープラッパー)
1074
-
1075
- メッセージに追加のメタデータを付与するためのラッパーです。
1076
-
1077
- ```plantuml
1078
- @startuml
1079
- title Envelope Wrapper パターン
1080
-
1081
- rectangle "アプリケーション\nデータ" as app_data
1082
-
1083
- rectangle "Envelope\nWrapper" as wrapper
1084
-
1085
- rectangle "エンベロープ付き\nメッセージ" as envelope {
1086
- rectangle "ルーティング情報" as routing
1087
- rectangle "セキュリティ情報" as security
1088
- rectangle "トレース情報" as trace
1089
- rectangle "アプリケーション\nデータ" as data
1090
- }
1091
-
1092
- app_data --> wrapper
1093
- wrapper --> envelope
1094
-
1095
- note right of envelope
1096
- 【エンベロープの内容】
1097
- ・送信元/宛先情報
1098
- ・認証トークン
1099
- ・トレースID(分散トレーシング)
1100
- ・タイムスタンプ
1101
- ・バージョン情報
1102
- end note
1103
-
1104
- @enduml
1105
- ```
1106
-
1107
- <details>
1108
- <summary>Java 実装例</summary>
1109
-
1110
- ```java
1111
- // エンベロープ
1112
- public record MessageEnvelope<T>(
1113
- RoutingInfo routing,
1114
- SecurityInfo security,
1115
- TraceInfo trace,
1116
- T payload
1117
- ) {
1118
- public record RoutingInfo(
1119
- String source,
1120
- String destination,
1121
- String replyTo,
1122
- int priority
1123
- ) {}
1124
-
1125
- public record SecurityInfo(
1126
- String authToken,
1127
- String userId,
1128
- List<String> roles
1129
- ) {}
1130
-
1131
- public record TraceInfo(
1132
- String traceId,
1133
- String spanId,
1134
- String parentSpanId,
1135
- Instant timestamp
1136
- ) {}
1137
-
1138
- public static <T> MessageEnvelope<T> wrap(
1139
- T payload,
1140
- String source,
1141
- String destination) {
1142
- return new MessageEnvelope<>(
1143
- new RoutingInfo(source, destination, null, 0),
1144
- null,
1145
- new TraceInfo(
1146
- UUID.randomUUID().toString(),
1147
- UUID.randomUUID().toString(),
1148
- null,
1149
- Instant.now()
1150
- ),
1151
- payload
1152
- );
1153
- }
1154
- }
1155
-
1156
- // Envelope Wrapper
1157
- @Component
1158
- public class EnvelopeWrapper {
1159
- private final SecurityContext securityContext;
1160
- private final TraceContext traceContext;
1161
-
1162
- public <T> MessageEnvelope<T> wrap(T payload, String destination) {
1163
- return new MessageEnvelope<>(
1164
- new RoutingInfo(
1165
- "current-service",
1166
- destination,
1167
- null,
1168
- 0
1169
- ),
1170
- new SecurityInfo(
1171
- securityContext.getToken(),
1172
- securityContext.getUserId(),
1173
- securityContext.getRoles()
1174
- ),
1175
- new TraceInfo(
1176
- traceContext.getTraceId(),
1177
- traceContext.newSpanId(),
1178
- traceContext.getCurrentSpanId(),
1179
- Instant.now()
1180
- ),
1181
- payload
1182
- );
1183
- }
1184
-
1185
- public <T> T unwrap(MessageEnvelope<T> envelope) {
1186
- // セキュリティ検証
1187
- validateSecurity(envelope.security());
1188
- // トレース情報の伝播
1189
- propagateTrace(envelope.trace());
1190
- return envelope.payload();
1191
- }
1192
- }
1193
- ```
1194
-
1195
- </details>
1196
-
1197
- ### Content Enricher(コンテンツエンリッチャー)
1198
-
1199
- メッセージに不足している情報を外部ソースから取得して追加します。
1200
-
1201
- ```plantuml
1202
- @startuml
1203
- title Content Enricher パターン
1204
-
1205
- rectangle "入力メッセージ" as input
1206
- note right of input
1207
- customerId: "CUS-001"
1208
- productId: "PRD-001"
1209
- quantity: 10
1210
- end note
1211
-
1212
- rectangle "Content\nEnricher" as enricher
1213
-
1214
- database "顧客マスタ" as customer_db
1215
- database "商品マスタ" as product_db
1216
-
1217
- rectangle "出力メッセージ" as output
1218
- note right of output
1219
- customerId: "CUS-001"
1220
- <b>customerName: "株式会社A"</b>
1221
- <b>creditLimit: 1000000</b>
1222
- productId: "PRD-001"
1223
- <b>productName: "商品A"</b>
1224
- <b>unitPrice: 1000</b>
1225
- quantity: 10
1226
- <b>amount: 10000</b>
1227
- end note
1228
-
1229
- input --> enricher
1230
- enricher --> customer_db : 顧客情報取得
1231
- enricher --> product_db : 商品情報取得
1232
- enricher --> output
1233
-
1234
- @enduml
1235
- ```
1236
-
1237
- #### 受注エンリッチメントの例
1238
-
1239
- ```plantuml
1240
- @startuml
1241
- title 受注データのエンリッチメント
1242
-
1243
- rectangle "受注イベント\n(基本情報のみ)" as input
1244
-
1245
- rectangle "Customer\nEnricher" as cust_enricher
1246
- rectangle "Product\nEnricher" as prod_enricher
1247
- rectangle "Price\nEnricher" as price_enricher
1248
- rectangle "Inventory\nEnricher" as inv_enricher
1249
-
1250
- database "顧客マスタ" as cust_db
1251
- database "商品マスタ" as prod_db
1252
- database "単価マスタ" as price_db
1253
- database "在庫情報" as inv_db
1254
-
1255
- rectangle "受注イベント\n(完全情報)" as output
1256
-
1257
- input --> cust_enricher
1258
- cust_enricher --> cust_db
1259
- cust_enricher --> prod_enricher
1260
- prod_enricher --> prod_db
1261
- prod_enricher --> price_enricher
1262
- price_enricher --> price_db
1263
- price_enricher --> inv_enricher
1264
- inv_enricher --> inv_db
1265
- inv_enricher --> output
1266
-
1267
- note bottom of output
1268
- 追加された情報:
1269
- ・顧客名、与信情報
1270
- ・商品名、商品区分
1271
- ・適用単価
1272
- ・在庫数、引当可能数
1273
- end note
1274
-
1275
- @enduml
1276
- ```
1277
-
1278
- <details>
1279
- <summary>Java 実装例</summary>
1280
-
1281
- ```java
1282
- // Enricherインターフェース
1283
- public interface ContentEnricher<T> {
1284
- T enrich(T message);
1285
- }
1286
-
1287
- // 受注エンリッチャーチェーン
1288
- @Component
1289
- public class OrderEnricherChain {
1290
- private final List<ContentEnricher<OrderEvent>> enrichers;
1291
-
1292
- public OrderEnricherChain(
1293
- CustomerEnricher customerEnricher,
1294
- ProductEnricher productEnricher,
1295
- PriceEnricher priceEnricher,
1296
- InventoryEnricher inventoryEnricher) {
1297
- this.enrichers = List.of(
1298
- customerEnricher,
1299
- productEnricher,
1300
- priceEnricher,
1301
- inventoryEnricher
1302
- );
1303
- }
1304
-
1305
- public OrderEvent enrich(OrderEvent order) {
1306
- OrderEvent enriched = order;
1307
- for (ContentEnricher<OrderEvent> enricher : enrichers) {
1308
- enriched = enricher.enrich(enriched);
1309
- }
1310
- return enriched;
1311
- }
1312
- }
1313
-
1314
- // 顧客情報エンリッチャー
1315
- @Component
1316
- public class CustomerEnricher implements ContentEnricher<OrderEvent> {
1317
- private final CustomerRepository customerRepository;
1318
-
1319
- @Override
1320
- public OrderEvent enrich(OrderEvent order) {
1321
- Customer customer = customerRepository.findById(order.customerId())
1322
- .orElseThrow(() -> new CustomerNotFoundException(order.customerId()));
1323
-
1324
- return order.toBuilder()
1325
- .customerName(customer.name())
1326
- .customerAddress(customer.address())
1327
- .creditLimit(customer.creditLimit())
1328
- .build();
1329
- }
1330
- }
1331
-
1332
- // 商品情報エンリッチャー
1333
- @Component
1334
- public class ProductEnricher implements ContentEnricher<OrderEvent> {
1335
- private final ProductRepository productRepository;
1336
-
1337
- @Override
1338
- public OrderEvent enrich(OrderEvent order) {
1339
- List<OrderLineEvent> enrichedLines = order.lines().stream()
1340
- .map(line -> {
1341
- Product product = productRepository.findById(line.productId())
1342
- .orElseThrow();
1343
- return line.toBuilder()
1344
- .productName(product.name())
1345
- .productCategory(product.category())
1346
- .taxRate(product.taxRate())
1347
- .build();
1348
- })
1349
- .toList();
1350
-
1351
- return order.toBuilder()
1352
- .lines(enrichedLines)
1353
- .build();
1354
- }
1355
- }
1356
- ```
1357
-
1358
- </details>
1359
-
1360
- ### Canonical Data Model(標準データモデル)
1361
-
1362
- 複数のシステム間で共通に使用するデータモデルを定義し、変換の複雑さを軽減します。
1363
-
1364
- ```plantuml
1365
- @startuml
1366
- title Canonical Data Model パターン
1367
-
1368
- rectangle "販売管理\nシステム" as sales {
1369
- rectangle "販売固有\nモデル" as sales_model
1370
- }
1371
-
1372
- rectangle "生産管理\nシステム" as production {
1373
- rectangle "生産固有\nモデル" as prod_model
1374
- }
1375
-
1376
- rectangle "会計\nシステム" as accounting {
1377
- rectangle "会計固有\nモデル" as acc_model
1378
- }
1379
-
1380
- rectangle "標準データモデル\n(Canonical Model)" as canonical {
1381
- rectangle "標準取引先" as std_partner
1382
- rectangle "標準商品/品目" as std_product
1383
- rectangle "標準取引" as std_transaction
1384
- }
1385
-
1386
- sales_model <--> canonical : 変換
1387
- prod_model <--> canonical : 変換
1388
- acc_model <--> canonical : 変換
1389
-
1390
- note bottom of canonical
1391
- 【標準データモデルの利点】
1392
- ・変換数の削減(N×N → 2×N)
1393
- ・一貫したデータ定義
1394
- ・システム追加時の影響最小化
1395
-
1396
- 【定義すべき項目】
1397
- ・共通エンティティ(取引先、商品等)
1398
- ・共通イベント(取引、在庫移動等)
1399
- ・共通コード体系
1400
- end note
1401
-
1402
- @enduml
1403
- ```
1404
-
1405
- #### 基幹業務システムの標準データモデル
1406
-
1407
- ```plantuml
1408
- @startuml
1409
- title 基幹業務システムの標準データモデル
1410
-
1411
- package "標準マスタモデル" as master {
1412
- class "StandardPartner" as partner {
1413
- +partnerId: String
1414
- +partnerType: PartnerType
1415
- +name: String
1416
- +address: Address
1417
- +contacts: List<Contact>
1418
- }
1419
-
1420
- class "StandardProduct" as product {
1421
- +productId: String
1422
- +productType: ProductType
1423
- +name: String
1424
- +unit: Unit
1425
- +prices: List<Price>
1426
- }
1427
-
1428
- class "StandardDepartment" as dept {
1429
- +departmentId: String
1430
- +name: String
1431
- +parentId: String
1432
- +level: int
1433
- }
1434
- }
1435
-
1436
- package "標準トランザクションモデル" as transaction {
1437
- class "StandardTransaction" as trans {
1438
- +transactionId: String
1439
- +transactionType: TransactionType
1440
- +transactionDate: Date
1441
- +partnerId: String
1442
- +totalAmount: Money
1443
- +lines: List<TransactionLine>
1444
- }
1445
-
1446
- class "TransactionLine" as line {
1447
- +lineNumber: int
1448
- +productId: String
1449
- +quantity: Quantity
1450
- +unitPrice: Money
1451
- +amount: Money
1452
- }
1453
- }
1454
-
1455
- package "標準イベントモデル" as event {
1456
- class "StandardEvent" as evt {
1457
- +eventId: String
1458
- +eventType: EventType
1459
- +timestamp: Instant
1460
- +source: String
1461
- +payload: Object
1462
- }
1463
- }
1464
-
1465
- trans "1" -- "*" line
1466
-
1467
- note bottom of master
1468
- 【コード体系の標準化】
1469
- ・取引先コード:PTN-XXXXXXXX
1470
- ・商品コード:PRD-XXXXXXXX
1471
- ・部門コード:DPT-XXXX
1472
- end note
1473
-
1474
- @enduml
1475
- ```
1476
-
1477
- <details>
1478
- <summary>Java 実装例</summary>
1479
-
1480
- ```java
1481
- // 標準取引先モデル
1482
- public record StandardPartner(
1483
- String partnerId,
1484
- PartnerType partnerType,
1485
- String name,
1486
- Address address,
1487
- List<Contact> contacts,
1488
- Map<String, String> attributes
1489
- ) {
1490
- public enum PartnerType {
1491
- CUSTOMER, // 顧客
1492
- SUPPLIER, // 仕入先
1493
- SUBCONTRACTOR // 外注先
1494
- }
1495
- }
1496
-
1497
- // 標準トランザクションモデル
1498
- public record StandardTransaction(
1499
- String transactionId,
1500
- TransactionType transactionType,
1501
- LocalDate transactionDate,
1502
- String partnerId,
1503
- Money totalAmount,
1504
- List<TransactionLine> lines,
1505
- Map<String, String> attributes
1506
- ) {
1507
- public enum TransactionType {
1508
- ORDER, // 受注
1509
- SHIPMENT, // 出荷
1510
- SALES, // 売上
1511
- PURCHASE_ORDER, // 発注
1512
- RECEIPT, // 入荷
1513
- PURCHASE, // 仕入
1514
- WORK_ORDER, // 製造指示
1515
- COMPLETION // 完成
1516
- }
1517
- }
1518
-
1519
- // 販売固有モデルから標準モデルへの変換
1520
- @Component
1521
- public class SalesOrderToCanonicalTranslator
1522
- implements MessageTranslator<SalesOrder, StandardTransaction> {
1523
-
1524
- @Override
1525
- public StandardTransaction translate(SalesOrder order) {
1526
- return new StandardTransaction(
1527
- "TXN-" + order.orderId(),
1528
- TransactionType.ORDER,
1529
- order.orderDate(),
1530
- "PTN-" + order.customerId(),
1531
- Money.of(order.totalAmount(), "JPY"),
1532
- order.lines().stream()
1533
- .map(this::translateLine)
1534
- .toList(),
1535
- Map.of(
1536
- "originalOrderId", order.orderId(),
1537
- "salesRepId", order.salesRepId()
1538
- )
1539
- );
1540
- }
1541
-
1542
- private TransactionLine translateLine(SalesOrderLine line) {
1543
- return new TransactionLine(
1544
- line.lineNumber(),
1545
- "PRD-" + line.productCode(),
1546
- Quantity.of(line.quantity(), line.unit()),
1547
- Money.of(line.unitPrice(), "JPY"),
1548
- Money.of(line.amount(), "JPY")
1549
- );
1550
- }
1551
- }
1552
-
1553
- // 標準モデルから会計固有モデルへの変換
1554
- @Component
1555
- public class CanonicalToJournalTranslator
1556
- implements MessageTranslator<StandardTransaction, JournalEntry> {
1557
-
1558
- @Override
1559
- public JournalEntry translate(StandardTransaction transaction) {
1560
- // 取引種別に応じた仕訳パターンを適用
1561
- JournalPattern pattern = determinePattern(transaction.transactionType());
1562
-
1563
- return new JournalEntry(
1564
- generateJournalId(),
1565
- transaction.transactionDate(),
1566
- pattern.journalType(),
1567
- createJournalLines(transaction, pattern)
1568
- );
1569
- }
1570
- }
1571
- ```
1572
-
1573
- </details>
1574
-
1575
- ---
1576
-
1577
- ## 34.4 まとめ
1578
-
1579
- 本章では、エンタープライズインテグレーションの基盤となるメッセージングパターンについて解説しました。
1580
-
1581
- ### 学んだパターン一覧
1582
-
1583
- | カテゴリ | パターン | 用途 |
1584
- |---------|---------|------|
1585
- | **基礎** | Message Channel | メッセージの伝送経路 |
1586
- | | Message | データとメタデータの構造 |
1587
- | | Pipes and Filters | 処理の分解と連結 |
1588
- | **ルーティング** | Content-Based Router | 内容に基づく振り分け |
1589
- | | Message Filter | 条件による通過/破棄 |
1590
- | | Splitter/Aggregator | 分割と集約 |
1591
- | | Resequencer | 順序の再整列 |
1592
- | **変換** | Message Translator | 形式変換 |
1593
- | | Envelope Wrapper | メタデータ付与 |
1594
- | | Content Enricher | 情報の追加 |
1595
- | | Canonical Data Model | 標準データ形式 |
1596
-
1597
- ### 基幹業務システムへの適用ポイント
1598
-
1599
- 1. **チャネル設計**
1600
-
1601
- - Point-to-Point:受注処理、仕訳生成など1対1の処理
1602
- - Pub/Sub:イベント通知、複数システムへの連携
1603
-
1604
- 2. **ルーティング設計**
1605
-
1606
- - 取引種別による振り分け
1607
- - 金額閾値によるフィルタリング
1608
- - 月次締めでの分割/集約
1609
-
1610
- 3. **変換設計**
1611
-
1612
- - 売上→仕訳の自動変換
1613
- - マスタ情報のエンリッチメント
1614
- - 標準データモデルによる統合
1615
-
1616
- ### 次章の予告
1617
-
1618
- 第35章では、システム間連携パターンについて詳しく解説します。販売管理と財務会計、販売管理と生産管理、生産管理と財務会計の具体的な連携方法を学びます。