@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,1924 +0,0 @@
1
- ---
2
- type: Article
3
- title: "第16章:仕訳の設計"
4
- description: "財務会計システムの核心部分である「仕訳処理」を TDD で設計していきます。"
5
- tags: [article, practical-database-design, part3]
6
- status: stable
7
- generated: { by: human:kakimomokuri, at: 2026-03-30T08:34:28Z }
8
- ---
9
-
10
- # 第16章:仕訳の設計
11
-
12
- 財務会計システムの核心部分である「仕訳処理」を TDD で設計していきます。複式簿記の原則に基づき、仕訳データの登録・管理を実現するテーブル構造を設計します。
13
-
14
- ---
15
-
16
- ## 16.1 仕訳テーブルの設計
17
-
18
- ### 複式簿記と仕訳の概念
19
-
20
- 複式簿記は、すべての取引を「借方(かりかた)」と「貸方(かしかた)」の2つの側面から記録する方式です。
21
-
22
- ```plantuml
23
- @startuml
24
-
25
- title 複式簿記の原則
26
-
27
- rectangle "取引" as transaction {
28
- rectangle "借方(Debit)\n資産の増加\n負債の減少\n費用の発生" as debit
29
- rectangle "貸方(Credit)\n資産の減少\n負債の増加\n収益の発生" as credit
30
- }
31
-
32
- debit -[hidden]right- credit
33
-
34
- note bottom of transaction
35
- **貸借一致の原則**
36
- 借方合計 = 貸方合計
37
- 必ず一致する
38
- end note
39
-
40
- @enduml
41
- ```
42
-
43
- #### 仕訳の具体例
44
-
45
- 商品を現金で販売した場合の仕訳:
46
-
47
- | 借方(Debit) | 貸方(Credit) |
48
- |--------------|---------------|
49
- | 現金 100,000円 | 売上 100,000円 |
50
-
51
- 売掛金を現金と受取手形で回収した場合の仕訳(複合仕訳):
52
-
53
- | 借方(Debit) | 貸方(Credit) |
54
- |--------------|---------------|
55
- | 現金 80,000円 | 売掛金 100,000円 |
56
- | 受取手形 20,000円 | |
57
-
58
- ### 仕訳処理の流れ
59
-
60
- ```plantuml
61
- @startuml
62
-
63
- title 仕訳の流れ
64
-
65
- |営業部門|
66
- start
67
- :売上取引発生;
68
- :売上伝票作成;
69
-
70
- |経理部門|
71
- :仕訳入力;
72
- :貸借バランスチェック;
73
-
74
- if (借方合計 = 貸方合計?) then (はい)
75
- :仕訳登録;
76
- :残高更新;
77
- else (いいえ)
78
- :エラー表示;
79
- :修正入力;
80
- stop
81
- endif
82
-
83
- :仕訳完了;
84
- stop
85
-
86
- @enduml
87
- ```
88
-
89
- ### 仕訳テーブルの項目設計
90
-
91
- | 項目 | 説明 |
92
- |-----|------|
93
- | **仕訳伝票番号** | 仕訳を一意に識別するキー |
94
- | **起票日** | 会計上の取引発生日 |
95
- | **入力日** | システムへの登録日 |
96
- | **決算仕訳フラグ** | 決算整理仕訳かどうか(0:通常、1:決算) |
97
- | **単振フラグ** | 単一仕訳か複合仕訳か(0:複合、1:単一) |
98
- | **仕訳伝票区分** | 仕訳の種類(通常/決算/自動/振替) |
99
- | **定期計上フラグ** | 定期的な計上か否か |
100
- | **社員コード** | 起票担当者 |
101
- | **部門コード** | 所属部門 |
102
- | **赤伝フラグ** | 赤伝(取消)かどうか(0:黒伝、1:赤伝) |
103
- | **赤黒伝票番号** | 関連する赤黒伝票の番号 |
104
-
105
- ### 仕訳テーブルのER図
106
-
107
- ```plantuml
108
- @startuml
109
-
110
- entity "仕訳" as Journal {
111
- * **仕訳伝票番号**: VARCHAR(10) <<PK>>
112
- --
113
- * **起票日**: DATE
114
- * **入力日**: DATE
115
- * **決算仕訳フラグ**: SMALLINT
116
- * **単振フラグ**: SMALLINT
117
- * **仕訳伝票区分**: 仕訳伝票区分
118
- * **定期計上フラグ**: SMALLINT
119
- **社員コード**: VARCHAR(10) <<FK>>
120
- **部門コード**: VARCHAR(5) <<FK>>
121
- * **赤伝フラグ**: SMALLINT
122
- **赤黒伝票番号**: INTEGER
123
- * **作成日時**: TIMESTAMP
124
- * **更新日時**: TIMESTAMP
125
- }
126
-
127
- entity "仕訳明細" as JournalDetail {
128
- * **仕訳伝票番号**: VARCHAR(10) <<PK>> <<FK>>
129
- * **仕訳行番号**: SMALLINT <<PK>>
130
- --
131
- **行摘要**: VARCHAR(1000)
132
- * **作成日時**: TIMESTAMP
133
- * **更新日時**: TIMESTAMP
134
- }
135
-
136
- entity "仕訳貸借明細" as JournalDebitCreditDetail {
137
- * **仕訳伝票番号**: VARCHAR(10) <<PK>> <<FK>>
138
- * **仕訳行番号**: SMALLINT <<PK>>
139
- * **仕訳行貸借区分**: 仕訳行貸借区分 <<PK>>
140
- --
141
- * **勘定科目コード**: VARCHAR(5) <<FK>>
142
- **補助科目コード**: VARCHAR(10)
143
- **部門コード**: VARCHAR(5) <<FK>>
144
- **プロジェクトコード**: VARCHAR(10)
145
- * **仕訳金額**: DECIMAL(14,2)
146
- **通貨コード**: VARCHAR(3)
147
- **為替レート**: DECIMAL(8,2)
148
- **基軸換算仕訳金額**: DECIMAL(14,2)
149
- **消費税区分**: 消費税区分
150
- **消費税率**: SMALLINT
151
- **消費税計算区分**: 消費税計算区分
152
- **期日**: DATE
153
- **資金繰フラグ**: SMALLINT
154
- **セグメントコード**: VARCHAR(10)
155
- **相手勘定科目コード**: VARCHAR(5)
156
- **相手補助科目コード**: VARCHAR(10)
157
- **付箋コード**: VARCHAR(1)
158
- **付箋内容**: VARCHAR(60)
159
- * **作成日時**: TIMESTAMP
160
- * **更新日時**: TIMESTAMP
161
- }
162
-
163
- Journal ||--o{ JournalDetail : "含む"
164
- JournalDetail ||--o{ JournalDebitCreditDetail : "含む"
165
-
166
- note right of Journal
167
- 仕訳伝票のヘッダ情報
168
- 起票日、入力日、各種フラグを管理
169
- end note
170
-
171
- note right of JournalDetail
172
- 仕訳の行単位の情報
173
- 1つの仕訳に複数の明細行
174
- end note
175
-
176
- note right of JournalDebitCreditDetail
177
- 借方・貸方の詳細情報
178
- 勘定科目、金額、補助情報を管理
179
- end note
180
-
181
- @enduml
182
- ```
183
-
184
- ### マイグレーション:仕訳テーブルの作成
185
-
186
- <details>
187
- <summary>マイグレーションSQL</summary>
188
-
189
- ```sql
190
- -- src/main/resources/db/migration/V006__create_journal_tables.sql
191
-
192
- -- 仕訳伝票区分
193
- CREATE TYPE 仕訳伝票区分 AS ENUM ('通常', '決算', '自動', '振替');
194
-
195
- -- 仕訳行貸借区分
196
- CREATE TYPE 仕訳行貸借区分 AS ENUM ('借方', '貸方');
197
-
198
- -- 消費税区分(仕訳用)
199
- CREATE TYPE 消費税区分 AS ENUM ('課税', '非課税', '免税', '不課税', '対象外');
200
-
201
- -- 消費税計算区分(仕訳用)
202
- CREATE TYPE 消費税計算区分 AS ENUM ('外税', '内税', '税なし');
203
-
204
- -- 仕訳ヘッダ
205
- CREATE TABLE "仕訳" (
206
- "仕訳伝票番号" VARCHAR(10) PRIMARY KEY,
207
- "起票日" DATE NOT NULL,
208
- "入力日" DATE NOT NULL DEFAULT CURRENT_DATE,
209
- "決算仕訳フラグ" SMALLINT DEFAULT 0 NOT NULL,
210
- "単振フラグ" SMALLINT DEFAULT 0 NOT NULL,
211
- "仕訳伝票区分" 仕訳伝票区分 DEFAULT '通常' NOT NULL,
212
- "定期計上フラグ" SMALLINT DEFAULT 0 NOT NULL,
213
- "社員コード" VARCHAR(10),
214
- "部門コード" VARCHAR(5),
215
- "赤伝フラグ" SMALLINT DEFAULT 0 NOT NULL,
216
- "赤黒伝票番号" INTEGER,
217
- "作成日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
218
- "更新日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
219
- CONSTRAINT "fk_仕訳_部門"
220
- FOREIGN KEY ("部門コード") REFERENCES "部門マスタ"("部門コード")
221
- );
222
-
223
- -- 仕訳明細
224
- CREATE TABLE "仕訳明細" (
225
- "仕訳伝票番号" VARCHAR(10) NOT NULL,
226
- "仕訳行番号" SMALLINT NOT NULL,
227
- "行摘要" VARCHAR(1000),
228
- "作成日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
229
- "更新日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
230
- PRIMARY KEY ("仕訳伝票番号", "仕訳行番号"),
231
- CONSTRAINT "fk_仕訳明細_仕訳"
232
- FOREIGN KEY ("仕訳伝票番号") REFERENCES "仕訳"("仕訳伝票番号") ON DELETE CASCADE
233
- );
234
-
235
- -- 仕訳貸借明細
236
- CREATE TABLE "仕訳貸借明細" (
237
- "仕訳伝票番号" VARCHAR(10) NOT NULL,
238
- "仕訳行番号" SMALLINT NOT NULL,
239
- "仕訳行貸借区分" 仕訳行貸借区分 NOT NULL,
240
- "勘定科目コード" VARCHAR(5) NOT NULL,
241
- "補助科目コード" VARCHAR(10),
242
- "部門コード" VARCHAR(5),
243
- "プロジェクトコード" VARCHAR(10),
244
- "仕訳金額" DECIMAL(14,2) NOT NULL,
245
- "通貨コード" VARCHAR(3) DEFAULT 'JPY',
246
- "為替レート" DECIMAL(8,2) DEFAULT 1.00,
247
- "基軸換算仕訳金額" DECIMAL(14,2),
248
- "消費税区分" 消費税区分 DEFAULT '課税',
249
- "消費税率" SMALLINT DEFAULT 10,
250
- "消費税計算区分" 消費税計算区分 DEFAULT '外税',
251
- "期日" DATE,
252
- "資金繰フラグ" SMALLINT DEFAULT 0,
253
- "セグメントコード" VARCHAR(10),
254
- "相手勘定科目コード" VARCHAR(5),
255
- "相手補助科目コード" VARCHAR(10),
256
- "付箋コード" VARCHAR(1),
257
- "付箋内容" VARCHAR(60),
258
- "作成日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
259
- "更新日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
260
- PRIMARY KEY ("仕訳伝票番号", "仕訳行番号", "仕訳行貸借区分"),
261
- CONSTRAINT "fk_仕訳貸借明細_仕訳明細"
262
- FOREIGN KEY ("仕訳伝票番号", "仕訳行番号")
263
- REFERENCES "仕訳明細"("仕訳伝票番号", "仕訳行番号") ON DELETE CASCADE,
264
- CONSTRAINT "fk_仕訳貸借明細_勘定科目"
265
- FOREIGN KEY ("勘定科目コード") REFERENCES "勘定科目マスタ"("勘定科目コード"),
266
- CONSTRAINT "fk_仕訳貸借明細_部門"
267
- FOREIGN KEY ("部門コード") REFERENCES "部門マスタ"("部門コード")
268
- );
269
-
270
- -- インデックス
271
- CREATE INDEX "idx_仕訳_起票日" ON "仕訳"("起票日");
272
- CREATE INDEX "idx_仕訳_部門コード" ON "仕訳"("部門コード");
273
- CREATE INDEX "idx_仕訳_仕訳伝票区分" ON "仕訳"("仕訳伝票区分");
274
- CREATE INDEX "idx_仕訳貸借明細_勘定科目コード" ON "仕訳貸借明細"("勘定科目コード");
275
- CREATE INDEX "idx_仕訳貸借明細_部門コード" ON "仕訳貸借明細"("部門コード");
276
- ```
277
-
278
- </details>
279
-
280
- <details>
281
- <summary>貸借バランスチェック関数</summary>
282
-
283
- ```sql
284
- -- 貸借バランスチェック関数
285
- CREATE OR REPLACE FUNCTION check_journal_balance()
286
- RETURNS TRIGGER AS $$
287
- DECLARE
288
- debit_total DECIMAL(14,2);
289
- credit_total DECIMAL(14,2);
290
- BEGIN
291
- -- 借方合計を計算
292
- SELECT COALESCE(SUM("仕訳金額"), 0) INTO debit_total
293
- FROM "仕訳貸借明細"
294
- WHERE "仕訳伝票番号" = NEW."仕訳伝票番号"
295
- AND "仕訳行貸借区分" = '借方';
296
-
297
- -- 貸方合計を計算
298
- SELECT COALESCE(SUM("仕訳金額"), 0) INTO credit_total
299
- FROM "仕訳貸借明細"
300
- WHERE "仕訳伝票番号" = NEW."仕訳伝票番号"
301
- AND "仕訳行貸借区分" = '貸方';
302
-
303
- -- 貸借一致チェック(トリガー内では警告のみ、アプリ側で制御)
304
- IF debit_total <> credit_total THEN
305
- RAISE WARNING '仕訳伝票番号 % の貸借が一致していません: 借方=%, 貸方=%',
306
- NEW."仕訳伝票番号", debit_total, credit_total;
307
- END IF;
308
-
309
- RETURN NEW;
310
- END;
311
- $$ LANGUAGE plpgsql;
312
-
313
- -- 貸借バランスチェックトリガー(挿入・更新時)
314
- CREATE TRIGGER "trg_check_journal_balance"
315
- AFTER INSERT OR UPDATE ON "仕訳貸借明細"
316
- FOR EACH ROW
317
- EXECUTE FUNCTION check_journal_balance();
318
- ```
319
-
320
- </details>
321
-
322
- ---
323
-
324
- ## 16.2 仕訳明細の設計
325
-
326
- ### 仕訳明細の役割
327
-
328
- 仕訳明細は、仕訳伝票の行単位の情報を管理します。1つの仕訳伝票に複数の明細行を持つことができます。
329
-
330
- | 項目 | 説明 |
331
- |-----|------|
332
- | **仕訳伝票番号** | 親となる仕訳伝票の番号(外部キー) |
333
- | **仕訳行番号** | 明細行の連番(1から始まる) |
334
- | **行摘要** | その行の取引内容の説明(最大1000文字) |
335
-
336
- ### 単一仕訳と複合仕訳
337
-
338
- ```plantuml
339
- @startuml
340
-
341
- title 単一仕訳と複合仕訳
342
-
343
- package "単一仕訳(単振フラグ=1)" {
344
- rectangle "仕訳明細 行番号1" as single {
345
- rectangle "借方: 現金 100,000円" as sd
346
- rectangle "貸方: 売上 100,000円" as sc
347
- }
348
- }
349
-
350
- package "複合仕訳(単振フラグ=0)" {
351
- rectangle "仕訳明細 行番号1" as line1 {
352
- rectangle "借方: 現金 80,000円" as d1
353
- rectangle "貸方: 売掛金 100,000円" as c1
354
- }
355
- rectangle "仕訳明細 行番号2" as line2 {
356
- rectangle "借方: 受取手形 20,000円" as d2
357
- }
358
- }
359
-
360
- @enduml
361
- ```
362
-
363
- ---
364
-
365
- ## 16.3 仕訳貸借明細の設計
366
-
367
- ### 仕訳貸借明細の項目
368
-
369
- 仕訳貸借明細は、借方・貸方それぞれの詳細情報を管理する最も粒度の細かいテーブルです。
370
-
371
- #### 基本情報
372
-
373
- | 項目 | 説明 |
374
- |-----|------|
375
- | **仕訳伝票番号** | 親となる仕訳伝票の番号 |
376
- | **仕訳行番号** | 親となる仕訳明細の行番号 |
377
- | **仕訳行貸借区分** | 借方/貸方の区分 |
378
- | **勘定科目コード** | 使用する勘定科目 |
379
- | **補助科目コード** | 補助科目(得意先、仕入先など) |
380
- | **仕訳金額** | 取引金額 |
381
-
382
- #### 多通貨対応
383
-
384
- | 項目 | 説明 |
385
- |-----|------|
386
- | **通貨コード** | 取引通貨(デフォルト: JPY) |
387
- | **為替レート** | 適用為替レート |
388
- | **基軸換算仕訳金額** | 基軸通貨(円)換算後の金額 |
389
-
390
- #### 管理会計情報
391
-
392
- | 項目 | 説明 |
393
- |-----|------|
394
- | **部門コード** | 配賦先部門 |
395
- | **プロジェクトコード** | 関連プロジェクト |
396
- | **セグメントコード** | セグメント情報 |
397
-
398
- #### 消費税情報
399
-
400
- | 項目 | 説明 |
401
- |-----|------|
402
- | **消費税区分** | 課税/非課税/免税/不課税/対象外 |
403
- | **消費税率** | 適用税率(10, 8 など) |
404
- | **消費税計算区分** | 外税/内税/税なし |
405
-
406
- #### その他
407
-
408
- | 項目 | 説明 |
409
- |-----|------|
410
- | **期日** | 支払期日・入金期日 |
411
- | **資金繰フラグ** | 資金繰表への計上対象か |
412
- | **相手勘定科目コード** | 相手勘定科目(元帳表示用) |
413
- | **相手補助科目コード** | 相手補助科目 |
414
- | **付箋コード** | 付箋の種類 |
415
- | **付箋内容** | 付箋の内容(メモ) |
416
-
417
- ### TDD による仕訳テーブルの実装
418
-
419
- #### ドメイン層:Enum定義
420
-
421
- <details>
422
- <summary>仕訳伝票区分 Enum</summary>
423
-
424
- ```java
425
- // src/main/java/com/example/accounting/domain/model/journal/JournalVoucherType.java
426
- package com.example.fas.domain.model.journal;
427
-
428
- import lombok.Getter;
429
- import lombok.RequiredArgsConstructor;
430
-
431
- @Getter
432
- @RequiredArgsConstructor
433
- public enum JournalVoucherType {
434
- NORMAL("通常"),
435
- CLOSING("決算"),
436
- AUTO("自動"),
437
- TRANSFER("振替");
438
-
439
- private final String displayName;
440
-
441
- public static JournalVoucherType fromDisplayName(String displayName) {
442
- for (JournalVoucherType type : values()) {
443
- if (type.displayName.equals(displayName)) {
444
- return type;
445
- }
446
- }
447
- throw new IllegalArgumentException("不正な仕訳伝票区分: " + displayName);
448
- }
449
- }
450
- ```
451
-
452
- </details>
453
-
454
- <details>
455
- <summary>消費税区分 Enum</summary>
456
-
457
- ```java
458
- // src/main/java/com/example/accounting/domain/model/journal/TaxType.java
459
- package com.example.fas.domain.model.journal;
460
-
461
- import lombok.Getter;
462
- import lombok.RequiredArgsConstructor;
463
-
464
- @Getter
465
- @RequiredArgsConstructor
466
- public enum TaxType {
467
- TAXABLE("課税"),
468
- NON_TAXABLE("非課税"),
469
- TAX_EXEMPT("免税"),
470
- NOT_TAXABLE("不課税"),
471
- OUT_OF_SCOPE("対象外");
472
-
473
- private final String displayName;
474
-
475
- public static TaxType fromDisplayName(String displayName) {
476
- for (TaxType type : values()) {
477
- if (type.displayName.equals(displayName)) {
478
- return type;
479
- }
480
- }
481
- throw new IllegalArgumentException("不正な消費税区分: " + displayName);
482
- }
483
- }
484
- ```
485
-
486
- </details>
487
-
488
- <details>
489
- <summary>消費税計算区分 Enum</summary>
490
-
491
- ```java
492
- // src/main/java/com/example/accounting/domain/model/journal/TaxCalculationType.java
493
- package com.example.fas.domain.model.journal;
494
-
495
- import lombok.Getter;
496
- import lombok.RequiredArgsConstructor;
497
-
498
- @Getter
499
- @RequiredArgsConstructor
500
- public enum TaxCalculationType {
501
- EXCLUSIVE("外税"),
502
- INCLUSIVE("内税"),
503
- NO_TAX("税なし");
504
-
505
- private final String displayName;
506
-
507
- public static TaxCalculationType fromDisplayName(String displayName) {
508
- for (TaxCalculationType type : values()) {
509
- if (type.displayName.equals(displayName)) {
510
- return type;
511
- }
512
- }
513
- throw new IllegalArgumentException("不正な消費税計算区分: " + displayName);
514
- }
515
- }
516
- ```
517
-
518
- </details>
519
-
520
- #### ドメイン層:エンティティ
521
-
522
- <details>
523
- <summary>仕訳エンティティ</summary>
524
-
525
- ```java
526
- // src/main/java/com/example/accounting/domain/model/journal/Journal.java
527
- package com.example.fas.domain.model.journal;
528
-
529
- import lombok.AllArgsConstructor;
530
- import lombok.Builder;
531
- import lombok.Data;
532
- import lombok.NoArgsConstructor;
533
-
534
- import java.math.BigDecimal;
535
- import java.time.LocalDate;
536
- import java.time.LocalDateTime;
537
- import java.util.ArrayList;
538
- import java.util.List;
539
-
540
- @Data
541
- @Builder
542
- @NoArgsConstructor
543
- @AllArgsConstructor
544
- public class Journal {
545
- private String journalVoucherNumber; // 仕訳伝票番号
546
- private LocalDate postingDate; // 起票日
547
- private LocalDate entryDate; // 入力日
548
- private Boolean closingJournalFlag; // 決算仕訳フラグ
549
- private Boolean singleEntryFlag; // 単振フラグ
550
- private JournalVoucherType voucherType; // 仕訳伝票区分
551
- private Boolean periodicPostingFlag; // 定期計上フラグ
552
- private String employeeCode; // 社員コード
553
- private String departmentCode; // 部門コード
554
- private Boolean redSlipFlag; // 赤伝フラグ
555
- private Integer redBlackVoucherNumber; // 赤黒伝票番号
556
- private LocalDateTime createdAt; // 作成日時
557
- private LocalDateTime updatedAt; // 更新日時
558
-
559
- // リレーション
560
- @Builder.Default
561
- private List<JournalDetail> details = new ArrayList<>();
562
-
563
- /**
564
- * 貸借バランスチェック
565
- * @return 借方合計と貸方合計が一致する場合 true
566
- */
567
- public boolean isBalanced() {
568
- BigDecimal debitTotal = details.stream()
569
- .flatMap(d -> d.getDebitCreditDetails().stream())
570
- .filter(dc -> dc.getDebitCreditType() == DebitCreditType.DEBIT)
571
- .map(JournalDebitCreditDetail::getAmount)
572
- .reduce(BigDecimal.ZERO, BigDecimal::add);
573
-
574
- BigDecimal creditTotal = details.stream()
575
- .flatMap(d -> d.getDebitCreditDetails().stream())
576
- .filter(dc -> dc.getDebitCreditType() == DebitCreditType.CREDIT)
577
- .map(JournalDebitCreditDetail::getAmount)
578
- .reduce(BigDecimal.ZERO, BigDecimal::add);
579
-
580
- return debitTotal.compareTo(creditTotal) == 0;
581
- }
582
-
583
- /**
584
- * 借方合計を取得
585
- */
586
- public BigDecimal getDebitTotal() {
587
- return details.stream()
588
- .flatMap(d -> d.getDebitCreditDetails().stream())
589
- .filter(dc -> dc.getDebitCreditType() == DebitCreditType.DEBIT)
590
- .map(JournalDebitCreditDetail::getAmount)
591
- .reduce(BigDecimal.ZERO, BigDecimal::add);
592
- }
593
-
594
- /**
595
- * 貸方合計を取得
596
- */
597
- public BigDecimal getCreditTotal() {
598
- return details.stream()
599
- .flatMap(d -> d.getDebitCreditDetails().stream())
600
- .filter(dc -> dc.getDebitCreditType() == DebitCreditType.CREDIT)
601
- .map(JournalDebitCreditDetail::getAmount)
602
- .reduce(BigDecimal.ZERO, BigDecimal::add);
603
- }
604
- }
605
- ```
606
-
607
- </details>
608
-
609
- <details>
610
- <summary>仕訳明細エンティティ</summary>
611
-
612
- ```java
613
- // src/main/java/com/example/accounting/domain/model/journal/JournalDetail.java
614
- package com.example.fas.domain.model.journal;
615
-
616
- import lombok.AllArgsConstructor;
617
- import lombok.Builder;
618
- import lombok.Data;
619
- import lombok.NoArgsConstructor;
620
-
621
- import java.time.LocalDateTime;
622
- import java.util.ArrayList;
623
- import java.util.List;
624
-
625
- @Data
626
- @Builder
627
- @NoArgsConstructor
628
- @AllArgsConstructor
629
- public class JournalDetail {
630
- private String journalVoucherNumber; // 仕訳伝票番号
631
- private Integer lineNumber; // 仕訳行番号
632
- private String lineSummary; // 行摘要
633
- private LocalDateTime createdAt; // 作成日時
634
- private LocalDateTime updatedAt; // 更新日時
635
-
636
- // リレーション
637
- @Builder.Default
638
- private List<JournalDebitCreditDetail> debitCreditDetails = new ArrayList<>();
639
- }
640
- ```
641
-
642
- </details>
643
-
644
- <details>
645
- <summary>仕訳貸借明細エンティティ</summary>
646
-
647
- ```java
648
- // src/main/java/com/example/accounting/domain/model/journal/JournalDebitCreditDetail.java
649
- package com.example.fas.domain.model.journal;
650
-
651
- import com.example.fas.domain.model.account.DebitCreditType;
652
- import lombok.AllArgsConstructor;
653
- import lombok.Builder;
654
- import lombok.Data;
655
- import lombok.NoArgsConstructor;
656
-
657
- import java.math.BigDecimal;
658
- import java.time.LocalDate;
659
- import java.time.LocalDateTime;
660
-
661
- @Data
662
- @Builder
663
- @NoArgsConstructor
664
- @AllArgsConstructor
665
- public class JournalDebitCreditDetail {
666
- private String journalVoucherNumber; // 仕訳伝票番号
667
- private Integer lineNumber; // 仕訳行番号
668
- private DebitCreditType debitCreditType; // 仕訳行貸借区分
669
- private String accountCode; // 勘定科目コード
670
- private String subAccountCode; // 補助科目コード
671
- private String departmentCode; // 部門コード
672
- private String projectCode; // プロジェクトコード
673
- private BigDecimal amount; // 仕訳金額
674
- private String currencyCode; // 通貨コード
675
- private BigDecimal exchangeRate; // 為替レート
676
- private BigDecimal baseCurrencyAmount; // 基軸換算仕訳金額
677
- private TaxType taxType; // 消費税区分
678
- private Integer taxRate; // 消費税率
679
- private TaxCalculationType taxCalcType; // 消費税計算区分
680
- private LocalDate dueDate; // 期日
681
- private Boolean cashFlowFlag; // 資金繰フラグ
682
- private String segmentCode; // セグメントコード
683
- private String counterAccountCode; // 相手勘定科目コード
684
- private String counterSubAccountCode; // 相手補助科目コード
685
- private String tagCode; // 付箋コード
686
- private String tagContent; // 付箋内容
687
- private LocalDateTime createdAt; // 作成日時
688
- private LocalDateTime updatedAt; // 更新日時
689
- }
690
- ```
691
-
692
- </details>
693
-
694
- #### テストコード
695
-
696
- <details>
697
- <summary>仕訳リポジトリテスト</summary>
698
-
699
- ```java
700
- // src/test/java/com/example/accounting/infrastructure/persistence/repository/JournalRepositoryTest.java
701
- package com.example.fas.infrastructure.persistence.repository;
702
-
703
- import com.example.fas.application.port.out.JournalRepository;
704
- import com.example.fas.domain.model.account.DebitCreditType;
705
- import com.example.fas.domain.model.journal.*;
706
- import com.example.fas.testsetup.BaseIntegrationTest;
707
- import org.junit.jupiter.api.*;
708
- import org.springframework.beans.factory.annotation.Autowired;
709
-
710
- import java.math.BigDecimal;
711
- import java.time.LocalDate;
712
- import java.util.List;
713
-
714
- import static org.assertj.core.api.Assertions.*;
715
-
716
- @DisplayName("仕訳リポジトリ")
717
- class JournalRepositoryTest extends BaseIntegrationTest {
718
-
719
- @Autowired
720
- private JournalRepository journalRepository;
721
-
722
- @BeforeEach
723
- void setUp() {
724
- journalRepository.deleteAll();
725
- }
726
-
727
- @Nested
728
- @DisplayName("仕訳の登録")
729
- class Registration {
730
-
731
- @Test
732
- @DisplayName("単純仕訳(1行借方・1行貸方)を登録できる")
733
- void canRegisterSimpleJournal() {
734
- // Arrange: 現金売上の仕訳データ
735
- var journal = createSimpleSalesJournal("J0001");
736
-
737
- // Act: 仕訳を登録
738
- journalRepository.save(journal);
739
-
740
- // Assert: 登録されたデータを確認
741
- var savedJournal = journalRepository.findByVoucherNumber("J0001");
742
- assertThat(savedJournal).isPresent();
743
- assertThat(savedJournal.get().getPostingDate()).isEqualTo(LocalDate.of(2024, 4, 1));
744
- assertThat(savedJournal.get().isBalanced()).isTrue();
745
- }
746
-
747
- @Test
748
- @DisplayName("複合仕訳(複数行)を登録できる")
749
- void canRegisterCompoundJournal() {
750
- // Arrange: 売掛金回収の複合仕訳
751
- var journal = createCompoundJournal("J0002");
752
-
753
- // Act: 仕訳を登録
754
- journalRepository.save(journal);
755
-
756
- // Assert: 登録されたデータを確認
757
- var savedJournal = journalRepository.findByVoucherNumber("J0002");
758
- assertThat(savedJournal).isPresent();
759
- assertThat(savedJournal.get().getDetails()).hasSize(2);
760
- assertThat(savedJournal.get().isBalanced()).isTrue();
761
- }
762
-
763
- @Test
764
- @DisplayName("貸借が一致しない仕訳はバランスチェックでfalseを返す")
765
- void shouldReturnFalseForUnbalancedJournal() {
766
- // Arrange: 貸借不一致の仕訳データ
767
- var journal = createUnbalancedJournal("J0003");
768
-
769
- // Assert: バランスチェック
770
- assertThat(journal.isBalanced()).isFalse();
771
- }
772
- }
773
-
774
- @Nested
775
- @DisplayName("仕訳の検索")
776
- class Search {
777
-
778
- @BeforeEach
779
- void setUpTestData() {
780
- journalRepository.save(createSimpleSalesJournal("J0001"));
781
- journalRepository.save(createCompoundJournal("J0002"));
782
- }
783
-
784
- @Test
785
- @DisplayName("起票日範囲で仕訳を検索できる")
786
- void canFindByDateRange() {
787
- // Act
788
- var journals = journalRepository.findByPostingDateBetween(
789
- LocalDate.of(2024, 4, 1),
790
- LocalDate.of(2024, 4, 30)
791
- );
792
-
793
- // Assert
794
- assertThat(journals).hasSize(2);
795
- }
796
-
797
- @Test
798
- @DisplayName("勘定科目コードで仕訳を検索できる")
799
- void canFindByAccountCode() {
800
- // Act
801
- var journals = journalRepository.findByAccountCode("11110");
802
-
803
- // Assert
804
- assertThat(journals).isNotEmpty();
805
- }
806
- }
807
-
808
- private Journal createSimpleSalesJournal(String voucherNumber) {
809
- var debitDetail = JournalDebitCreditDetail.builder()
810
- .journalVoucherNumber(voucherNumber)
811
- .lineNumber(1)
812
- .debitCreditType(DebitCreditType.DEBIT)
813
- .accountCode("11110") // 現金
814
- .amount(new BigDecimal("100000"))
815
- .currencyCode("JPY")
816
- .exchangeRate(BigDecimal.ONE)
817
- .build();
818
-
819
- var creditDetail = JournalDebitCreditDetail.builder()
820
- .journalVoucherNumber(voucherNumber)
821
- .lineNumber(1)
822
- .debitCreditType(DebitCreditType.CREDIT)
823
- .accountCode("41100") // 売上
824
- .amount(new BigDecimal("100000"))
825
- .currencyCode("JPY")
826
- .exchangeRate(BigDecimal.ONE)
827
- .build();
828
-
829
- var journalDetail = JournalDetail.builder()
830
- .journalVoucherNumber(voucherNumber)
831
- .lineNumber(1)
832
- .lineSummary("現金売上")
833
- .debitCreditDetails(List.of(debitDetail, creditDetail))
834
- .build();
835
-
836
- return Journal.builder()
837
- .journalVoucherNumber(voucherNumber)
838
- .postingDate(LocalDate.of(2024, 4, 1))
839
- .entryDate(LocalDate.now())
840
- .closingJournalFlag(false)
841
- .singleEntryFlag(true)
842
- .voucherType(JournalVoucherType.NORMAL)
843
- .periodicPostingFlag(false)
844
- .redSlipFlag(false)
845
- .details(List.of(journalDetail))
846
- .build();
847
- }
848
-
849
- private Journal createCompoundJournal(String voucherNumber) {
850
- // 売掛金100,000円を現金80,000円と受取手形20,000円で回収
851
- var debit1 = JournalDebitCreditDetail.builder()
852
- .journalVoucherNumber(voucherNumber)
853
- .lineNumber(1)
854
- .debitCreditType(DebitCreditType.DEBIT)
855
- .accountCode("11110") // 現金
856
- .amount(new BigDecimal("80000"))
857
- .build();
858
-
859
- var credit1 = JournalDebitCreditDetail.builder()
860
- .journalVoucherNumber(voucherNumber)
861
- .lineNumber(1)
862
- .debitCreditType(DebitCreditType.CREDIT)
863
- .accountCode("11300") // 売掛金
864
- .amount(new BigDecimal("100000"))
865
- .build();
866
-
867
- var debit2 = JournalDebitCreditDetail.builder()
868
- .journalVoucherNumber(voucherNumber)
869
- .lineNumber(2)
870
- .debitCreditType(DebitCreditType.DEBIT)
871
- .accountCode("11200") // 受取手形
872
- .amount(new BigDecimal("20000"))
873
- .build();
874
-
875
- var detail1 = JournalDetail.builder()
876
- .journalVoucherNumber(voucherNumber)
877
- .lineNumber(1)
878
- .lineSummary("現金入金")
879
- .debitCreditDetails(List.of(debit1, credit1))
880
- .build();
881
-
882
- var detail2 = JournalDetail.builder()
883
- .journalVoucherNumber(voucherNumber)
884
- .lineNumber(2)
885
- .lineSummary("手形入金")
886
- .debitCreditDetails(List.of(debit2))
887
- .build();
888
-
889
- return Journal.builder()
890
- .journalVoucherNumber(voucherNumber)
891
- .postingDate(LocalDate.of(2024, 4, 5))
892
- .entryDate(LocalDate.now())
893
- .closingJournalFlag(false)
894
- .singleEntryFlag(false) // 複合仕訳
895
- .voucherType(JournalVoucherType.NORMAL)
896
- .details(List.of(detail1, detail2))
897
- .build();
898
- }
899
-
900
- private Journal createUnbalancedJournal(String voucherNumber) {
901
- var debitDetail = JournalDebitCreditDetail.builder()
902
- .journalVoucherNumber(voucherNumber)
903
- .lineNumber(1)
904
- .debitCreditType(DebitCreditType.DEBIT)
905
- .accountCode("11110")
906
- .amount(new BigDecimal("100000"))
907
- .build();
908
-
909
- var creditDetail = JournalDebitCreditDetail.builder()
910
- .journalVoucherNumber(voucherNumber)
911
- .lineNumber(1)
912
- .debitCreditType(DebitCreditType.CREDIT)
913
- .accountCode("41100")
914
- .amount(new BigDecimal("90000")) // 不一致
915
- .build();
916
-
917
- var journalDetail = JournalDetail.builder()
918
- .journalVoucherNumber(voucherNumber)
919
- .lineNumber(1)
920
- .debitCreditDetails(List.of(debitDetail, creditDetail))
921
- .build();
922
-
923
- return Journal.builder()
924
- .journalVoucherNumber(voucherNumber)
925
- .postingDate(LocalDate.of(2024, 4, 1))
926
- .details(List.of(journalDetail))
927
- .build();
928
- }
929
- }
930
- ```
931
-
932
- </details>
933
-
934
- #### アプリケーション層(Output Port)
935
-
936
- <details>
937
- <summary>仕訳リポジトリインターフェース</summary>
938
-
939
- ```java
940
- // src/main/java/com/example/accounting/application/port/out/JournalRepository.java
941
- package com.example.fas.application.port.out;
942
-
943
- import com.example.fas.domain.model.journal.Journal;
944
-
945
- import java.time.LocalDate;
946
- import java.util.List;
947
- import java.util.Optional;
948
-
949
- /**
950
- * 仕訳リポジトリ(Output Port)
951
- */
952
- public interface JournalRepository {
953
-
954
- void save(Journal journal);
955
-
956
- Optional<Journal> findByVoucherNumber(String voucherNumber);
957
-
958
- List<Journal> findByPostingDateBetween(LocalDate fromDate, LocalDate toDate);
959
-
960
- List<Journal> findByAccountCode(String accountCode);
961
-
962
- List<Journal> findByDepartmentCode(String departmentCode);
963
-
964
- void delete(String voucherNumber);
965
-
966
- void deleteAll();
967
- }
968
- ```
969
-
970
- </details>
971
-
972
- #### インフラストラクチャ層
973
-
974
- <details>
975
- <summary>MyBatis XML Mapper</summary>
976
-
977
- ```xml
978
- <?xml version="1.0" encoding="UTF-8" ?>
979
- <!DOCTYPE mapper
980
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
981
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
982
- <mapper namespace="com.example.fas.infrastructure.persistence.mapper.JournalMapper">
983
-
984
- <!-- 仕訳 ResultMap -->
985
- <resultMap id="JournalResultMap" type="com.example.fas.domain.model.journal.Journal">
986
- <result property="journalVoucherNumber" column="仕訳伝票番号"/>
987
- <result property="postingDate" column="起票日"/>
988
- <result property="entryDate" column="入力日"/>
989
- <result property="closingJournalFlag" column="決算仕訳フラグ"/>
990
- <result property="singleEntryFlag" column="単振フラグ"/>
991
- <result property="voucherType" column="仕訳伝票区分"
992
- typeHandler="com.example.fas.infrastructure.persistence.typehandler.JournalVoucherTypeHandler"/>
993
- <result property="periodicPostingFlag" column="定期計上フラグ"/>
994
- <result property="employeeCode" column="社員コード"/>
995
- <result property="departmentCode" column="部門コード"/>
996
- <result property="redSlipFlag" column="赤伝フラグ"/>
997
- <result property="redBlackVoucherNumber" column="赤黒伝票番号"/>
998
- <result property="createdAt" column="作成日時"/>
999
- <result property="updatedAt" column="更新日時"/>
1000
- </resultMap>
1001
-
1002
- <!-- 仕訳明細 ResultMap -->
1003
- <resultMap id="JournalDetailResultMap" type="com.example.fas.domain.model.journal.JournalDetail">
1004
- <result property="journalVoucherNumber" column="仕訳伝票番号"/>
1005
- <result property="lineNumber" column="仕訳行番号"/>
1006
- <result property="lineSummary" column="行摘要"/>
1007
- <result property="createdAt" column="作成日時"/>
1008
- <result property="updatedAt" column="更新日時"/>
1009
- </resultMap>
1010
-
1011
- <!-- 仕訳貸借明細 ResultMap -->
1012
- <resultMap id="JournalDebitCreditDetailResultMap" type="com.example.fas.domain.model.journal.JournalDebitCreditDetail">
1013
- <result property="journalVoucherNumber" column="仕訳伝票番号"/>
1014
- <result property="lineNumber" column="仕訳行番号"/>
1015
- <result property="debitCreditType" column="仕訳行貸借区分"
1016
- typeHandler="com.example.fas.infrastructure.persistence.typehandler.DebitCreditTypeHandler"/>
1017
- <result property="accountCode" column="勘定科目コード"/>
1018
- <result property="subAccountCode" column="補助科目コード"/>
1019
- <result property="departmentCode" column="部門コード"/>
1020
- <result property="projectCode" column="プロジェクトコード"/>
1021
- <result property="amount" column="仕訳金額"/>
1022
- <result property="currencyCode" column="通貨コード"/>
1023
- <result property="exchangeRate" column="為替レート"/>
1024
- <result property="baseCurrencyAmount" column="基軸換算仕訳金額"/>
1025
- <result property="taxType" column="消費税区分"
1026
- typeHandler="com.example.fas.infrastructure.persistence.typehandler.TaxTypeHandler"/>
1027
- <result property="taxRate" column="消費税率"/>
1028
- <result property="taxCalcType" column="消費税計算区分"
1029
- typeHandler="com.example.fas.infrastructure.persistence.typehandler.TaxCalculationTypeHandler"/>
1030
- <result property="dueDate" column="期日"/>
1031
- <result property="cashFlowFlag" column="資金繰フラグ"/>
1032
- <result property="segmentCode" column="セグメントコード"/>
1033
- <result property="counterAccountCode" column="相手勘定科目コード"/>
1034
- <result property="counterSubAccountCode" column="相手補助科目コード"/>
1035
- <result property="tagCode" column="付箋コード"/>
1036
- <result property="tagContent" column="付箋内容"/>
1037
- <result property="createdAt" column="作成日時"/>
1038
- <result property="updatedAt" column="更新日時"/>
1039
- </resultMap>
1040
-
1041
- <!-- 仕訳ヘッダ登録 -->
1042
- <insert id="insertJournal" parameterType="com.example.fas.domain.model.journal.Journal">
1043
- INSERT INTO "仕訳" (
1044
- "仕訳伝票番号", "起票日", "入力日", "決算仕訳フラグ", "単振フラグ",
1045
- "仕訳伝票区分", "定期計上フラグ", "社員コード", "部門コード",
1046
- "赤伝フラグ", "赤黒伝票番号", "作成日時", "更新日時"
1047
- ) VALUES (
1048
- #{journalVoucherNumber}, #{postingDate}, #{entryDate},
1049
- #{closingJournalFlag}, #{singleEntryFlag},
1050
- #{voucherType, typeHandler=com.example.fas.infrastructure.persistence.typehandler.JournalVoucherTypeHandler}::仕訳伝票区分,
1051
- #{periodicPostingFlag}, #{employeeCode}, #{departmentCode},
1052
- #{redSlipFlag}, #{redBlackVoucherNumber},
1053
- CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
1054
- )
1055
- </insert>
1056
-
1057
- <!-- 仕訳明細登録 -->
1058
- <insert id="insertJournalDetail" parameterType="com.example.fas.domain.model.journal.JournalDetail">
1059
- INSERT INTO "仕訳明細" (
1060
- "仕訳伝票番号", "仕訳行番号", "行摘要", "作成日時", "更新日時"
1061
- ) VALUES (
1062
- #{journalVoucherNumber}, #{lineNumber}, #{lineSummary},
1063
- CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
1064
- )
1065
- </insert>
1066
-
1067
- <!-- 仕訳貸借明細登録 -->
1068
- <insert id="insertJournalDebitCreditDetail" parameterType="com.example.fas.domain.model.journal.JournalDebitCreditDetail">
1069
- INSERT INTO "仕訳貸借明細" (
1070
- "仕訳伝票番号", "仕訳行番号", "仕訳行貸借区分",
1071
- "勘定科目コード", "補助科目コード", "部門コード", "プロジェクトコード",
1072
- "仕訳金額", "通貨コード", "為替レート", "基軸換算仕訳金額",
1073
- "消費税区分", "消費税率", "消費税計算区分",
1074
- "期日", "資金繰フラグ", "セグメントコード",
1075
- "相手勘定科目コード", "相手補助科目コード",
1076
- "付箋コード", "付箋内容", "作成日時", "更新日時"
1077
- ) VALUES (
1078
- #{journalVoucherNumber}, #{lineNumber},
1079
- #{debitCreditType, typeHandler=com.example.fas.infrastructure.persistence.typehandler.DebitCreditTypeHandler}::仕訳行貸借区分,
1080
- #{accountCode}, #{subAccountCode}, #{departmentCode}, #{projectCode},
1081
- #{amount}, #{currencyCode}, #{exchangeRate}, #{baseCurrencyAmount},
1082
- #{taxType, typeHandler=com.example.fas.infrastructure.persistence.typehandler.TaxTypeHandler}::消費税区分,
1083
- #{taxRate},
1084
- #{taxCalcType, typeHandler=com.example.fas.infrastructure.persistence.typehandler.TaxCalculationTypeHandler}::消費税計算区分,
1085
- #{dueDate}, #{cashFlowFlag}, #{segmentCode},
1086
- #{counterAccountCode}, #{counterSubAccountCode},
1087
- #{tagCode}, #{tagContent}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
1088
- )
1089
- </insert>
1090
-
1091
- <!-- 仕訳伝票番号で検索 -->
1092
- <select id="findByVoucherNumber" resultMap="JournalResultMap">
1093
- SELECT * FROM "仕訳"
1094
- WHERE "仕訳伝票番号" = #{voucherNumber}
1095
- </select>
1096
-
1097
- <!-- 仕訳明細検索 -->
1098
- <select id="findDetailsByVoucherNumber" resultMap="JournalDetailResultMap">
1099
- SELECT * FROM "仕訳明細"
1100
- WHERE "仕訳伝票番号" = #{voucherNumber}
1101
- ORDER BY "仕訳行番号"
1102
- </select>
1103
-
1104
- <!-- 仕訳貸借明細検索 -->
1105
- <select id="findDCDetailsByVoucherAndLine" resultMap="JournalDebitCreditDetailResultMap">
1106
- SELECT * FROM "仕訳貸借明細"
1107
- WHERE "仕訳伝票番号" = #{voucherNumber}
1108
- AND "仕訳行番号" = #{lineNumber}
1109
- </select>
1110
-
1111
- <!-- 起票日範囲で検索 -->
1112
- <select id="findVoucherNumbersByDateRange" resultType="String">
1113
- SELECT "仕訳伝票番号" FROM "仕訳"
1114
- WHERE "起票日" BETWEEN #{fromDate} AND #{toDate}
1115
- ORDER BY "仕訳伝票番号"
1116
- </select>
1117
-
1118
- <!-- 勘定科目コードで検索 -->
1119
- <select id="findVoucherNumbersByAccountCode" resultType="String">
1120
- SELECT DISTINCT "仕訳伝票番号" FROM "仕訳貸借明細"
1121
- WHERE "勘定科目コード" = #{accountCode}
1122
- ORDER BY "仕訳伝票番号"
1123
- </select>
1124
-
1125
- <!-- 削除 -->
1126
- <delete id="deleteJournal">
1127
- DELETE FROM "仕訳" WHERE "仕訳伝票番号" = #{voucherNumber}
1128
- </delete>
1129
-
1130
- <delete id="deleteAll">
1131
- TRUNCATE TABLE "仕訳" CASCADE
1132
- </delete>
1133
- </mapper>
1134
- ```
1135
-
1136
- </details>
1137
-
1138
- <details>
1139
- <summary>仕訳リポジトリ実装</summary>
1140
-
1141
- ```java
1142
- // src/main/java/com/example/accounting/infrastructure/persistence/repository/JournalRepositoryImpl.java
1143
- package com.example.fas.infrastructure.persistence.repository;
1144
-
1145
- import com.example.fas.application.port.out.JournalRepository;
1146
- import com.example.fas.domain.model.journal.Journal;
1147
- import com.example.fas.infrastructure.persistence.mapper.JournalMapper;
1148
- import lombok.RequiredArgsConstructor;
1149
- import org.springframework.stereotype.Repository;
1150
- import org.springframework.transaction.annotation.Transactional;
1151
-
1152
- import java.time.LocalDate;
1153
- import java.util.List;
1154
- import java.util.Optional;
1155
- import java.util.stream.Collectors;
1156
-
1157
- @Repository
1158
- @RequiredArgsConstructor
1159
- public class JournalRepositoryImpl implements JournalRepository {
1160
-
1161
- private final JournalMapper journalMapper;
1162
-
1163
- @Override
1164
- @Transactional
1165
- public void save(Journal journal) {
1166
- // 1. 仕訳ヘッダを登録
1167
- journalMapper.insertJournal(journal);
1168
-
1169
- // 2. 仕訳明細を登録
1170
- journal.getDetails().forEach(detail -> {
1171
- journalMapper.insertJournalDetail(detail);
1172
-
1173
- // 3. 仕訳貸借明細を登録
1174
- detail.getDebitCreditDetails().forEach(dcDetail -> {
1175
- journalMapper.insertJournalDebitCreditDetail(dcDetail);
1176
- });
1177
- });
1178
- }
1179
-
1180
- @Override
1181
- public Optional<Journal> findByVoucherNumber(String voucherNumber) {
1182
- return journalMapper.findByVoucherNumber(voucherNumber)
1183
- .map(journal -> {
1184
- var details = journalMapper.findDetailsByVoucherNumber(voucherNumber);
1185
- details.forEach(detail -> {
1186
- var dcDetails = journalMapper.findDCDetailsByVoucherAndLine(
1187
- voucherNumber, detail.getLineNumber());
1188
- detail.setDebitCreditDetails(dcDetails);
1189
- });
1190
- journal.setDetails(details);
1191
- return journal;
1192
- });
1193
- }
1194
-
1195
- @Override
1196
- public List<Journal> findByPostingDateBetween(LocalDate fromDate, LocalDate toDate) {
1197
- return journalMapper.findVoucherNumbersByDateRange(fromDate, toDate).stream()
1198
- .map(this::findByVoucherNumber)
1199
- .filter(Optional::isPresent)
1200
- .map(Optional::get)
1201
- .collect(Collectors.toList());
1202
- }
1203
-
1204
- @Override
1205
- public List<Journal> findByAccountCode(String accountCode) {
1206
- return journalMapper.findVoucherNumbersByAccountCode(accountCode).stream()
1207
- .map(this::findByVoucherNumber)
1208
- .filter(Optional::isPresent)
1209
- .map(Optional::get)
1210
- .collect(Collectors.toList());
1211
- }
1212
-
1213
- @Override
1214
- public List<Journal> findByDepartmentCode(String departmentCode) {
1215
- return journalMapper.findVoucherNumbersByDepartmentCode(departmentCode).stream()
1216
- .map(this::findByVoucherNumber)
1217
- .filter(Optional::isPresent)
1218
- .map(Optional::get)
1219
- .collect(Collectors.toList());
1220
- }
1221
-
1222
- @Override
1223
- @Transactional
1224
- public void delete(String voucherNumber) {
1225
- journalMapper.deleteJournal(voucherNumber);
1226
- }
1227
-
1228
- @Override
1229
- @Transactional
1230
- public void deleteAll() {
1231
- journalMapper.deleteAll();
1232
- }
1233
- }
1234
- ```
1235
-
1236
- </details>
1237
-
1238
- ---
1239
-
1240
- ## 16.4 リレーションと楽観ロックの設計
1241
-
1242
- ### MyBatis ネストした ResultMap によるリレーション設定
1243
-
1244
- 仕訳データは、仕訳(ヘッダ)→ 仕訳明細 → 仕訳貸借明細の3層構造を持ちます。MyBatis でこの親子関係を効率的に取得するためのリレーション設定を実装します。
1245
-
1246
- #### ネストした ResultMap の定義
1247
-
1248
- <details>
1249
- <summary>JournalMapper.xml(リレーション設定)</summary>
1250
-
1251
- ```xml
1252
- <?xml version="1.0" encoding="UTF-8" ?>
1253
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
1254
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
1255
-
1256
- <!-- src/main/resources/mapper/JournalMapper.xml -->
1257
- <mapper namespace="com.example.fas.infrastructure.persistence.mapper.JournalMapper">
1258
-
1259
- <!-- 仕訳(ヘッダ)の ResultMap(リレーション込み) -->
1260
- <resultMap id="journalWithDetailsResultMap" type="com.example.fas.domain.model.journal.Journal">
1261
- <id property="journalVoucherNumber" column="j_仕訳伝票番号"/>
1262
- <result property="postingDate" column="j_起票日"/>
1263
- <result property="entryDate" column="j_入力日"/>
1264
- <result property="closingJournalFlag" column="j_決算仕訳フラグ"/>
1265
- <result property="singleEntryFlag" column="j_単振フラグ"/>
1266
- <result property="voucherType" column="j_仕訳伝票区分"
1267
- typeHandler="com.example.fas.infrastructure.persistence.typehandler.JournalVoucherTypeHandler"/>
1268
- <result property="periodicPostingFlag" column="j_定期計上フラグ"/>
1269
- <result property="employeeCode" column="j_社員コード"/>
1270
- <result property="departmentCode" column="j_部門コード"/>
1271
- <result property="redSlipFlag" column="j_赤伝フラグ"/>
1272
- <result property="redBlackVoucherNumber" column="j_赤黒伝票番号"/>
1273
- <result property="version" column="j_バージョン"/>
1274
- <result property="createdAt" column="j_作成日時"/>
1275
- <result property="updatedAt" column="j_更新日時"/>
1276
- <!-- 仕訳明細との1:N関連 -->
1277
- <collection property="details" ofType="com.example.fas.domain.model.journal.JournalDetail"
1278
- resultMap="journalDetailNestedResultMap"/>
1279
- </resultMap>
1280
-
1281
- <!-- 仕訳明細のネスト ResultMap -->
1282
- <resultMap id="journalDetailNestedResultMap" type="com.example.fas.domain.model.journal.JournalDetail">
1283
- <id property="journalVoucherNumber" column="d_仕訳伝票番号"/>
1284
- <id property="lineNumber" column="d_仕訳行番号"/>
1285
- <result property="lineSummary" column="d_行摘要"/>
1286
- <result property="version" column="d_バージョン"/>
1287
- <result property="createdAt" column="d_作成日時"/>
1288
- <result property="updatedAt" column="d_更新日時"/>
1289
- <!-- 仕訳貸借明細との1:N関連 -->
1290
- <collection property="debitCreditDetails" ofType="com.example.fas.domain.model.journal.JournalDebitCreditDetail"
1291
- resultMap="journalDebitCreditDetailNestedResultMap"/>
1292
- </resultMap>
1293
-
1294
- <!-- 仕訳貸借明細のネスト ResultMap -->
1295
- <resultMap id="journalDebitCreditDetailNestedResultMap" type="com.example.fas.domain.model.journal.JournalDebitCreditDetail">
1296
- <id property="journalVoucherNumber" column="dc_仕訳伝票番号"/>
1297
- <id property="lineNumber" column="dc_仕訳行番号"/>
1298
- <id property="debitCreditType" column="dc_仕訳行貸借区分"
1299
- typeHandler="com.example.fas.infrastructure.persistence.typehandler.DebitCreditTypeHandler"/>
1300
- <result property="accountCode" column="dc_勘定科目コード"/>
1301
- <result property="subAccountCode" column="dc_補助科目コード"/>
1302
- <result property="departmentCode" column="dc_部門コード"/>
1303
- <result property="projectCode" column="dc_プロジェクトコード"/>
1304
- <result property="amount" column="dc_仕訳金額"/>
1305
- <result property="currencyCode" column="dc_通貨コード"/>
1306
- <result property="exchangeRate" column="dc_為替レート"/>
1307
- <result property="baseCurrencyAmount" column="dc_基軸換算仕訳金額"/>
1308
- <result property="taxType" column="dc_消費税区分"
1309
- typeHandler="com.example.fas.infrastructure.persistence.typehandler.TaxTypeHandler"/>
1310
- <result property="taxRate" column="dc_消費税率"/>
1311
- <result property="taxCalcType" column="dc_消費税計算区分"
1312
- typeHandler="com.example.fas.infrastructure.persistence.typehandler.TaxCalculationTypeHandler"/>
1313
- <result property="dueDate" column="dc_期日"/>
1314
- <result property="cashFlowFlag" column="dc_資金繰フラグ"/>
1315
- <result property="segmentCode" column="dc_セグメントコード"/>
1316
- <result property="counterAccountCode" column="dc_相手勘定科目コード"/>
1317
- <result property="counterSubAccountCode" column="dc_相手補助科目コード"/>
1318
- <result property="tagCode" column="dc_付箋コード"/>
1319
- <result property="tagContent" column="dc_付箋内容"/>
1320
- <result property="version" column="dc_バージョン"/>
1321
- <result property="createdAt" column="dc_作成日時"/>
1322
- <result property="updatedAt" column="dc_更新日時"/>
1323
- </resultMap>
1324
-
1325
- <!-- JOIN による一括取得クエリ(3層構造) -->
1326
- <select id="findWithDetailsByVoucherNumber" resultMap="journalWithDetailsResultMap">
1327
- SELECT
1328
- j."仕訳伝票番号" AS j_仕訳伝票番号,
1329
- j."起票日" AS j_起票日,
1330
- j."入力日" AS j_入力日,
1331
- j."決算仕訳フラグ" AS j_決算仕訳フラグ,
1332
- j."単振フラグ" AS j_単振フラグ,
1333
- j."仕訳伝票区分" AS j_仕訳伝票区分,
1334
- j."定期計上フラグ" AS j_定期計上フラグ,
1335
- j."社員コード" AS j_社員コード,
1336
- j."部門コード" AS j_部門コード,
1337
- j."赤伝フラグ" AS j_赤伝フラグ,
1338
- j."赤黒伝票番号" AS j_赤黒伝票番号,
1339
- j."バージョン" AS j_バージョン,
1340
- j."作成日時" AS j_作成日時,
1341
- j."更新日時" AS j_更新日時,
1342
- d."仕訳伝票番号" AS d_仕訳伝票番号,
1343
- d."仕訳行番号" AS d_仕訳行番号,
1344
- d."行摘要" AS d_行摘要,
1345
- d."バージョン" AS d_バージョン,
1346
- d."作成日時" AS d_作成日時,
1347
- d."更新日時" AS d_更新日時,
1348
- dc."仕訳伝票番号" AS dc_仕訳伝票番号,
1349
- dc."仕訳行番号" AS dc_仕訳行番号,
1350
- dc."仕訳行貸借区分" AS dc_仕訳行貸借区分,
1351
- dc."勘定科目コード" AS dc_勘定科目コード,
1352
- dc."補助科目コード" AS dc_補助科目コード,
1353
- dc."部門コード" AS dc_部門コード,
1354
- dc."プロジェクトコード" AS dc_プロジェクトコード,
1355
- dc."仕訳金額" AS dc_仕訳金額,
1356
- dc."通貨コード" AS dc_通貨コード,
1357
- dc."為替レート" AS dc_為替レート,
1358
- dc."基軸換算仕訳金額" AS dc_基軸換算仕訳金額,
1359
- dc."消費税区分" AS dc_消費税区分,
1360
- dc."消費税率" AS dc_消費税率,
1361
- dc."消費税計算区分" AS dc_消費税計算区分,
1362
- dc."期日" AS dc_期日,
1363
- dc."資金繰フラグ" AS dc_資金繰フラグ,
1364
- dc."セグメントコード" AS dc_セグメントコード,
1365
- dc."相手勘定科目コード" AS dc_相手勘定科目コード,
1366
- dc."相手補助科目コード" AS dc_相手補助科目コード,
1367
- dc."付箋コード" AS dc_付箋コード,
1368
- dc."付箋内容" AS dc_付箋内容,
1369
- dc."バージョン" AS dc_バージョン,
1370
- dc."作成日時" AS dc_作成日時,
1371
- dc."更新日時" AS dc_更新日時
1372
- FROM "仕訳" j
1373
- LEFT JOIN "仕訳明細" d ON j."仕訳伝票番号" = d."仕訳伝票番号"
1374
- LEFT JOIN "仕訳貸借明細" dc ON d."仕訳伝票番号" = dc."仕訳伝票番号"
1375
- AND d."仕訳行番号" = dc."仕訳行番号"
1376
- WHERE j."仕訳伝票番号" = #{voucherNumber}
1377
- ORDER BY d."仕訳行番号", dc."仕訳行貸借区分"
1378
- </select>
1379
-
1380
- </mapper>
1381
- ```
1382
-
1383
- </details>
1384
-
1385
- #### リレーション設定のポイント
1386
-
1387
- | 設定項目 | 説明 |
1388
- |---------|------|
1389
- | `<collection>` | 1:N 関連のマッピング |
1390
- | `<id>` | 主キーの識別(MyBatis が重複排除に使用) |
1391
- | 複合主キー | 仕訳明細・仕訳貸借明細は複数の `<id>` で複合主キーを表現 |
1392
- | `resultMap` | ネストした ResultMap の参照 |
1393
- | エイリアス(AS) | カラム名の重複を避けるためのプレフィックス(j_, d_, dc_) |
1394
- | `ORDER BY` | コレクションの順序を保証 |
1395
-
1396
- ### 楽観ロックの実装
1397
-
1398
- 複数ユーザーが同時に仕訳データを編集する場合、データの整合性を保つために楽観ロック(Optimistic Locking)を実装します。
1399
-
1400
- #### Flyway マイグレーション: バージョンカラム追加
1401
-
1402
- <details>
1403
- <summary>V006__add_journal_version_columns.sql</summary>
1404
-
1405
- ```sql
1406
- -- src/main/resources/db/migration/V006__add_journal_version_columns.sql
1407
-
1408
- -- 仕訳テーブルにバージョンカラムを追加
1409
- ALTER TABLE "仕訳" ADD COLUMN "バージョン" INTEGER DEFAULT 1 NOT NULL;
1410
-
1411
- -- 仕訳明細テーブルにバージョンカラムを追加
1412
- ALTER TABLE "仕訳明細" ADD COLUMN "バージョン" INTEGER DEFAULT 1 NOT NULL;
1413
-
1414
- -- 仕訳貸借明細テーブルにバージョンカラムを追加
1415
- ALTER TABLE "仕訳貸借明細" ADD COLUMN "バージョン" INTEGER DEFAULT 1 NOT NULL;
1416
-
1417
- -- コメント追加
1418
- COMMENT ON COLUMN "仕訳"."バージョン" IS '楽観ロック用バージョン番号';
1419
- COMMENT ON COLUMN "仕訳明細"."バージョン" IS '楽観ロック用バージョン番号';
1420
- COMMENT ON COLUMN "仕訳貸借明細"."バージョン" IS '楽観ロック用バージョン番号';
1421
- ```
1422
-
1423
- </details>
1424
-
1425
- #### エンティティへのバージョンフィールド追加
1426
-
1427
- <details>
1428
- <summary>Journal.java(バージョンフィールド追加)</summary>
1429
-
1430
- ```java
1431
- // src/main/java/com/example/fas/domain/model/journal/Journal.java
1432
- package com.example.fas.domain.model.journal;
1433
-
1434
- import lombok.AllArgsConstructor;
1435
- import lombok.Builder;
1436
- import lombok.Data;
1437
- import lombok.NoArgsConstructor;
1438
-
1439
- import java.math.BigDecimal;
1440
- import java.time.LocalDate;
1441
- import java.time.LocalDateTime;
1442
- import java.util.ArrayList;
1443
- import java.util.List;
1444
-
1445
- @Data
1446
- @Builder
1447
- @NoArgsConstructor
1448
- @AllArgsConstructor
1449
- public class Journal {
1450
- private String journalVoucherNumber; // 仕訳伝票番号
1451
- private LocalDate postingDate; // 起票日
1452
- private LocalDate entryDate; // 入力日
1453
- private Boolean closingJournalFlag; // 決算仕訳フラグ
1454
- private Boolean singleEntryFlag; // 単振フラグ
1455
- private JournalVoucherType voucherType; // 仕訳伝票区分
1456
- private Boolean periodicPostingFlag; // 定期計上フラグ
1457
- private String employeeCode; // 社員コード
1458
- private String departmentCode; // 部門コード
1459
- private Boolean redSlipFlag; // 赤伝フラグ
1460
- private Integer redBlackVoucherNumber; // 赤黒伝票番号
1461
- private LocalDateTime createdAt; // 作成日時
1462
- private LocalDateTime updatedAt; // 更新日時
1463
-
1464
- // 楽観ロック用バージョン
1465
- @Builder.Default
1466
- private Integer version = 1;
1467
-
1468
- // リレーション
1469
- @Builder.Default
1470
- private List<JournalDetail> details = new ArrayList<>();
1471
-
1472
- // 以下、既存のビジネスロジック...
1473
- }
1474
- ```
1475
-
1476
- </details>
1477
-
1478
- #### MyBatis Mapper: 楽観ロック対応の更新
1479
-
1480
- <details>
1481
- <summary>JournalMapper.xml(楽観ロック対応 UPDATE)</summary>
1482
-
1483
- ```xml
1484
- <!-- 楽観ロック対応の更新(バージョンチェック付き) -->
1485
- <update id="updateWithOptimisticLock" parameterType="com.example.fas.domain.model.journal.Journal">
1486
- UPDATE "仕訳"
1487
- SET
1488
- "起票日" = #{postingDate},
1489
- "入力日" = #{entryDate},
1490
- "決算仕訳フラグ" = #{closingJournalFlag},
1491
- "単振フラグ" = #{singleEntryFlag},
1492
- "仕訳伝票区分" = #{voucherType, typeHandler=com.example.fas.infrastructure.persistence.typehandler.JournalVoucherTypeHandler}::仕訳伝票区分,
1493
- "定期計上フラグ" = #{periodicPostingFlag},
1494
- "社員コード" = #{employeeCode},
1495
- "部門コード" = #{departmentCode},
1496
- "赤伝フラグ" = #{redSlipFlag},
1497
- "赤黒伝票番号" = #{redBlackVoucherNumber},
1498
- "更新日時" = CURRENT_TIMESTAMP,
1499
- "バージョン" = "バージョン" + 1
1500
- WHERE "仕訳伝票番号" = #{journalVoucherNumber}
1501
- AND "バージョン" = #{version}
1502
- </update>
1503
-
1504
- <!-- バージョンのみ取得 -->
1505
- <select id="findVersionByVoucherNumber" resultType="Integer">
1506
- SELECT "バージョン" FROM "仕訳"
1507
- WHERE "仕訳伝票番号" = #{voucherNumber}
1508
- </select>
1509
- ```
1510
-
1511
- </details>
1512
-
1513
- #### 楽観ロック例外クラス
1514
-
1515
- <details>
1516
- <summary>OptimisticLockException.java</summary>
1517
-
1518
- ```java
1519
- // src/main/java/com/example/fas/domain/exception/OptimisticLockException.java
1520
- package com.example.fas.domain.exception;
1521
-
1522
- public class OptimisticLockException extends RuntimeException {
1523
-
1524
- private final String entityName;
1525
- private final String entityId;
1526
- private final Integer expectedVersion;
1527
- private final Integer actualVersion;
1528
-
1529
- public OptimisticLockException(String entityName, String entityId) {
1530
- super(String.format("%s (ID: %s) は既に削除されています", entityName, entityId));
1531
- this.entityName = entityName;
1532
- this.entityId = entityId;
1533
- this.expectedVersion = null;
1534
- this.actualVersion = null;
1535
- }
1536
-
1537
- public OptimisticLockException(String entityName, String entityId,
1538
- Integer expectedVersion, Integer actualVersion) {
1539
- super(String.format("%s (ID: %s) は他のユーザーによって更新されています。" +
1540
- "期待バージョン: %d, 実際のバージョン: %d",
1541
- entityName, entityId, expectedVersion, actualVersion));
1542
- this.entityName = entityName;
1543
- this.entityId = entityId;
1544
- this.expectedVersion = expectedVersion;
1545
- this.actualVersion = actualVersion;
1546
- }
1547
-
1548
- public String getEntityName() {
1549
- return entityName;
1550
- }
1551
-
1552
- public String getEntityId() {
1553
- return entityId;
1554
- }
1555
-
1556
- public Integer getExpectedVersion() {
1557
- return expectedVersion;
1558
- }
1559
-
1560
- public Integer getActualVersion() {
1561
- return actualVersion;
1562
- }
1563
- }
1564
- ```
1565
-
1566
- </details>
1567
-
1568
- #### Repository 実装: 楽観ロック対応
1569
-
1570
- <details>
1571
- <summary>JournalRepositoryImpl.java(楽観ロック対応)</summary>
1572
-
1573
- ```java
1574
- // src/main/java/com/example/fas/infrastructure/persistence/repository/JournalRepositoryImpl.java
1575
- package com.example.fas.infrastructure.persistence.repository;
1576
-
1577
- import com.example.fas.application.port.out.JournalRepository;
1578
- import com.example.fas.domain.exception.OptimisticLockException;
1579
- import com.example.fas.domain.model.journal.Journal;
1580
- import com.example.fas.infrastructure.persistence.mapper.JournalMapper;
1581
- import lombok.RequiredArgsConstructor;
1582
- import org.springframework.stereotype.Repository;
1583
- import org.springframework.transaction.annotation.Transactional;
1584
-
1585
- import java.time.LocalDate;
1586
- import java.util.List;
1587
- import java.util.Optional;
1588
- import java.util.stream.Collectors;
1589
-
1590
- @Repository
1591
- @RequiredArgsConstructor
1592
- public class JournalRepositoryImpl implements JournalRepository {
1593
-
1594
- private final JournalMapper journalMapper;
1595
-
1596
- @Override
1597
- @Transactional
1598
- public void update(Journal journal) {
1599
- int updatedCount = journalMapper.updateWithOptimisticLock(journal);
1600
-
1601
- if (updatedCount == 0) {
1602
- // バージョン不一致または削除済み
1603
- Integer currentVersion = journalMapper.findVersionByVoucherNumber(
1604
- journal.getJournalVoucherNumber());
1605
- if (currentVersion == null) {
1606
- throw new OptimisticLockException("仕訳", journal.getJournalVoucherNumber());
1607
- } else {
1608
- throw new OptimisticLockException("仕訳", journal.getJournalVoucherNumber(),
1609
- journal.getVersion(), currentVersion);
1610
- }
1611
- }
1612
- }
1613
-
1614
- @Override
1615
- public Optional<Journal> findByVoucherNumberWithDetails(String voucherNumber) {
1616
- return Optional.ofNullable(journalMapper.findWithDetailsByVoucherNumber(voucherNumber));
1617
- }
1618
-
1619
- // その他のメソッド...
1620
- }
1621
- ```
1622
-
1623
- </details>
1624
-
1625
- #### TDD: 楽観ロックのテスト
1626
-
1627
- <details>
1628
- <summary>JournalRepositoryOptimisticLockTest.java</summary>
1629
-
1630
- ```java
1631
- // src/test/java/com/example/fas/infrastructure/persistence/repository/JournalRepositoryOptimisticLockTest.java
1632
- package com.example.fas.infrastructure.persistence.repository;
1633
-
1634
- import com.example.fas.application.port.out.JournalRepository;
1635
- import com.example.fas.domain.exception.OptimisticLockException;
1636
- import com.example.fas.domain.model.account.DebitCreditType;
1637
- import com.example.fas.domain.model.journal.*;
1638
- import com.example.fas.testsetup.BaseIntegrationTest;
1639
- import org.junit.jupiter.api.*;
1640
- import org.springframework.beans.factory.annotation.Autowired;
1641
-
1642
- import java.math.BigDecimal;
1643
- import java.time.LocalDate;
1644
- import java.util.List;
1645
-
1646
- import static org.assertj.core.api.Assertions.*;
1647
-
1648
- @DisplayName("仕訳リポジトリ - 楽観ロック")
1649
- class JournalRepositoryOptimisticLockTest extends BaseIntegrationTest {
1650
-
1651
- @Autowired
1652
- private JournalRepository journalRepository;
1653
-
1654
- @BeforeEach
1655
- void setUp() {
1656
- journalRepository.deleteAll();
1657
- }
1658
-
1659
- @Nested
1660
- @DisplayName("楽観ロック")
1661
- class OptimisticLocking {
1662
-
1663
- @Test
1664
- @DisplayName("同じバージョンで更新できる")
1665
- void canUpdateWithSameVersion() {
1666
- // Arrange
1667
- var journal = createTestJournal("J0001");
1668
- journalRepository.save(journal);
1669
-
1670
- // Act
1671
- var fetched = journalRepository.findByVoucherNumber("J0001").get();
1672
- fetched.setDepartmentCode("DEPT-002");
1673
- journalRepository.update(fetched);
1674
-
1675
- // Assert
1676
- var updated = journalRepository.findByVoucherNumber("J0001").get();
1677
- assertThat(updated.getDepartmentCode()).isEqualTo("DEPT-002");
1678
- assertThat(updated.getVersion()).isEqualTo(2); // バージョンがインクリメント
1679
- }
1680
-
1681
- @Test
1682
- @DisplayName("異なるバージョンで更新すると楽観ロック例外が発生する")
1683
- void throwsExceptionWhenVersionMismatch() {
1684
- // Arrange
1685
- var journal = createTestJournal("J0002");
1686
- journalRepository.save(journal);
1687
-
1688
- // ユーザーAが取得
1689
- var journalA = journalRepository.findByVoucherNumber("J0002").get();
1690
- // ユーザーBが取得
1691
- var journalB = journalRepository.findByVoucherNumber("J0002").get();
1692
-
1693
- // ユーザーAが更新(成功)
1694
- journalA.setDepartmentCode("DEPT-A");
1695
- journalRepository.update(journalA);
1696
-
1697
- // Act & Assert: ユーザーBが古いバージョンで更新(失敗)
1698
- journalB.setDepartmentCode("DEPT-B");
1699
- assertThatThrownBy(() -> journalRepository.update(journalB))
1700
- .isInstanceOf(OptimisticLockException.class)
1701
- .hasMessageContaining("他のユーザーによって更新されています");
1702
- }
1703
-
1704
- @Test
1705
- @DisplayName("削除済みデータを更新すると楽観ロック例外が発生する")
1706
- void throwsExceptionWhenAlreadyDeleted() {
1707
- // Arrange
1708
- var journal = createTestJournal("J0003");
1709
- journalRepository.save(journal);
1710
-
1711
- var fetched = journalRepository.findByVoucherNumber("J0003").get();
1712
- journalRepository.delete("J0003");
1713
-
1714
- // Act & Assert
1715
- assertThatThrownBy(() -> journalRepository.update(fetched))
1716
- .isInstanceOf(OptimisticLockException.class)
1717
- .hasMessageContaining("既に削除されています");
1718
- }
1719
- }
1720
-
1721
- private Journal createTestJournal(String voucherNumber) {
1722
- var debitDetail = JournalDebitCreditDetail.builder()
1723
- .journalVoucherNumber(voucherNumber)
1724
- .lineNumber(1)
1725
- .debitCreditType(DebitCreditType.DEBIT)
1726
- .accountCode("11110")
1727
- .amount(new BigDecimal("100000"))
1728
- .build();
1729
-
1730
- var creditDetail = JournalDebitCreditDetail.builder()
1731
- .journalVoucherNumber(voucherNumber)
1732
- .lineNumber(1)
1733
- .debitCreditType(DebitCreditType.CREDIT)
1734
- .accountCode("41100")
1735
- .amount(new BigDecimal("100000"))
1736
- .build();
1737
-
1738
- var journalDetail = JournalDetail.builder()
1739
- .journalVoucherNumber(voucherNumber)
1740
- .lineNumber(1)
1741
- .lineSummary("テスト仕訳")
1742
- .debitCreditDetails(List.of(debitDetail, creditDetail))
1743
- .build();
1744
-
1745
- return Journal.builder()
1746
- .journalVoucherNumber(voucherNumber)
1747
- .postingDate(LocalDate.of(2024, 4, 1))
1748
- .entryDate(LocalDate.now())
1749
- .closingJournalFlag(false)
1750
- .singleEntryFlag(true)
1751
- .voucherType(JournalVoucherType.NORMAL)
1752
- .periodicPostingFlag(false)
1753
- .departmentCode("DEPT-001")
1754
- .redSlipFlag(false)
1755
- .details(List.of(journalDetail))
1756
- .build();
1757
- }
1758
- }
1759
- ```
1760
-
1761
- </details>
1762
-
1763
- #### 楽観ロックのベストプラクティス
1764
-
1765
- | ポイント | 説明 |
1766
- |---------|------|
1767
- | **バージョンカラム** | INTEGER 型で十分(オーバーフローは実用上問題なし) |
1768
- | **WHERE 条件** | 必ず `AND "バージョン" = #{version}` を含める |
1769
- | **インクリメント** | `"バージョン" = "バージョン" + 1` でアトミックに更新 |
1770
- | **例外処理** | 更新件数が0の場合は楽観ロック例外をスロー |
1771
- | **リトライ** | 必要に応じて再取得・再更新のリトライロジックを実装 |
1772
- | **3層構造の考慮** | 仕訳は通常ヘッダ単位でロック、明細の個別ロックは必要に応じて追加 |
1773
-
1774
- ### 3層構造におけるリレーションと整合性
1775
-
1776
- 仕訳データは3層構造(仕訳 → 仕訳明細 → 仕訳貸借明細)を持つため、更新時の整合性確保が重要です。
1777
-
1778
- #### 更新パターン
1779
-
1780
- | パターン | 説明 | 推奨 |
1781
- |---------|------|------|
1782
- | **ヘッダ単位ロック** | 仕訳ヘッダのバージョンのみチェック | ○ シンプルで実用的 |
1783
- | **全層ロック** | 仕訳・明細・貸借明細すべてのバージョンをチェック | △ 複雑だが厳密 |
1784
- | **カスケード更新** | ヘッダ更新時に明細も一括削除・再挿入 | △ 実装が簡単だが履歴管理に注意 |
1785
-
1786
- #### 推奨アプローチ
1787
-
1788
- 仕訳データは通常、伝票単位で一括編集されるため、**ヘッダ単位ロック**が推奨されます。明細の部分更新が必要な場合は、明細レベルのバージョンチェックを追加します。
1789
-
1790
- ```plantuml
1791
- @startuml
1792
-
1793
- title 仕訳更新の楽観ロックフロー
1794
-
1795
- actor ユーザーA
1796
- actor ユーザーB
1797
- database DB
1798
-
1799
- == 取得フェーズ ==
1800
- ユーザーA -> DB : 仕訳J0001取得
1801
- DB --> ユーザーA : Journal(version=1)
1802
- ユーザーB -> DB : 仕訳J0001取得
1803
- DB --> ユーザーB : Journal(version=1)
1804
-
1805
- == 更新フェーズ ==
1806
- ユーザーA -> DB : UPDATE WHERE version=1
1807
- DB --> ユーザーA : 更新成功 (version=2)
1808
-
1809
- ユーザーB -> DB : UPDATE WHERE version=1
1810
- DB --> ユーザーB : 更新件数=0
1811
- ユーザーB -> ユーザーB : OptimisticLockException
1812
-
1813
- @enduml
1814
- ```
1815
-
1816
- ---
1817
-
1818
- ## 第16章のまとめ
1819
-
1820
- ### 作成したテーブル
1821
-
1822
- | テーブル名 | 説明 |
1823
- |----------|------|
1824
- | `仕訳` | 仕訳伝票のヘッダ情報(起票日、入力日、各種フラグ) |
1825
- | `仕訳明細` | 仕訳の行単位の情報(行摘要) |
1826
- | `仕訳貸借明細` | 借方・貸方の詳細(勘定科目、金額、補助情報) |
1827
-
1828
- ### ER図
1829
-
1830
- ```plantuml
1831
- @startuml
1832
-
1833
- title 仕訳テーブル ER図
1834
-
1835
- entity 仕訳 {
1836
- 仕訳伝票番号 <<PK>>
1837
- --
1838
- 起票日
1839
- 入力日
1840
- 決算仕訳フラグ
1841
- 単振フラグ
1842
- 仕訳伝票区分
1843
- 定期計上フラグ
1844
- 社員コード
1845
- 部門コード
1846
- 赤伝フラグ
1847
- 赤黒伝票番号
1848
- 作成日時
1849
- 更新日時
1850
- }
1851
-
1852
- entity 仕訳明細 {
1853
- 仕訳伝票番号 <<PK,FK>>
1854
- 仕訳行番号 <<PK>>
1855
- --
1856
- 行摘要
1857
- 作成日時
1858
- 更新日時
1859
- }
1860
-
1861
- entity 仕訳貸借明細 {
1862
- 仕訳伝票番号 <<PK,FK>>
1863
- 仕訳行番号 <<PK>>
1864
- 仕訳行貸借区分 <<PK>>
1865
- --
1866
- 勘定科目コード <<FK>>
1867
- 補助科目コード
1868
- 部門コード <<FK>>
1869
- プロジェクトコード
1870
- 仕訳金額
1871
- 通貨コード
1872
- 為替レート
1873
- 基軸換算仕訳金額
1874
- 消費税区分
1875
- 消費税率
1876
- 消費税計算区分
1877
- 期日
1878
- ...
1879
- }
1880
-
1881
- entity 勘定科目マスタ {
1882
- 勘定科目コード <<PK>>
1883
- --
1884
- ...
1885
- }
1886
-
1887
- entity 部門マスタ {
1888
- 部門コード <<PK>>
1889
- --
1890
- ...
1891
- }
1892
-
1893
- 仕訳 ||--o{ 仕訳明細 : "含む"
1894
- 仕訳明細 ||--o{ 仕訳貸借明細 : "含む"
1895
- 仕訳貸借明細 }o..|| 勘定科目マスタ : "参照"
1896
- 仕訳貸借明細 }o..o| 部門マスタ : "参照"
1897
- 仕訳 }o..o| 部門マスタ : "参照"
1898
-
1899
- @enduml
1900
- ```
1901
-
1902
- ### 設計のポイント
1903
-
1904
- 1. **3階層構造**: 仕訳 → 仕訳明細 → 仕訳貸借明細の親子関係
1905
- 2. **複式簿記の原則**: 借方合計 = 貸方合計の貸借一致チェック
1906
- 3. **単一仕訳と複合仕訳**: 単振フラグで区別
1907
- 4. **赤黒処理対応**: 赤伝フラグと赤黒伝票番号で訂正履歴を管理
1908
- 5. **多通貨対応**: 通貨コード、為替レート、基軸換算金額
1909
- 6. **消費税対応**: 消費税区分、消費税率、消費税計算区分
1910
- 7. **管理会計対応**: 部門コード、プロジェクトコード、セグメントコード
1911
-
1912
- ### ドメインロジック
1913
-
1914
- | メソッド | 説明 |
1915
- |---------|------|
1916
- | `isBalanced()` | 借方合計と貸方合計が一致するかチェック |
1917
- | `getDebitTotal()` | 借方合計を取得 |
1918
- | `getCreditTotal()` | 貸方合計を取得 |
1919
-
1920
- ---
1921
-
1922
- ## 次章の予告
1923
-
1924
- 第17章では、自動仕訳の設計に進みます。販売管理システムと会計システムの連携、自動仕訳パターンマスタの設計、売上伝票から仕訳伝票への転記ロジックを TDD で実装していきます。