@k2works/claude-code-booster 4.7.0 → 4.9.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 (745) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +42 -42
  3. package/bin/claude-code-booster +90 -90
  4. package/lib/assets/.claude/README.md +275 -269
  5. package/lib/assets/.claude/agents/xp-architect.md +250 -250
  6. package/lib/assets/.claude/agents/xp-executive.md +207 -207
  7. package/lib/assets/.claude/agents/xp-interaction-designer.md +239 -239
  8. package/lib/assets/.claude/agents/xp-product-manager.md +245 -245
  9. package/lib/assets/.claude/agents/xp-programmer.md +268 -268
  10. package/lib/assets/.claude/agents/xp-project-manager.md +229 -229
  11. package/lib/assets/.claude/agents/xp-technical-writer.md +224 -224
  12. package/lib/assets/.claude/agents/xp-tester.md +265 -265
  13. package/lib/assets/.claude/agents/xp-user-representative.md +204 -204
  14. package/lib/assets/.claude/scripts/generate-inception-deck.mjs +911 -911
  15. package/lib/assets/.claude/settings.json +11 -11
  16. package/lib/assets/.claude/skills/ai-agent-guidelines/SKILL.md +111 -111
  17. package/lib/assets/.claude/skills/analyzing-architecture/SKILL.md +83 -83
  18. package/lib/assets/.claude/skills/analyzing-business-architecture/SKILL.md +122 -122
  19. package/lib/assets/.claude/skills/analyzing-business-case/SKILL.md +148 -148
  20. package/lib/assets/.claude/skills/analyzing-business-strategy/SKILL.md +277 -277
  21. package/lib/assets/.claude/skills/analyzing-data-model/SKILL.md +77 -77
  22. package/lib/assets/.claude/skills/analyzing-domain-model/SKILL.md +117 -117
  23. package/lib/assets/.claude/skills/analyzing-inception-deck/SKILL.md +84 -84
  24. package/lib/assets/.claude/skills/analyzing-non-functional/SKILL.md +95 -95
  25. package/lib/assets/.claude/skills/analyzing-operation/SKILL.md +95 -95
  26. package/lib/assets/.claude/skills/analyzing-requirements/SKILL.md +91 -91
  27. package/lib/assets/.claude/skills/analyzing-review/SKILL.md +174 -174
  28. package/lib/assets/.claude/skills/analyzing-tech-stack/SKILL.md +101 -101
  29. package/lib/assets/.claude/skills/analyzing-test-strategy/SKILL.md +89 -89
  30. package/lib/assets/.claude/skills/analyzing-ui-design/SKILL.md +80 -80
  31. package/lib/assets/.claude/skills/analyzing-usecases/SKILL.md +72 -72
  32. package/lib/assets/.claude/skills/creating-adr/SKILL.md +113 -113
  33. package/lib/assets/.claude/skills/creating-iteration-report/SKILL.md +210 -210
  34. package/lib/assets/.claude/skills/creating-journal/SKILL.md +129 -0
  35. package/lib/assets/.claude/skills/creating-release-report/SKILL.md +161 -161
  36. package/lib/assets/.claude/skills/creating-slides/SKILL.md +86 -86
  37. package/lib/assets/.claude/skills/creating-slides/agents/openai.yaml +4 -4
  38. package/lib/assets/.claude/skills/creating-slides/references/manga-css.md +45 -45
  39. package/lib/assets/.claude/skills/creating-slides/scripts/slide_tools.py +239 -239
  40. package/lib/assets/.claude/skills/developing-backend/SKILL.md +100 -100
  41. package/lib/assets/.claude/skills/developing-frontend/SKILL.md +93 -93
  42. package/lib/assets/.claude/skills/developing-release/SKILL.md +120 -120
  43. package/lib/assets/.claude/skills/developing-review/SKILL.md +175 -175
  44. package/lib/assets/.claude/skills/developing-uiux-review/SKILL.md +207 -207
  45. package/lib/assets/.claude/skills/generating-bmc/SKILL.md +123 -123
  46. package/lib/assets/.claude/skills/generating-slides/SKILL.md +94 -94
  47. package/lib/assets/.claude/skills/git-commit/SKILL.md +81 -81
  48. package/lib/assets/.claude/skills/killing-processes/SKILL.md +44 -44
  49. package/lib/assets/.claude/skills/operating-backup/SKILL.md +59 -59
  50. package/lib/assets/.claude/skills/operating-cicd/SKILL.md +54 -54
  51. package/lib/assets/.claude/skills/operating-deploy/SKILL.md +67 -67
  52. package/lib/assets/.claude/skills/operating-docs/SKILL.md +219 -219
  53. package/lib/assets/.claude/skills/operating-provision/SKILL.md +77 -77
  54. package/lib/assets/.claude/skills/operating-qt/SKILL.md +147 -147
  55. package/lib/assets/.claude/skills/operating-review/SKILL.md +171 -171
  56. package/lib/assets/.claude/skills/operating-script/SKILL.md +145 -145
  57. package/lib/assets/.claude/skills/operating-setup/SKILL.md +63 -63
  58. package/lib/assets/.claude/skills/orchestrating-analysis/SKILL.md +104 -104
  59. package/lib/assets/.claude/skills/orchestrating-development/SKILL.md +168 -168
  60. package/lib/assets/.claude/skills/orchestrating-operation/SKILL.md +158 -158
  61. package/lib/assets/.claude/skills/orchestrating-project/SKILL.md +144 -144
  62. package/lib/assets/.claude/skills/planning-releases/SKILL.md +119 -119
  63. package/lib/assets/.claude/skills/practicing-getting-start-tdd/SKILL.md +266 -266
  64. package/lib/assets/.claude/skills/syncing-github-project/SKILL.md +151 -151
  65. package/lib/assets/.claude/skills/tracking-progress/SKILL.md +91 -91
  66. package/lib/assets/.claude/skills/validating-iteration-plan/SKILL.md +238 -238
  67. package/lib/assets/.claude/skills/validating-operating-setup/SKILL.md +118 -0
  68. package/lib/assets/.devcontainer/devcontainer.json +37 -37
  69. package/lib/assets/.env.example +17 -17
  70. package/lib/assets/.gitattributes +4 -4
  71. package/lib/assets/.github/workflows/docker-publish.yml +77 -77
  72. package/lib/assets/.github/workflows/mkdocs.yml +39 -39
  73. package/lib/assets/AGENTS.md +94 -94
  74. package/lib/assets/CLAUDE.md +193 -193
  75. package/lib/assets/README.md +291 -291
  76. package/lib/assets/docker-compose.yml +33 -33
  77. package/lib/assets/docs/adr/index.md +10 -10
  78. package/lib/assets/docs/article/functional-desgin-ppp/all/01-immutability-and-data-transformation.md +475 -475
  79. package/lib/assets/docs/article/functional-desgin-ppp/all/02-function-composition.md +519 -519
  80. package/lib/assets/docs/article/functional-desgin-ppp/all/03-polymorphism.md +537 -537
  81. package/lib/assets/docs/article/functional-desgin-ppp/all/04-data-validation.md +300 -300
  82. package/lib/assets/docs/article/functional-desgin-ppp/all/05-property-based-testing.md +320 -320
  83. package/lib/assets/docs/article/functional-desgin-ppp/all/06-tdd-and-functional.md +498 -498
  84. package/lib/assets/docs/article/functional-desgin-ppp/all/07-composite-pattern.md +298 -298
  85. package/lib/assets/docs/article/functional-desgin-ppp/all/08-decorator-pattern.md +291 -291
  86. package/lib/assets/docs/article/functional-desgin-ppp/all/09-adapter-pattern.md +336 -336
  87. package/lib/assets/docs/article/functional-desgin-ppp/all/10-strategy-pattern.md +303 -303
  88. package/lib/assets/docs/article/functional-desgin-ppp/all/11-command-pattern.md +286 -286
  89. package/lib/assets/docs/article/functional-desgin-ppp/all/12-visitor-pattern.md +322 -322
  90. package/lib/assets/docs/article/functional-desgin-ppp/all/13-abstract-factory-pattern.md +319 -319
  91. package/lib/assets/docs/article/functional-desgin-ppp/all/14-abstract-server-pattern.md +365 -365
  92. package/lib/assets/docs/article/functional-desgin-ppp/all/15-gossiping-bus-drivers.md +156 -156
  93. package/lib/assets/docs/article/functional-desgin-ppp/all/16-payroll-system.md +178 -178
  94. package/lib/assets/docs/article/functional-desgin-ppp/all/17-video-rental-system.md +312 -312
  95. package/lib/assets/docs/article/functional-desgin-ppp/all/18-concurrency-system.md +287 -287
  96. package/lib/assets/docs/article/functional-desgin-ppp/all/19-wa-tor-simulation.md +286 -286
  97. package/lib/assets/docs/article/functional-desgin-ppp/all/20-pattern-interactions.md +274 -274
  98. package/lib/assets/docs/article/functional-desgin-ppp/all/21-best-practices.md +294 -294
  99. package/lib/assets/docs/article/functional-desgin-ppp/all/22-oo-to-fp-migration.md +337 -337
  100. package/lib/assets/docs/article/functional-desgin-ppp/all/index.md +388 -388
  101. package/lib/assets/docs/article/functional-desgin-ppp/clojure/01-immutability-and-data-transformation.md +273 -273
  102. package/lib/assets/docs/article/functional-desgin-ppp/clojure/02-function-composition.md +380 -380
  103. package/lib/assets/docs/article/functional-desgin-ppp/clojure/03-polymorphism.md +384 -384
  104. package/lib/assets/docs/article/functional-desgin-ppp/clojure/04-clojure-spec.md +350 -350
  105. package/lib/assets/docs/article/functional-desgin-ppp/clojure/05-property-based-testing.md +352 -352
  106. package/lib/assets/docs/article/functional-desgin-ppp/clojure/06-tdd-in-functional.md +383 -383
  107. package/lib/assets/docs/article/functional-desgin-ppp/clojure/07-composite-pattern.md +529 -529
  108. package/lib/assets/docs/article/functional-desgin-ppp/clojure/08-decorator-pattern.md +395 -395
  109. package/lib/assets/docs/article/functional-desgin-ppp/clojure/09-adapter-pattern.md +399 -399
  110. package/lib/assets/docs/article/functional-desgin-ppp/clojure/10-strategy-pattern.md +485 -485
  111. package/lib/assets/docs/article/functional-desgin-ppp/clojure/11-command-pattern.md +566 -566
  112. package/lib/assets/docs/article/functional-desgin-ppp/clojure/12-visitor-pattern.md +567 -567
  113. package/lib/assets/docs/article/functional-desgin-ppp/clojure/13-abstract-factory-pattern.md +475 -475
  114. package/lib/assets/docs/article/functional-desgin-ppp/clojure/14-abstract-server-pattern.md +462 -462
  115. package/lib/assets/docs/article/functional-desgin-ppp/clojure/15-gossiping-bus-drivers.md +325 -325
  116. package/lib/assets/docs/article/functional-desgin-ppp/clojure/16-payroll-system.md +401 -401
  117. package/lib/assets/docs/article/functional-desgin-ppp/clojure/17-video-rental-system.md +450 -450
  118. package/lib/assets/docs/article/functional-desgin-ppp/clojure/18-concurrency-system.md +475 -475
  119. package/lib/assets/docs/article/functional-desgin-ppp/clojure/19-wator-simulation.md +739 -739
  120. package/lib/assets/docs/article/functional-desgin-ppp/clojure/20-pattern-interactions.md +567 -567
  121. package/lib/assets/docs/article/functional-desgin-ppp/clojure/21-best-practices.md +518 -518
  122. package/lib/assets/docs/article/functional-desgin-ppp/clojure/22-oo-to-fp-migration.md +532 -532
  123. package/lib/assets/docs/article/functional-desgin-ppp/clojure/index.md +241 -241
  124. package/lib/assets/docs/article/functional-desgin-ppp/elixir/01-immutability-and-data-transformation.md +383 -383
  125. package/lib/assets/docs/article/functional-desgin-ppp/elixir/02-function-composition.md +374 -374
  126. package/lib/assets/docs/article/functional-desgin-ppp/elixir/03-polymorphism.md +375 -375
  127. package/lib/assets/docs/article/functional-desgin-ppp/elixir/04-data-validation.md +195 -195
  128. package/lib/assets/docs/article/functional-desgin-ppp/elixir/05-property-based-testing.md +268 -268
  129. package/lib/assets/docs/article/functional-desgin-ppp/elixir/06-tdd-and-fp.md +294 -294
  130. package/lib/assets/docs/article/functional-desgin-ppp/elixir/07-effects-and-pure-functions.md +164 -164
  131. package/lib/assets/docs/article/functional-desgin-ppp/elixir/08-error-handling-strategies.md +168 -168
  132. package/lib/assets/docs/article/functional-desgin-ppp/elixir/09-io-and-external-systems.md +254 -254
  133. package/lib/assets/docs/article/functional-desgin-ppp/elixir/10-concurrency-patterns.md +269 -269
  134. package/lib/assets/docs/article/functional-desgin-ppp/elixir/11-command-pattern.md +148 -148
  135. package/lib/assets/docs/article/functional-desgin-ppp/elixir/12-visitor-pattern.md +176 -176
  136. package/lib/assets/docs/article/functional-desgin-ppp/elixir/13-abstract-factory-pattern.md +604 -604
  137. package/lib/assets/docs/article/functional-desgin-ppp/elixir/14-abstract-server-pattern.md +729 -729
  138. package/lib/assets/docs/article/functional-desgin-ppp/elixir/15-gossiping-bus-drivers.md +291 -291
  139. package/lib/assets/docs/article/functional-desgin-ppp/elixir/16-payroll-system.md +420 -420
  140. package/lib/assets/docs/article/functional-desgin-ppp/elixir/17-video-rental-system.md +319 -319
  141. package/lib/assets/docs/article/functional-desgin-ppp/elixir/18-concurrency-system.md +466 -466
  142. package/lib/assets/docs/article/functional-desgin-ppp/elixir/19-wator-simulation.md +523 -523
  143. package/lib/assets/docs/article/functional-desgin-ppp/elixir/20-pattern-interactions.md +287 -287
  144. package/lib/assets/docs/article/functional-desgin-ppp/elixir/21-best-practices.md +340 -340
  145. package/lib/assets/docs/article/functional-desgin-ppp/elixir/22-oo-to-fp-migration.md +395 -395
  146. package/lib/assets/docs/article/functional-desgin-ppp/elixir/index.md +248 -248
  147. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/01-immutability-and-data-transformation.md +384 -384
  148. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/02-function-composition.md +452 -452
  149. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/03-polymorphism.md +495 -495
  150. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/04-data-validation.md +416 -416
  151. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/05-property-based-testing.md +382 -382
  152. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/06-tdd-functional.md +687 -687
  153. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/07-composite-pattern.md +442 -442
  154. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/08-decorator-pattern.md +479 -479
  155. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/09-adapter-pattern.md +479 -479
  156. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/10-strategy-pattern.md +427 -427
  157. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/11-command-pattern.md +428 -428
  158. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/12-visitor-pattern.md +339 -339
  159. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/13-abstract-factory-pattern.md +309 -309
  160. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/14-abstract-server-pattern.md +596 -596
  161. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/15-gossiping-bus-drivers.md +355 -355
  162. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/16-payroll-system.md +350 -350
  163. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/17-video-rental-system.md +414 -414
  164. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/18-concurrency-system.md +367 -367
  165. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/19-wator-simulation.md +403 -403
  166. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/20-pattern-interactions.md +291 -291
  167. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/21-best-practices.md +324 -324
  168. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/22-oo-to-fp-migration.md +332 -332
  169. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/index.md +274 -274
  170. package/lib/assets/docs/article/functional-desgin-ppp/haskell/01-immutability-and-data-transformation.md +298 -298
  171. package/lib/assets/docs/article/functional-desgin-ppp/haskell/02-function-composition.md +304 -304
  172. package/lib/assets/docs/article/functional-desgin-ppp/haskell/03-polymorphism.md +362 -362
  173. package/lib/assets/docs/article/functional-desgin-ppp/haskell/04-data-validation.md +257 -257
  174. package/lib/assets/docs/article/functional-desgin-ppp/haskell/05-property-based-testing.md +254 -254
  175. package/lib/assets/docs/article/functional-desgin-ppp/haskell/06-tdd-functional.md +283 -283
  176. package/lib/assets/docs/article/functional-desgin-ppp/haskell/07-composite-pattern.md +395 -395
  177. package/lib/assets/docs/article/functional-desgin-ppp/haskell/08-decorator-pattern.md +319 -319
  178. package/lib/assets/docs/article/functional-desgin-ppp/haskell/09-adapter-pattern.md +382 -382
  179. package/lib/assets/docs/article/functional-desgin-ppp/haskell/10-strategy-pattern.md +287 -287
  180. package/lib/assets/docs/article/functional-desgin-ppp/haskell/11-command-pattern.md +303 -303
  181. package/lib/assets/docs/article/functional-desgin-ppp/haskell/12-visitor-pattern.md +326 -326
  182. package/lib/assets/docs/article/functional-desgin-ppp/haskell/13-abstract-factory-pattern.md +332 -332
  183. package/lib/assets/docs/article/functional-desgin-ppp/haskell/14-abstract-server-pattern.md +379 -379
  184. package/lib/assets/docs/article/functional-desgin-ppp/haskell/15-gossiping-bus-drivers.md +177 -177
  185. package/lib/assets/docs/article/functional-desgin-ppp/haskell/16-payroll-system.md +219 -219
  186. package/lib/assets/docs/article/functional-desgin-ppp/haskell/17-video-rental-system.md +244 -244
  187. package/lib/assets/docs/article/functional-desgin-ppp/haskell/18-concurrency-system.md +363 -363
  188. package/lib/assets/docs/article/functional-desgin-ppp/haskell/19-wator-simulation.md +438 -438
  189. package/lib/assets/docs/article/functional-desgin-ppp/haskell/20-pattern-interactions.md +325 -325
  190. package/lib/assets/docs/article/functional-desgin-ppp/haskell/21-best-practices.md +403 -403
  191. package/lib/assets/docs/article/functional-desgin-ppp/haskell/22-oo-to-fp-migration.md +469 -469
  192. package/lib/assets/docs/article/functional-desgin-ppp/haskell/index.md +174 -174
  193. package/lib/assets/docs/article/functional-desgin-ppp/index.md +90 -90
  194. package/lib/assets/docs/article/functional-desgin-ppp/rust/01-immutability-and-data-transformation.md +450 -450
  195. package/lib/assets/docs/article/functional-desgin-ppp/rust/02-function-composition.md +463 -463
  196. package/lib/assets/docs/article/functional-desgin-ppp/rust/03-polymorphism.md +425 -425
  197. package/lib/assets/docs/article/functional-desgin-ppp/rust/04-data-validation.md +273 -273
  198. package/lib/assets/docs/article/functional-desgin-ppp/rust/05-property-based-testing.md +247 -247
  199. package/lib/assets/docs/article/functional-desgin-ppp/rust/06-tdd-and-functional.md +841 -841
  200. package/lib/assets/docs/article/functional-desgin-ppp/rust/07-composite-pattern.md +384 -384
  201. package/lib/assets/docs/article/functional-desgin-ppp/rust/08-decorator-pattern.md +383 -383
  202. package/lib/assets/docs/article/functional-desgin-ppp/rust/09-adapter-pattern.md +339 -339
  203. package/lib/assets/docs/article/functional-desgin-ppp/rust/10-strategy-pattern.md +331 -331
  204. package/lib/assets/docs/article/functional-desgin-ppp/rust/11-command-pattern.md +356 -356
  205. package/lib/assets/docs/article/functional-desgin-ppp/rust/12-visitor-pattern.md +379 -379
  206. package/lib/assets/docs/article/functional-desgin-ppp/rust/13-abstract-factory-pattern.md +361 -361
  207. package/lib/assets/docs/article/functional-desgin-ppp/rust/14-abstract-server-pattern.md +392 -392
  208. package/lib/assets/docs/article/functional-desgin-ppp/rust/15-gossiping-bus-drivers.md +300 -300
  209. package/lib/assets/docs/article/functional-desgin-ppp/rust/16-payroll-system.md +297 -297
  210. package/lib/assets/docs/article/functional-desgin-ppp/rust/17-video-rental-system.md +304 -304
  211. package/lib/assets/docs/article/functional-desgin-ppp/rust/18-concurrency-system.md +315 -315
  212. package/lib/assets/docs/article/functional-desgin-ppp/rust/19-wator-simulation.md +311 -311
  213. package/lib/assets/docs/article/functional-desgin-ppp/rust/20-pattern-interactions.md +304 -304
  214. package/lib/assets/docs/article/functional-desgin-ppp/rust/21-best-practices.md +336 -336
  215. package/lib/assets/docs/article/functional-desgin-ppp/rust/22-oo-to-fp-migration.md +349 -349
  216. package/lib/assets/docs/article/functional-desgin-ppp/rust/index.md +243 -243
  217. package/lib/assets/docs/article/functional-desgin-ppp/scala/01-immutability-and-data-transformation.md +328 -328
  218. package/lib/assets/docs/article/functional-desgin-ppp/scala/02-function-composition.md +348 -348
  219. package/lib/assets/docs/article/functional-desgin-ppp/scala/03-polymorphism.md +357 -357
  220. package/lib/assets/docs/article/functional-desgin-ppp/scala/04-data-validation.md +364 -364
  221. package/lib/assets/docs/article/functional-desgin-ppp/scala/05-property-based-testing.md +515 -515
  222. package/lib/assets/docs/article/functional-desgin-ppp/scala/06-tdd-functional.md +557 -557
  223. package/lib/assets/docs/article/functional-desgin-ppp/scala/07-composite-pattern.md +363 -363
  224. package/lib/assets/docs/article/functional-desgin-ppp/scala/08-decorator-pattern.md +327 -327
  225. package/lib/assets/docs/article/functional-desgin-ppp/scala/09-adapter-pattern.md +517 -517
  226. package/lib/assets/docs/article/functional-desgin-ppp/scala/10-strategy-pattern.md +441 -441
  227. package/lib/assets/docs/article/functional-desgin-ppp/scala/11-command-pattern.md +407 -407
  228. package/lib/assets/docs/article/functional-desgin-ppp/scala/12-visitor-pattern.md +379 -379
  229. package/lib/assets/docs/article/functional-desgin-ppp/scala/13-abstract-factory-pattern.md +398 -398
  230. package/lib/assets/docs/article/functional-desgin-ppp/scala/14-abstract-server-pattern.md +476 -476
  231. package/lib/assets/docs/article/functional-desgin-ppp/scala/15-gossiping-bus-drivers.md +391 -391
  232. package/lib/assets/docs/article/functional-desgin-ppp/scala/16-payroll-system.md +342 -342
  233. package/lib/assets/docs/article/functional-desgin-ppp/scala/17-video-rental-system.md +324 -324
  234. package/lib/assets/docs/article/functional-desgin-ppp/scala/18-concurrency-system.md +730 -730
  235. package/lib/assets/docs/article/functional-desgin-ppp/scala/19-wator-simulation.md +624 -624
  236. package/lib/assets/docs/article/functional-desgin-ppp/scala/20-pattern-interactions.md +512 -512
  237. package/lib/assets/docs/article/functional-desgin-ppp/scala/21-best-practices.md +433 -433
  238. package/lib/assets/docs/article/functional-desgin-ppp/scala/22-oo-to-fp-migration.md +688 -688
  239. package/lib/assets/docs/article/functional-desgin-ppp/scala/index.md +243 -243
  240. package/lib/assets/docs/article/getting-start-tdd/clojure/01-todo-list-and-first-test.md +166 -166
  241. package/lib/assets/docs/article/getting-start-tdd/clojure/02-fake-it-and-triangulation.md +162 -162
  242. package/lib/assets/docs/article/getting-start-tdd/clojure/03-obvious-implementation-and-refactoring.md +135 -135
  243. package/lib/assets/docs/article/getting-start-tdd/clojure/04-version-control-and-conventional-commits.md +88 -88
  244. package/lib/assets/docs/article/getting-start-tdd/clojure/05-package-management-and-static-analysis.md +299 -299
  245. package/lib/assets/docs/article/getting-start-tdd/clojure/06-task-runner-and-ci-cd.md +241 -241
  246. package/lib/assets/docs/article/getting-start-tdd/clojure/07-protocols-and-records.md +131 -131
  247. package/lib/assets/docs/article/getting-start-tdd/clojure/08-multimethods-and-design-patterns.md +130 -130
  248. package/lib/assets/docs/article/getting-start-tdd/clojure/09-namespaces-and-module-design.md +127 -127
  249. package/lib/assets/docs/article/getting-start-tdd/clojure/10-higher-order-functions-and-composition.md +114 -114
  250. package/lib/assets/docs/article/getting-start-tdd/clojure/11-persistent-data-and-pipeline.md +138 -138
  251. package/lib/assets/docs/article/getting-start-tdd/clojure/12-error-handling-and-spec.md +161 -161
  252. package/lib/assets/docs/article/getting-start-tdd/clojure/index.md +65 -65
  253. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter01.md +232 -232
  254. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter02.md +244 -244
  255. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter03.md +202 -202
  256. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter04.md +92 -92
  257. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter05.md +256 -256
  258. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter06.md +195 -195
  259. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter07.md +214 -214
  260. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter08.md +249 -249
  261. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter09.md +174 -174
  262. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter10.md +166 -166
  263. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter11.md +192 -192
  264. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter12.md +211 -211
  265. package/lib/assets/docs/article/getting-start-tdd/csharp/index.md +83 -83
  266. package/lib/assets/docs/article/getting-start-tdd/elixir/01-todo-list-and-first-test.md +87 -87
  267. package/lib/assets/docs/article/getting-start-tdd/elixir/02-fake-it-and-triangulation.md +95 -95
  268. package/lib/assets/docs/article/getting-start-tdd/elixir/03-obvious-implementation-and-refactoring.md +109 -109
  269. package/lib/assets/docs/article/getting-start-tdd/elixir/04-version-control-and-conventional-commits.md +96 -96
  270. package/lib/assets/docs/article/getting-start-tdd/elixir/05-package-management-and-static-analysis.md +88 -88
  271. package/lib/assets/docs/article/getting-start-tdd/elixir/06-task-runner-and-ci-cd.md +71 -71
  272. package/lib/assets/docs/article/getting-start-tdd/elixir/07-structs-and-protocols.md +110 -110
  273. package/lib/assets/docs/article/getting-start-tdd/elixir/08-pattern-matching-and-guards.md +108 -108
  274. package/lib/assets/docs/article/getting-start-tdd/elixir/09-module-design-and-behaviours.md +104 -104
  275. package/lib/assets/docs/article/getting-start-tdd/elixir/10-higher-order-functions-and-pipeline.md +178 -178
  276. package/lib/assets/docs/article/getting-start-tdd/elixir/11-stream-and-lazy-evaluation.md +142 -142
  277. package/lib/assets/docs/article/getting-start-tdd/elixir/12-error-handling-and-with.md +145 -145
  278. package/lib/assets/docs/article/getting-start-tdd/elixir/index.md +35 -35
  279. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter01.md +202 -202
  280. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter02.md +246 -246
  281. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter03.md +218 -218
  282. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter04.md +179 -179
  283. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter05.md +267 -267
  284. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter06.md +190 -190
  285. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter07.md +161 -161
  286. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter08.md +175 -175
  287. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter09.md +222 -222
  288. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter10.md +189 -189
  289. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter11.md +212 -212
  290. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter12.md +215 -215
  291. package/lib/assets/docs/article/getting-start-tdd/fsharp/index.md +71 -71
  292. package/lib/assets/docs/article/getting-start-tdd/go/01-todo-list-and-first-test.md +213 -213
  293. package/lib/assets/docs/article/getting-start-tdd/go/02-fake-it-and-triangulation.md +302 -302
  294. package/lib/assets/docs/article/getting-start-tdd/go/03-obvious-implementation-and-refactoring.md +339 -339
  295. package/lib/assets/docs/article/getting-start-tdd/go/04-version-control-and-conventional-commits.md +112 -112
  296. package/lib/assets/docs/article/getting-start-tdd/go/05-package-management-and-static-analysis.md +272 -272
  297. package/lib/assets/docs/article/getting-start-tdd/go/06-task-runner-and-ci-cd.md +233 -233
  298. package/lib/assets/docs/article/getting-start-tdd/go/07-encapsulation-and-polymorphism.md +394 -394
  299. package/lib/assets/docs/article/getting-start-tdd/go/08-design-patterns.md +422 -422
  300. package/lib/assets/docs/article/getting-start-tdd/go/09-solid-principles-and-module-design.md +400 -400
  301. package/lib/assets/docs/article/getting-start-tdd/go/10-higher-order-functions-and-composition.md +226 -226
  302. package/lib/assets/docs/article/getting-start-tdd/go/11-immutable-data-and-pipeline.md +296 -296
  303. package/lib/assets/docs/article/getting-start-tdd/go/12-error-handling-and-type-safety.md +411 -411
  304. package/lib/assets/docs/article/getting-start-tdd/go/index.md +83 -83
  305. package/lib/assets/docs/article/getting-start-tdd/haskell/01-todo-list-and-first-test.md +279 -279
  306. package/lib/assets/docs/article/getting-start-tdd/haskell/02-fake-it-and-triangulation.md +337 -337
  307. package/lib/assets/docs/article/getting-start-tdd/haskell/03-obvious-implementation-and-refactoring.md +257 -257
  308. package/lib/assets/docs/article/getting-start-tdd/haskell/04-version-control-and-conventional-commits.md +182 -182
  309. package/lib/assets/docs/article/getting-start-tdd/haskell/05-package-management-and-static-analysis.md +313 -313
  310. package/lib/assets/docs/article/getting-start-tdd/haskell/06-task-runner-and-ci-cd.md +309 -309
  311. package/lib/assets/docs/article/getting-start-tdd/haskell/07-algebraic-data-types-and-type-classes.md +412 -412
  312. package/lib/assets/docs/article/getting-start-tdd/haskell/08-pattern-matching-and-guards.md +390 -390
  313. package/lib/assets/docs/article/getting-start-tdd/haskell/09-module-design-and-smart-constructors.md +461 -461
  314. package/lib/assets/docs/article/getting-start-tdd/haskell/10-higher-order-functions-and-currying.md +434 -434
  315. package/lib/assets/docs/article/getting-start-tdd/haskell/11-function-composition-and-point-free.md +392 -392
  316. package/lib/assets/docs/article/getting-start-tdd/haskell/12-monad-and-error-handling.md +631 -631
  317. package/lib/assets/docs/article/getting-start-tdd/haskell/index.md +49 -49
  318. package/lib/assets/docs/article/getting-start-tdd/index.md +93 -93
  319. package/lib/assets/docs/article/getting-start-tdd/integration/01-language-overview.md +375 -375
  320. package/lib/assets/docs/article/getting-start-tdd/integration/02-test-framework-comparison.md +349 -349
  321. package/lib/assets/docs/article/getting-start-tdd/integration/03-tdd-pattern-comparison.md +445 -445
  322. package/lib/assets/docs/article/getting-start-tdd/integration/04-type-system-comparison.md +409 -409
  323. package/lib/assets/docs/article/getting-start-tdd/integration/05-dev-environment-comparison.md +330 -330
  324. package/lib/assets/docs/article/getting-start-tdd/integration/06-learning-roadmap.md +290 -290
  325. package/lib/assets/docs/article/getting-start-tdd/integration/index.md +69 -69
  326. package/lib/assets/docs/article/getting-start-tdd/java/01-todo-list-and-first-test.md +234 -234
  327. package/lib/assets/docs/article/getting-start-tdd/java/02-fake-it-and-triangulation.md +261 -261
  328. package/lib/assets/docs/article/getting-start-tdd/java/03-obvious-implementation-and-refactoring.md +185 -185
  329. package/lib/assets/docs/article/getting-start-tdd/java/04-version-control-and-conventional-commits.md +115 -115
  330. package/lib/assets/docs/article/getting-start-tdd/java/05-package-management-and-static-analysis.md +382 -382
  331. package/lib/assets/docs/article/getting-start-tdd/java/06-task-runner-and-ci-cd.md +272 -272
  332. package/lib/assets/docs/article/getting-start-tdd/java/07-encapsulation-and-polymorphism.md +626 -626
  333. package/lib/assets/docs/article/getting-start-tdd/java/08-design-patterns.md +393 -393
  334. package/lib/assets/docs/article/getting-start-tdd/java/09-solid-principles-and-module-design.md +310 -310
  335. package/lib/assets/docs/article/getting-start-tdd/java/10-higher-order-functions-and-composition.md +188 -188
  336. package/lib/assets/docs/article/getting-start-tdd/java/11-immutable-data-and-pipeline.md +167 -167
  337. package/lib/assets/docs/article/getting-start-tdd/java/12-error-handling-and-type-safety.md +205 -205
  338. package/lib/assets/docs/article/getting-start-tdd/java/index.md +61 -61
  339. package/lib/assets/docs/article/getting-start-tdd/node/01-todo-list-and-first-test.md +244 -244
  340. package/lib/assets/docs/article/getting-start-tdd/node/02-fake-it-and-triangulation.md +262 -262
  341. package/lib/assets/docs/article/getting-start-tdd/node/03-obvious-implementation-and-refactoring.md +169 -169
  342. package/lib/assets/docs/article/getting-start-tdd/node/04-version-control-and-conventional-commits.md +112 -112
  343. package/lib/assets/docs/article/getting-start-tdd/node/05-package-management-and-static-analysis.md +314 -314
  344. package/lib/assets/docs/article/getting-start-tdd/node/06-task-runner-and-ci-cd.md +235 -235
  345. package/lib/assets/docs/article/getting-start-tdd/node/07-encapsulation-and-polymorphism.md +327 -327
  346. package/lib/assets/docs/article/getting-start-tdd/node/08-design-patterns.md +322 -322
  347. package/lib/assets/docs/article/getting-start-tdd/node/09-solid-principles-and-module-design.md +285 -285
  348. package/lib/assets/docs/article/getting-start-tdd/node/10-higher-order-functions-and-composition.md +199 -199
  349. package/lib/assets/docs/article/getting-start-tdd/node/11-immutable-data-and-pipeline.md +207 -207
  350. package/lib/assets/docs/article/getting-start-tdd/node/12-error-handling-and-type-safety.md +295 -295
  351. package/lib/assets/docs/article/getting-start-tdd/node/index.md +56 -56
  352. package/lib/assets/docs/article/getting-start-tdd/php/01-todo-list-and-first-test.md +259 -259
  353. package/lib/assets/docs/article/getting-start-tdd/php/02-fake-it-and-triangulation.md +200 -200
  354. package/lib/assets/docs/article/getting-start-tdd/php/03-obvious-implementation-and-refactoring.md +248 -248
  355. package/lib/assets/docs/article/getting-start-tdd/php/04-version-control-and-conventional-commits.md +141 -141
  356. package/lib/assets/docs/article/getting-start-tdd/php/05-package-management-and-static-analysis.md +410 -410
  357. package/lib/assets/docs/article/getting-start-tdd/php/06-task-runner-and-ci-cd.md +321 -321
  358. package/lib/assets/docs/article/getting-start-tdd/php/07-encapsulation-and-polymorphism.md +372 -372
  359. package/lib/assets/docs/article/getting-start-tdd/php/08-design-patterns.md +453 -453
  360. package/lib/assets/docs/article/getting-start-tdd/php/09-solid-principles-and-module-design.md +460 -460
  361. package/lib/assets/docs/article/getting-start-tdd/php/10-higher-order-functions-and-composition.md +182 -182
  362. package/lib/assets/docs/article/getting-start-tdd/php/11-immutable-data-and-pipeline.md +266 -266
  363. package/lib/assets/docs/article/getting-start-tdd/php/12-error-handling-and-type-safety.md +308 -308
  364. package/lib/assets/docs/article/getting-start-tdd/php/index.md +84 -84
  365. package/lib/assets/docs/article/getting-start-tdd/python/01-todo-list-and-first-test.md +201 -201
  366. package/lib/assets/docs/article/getting-start-tdd/python/02-fake-it-and-triangulation.md +247 -247
  367. package/lib/assets/docs/article/getting-start-tdd/python/03-obvious-implementation-and-refactoring.md +199 -199
  368. package/lib/assets/docs/article/getting-start-tdd/python/04-version-control-and-conventional-commits.md +87 -87
  369. package/lib/assets/docs/article/getting-start-tdd/python/05-package-management-and-static-analysis.md +274 -274
  370. package/lib/assets/docs/article/getting-start-tdd/python/06-task-runner-and-ci-cd.md +190 -190
  371. package/lib/assets/docs/article/getting-start-tdd/python/07-encapsulation-and-polymorphism.md +208 -208
  372. package/lib/assets/docs/article/getting-start-tdd/python/08-design-patterns.md +172 -172
  373. package/lib/assets/docs/article/getting-start-tdd/python/09-solid-principles-and-module-design.md +130 -130
  374. package/lib/assets/docs/article/getting-start-tdd/python/10-higher-order-functions-and-composition.md +122 -122
  375. package/lib/assets/docs/article/getting-start-tdd/python/11-immutable-data-and-pipeline.md +116 -116
  376. package/lib/assets/docs/article/getting-start-tdd/python/12-error-handling-and-type-safety.md +126 -126
  377. package/lib/assets/docs/article/getting-start-tdd/python/index.md +55 -55
  378. package/lib/assets/docs/article/getting-start-tdd/ruby/01-todo-list-and-first-test.md +231 -231
  379. package/lib/assets/docs/article/getting-start-tdd/ruby/02-fake-it-and-triangulation.md +238 -238
  380. package/lib/assets/docs/article/getting-start-tdd/ruby/03-obvious-implementation-and-refactoring.md +228 -228
  381. package/lib/assets/docs/article/getting-start-tdd/ruby/04-version-control-and-conventional-commits.md +112 -112
  382. package/lib/assets/docs/article/getting-start-tdd/ruby/05-package-management-and-static-analysis.md +287 -287
  383. package/lib/assets/docs/article/getting-start-tdd/ruby/06-task-runner-and-ci-cd.md +248 -248
  384. package/lib/assets/docs/article/getting-start-tdd/ruby/07-encapsulation-and-polymorphism.md +279 -279
  385. package/lib/assets/docs/article/getting-start-tdd/ruby/08-design-patterns.md +329 -329
  386. package/lib/assets/docs/article/getting-start-tdd/ruby/09-solid-principles-and-module-design.md +196 -196
  387. package/lib/assets/docs/article/getting-start-tdd/ruby/10-higher-order-functions-and-composition.md +175 -175
  388. package/lib/assets/docs/article/getting-start-tdd/ruby/11-immutable-data-and-pipeline.md +237 -237
  389. package/lib/assets/docs/article/getting-start-tdd/ruby/12-error-handling-and-type-safety.md +398 -398
  390. package/lib/assets/docs/article/getting-start-tdd/ruby/index.md +83 -83
  391. package/lib/assets/docs/article/getting-start-tdd/rust/01-todo-list-and-first-test.md +211 -211
  392. package/lib/assets/docs/article/getting-start-tdd/rust/02-fake-it-and-triangulation.md +264 -264
  393. package/lib/assets/docs/article/getting-start-tdd/rust/03-obvious-implementation-and-refactoring.md +233 -233
  394. package/lib/assets/docs/article/getting-start-tdd/rust/04-version-control-and-conventional-commits.md +92 -92
  395. package/lib/assets/docs/article/getting-start-tdd/rust/05-package-management-and-static-analysis.md +212 -212
  396. package/lib/assets/docs/article/getting-start-tdd/rust/06-task-runner-and-ci-cd.md +164 -164
  397. package/lib/assets/docs/article/getting-start-tdd/rust/07-encapsulation-and-polymorphism.md +142 -142
  398. package/lib/assets/docs/article/getting-start-tdd/rust/08-design-patterns.md +145 -145
  399. package/lib/assets/docs/article/getting-start-tdd/rust/09-solid-principles-and-module-design.md +110 -110
  400. package/lib/assets/docs/article/getting-start-tdd/rust/10-higher-order-functions-and-composition.md +94 -94
  401. package/lib/assets/docs/article/getting-start-tdd/rust/11-immutable-data-and-pipeline.md +105 -105
  402. package/lib/assets/docs/article/getting-start-tdd/rust/12-error-handling-and-type-safety.md +112 -112
  403. package/lib/assets/docs/article/getting-start-tdd/rust/index.md +83 -83
  404. package/lib/assets/docs/article/getting-start-tdd/scala/01-todo-list-and-first-test.md +111 -111
  405. package/lib/assets/docs/article/getting-start-tdd/scala/02-fake-it-and-triangulation.md +107 -107
  406. package/lib/assets/docs/article/getting-start-tdd/scala/03-obvious-implementation-and-refactoring.md +99 -99
  407. package/lib/assets/docs/article/getting-start-tdd/scala/04-version-control-and-conventional-commits.md +123 -123
  408. package/lib/assets/docs/article/getting-start-tdd/scala/05-package-management-and-static-analysis.md +196 -196
  409. package/lib/assets/docs/article/getting-start-tdd/scala/06-task-runner-and-ci-cd.md +186 -186
  410. package/lib/assets/docs/article/getting-start-tdd/scala/07-case-classes-and-traits.md +139 -139
  411. package/lib/assets/docs/article/getting-start-tdd/scala/08-pattern-matching-and-sealed-traits.md +106 -106
  412. package/lib/assets/docs/article/getting-start-tdd/scala/09-packages-and-module-design.md +75 -75
  413. package/lib/assets/docs/article/getting-start-tdd/scala/10-higher-order-functions-and-composition.md +104 -104
  414. package/lib/assets/docs/article/getting-start-tdd/scala/11-collections-and-lazy-evaluation.md +94 -94
  415. package/lib/assets/docs/article/getting-start-tdd/scala/12-error-handling-and-type-safety.md +92 -92
  416. package/lib/assets/docs/article/getting-start-tdd/scala/index.md +65 -65
  417. package/lib/assets/docs/article/grokking-concurrency/all/index.md +404 -404
  418. package/lib/assets/docs/article/grokking-concurrency/all/part-1-ch02-sequential.md +554 -554
  419. package/lib/assets/docs/article/grokking-concurrency/all/part-2-ch04-05-threads.md +469 -469
  420. package/lib/assets/docs/article/grokking-concurrency/all/part-3-ch06-multitasking.md +520 -520
  421. package/lib/assets/docs/article/grokking-concurrency/all/part-4-ch07-parallel-patterns.md +420 -420
  422. package/lib/assets/docs/article/grokking-concurrency/all/part-5-ch08-09-synchronization.md +510 -510
  423. package/lib/assets/docs/article/grokking-concurrency/all/part-6-ch10-11-nonblocking-io.md +435 -435
  424. package/lib/assets/docs/article/grokking-concurrency/all/part-7-ch12-async.md +465 -465
  425. package/lib/assets/docs/article/grokking-concurrency/all/part-8-ch13-mapreduce.md +377 -377
  426. package/lib/assets/docs/article/grokking-concurrency/clojure/index.md +116 -116
  427. package/lib/assets/docs/article/grokking-concurrency/clojure/part-1.md +108 -108
  428. package/lib/assets/docs/article/grokking-concurrency/clojure/part-2.md +101 -101
  429. package/lib/assets/docs/article/grokking-concurrency/clojure/part-3.md +122 -122
  430. package/lib/assets/docs/article/grokking-concurrency/clojure/part-4.md +123 -123
  431. package/lib/assets/docs/article/grokking-concurrency/clojure/part-5.md +118 -118
  432. package/lib/assets/docs/article/grokking-concurrency/clojure/part-6.md +89 -89
  433. package/lib/assets/docs/article/grokking-concurrency/clojure/part-7.md +100 -100
  434. package/lib/assets/docs/article/grokking-concurrency/clojure/part-8.md +120 -120
  435. package/lib/assets/docs/article/grokking-concurrency/csharp/index.md +101 -101
  436. package/lib/assets/docs/article/grokking-concurrency/csharp/part-1.md +97 -97
  437. package/lib/assets/docs/article/grokking-concurrency/csharp/part-2.md +123 -123
  438. package/lib/assets/docs/article/grokking-concurrency/csharp/part-3.md +101 -101
  439. package/lib/assets/docs/article/grokking-concurrency/csharp/part-4.md +112 -112
  440. package/lib/assets/docs/article/grokking-concurrency/csharp/part-5.md +99 -99
  441. package/lib/assets/docs/article/grokking-concurrency/csharp/part-6.md +61 -61
  442. package/lib/assets/docs/article/grokking-concurrency/csharp/part-7.md +84 -84
  443. package/lib/assets/docs/article/grokking-concurrency/csharp/part-8.md +92 -92
  444. package/lib/assets/docs/article/grokking-concurrency/fsharp/index.md +65 -65
  445. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-1.md +80 -80
  446. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-2.md +103 -103
  447. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-3.md +94 -94
  448. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-4.md +110 -110
  449. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-5.md +104 -104
  450. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-6.md +93 -93
  451. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-7.md +121 -121
  452. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-8.md +107 -107
  453. package/lib/assets/docs/article/grokking-concurrency/haskell/index.md +248 -248
  454. package/lib/assets/docs/article/grokking-concurrency/haskell/part-1.md +96 -96
  455. package/lib/assets/docs/article/grokking-concurrency/haskell/part-2.md +96 -96
  456. package/lib/assets/docs/article/grokking-concurrency/haskell/part-3.md +91 -91
  457. package/lib/assets/docs/article/grokking-concurrency/haskell/part-4.md +106 -106
  458. package/lib/assets/docs/article/grokking-concurrency/haskell/part-5.md +99 -99
  459. package/lib/assets/docs/article/grokking-concurrency/haskell/part-6.md +95 -95
  460. package/lib/assets/docs/article/grokking-concurrency/haskell/part-7.md +111 -111
  461. package/lib/assets/docs/article/grokking-concurrency/haskell/part-8.md +118 -118
  462. package/lib/assets/docs/article/grokking-concurrency/index.md +66 -66
  463. package/lib/assets/docs/article/grokking-concurrency/java/index.md +102 -102
  464. package/lib/assets/docs/article/grokking-concurrency/java/part-1.md +308 -308
  465. package/lib/assets/docs/article/grokking-concurrency/java/part-2.md +334 -334
  466. package/lib/assets/docs/article/grokking-concurrency/java/part-3.md +221 -221
  467. package/lib/assets/docs/article/grokking-concurrency/java/part-4.md +213 -213
  468. package/lib/assets/docs/article/grokking-concurrency/java/part-5.md +112 -112
  469. package/lib/assets/docs/article/grokking-concurrency/java/part-6.md +69 -69
  470. package/lib/assets/docs/article/grokking-concurrency/java/part-7.md +101 -101
  471. package/lib/assets/docs/article/grokking-concurrency/java/part-8.md +101 -101
  472. package/lib/assets/docs/article/grokking-concurrency/python/index.md +313 -313
  473. package/lib/assets/docs/article/grokking-concurrency/python/part-1.md +239 -239
  474. package/lib/assets/docs/article/grokking-concurrency/python/part-2.md +418 -418
  475. package/lib/assets/docs/article/grokking-concurrency/python/part-3.md +227 -227
  476. package/lib/assets/docs/article/grokking-concurrency/python/part-4.md +299 -299
  477. package/lib/assets/docs/article/grokking-concurrency/python/part-5.md +315 -315
  478. package/lib/assets/docs/article/grokking-concurrency/python/part-6.md +297 -297
  479. package/lib/assets/docs/article/grokking-concurrency/python/part-7.md +314 -314
  480. package/lib/assets/docs/article/grokking-concurrency/python/part-8.md +360 -360
  481. package/lib/assets/docs/article/grokking-concurrency/rust/index.md +270 -270
  482. package/lib/assets/docs/article/grokking-concurrency/rust/part-1.md +108 -108
  483. package/lib/assets/docs/article/grokking-concurrency/rust/part-2.md +120 -120
  484. package/lib/assets/docs/article/grokking-concurrency/rust/part-3.md +126 -126
  485. package/lib/assets/docs/article/grokking-concurrency/rust/part-4.md +175 -175
  486. package/lib/assets/docs/article/grokking-concurrency/rust/part-5.md +158 -158
  487. package/lib/assets/docs/article/grokking-concurrency/rust/part-6.md +94 -94
  488. package/lib/assets/docs/article/grokking-concurrency/rust/part-7.md +133 -133
  489. package/lib/assets/docs/article/grokking-concurrency/rust/part-8.md +155 -155
  490. package/lib/assets/docs/article/grokking-concurrency/scala/index.md +69 -69
  491. package/lib/assets/docs/article/grokking-concurrency/scala/part-1.md +78 -78
  492. package/lib/assets/docs/article/grokking-concurrency/scala/part-2.md +112 -112
  493. package/lib/assets/docs/article/grokking-concurrency/scala/part-3.md +93 -93
  494. package/lib/assets/docs/article/grokking-concurrency/scala/part-4.md +110 -110
  495. package/lib/assets/docs/article/grokking-concurrency/scala/part-5.md +119 -119
  496. package/lib/assets/docs/article/grokking-concurrency/scala/part-6.md +83 -83
  497. package/lib/assets/docs/article/grokking-concurrency/scala/part-7.md +131 -131
  498. package/lib/assets/docs/article/grokking-concurrency/scala/part-8.md +129 -129
  499. package/lib/assets/docs/article/grokkingfp/all/index.md +368 -368
  500. package/lib/assets/docs/article/grokkingfp/all/part-1-ch01-fp-introduction.md +530 -530
  501. package/lib/assets/docs/article/grokkingfp/all/part-1-ch02-pure-functions.md +923 -923
  502. package/lib/assets/docs/article/grokkingfp/all/part-2-ch03-immutable-data.md +1128 -1128
  503. package/lib/assets/docs/article/grokkingfp/all/part-2-ch04-higher-order-functions.md +1104 -1104
  504. package/lib/assets/docs/article/grokkingfp/all/part-2-ch05-flatmap.md +1026 -1026
  505. package/lib/assets/docs/article/grokkingfp/all/part-3-ch06-option.md +785 -785
  506. package/lib/assets/docs/article/grokkingfp/all/part-3-ch07-either-adt.md +871 -871
  507. package/lib/assets/docs/article/grokkingfp/all/part-4-ch08-io-monad.md +972 -972
  508. package/lib/assets/docs/article/grokkingfp/all/part-4-ch09-streams.md +926 -926
  509. package/lib/assets/docs/article/grokkingfp/all/part-5-ch10-concurrency.md +870 -870
  510. package/lib/assets/docs/article/grokkingfp/all/part-6-ch11-application.md +715 -715
  511. package/lib/assets/docs/article/grokkingfp/all/part-6-ch12-testing.md +626 -626
  512. package/lib/assets/docs/article/grokkingfp/all/writing-plan.md +712 -712
  513. package/lib/assets/docs/article/grokkingfp/clojure/index.md +276 -276
  514. package/lib/assets/docs/article/grokkingfp/clojure/part-1.md +667 -667
  515. package/lib/assets/docs/article/grokkingfp/clojure/part-2.md +643 -643
  516. package/lib/assets/docs/article/grokkingfp/clojure/part-3.md +620 -620
  517. package/lib/assets/docs/article/grokkingfp/clojure/part-4.md +697 -697
  518. package/lib/assets/docs/article/grokkingfp/clojure/part-5.md +751 -751
  519. package/lib/assets/docs/article/grokkingfp/clojure/part-6.md +721 -721
  520. package/lib/assets/docs/article/grokkingfp/csharp/index.md +246 -246
  521. package/lib/assets/docs/article/grokkingfp/csharp/part-1.md +811 -811
  522. package/lib/assets/docs/article/grokkingfp/csharp/part-2.md +971 -971
  523. package/lib/assets/docs/article/grokkingfp/csharp/part-3.md +981 -981
  524. package/lib/assets/docs/article/grokkingfp/csharp/part-4.md +949 -949
  525. package/lib/assets/docs/article/grokkingfp/csharp/part-5.md +947 -947
  526. package/lib/assets/docs/article/grokkingfp/csharp/part-6.md +739 -739
  527. package/lib/assets/docs/article/grokkingfp/elixir/index.md +203 -203
  528. package/lib/assets/docs/article/grokkingfp/elixir/part-1.md +712 -712
  529. package/lib/assets/docs/article/grokkingfp/elixir/part-2.md +838 -838
  530. package/lib/assets/docs/article/grokkingfp/elixir/part-3.md +985 -985
  531. package/lib/assets/docs/article/grokkingfp/elixir/part-4.md +974 -974
  532. package/lib/assets/docs/article/grokkingfp/elixir/part-5.md +1286 -1286
  533. package/lib/assets/docs/article/grokkingfp/elixir/part-6.md +1049 -1049
  534. package/lib/assets/docs/article/grokkingfp/fsharp/index.md +210 -210
  535. package/lib/assets/docs/article/grokkingfp/fsharp/part-1.md +714 -714
  536. package/lib/assets/docs/article/grokkingfp/fsharp/part-2.md +961 -961
  537. package/lib/assets/docs/article/grokkingfp/fsharp/part-3.md +972 -972
  538. package/lib/assets/docs/article/grokkingfp/fsharp/part-4.md +832 -832
  539. package/lib/assets/docs/article/grokkingfp/fsharp/part-5.md +911 -911
  540. package/lib/assets/docs/article/grokkingfp/fsharp/part-6.md +922 -922
  541. package/lib/assets/docs/article/grokkingfp/haskell/index.md +234 -234
  542. package/lib/assets/docs/article/grokkingfp/haskell/part-1.md +591 -591
  543. package/lib/assets/docs/article/grokkingfp/haskell/part-2.md +866 -866
  544. package/lib/assets/docs/article/grokkingfp/haskell/part-3.md +915 -915
  545. package/lib/assets/docs/article/grokkingfp/haskell/part-4.md +878 -878
  546. package/lib/assets/docs/article/grokkingfp/haskell/part-5.md +845 -845
  547. package/lib/assets/docs/article/grokkingfp/haskell/part-6.md +844 -844
  548. package/lib/assets/docs/article/grokkingfp/index.md +143 -143
  549. package/lib/assets/docs/article/grokkingfp/java/index.md +211 -211
  550. package/lib/assets/docs/article/grokkingfp/java/part-1.md +648 -648
  551. package/lib/assets/docs/article/grokkingfp/java/part-2.md +675 -675
  552. package/lib/assets/docs/article/grokkingfp/java/part-3.md +672 -672
  553. package/lib/assets/docs/article/grokkingfp/java/part-4.md +771 -771
  554. package/lib/assets/docs/article/grokkingfp/java/part-5.md +959 -959
  555. package/lib/assets/docs/article/grokkingfp/java/part-6.md +1328 -1328
  556. package/lib/assets/docs/article/grokkingfp/python/index.md +258 -258
  557. package/lib/assets/docs/article/grokkingfp/python/part-1.md +443 -443
  558. package/lib/assets/docs/article/grokkingfp/python/part-2.md +958 -958
  559. package/lib/assets/docs/article/grokkingfp/python/part-3.md +1004 -1004
  560. package/lib/assets/docs/article/grokkingfp/python/part-4.md +765 -765
  561. package/lib/assets/docs/article/grokkingfp/python/part-5.md +747 -747
  562. package/lib/assets/docs/article/grokkingfp/python/part-6.md +861 -861
  563. package/lib/assets/docs/article/grokkingfp/ruby/index.md +330 -330
  564. package/lib/assets/docs/article/grokkingfp/ruby/part-1.md +755 -755
  565. package/lib/assets/docs/article/grokkingfp/ruby/part-2.md +938 -938
  566. package/lib/assets/docs/article/grokkingfp/ruby/part-3.md +946 -946
  567. package/lib/assets/docs/article/grokkingfp/ruby/part-4.md +921 -921
  568. package/lib/assets/docs/article/grokkingfp/ruby/part-5.md +908 -908
  569. package/lib/assets/docs/article/grokkingfp/ruby/part-6.md +1412 -1412
  570. package/lib/assets/docs/article/grokkingfp/rust/index.md +242 -242
  571. package/lib/assets/docs/article/grokkingfp/rust/part-1.md +634 -634
  572. package/lib/assets/docs/article/grokkingfp/rust/part-2.md +1060 -1060
  573. package/lib/assets/docs/article/grokkingfp/rust/part-3.md +994 -994
  574. package/lib/assets/docs/article/grokkingfp/rust/part-4.md +573 -573
  575. package/lib/assets/docs/article/grokkingfp/rust/part-5.md +705 -705
  576. package/lib/assets/docs/article/grokkingfp/rust/part-6.md +508 -508
  577. package/lib/assets/docs/article/grokkingfp/scala/index.md +171 -171
  578. package/lib/assets/docs/article/grokkingfp/scala/part-1.md +543 -543
  579. package/lib/assets/docs/article/grokkingfp/scala/part-2.md +946 -946
  580. package/lib/assets/docs/article/grokkingfp/scala/part-3.md +919 -919
  581. package/lib/assets/docs/article/grokkingfp/scala/part-4.md +742 -742
  582. package/lib/assets/docs/article/grokkingfp/scala/part-5.md +722 -722
  583. package/lib/assets/docs/article/grokkingfp/scala/part-6.md +867 -867
  584. package/lib/assets/docs/article/grokkingfp/typescript/index.md +273 -273
  585. package/lib/assets/docs/article/grokkingfp/typescript/part-1.md +561 -561
  586. package/lib/assets/docs/article/grokkingfp/typescript/part-2.md +1129 -1129
  587. package/lib/assets/docs/article/grokkingfp/typescript/part-3.md +842 -842
  588. package/lib/assets/docs/article/grokkingfp/typescript/part-4.md +1087 -1087
  589. package/lib/assets/docs/article/grokkingfp/typescript/part-5.md +717 -717
  590. package/lib/assets/docs/article/grokkingfp/typescript/part-6.md +982 -982
  591. package/lib/assets/docs/article/index.md +41 -41
  592. package/lib/assets/docs/article/practical-database-design/index.md +121 -121
  593. package/lib/assets/docs/article/practical-database-design/part1/chapter01.md +288 -288
  594. package/lib/assets/docs/article/practical-database-design/part1/chapter02.md +518 -518
  595. package/lib/assets/docs/article/practical-database-design/part1/chapter03.md +557 -557
  596. package/lib/assets/docs/article/practical-database-design/part2/chapter04.md +924 -924
  597. package/lib/assets/docs/article/practical-database-design/part2/chapter05.md +1627 -1627
  598. package/lib/assets/docs/article/practical-database-design/part2/chapter06.md +2716 -2716
  599. package/lib/assets/docs/article/practical-database-design/part2/chapter07.md +2082 -2082
  600. package/lib/assets/docs/article/practical-database-design/part2/chapter08.md +2105 -2105
  601. package/lib/assets/docs/article/practical-database-design/part2/chapter09.md +2031 -2031
  602. package/lib/assets/docs/article/practical-database-design/part2/chapter10.md +1387 -1387
  603. package/lib/assets/docs/article/practical-database-design/part2/chapter11.md +1677 -1677
  604. package/lib/assets/docs/article/practical-database-design/part2/chapter12.md +1417 -1417
  605. package/lib/assets/docs/article/practical-database-design/part2/chapter13.md +1434 -1434
  606. package/lib/assets/docs/article/practical-database-design/part3/chapter14.md +667 -667
  607. package/lib/assets/docs/article/practical-database-design/part3/chapter15.md +1625 -1625
  608. package/lib/assets/docs/article/practical-database-design/part3/chapter16.md +1915 -1915
  609. package/lib/assets/docs/article/practical-database-design/part3/chapter17.md +1708 -1708
  610. package/lib/assets/docs/article/practical-database-design/part3/chapter18.md +2095 -2095
  611. package/lib/assets/docs/article/practical-database-design/part3/chapter19.md +1123 -1123
  612. package/lib/assets/docs/article/practical-database-design/part3/chapter20.md +1031 -1031
  613. package/lib/assets/docs/article/practical-database-design/part3/chapter21.md +1382 -1382
  614. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter14-orm.md +991 -991
  615. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter15-orm.md +1300 -1300
  616. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter16-orm.md +1166 -1166
  617. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter17-orm.md +1584 -1584
  618. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter18-orm.md +1183 -1183
  619. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter19-orm.md +1016 -1016
  620. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter20-orm.md +1753 -1753
  621. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter21-orm.md +1447 -1447
  622. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter22-orm.md +1878 -1878
  623. package/lib/assets/docs/article/practical-database-design/part4/chapter22.md +965 -965
  624. package/lib/assets/docs/article/practical-database-design/part4/chapter23.md +2069 -2069
  625. package/lib/assets/docs/article/practical-database-design/part4/chapter24.md +2439 -2439
  626. package/lib/assets/docs/article/practical-database-design/part4/chapter25.md +3661 -3661
  627. package/lib/assets/docs/article/practical-database-design/part4/chapter26.md +2916 -2916
  628. package/lib/assets/docs/article/practical-database-design/part4/chapter27.md +3105 -3105
  629. package/lib/assets/docs/article/practical-database-design/part4/chapter28.md +2697 -2697
  630. package/lib/assets/docs/article/practical-database-design/part4/chapter29.md +2544 -2544
  631. package/lib/assets/docs/article/practical-database-design/part4/chapter30.md +2180 -2180
  632. package/lib/assets/docs/article/practical-database-design/part4/chapter31.md +1192 -1192
  633. package/lib/assets/docs/article/practical-database-design/part4/chapter32.md +2101 -2101
  634. package/lib/assets/docs/article/practical-database-design/part5/chapter33.md +1032 -1032
  635. package/lib/assets/docs/article/practical-database-design/part5/chapter34.md +1609 -1609
  636. package/lib/assets/docs/article/practical-database-design/part5/chapter35.md +1453 -1453
  637. package/lib/assets/docs/article/practical-database-design/part5/chapter36.md +1292 -1292
  638. package/lib/assets/docs/article/practical-database-design/part5/chapter37.md +1470 -1470
  639. package/lib/assets/docs/article/practical-database-design/part5/chapter38.md +1698 -1698
  640. package/lib/assets/docs/article/practical-database-design/part5/chapter39.md +2334 -2334
  641. package/lib/assets/docs/article/practical-database-design/study/study2-1.md +1693 -1693
  642. package/lib/assets/docs/article/practical-database-design/study/study2-2.md +1347 -1347
  643. package/lib/assets/docs/article/practical-database-design/study/study2-3.md +2044 -2044
  644. package/lib/assets/docs/article/practical-database-design/study/study2-4.md +2229 -2229
  645. package/lib/assets/docs/article/practical-database-design/study/study2-5.md +2418 -2418
  646. package/lib/assets/docs/article/practical-database-design/study/study3-1.md +2205 -2205
  647. package/lib/assets/docs/article/practical-database-design/study/study3-2.md +2221 -2221
  648. package/lib/assets/docs/article/practical-database-design/study/study3-3.md +2253 -2253
  649. package/lib/assets/docs/article/practical-database-design/study/study3-4.md +2106 -2106
  650. package/lib/assets/docs/article/practical-database-design/study/study3-5.md +2507 -2507
  651. package/lib/assets/docs/article/practical-database-design/study/study4-1.md +2587 -2587
  652. package/lib/assets/docs/article/practical-database-design/study/study4-2.md +2075 -2075
  653. package/lib/assets/docs/article/practical-database-design/study/study4-3.md +1805 -1805
  654. package/lib/assets/docs/article/practical-database-design/study/study4-4.md +1895 -1895
  655. package/lib/assets/docs/article/practical-database-design/study/study4-5.md +2878 -2878
  656. package/lib/assets/docs/assets/css/extra.css +29 -29
  657. package/lib/assets/docs/assets/js/extra.js +44 -44
  658. package/lib/assets/docs/design/index.md +44 -44
  659. package/lib/assets/docs/development/index.md +39 -39
  660. package/lib/assets/docs/index.md +33 -33
  661. package/lib/assets/docs/operation/index.md +27 -27
  662. package/lib/assets/docs/reference/CodexCLIMCP/343/202/242/343/203/227/343/203/252/343/202/261/343/203/274/343/202/267/343/203/247/343/203/263/351/226/213/347/231/272/343/203/225/343/203/255/343/203/274.md +546 -546
  663. package/lib/assets/docs/reference/CodexCLIMCP/343/202/265/343/203/274/343/203/220/343/203/274/350/250/255/345/256/232/346/211/213/351/240/206.md +341 -341
  664. package/lib/assets/docs/reference/Java/343/202/242/343/203/227/343/203/252/343/202/261/343/203/274/343/202/267/343/203/247/343/203/263/347/222/260/345/242/203/346/247/213/347/257/211/343/202/254/343/202/244/343/203/211.md +581 -581
  665. package/lib/assets/docs/reference/SonarQube/343/203/255/343/203/274/343/202/253/343/203/253/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +642 -642
  666. package/lib/assets/docs/reference/TypeScript/343/202/242/343/203/227/343/203/252/343/202/261/343/203/274/343/202/267/343/203/247/343/203/263/347/222/260/345/242/203/346/247/213/347/257/211/343/202/254/343/202/244/343/203/211.md +465 -465
  667. package/lib/assets/docs/reference/UI/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +450 -450
  668. package/lib/assets/docs/reference/images/Ansoff.drawio.svg +3 -3
  669. package/lib/assets/docs/reference/images/BMC.drawio.svg +3 -3
  670. package/lib/assets/docs/reference/images/BrandBasicStrategy.drawio.svg +3 -3
  671. package/lib/assets/docs/reference/images/BrandCategorization.drawio.svg +3 -3
  672. package/lib/assets/docs/reference/images/BrandRecurutementStrategy.drawio.svg +3 -3
  673. package/lib/assets/docs/reference/images/BrandValue.drawio.svg +3 -3
  674. package/lib/assets/docs/reference/images/BusinessActivitiy.svg +3 -3
  675. package/lib/assets/docs/reference/images/HRM.drawio.svg +3 -3
  676. package/lib/assets/docs/reference/images/MarketingStructure.drawio.svg +3 -3
  677. package/lib/assets/docs/reference/images/OrganizationElemnts.svg +3 -3
  678. package/lib/assets/docs/reference/images/PPM.drawio.svg +3 -3
  679. package/lib/assets/docs/reference/images/PositioningMap.drawio.svg +3 -3
  680. package/lib/assets/docs/reference/images/ProductLayer.drawio.svg +3 -3
  681. package/lib/assets/docs/reference/images/ProductMix.drawio.svg +3 -3
  682. package/lib/assets/docs/reference/images/SWOT.drawio.svg +3 -3
  683. package/lib/assets/docs/reference/images/TargetMarket.drawio.svg +3 -3
  684. package/lib/assets/docs/reference/images/ThreeGenericStrategies.drawio.svg +3 -3
  685. package/lib/assets/docs/reference/images/VRIO.drawio.svg +3 -3
  686. package/lib/assets/docs/reference/images/ValueChain.drawio.svg +3 -3
  687. package/lib/assets/docs/reference/index.md +53 -53
  688. package/lib/assets/docs/reference//343/202/210/343/201/204/343/202/275/343/203/225/343/203/210/343/202/246/343/202/247/343/202/242/343/201/250/343/201/257.md +250 -250
  689. package/lib/assets/docs/reference//343/202/242/343/203/274/343/202/255/343/203/206/343/202/257/343/203/201/343/203/243/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +2216 -2216
  690. package/lib/assets/docs/reference//343/202/244/343/203/263/343/203/225/343/203/251/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +1878 -1878
  691. package/lib/assets/docs/reference//343/202/250/343/202/257/343/202/271/343/203/210/343/203/252/343/203/274/343/203/240/343/203/227/343/203/255/343/202/260/343/203/251/343/203/237/343/203/263/343/202/260.md +550 -550
  692. package/lib/assets/docs/reference//343/202/263/343/203/274/343/203/207/343/202/243/343/203/263/343/202/260/343/201/250/343/203/206/343/202/271/343/203/210/343/202/254/343/202/244/343/203/211.md +705 -705
  693. package/lib/assets/docs/reference//343/203/206/343/202/271/343/203/210/346/210/246/347/225/245/343/202/254/343/202/244/343/203/211.md +1313 -1313
  694. package/lib/assets/docs/reference//343/203/207/343/203/274/343/202/277/343/203/242/343/203/207/343/203/253/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +311 -311
  695. package/lib/assets/docs/reference//343/203/211/343/203/241/343/202/244/343/203/263/343/203/242/343/203/207/343/203/253/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +599 -599
  696. package/lib/assets/docs/reference//343/203/223/343/202/270/343/203/215/343/202/271/343/202/242/343/203/274/343/202/255/343/203/206/343/202/257/343/203/201/343/203/243/345/210/206/346/236/220/343/202/254/343/202/244/343/203/211.md +528 -528
  697. package/lib/assets/docs/reference//343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271/344/275/234/346/210/220/343/202/254/343/202/244/343/203/211.md +689 -689
  698. package/lib/assets/docs/reference//343/203/252/343/203/252/343/203/274/343/202/271/343/202/254/343/202/244/343/203/211.md +461 -461
  699. package/lib/assets/docs/reference//343/203/252/343/203/252/343/203/274/343/202/271/343/203/273/343/202/244/343/203/206/343/203/254/343/203/274/343/202/267/343/203/247/343/203/263/350/250/210/347/224/273/343/202/254/343/202/244/343/203/211.md +580 -580
  700. package/lib/assets/docs/reference//343/203/255/343/202/270/343/202/253/343/203/253/343/202/267/343/203/263/343/202/255/343/203/263/343/202/260.md +1367 -1367
  701. package/lib/assets/docs/reference//344/274/201/346/245/255/347/265/214/345/226/266/350/253/226.md +2637 -2637
  702. package/lib/assets/docs/reference//347/222/260/345/242/203/345/244/211/346/225/260/347/256/241/347/220/206/343/202/254/343/202/244/343/203/211.md +665 -665
  703. package/lib/assets/docs/reference//347/265/214/345/226/266/346/210/246/347/225/245/345/210/206/346/236/220/343/202/254/343/202/244/343/203/211.md +566 -566
  704. package/lib/assets/docs/reference//350/246/201/344/273/266/345/256/232/347/276/251/343/202/254/343/202/244/343/203/211.md +1248 -1248
  705. package/lib/assets/docs/reference//350/250/200/350/252/236/345/210/245/351/226/213/347/231/272/343/202/254/343/202/244/343/203/211.md +518 -518
  706. package/lib/assets/docs/reference//351/201/213/345/226/266/347/256/241/347/220/206.md +1482 -1482
  707. package/lib/assets/docs/reference//351/201/213/347/224/250/343/202/271/343/202/257/343/203/252/343/203/227/343/203/210/344/275/234/346/210/220/343/202/254/343/202/244/343/203/211.md +421 -421
  708. package/lib/assets/docs/reference//351/201/213/347/224/250/350/246/201/344/273/266/345/256/232/347/276/251/343/202/254/343/202/244/343/203/211.md +392 -392
  709. package/lib/assets/docs/reference//351/226/213/347/231/272/343/202/254/343/202/244/343/203/211.md +305 -305
  710. package/lib/assets/docs/reference//351/235/236/346/251/237/350/203/275/350/246/201/344/273/266/345/256/232/347/276/251/343/202/254/343/202/244/343/203/211.md +1236 -1236
  711. package/lib/assets/docs/requirements/index.md +17 -17
  712. package/lib/assets/docs/review/index.md +5 -5
  713. package/lib/assets/docs/strategy/index.md +17 -17
  714. package/lib/assets/docs/template/ADR.md +30 -30
  715. package/lib/assets/docs/template/AWS/343/202/271/343/203/206/343/203/274/343/202/270/343/203/263/343/202/260/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +1366 -1366
  716. package/lib/assets/docs/template/AWS/343/203/227/343/203/255/343/203/200/343/202/257/343/202/267/343/203/247/343/203/263/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +634 -634
  717. package/lib/assets/docs/template/README.md +50 -50
  718. package/lib/assets/docs/template/index.md +24 -24
  719. package/lib/assets/docs/template//343/201/276/343/201/232/343/201/223/343/202/214/343/202/222/350/252/255/343/202/202/343/201/206/343/203/252/343/202/271/343/203/210.md +12 -12
  720. package/lib/assets/docs/template//343/202/242/343/203/227/343/203/252/343/202/261/343/203/274/343/202/267/343/203/247/343/203/263/351/226/213/347/231/272/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +547 -547
  721. package/lib/assets/docs/template//343/202/244/343/203/206/343/203/254/343/203/274/343/202/267/343/203/247/343/203/263/345/256/214/344/272/206/345/240/261/345/221/212/346/233/270.md +58 -58
  722. package/lib/assets/docs/template//343/202/244/343/203/206/343/203/254/343/203/274/343/202/267/343/203/247/343/203/263/350/250/210/347/224/273.md +327 -327
  723. package/lib/assets/docs/template//343/202/244/343/203/263/343/202/273/343/203/227/343/202/267/343/203/247/343/203/263/343/203/207/343/203/203/343/202/255.md +13 -13
  724. package/lib/assets/docs/template//343/203/223/343/202/270/343/203/215/343/202/271/343/202/242/343/203/274/343/202/255/343/203/206/343/202/257/343/203/201/343/203/243.md +379 -379
  725. package/lib/assets/docs/template//343/203/252/343/203/252/343/203/274/343/202/271/345/256/214/344/272/206/345/240/261/345/221/212/346/233/270.md +275 -275
  726. package/lib/assets/docs/template//344/272/213/344/276/213/345/210/206/346/236/220.md +513 -513
  727. package/lib/assets/docs/template//344/274/201/346/245/255/345/210/206/346/236/220.md +573 -573
  728. package/lib/assets/docs/template//345/256/214/345/205/250/345/275/242/345/274/217/343/201/256/343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271.md +69 -69
  729. package/lib/assets/docs/template//350/246/201/344/273/266/345/256/232/347/276/251.md +669 -669
  730. package/lib/assets/docs/template//350/250/255/350/250/210.md +173 -173
  731. package/lib/assets/docs/template//351/226/213/347/231/272/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +688 -688
  732. package/lib/assets/gulpfile.js +25 -25
  733. package/lib/assets/mkdocs.yml +139 -139
  734. package/lib/assets/ops/docker/mkdoc/Dockerfile +19 -19
  735. package/lib/assets/ops/docker/sonarqube-local/docker-compose.yml +57 -57
  736. package/lib/assets/ops/scripts/journal.js +180 -180
  737. package/lib/assets/ops/scripts/mkdocs.js +82 -82
  738. package/lib/assets/ops/scripts/release.js +431 -431
  739. package/lib/assets/ops/scripts/sonar_local.js +726 -726
  740. package/lib/assets/ops/scripts/ssh.js +190 -190
  741. package/lib/assets/ops/scripts/vault.js +299 -299
  742. package/lib/assets/package-lock.json +1653 -1653
  743. package/lib/assets/package.json +40 -40
  744. package/lib/gulpfile.js +37 -37
  745. package/package.json +41 -41
@@ -1,1183 +1,1183 @@
1
- # 第18章:勘定科目残高の設計(ORM版)
2
-
3
- 会計システムにおける残高管理の基盤となる「勘定科目別残高テーブル」を TDD で設計していきます。日次・月次の残高管理と、帳票出力に必要なテーブル構造を実装します。
4
-
5
- JPA 版では、@EmbeddedId による複合主キー、@Query による集計クエリ、Projection インターフェースを活用します。
6
-
7
- ---
8
-
9
- ## 18.1 日次勘定科目残高の設計
10
-
11
- ### 日次残高管理の目的
12
-
13
- 日次勘定科目残高は、日々の仕訳処理に連動して更新される残高情報を管理します。日計表の出力やリアルタイムな残高把握に使用します。
14
-
15
- ```plantuml
16
- @startuml
17
-
18
- title 日次残高管理の役割
19
-
20
- rectangle "仕訳処理" as journal {
21
- card "仕訳入力" as j1
22
- card "仕訳承認" as j2
23
- card "仕訳転記" as j3
24
- }
25
-
26
- rectangle "残高更新" as balance {
27
- card "日次残高更新" as b1
28
- card "月次残高更新" as b2
29
- }
30
-
31
- rectangle "帳票出力" as report {
32
- card "日計表" as r1
33
- card "合計残高試算表" as r2
34
- card "財務諸表" as r3
35
- }
36
-
37
- j3 --> b1 : 即時更新
38
- b1 --> b2 : 月末集計
39
- b1 --> r1 : データ参照
40
- b2 --> r2 : データ参照
41
- b2 --> r3 : データ参照
42
-
43
- note bottom of b1
44
- 日次勘定科目残高は
45
- 仕訳入力時に即座に更新
46
- リアルタイムな残高把握を実現
47
- end note
48
-
49
- @enduml
50
- ```
51
-
52
- | 目的 | 説明 |
53
- |-----|------|
54
- | 日計表出力 | 日単位の勘定科目別借方・貸方合計の集計 |
55
- | リアルタイム残高 | 仕訳入力と同時に残高を更新 |
56
- | 監査証跡 | 日付別の取引履歴の保持 |
57
- | 決算仕訳の区別 | 通常仕訳と決算仕訳の分離管理 |
58
-
59
- ### 複合主キーによる多次元管理
60
-
61
- 日次残高テーブルは、以下の6つのカラムで複合主キーを構成します。
62
-
63
- | カラム | 説明 | 例 |
64
- |--------|------|-----|
65
- | 起票日 | 仕訳の起票日 | 2024-04-01 |
66
- | 勘定科目コード | 勘定科目マスタのコード | 11110 |
67
- | 補助科目コード | 補助的な分類(空文字可) | 空文字 |
68
- | 部門コード | 部門マスタのコード | 10100 |
69
- | プロジェクトコード | プロジェクト単位管理(空文字可) | P001 |
70
- | 決算仕訳フラグ | 決算仕訳か否か | false |
71
-
72
- この設計により、同じ勘定科目でも以下の粒度で残高を分けて管理できます。
73
-
74
- - 部門別の売上高
75
- - プロジェクト別の原価
76
- - 通常仕訳と決算仕訳の分離
77
-
78
- ---
79
-
80
- ## 18.2 MyBatis 版との実装比較
81
-
82
- ### データアクセス層の比較
83
-
84
- | 機能 | MyBatis 版 | JPA 版 |
85
- |-----|-----------|--------|
86
- | 複合主キー | Key 内部クラス | @EmbeddedId + @Embeddable |
87
- | 検索結果マッピング | resultMap + DTO | Projection インターフェース |
88
- | UPSERT | XML で INSERT ON CONFLICT | @Query + nativeQuery |
89
- | 集計クエリ | XML で GROUP BY | Native Query + Projection |
90
- | 日計表出力 | resultMap でマッピング | Projection → DTO 変換 |
91
-
92
- ### Flyway マイグレーション
93
-
94
- <details>
95
- <summary>V008__create_daily_account_balance_table.sql</summary>
96
-
97
- ```sql
98
- -- 日次勘定科目残高
99
- CREATE TABLE "日次勘定科目残高" (
100
- "起票日" DATE NOT NULL,
101
- "勘定科目コード" VARCHAR(5) NOT NULL,
102
- "補助科目コード" VARCHAR(10) NOT NULL DEFAULT '',
103
- "部門コード" VARCHAR(5) NOT NULL DEFAULT '00000',
104
- "プロジェクトコード" VARCHAR(10) NOT NULL DEFAULT '',
105
- "決算仕訳フラグ" SMALLINT NOT NULL DEFAULT 0,
106
- "借方金額" DECIMAL(14,2) NOT NULL DEFAULT 0,
107
- "貸方金額" DECIMAL(14,2) NOT NULL DEFAULT 0,
108
- "作成日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
109
- "更新日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
110
- PRIMARY KEY (
111
- "起票日",
112
- "勘定科目コード",
113
- "補助科目コード",
114
- "部門コード",
115
- "プロジェクトコード",
116
- "決算仕訳フラグ"
117
- ),
118
- CONSTRAINT "fk_日次残高_勘定科目"
119
- FOREIGN KEY ("勘定科目コード") REFERENCES "勘定科目マスタ"("勘定科目コード"),
120
- CONSTRAINT "fk_日次残高_部門"
121
- FOREIGN KEY ("部門コード") REFERENCES "部門マスタ"("部門コード")
122
- );
123
-
124
- -- インデックス
125
- CREATE INDEX "idx_日次残高_起票日" ON "日次勘定科目残高"("起票日");
126
- CREATE INDEX "idx_日次残高_勘定科目" ON "日次勘定科目残高"("勘定科目コード");
127
- CREATE INDEX "idx_日次残高_部門" ON "日次勘定科目残高"("部門コード");
128
- ```
129
-
130
- </details>
131
-
132
- ---
133
-
134
- ## 18.3 JPA エンティティの実装
135
-
136
- ### 複合主キークラス(@Embeddable)
137
-
138
- <details>
139
- <summary>DailyAccountBalanceId.java</summary>
140
-
141
- ```java
142
- package com.example.accounting.domain.model.balance;
143
-
144
- import jakarta.persistence.Column;
145
- import jakarta.persistence.Embeddable;
146
- import lombok.*;
147
-
148
- import java.io.Serializable;
149
- import java.time.LocalDate;
150
- import java.util.Objects;
151
-
152
- /**
153
- * 日次勘定科目残高の複合主キー
154
- *
155
- * JPA では @EmbeddedId で複合主キーを表現
156
- * MyBatis 版では Key 内部クラスを使用していたが、
157
- * JPA 版では @Embeddable アノテーション付きクラスで実装
158
- *
159
- * 注意: equals() と hashCode() の実装が必須
160
- */
161
- @Embeddable
162
- @Data
163
- @Builder
164
- @NoArgsConstructor
165
- @AllArgsConstructor
166
- public class DailyAccountBalanceId implements Serializable {
167
-
168
- @Column(name = "起票日", nullable = false)
169
- private LocalDate postingDate;
170
-
171
- @Column(name = "勘定科目コード", length = 5, nullable = false)
172
- private String accountCode;
173
-
174
- @Column(name = "補助科目コード", length = 10, nullable = false)
175
- private String subAccountCode;
176
-
177
- @Column(name = "部門コード", length = 5, nullable = false)
178
- private String departmentCode;
179
-
180
- @Column(name = "プロジェクトコード", length = 10, nullable = false)
181
- private String projectCode;
182
-
183
- @Column(name = "決算仕訳フラグ", nullable = false)
184
- private Boolean closingJournalFlag;
185
-
186
- @Override
187
- public boolean equals(Object o) {
188
- if (this == o) return true;
189
- if (o == null || getClass() != o.getClass()) return false;
190
- DailyAccountBalanceId that = (DailyAccountBalanceId) o;
191
- return Objects.equals(postingDate, that.postingDate) &&
192
- Objects.equals(accountCode, that.accountCode) &&
193
- Objects.equals(subAccountCode, that.subAccountCode) &&
194
- Objects.equals(departmentCode, that.departmentCode) &&
195
- Objects.equals(projectCode, that.projectCode) &&
196
- Objects.equals(closingJournalFlag, that.closingJournalFlag);
197
- }
198
-
199
- @Override
200
- public int hashCode() {
201
- return Objects.hash(postingDate, accountCode, subAccountCode,
202
- departmentCode, projectCode, closingJournalFlag);
203
- }
204
- }
205
- ```
206
-
207
- </details>
208
-
209
- ### 日次勘定科目残高 Entity
210
-
211
- <details>
212
- <summary>DailyAccountBalance.java</summary>
213
-
214
- ```java
215
- package com.example.accounting.domain.model.balance;
216
-
217
- import com.example.accounting.domain.model.account.Account;
218
- import com.example.accounting.domain.model.department.Department;
219
- import jakarta.persistence.*;
220
- import lombok.*;
221
-
222
- import java.math.BigDecimal;
223
- import java.time.LocalDateTime;
224
-
225
- /**
226
- * 日次勘定科目残高 Entity
227
- *
228
- * JPA 版では @EmbeddedId で複合主キーを定義
229
- * MyBatis 版では単純な POJO + Key 内部クラスだったが、
230
- * JPA 版では Entity アノテーションと関連定義が必要
231
- */
232
- @Entity
233
- @Table(name = "日次勘定科目残高")
234
- @Data
235
- @Builder
236
- @NoArgsConstructor
237
- @AllArgsConstructor
238
- public class DailyAccountBalance {
239
-
240
- /**
241
- * 複合主キー
242
- * @EmbeddedId で埋め込みIDを使用
243
- */
244
- @EmbeddedId
245
- private DailyAccountBalanceId id;
246
-
247
- /**
248
- * 勘定科目マスタとの関連
249
- */
250
- @ManyToOne(fetch = FetchType.LAZY)
251
- @JoinColumn(name = "勘定科目コード", referencedColumnName = "勘定科目コード",
252
- insertable = false, updatable = false)
253
- private Account account;
254
-
255
- /**
256
- * 部門マスタとの関連
257
- */
258
- @ManyToOne(fetch = FetchType.LAZY)
259
- @JoinColumn(name = "部門コード", referencedColumnName = "部門コード",
260
- insertable = false, updatable = false)
261
- private Department department;
262
-
263
- @Column(name = "借方金額", nullable = false, precision = 14, scale = 2)
264
- private BigDecimal debitAmount;
265
-
266
- @Column(name = "貸方金額", nullable = false, precision = 14, scale = 2)
267
- private BigDecimal creditAmount;
268
-
269
- @Column(name = "作成日時", nullable = false, updatable = false)
270
- private LocalDateTime createdAt;
271
-
272
- @Column(name = "更新日時", nullable = false)
273
- private LocalDateTime updatedAt;
274
-
275
- /**
276
- * 残高を計算する(貸借区分に応じて)
277
- * @param isDebitAccount 借方勘定かどうか
278
- * @return 残高
279
- */
280
- public BigDecimal calculateBalance(boolean isDebitAccount) {
281
- if (isDebitAccount) {
282
- // 借方勘定:借方 - 貸方
283
- return debitAmount.subtract(creditAmount);
284
- } else {
285
- // 貸方勘定:貸方 - 借方
286
- return creditAmount.subtract(debitAmount);
287
- }
288
- }
289
-
290
- /**
291
- * 金額を加算する
292
- */
293
- public void addAmounts(BigDecimal debit, BigDecimal credit) {
294
- this.debitAmount = this.debitAmount.add(debit);
295
- this.creditAmount = this.creditAmount.add(credit);
296
- this.updatedAt = LocalDateTime.now();
297
- }
298
-
299
- @PrePersist
300
- protected void onCreate() {
301
- LocalDateTime now = LocalDateTime.now();
302
- this.createdAt = now;
303
- this.updatedAt = now;
304
- if (this.debitAmount == null) {
305
- this.debitAmount = BigDecimal.ZERO;
306
- }
307
- if (this.creditAmount == null) {
308
- this.creditAmount = BigDecimal.ZERO;
309
- }
310
- }
311
-
312
- @PreUpdate
313
- protected void onUpdate() {
314
- this.updatedAt = LocalDateTime.now();
315
- }
316
- }
317
- ```
318
-
319
- </details>
320
-
321
- ### 日計表行用 Projection インターフェース
322
-
323
- <details>
324
- <summary>DailyReportLineProjection.java と DailyReportLine.java</summary>
325
-
326
- ```java
327
- package com.example.accounting.domain.model.balance;
328
-
329
- import java.math.BigDecimal;
330
- import java.time.LocalDate;
331
-
332
- /**
333
- * 日計表行の Projection インターフェース
334
- *
335
- * JPA 版では Projection インターフェースを使用して
336
- * 集計クエリの結果をマッピング
337
- * MyBatis 版では resultMap で DTO にマッピングしていた
338
- */
339
- public interface DailyReportLineProjection {
340
- LocalDate getReportDate();
341
- String getAccountCode();
342
- String getAccountName();
343
- String getSubAccountCode();
344
- String getSubAccountName();
345
- BigDecimal getDebitTotal();
346
- BigDecimal getCreditTotal();
347
- BigDecimal getBalance();
348
- }
349
- ```
350
-
351
- ```java
352
- package com.example.accounting.domain.model.balance;
353
-
354
- import lombok.AllArgsConstructor;
355
- import lombok.Builder;
356
- import lombok.Data;
357
- import lombok.NoArgsConstructor;
358
-
359
- import java.math.BigDecimal;
360
- import java.time.LocalDate;
361
-
362
- /**
363
- * 日計表行 DTO
364
- */
365
- @Data
366
- @Builder
367
- @NoArgsConstructor
368
- @AllArgsConstructor
369
- public class DailyReportLine {
370
- private LocalDate reportDate; // 対象日
371
- private String accountCode; // 勘定科目コード
372
- private String accountName; // 勘定科目名
373
- private String subAccountCode; // 補助科目コード
374
- private String subAccountName; // 補助科目名
375
- private BigDecimal debitTotal; // 借方合計
376
- private BigDecimal creditTotal; // 貸方合計
377
- private BigDecimal balance; // 残高
378
-
379
- /**
380
- * Projection から DTO を生成
381
- */
382
- public static DailyReportLine fromProjection(DailyReportLineProjection projection) {
383
- return DailyReportLine.builder()
384
- .reportDate(projection.getReportDate())
385
- .accountCode(projection.getAccountCode())
386
- .accountName(projection.getAccountName())
387
- .subAccountCode(projection.getSubAccountCode())
388
- .subAccountName(projection.getSubAccountName())
389
- .debitTotal(projection.getDebitTotal())
390
- .creditTotal(projection.getCreditTotal())
391
- .balance(projection.getBalance())
392
- .build();
393
- }
394
- }
395
- ```
396
-
397
- </details>
398
-
399
- ---
400
-
401
- ## 18.4 TDD による日次残高テーブルの実装
402
-
403
- ### リポジトリのテスト
404
-
405
- <details>
406
- <summary>DailyAccountBalanceRepositoryTest.java</summary>
407
-
408
- ```java
409
- package com.example.accounting.infrastructure.persistence;
410
-
411
- import com.example.accounting.domain.model.balance.DailyAccountBalance;
412
- import com.example.accounting.domain.model.balance.DailyAccountBalanceId;
413
- import com.example.accounting.infrastructure.persistence.repository.DailyAccountBalanceJpaRepository;
414
- import org.junit.jupiter.api.DisplayName;
415
- import org.junit.jupiter.api.Nested;
416
- import org.junit.jupiter.api.Test;
417
- import org.springframework.beans.factory.annotation.Autowired;
418
- import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
419
- import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
420
- import org.springframework.test.context.DynamicPropertyRegistry;
421
- import org.springframework.test.context.DynamicPropertySource;
422
- import org.testcontainers.containers.PostgreSQLContainer;
423
- import org.testcontainers.junit.jupiter.Container;
424
- import org.testcontainers.junit.jupiter.Testcontainers;
425
-
426
- import java.math.BigDecimal;
427
- import java.time.LocalDate;
428
-
429
- import static org.assertj.core.api.Assertions.*;
430
-
431
- /**
432
- * 日次勘定科目残高リポジトリのテスト
433
- *
434
- * JPA 版では @DataJpaTest を使用(MyBatis 版では @MybatisTest)
435
- */
436
- @DataJpaTest
437
- @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
438
- @Testcontainers
439
- @DisplayName("日次勘定科目残高リポジトリのテスト")
440
- class DailyAccountBalanceRepositoryTest {
441
-
442
- @Container
443
- static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16")
444
- .withDatabaseName("testdb")
445
- .withUsername("test")
446
- .withPassword("test");
447
-
448
- @DynamicPropertySource
449
- static void configureProperties(DynamicPropertyRegistry registry) {
450
- registry.add("spring.datasource.url", postgres::getJdbcUrl);
451
- registry.add("spring.datasource.username", postgres::getUsername);
452
- registry.add("spring.datasource.password", postgres::getPassword);
453
- }
454
-
455
- @Autowired
456
- private DailyAccountBalanceJpaRepository dailyBalanceRepository;
457
-
458
- @Nested
459
- @DisplayName("日次残高の登録・更新")
460
- class DailyBalanceUpsertTest {
461
-
462
- @Test
463
- @DisplayName("新規の日次残高を登録できる")
464
- void shouldInsertNewDailyBalance() {
465
- // Given
466
- var id = DailyAccountBalanceId.builder()
467
- .postingDate(LocalDate.of(2024, 4, 1))
468
- .accountCode("11110") // 現金
469
- .subAccountCode("")
470
- .departmentCode("10100")
471
- .projectCode("")
472
- .closingJournalFlag(false)
473
- .build();
474
-
475
- var balance = DailyAccountBalance.builder()
476
- .id(id)
477
- .debitAmount(new BigDecimal("100000"))
478
- .creditAmount(BigDecimal.ZERO)
479
- .build();
480
-
481
- // When
482
- dailyBalanceRepository.save(balance);
483
-
484
- // Then
485
- var saved = dailyBalanceRepository.findById(id);
486
- assertThat(saved).isPresent();
487
- assertThat(saved.get().getDebitAmount())
488
- .isEqualByComparingTo("100000");
489
- }
490
-
491
- @Test
492
- @DisplayName("既存の日次残高を更新できる")
493
- void shouldUpdateExistingDailyBalance() {
494
- // Given: 初回登録
495
- var id = DailyAccountBalanceId.builder()
496
- .postingDate(LocalDate.of(2024, 4, 1))
497
- .accountCode("11110")
498
- .subAccountCode("")
499
- .departmentCode("10100")
500
- .projectCode("")
501
- .closingJournalFlag(false)
502
- .build();
503
-
504
- var balance1 = DailyAccountBalance.builder()
505
- .id(id)
506
- .debitAmount(new BigDecimal("100000"))
507
- .creditAmount(BigDecimal.ZERO)
508
- .build();
509
- dailyBalanceRepository.save(balance1);
510
-
511
- // When: 金額を追加
512
- var saved = dailyBalanceRepository.findById(id).orElseThrow();
513
- saved.addAmounts(new BigDecimal("50000"), BigDecimal.ZERO);
514
- dailyBalanceRepository.save(saved);
515
-
516
- // Then: 合算される
517
- var updated = dailyBalanceRepository.findById(id);
518
- assertThat(updated).isPresent();
519
- assertThat(updated.get().getDebitAmount())
520
- .isEqualByComparingTo("150000");
521
- }
522
- }
523
-
524
- @Nested
525
- @DisplayName("日次残高の検索")
526
- class DailyBalanceSearchTest {
527
-
528
- @Test
529
- @DisplayName("日付範囲で日次残高を検索できる")
530
- void shouldFindBalancesByDateRange() {
531
- // When
532
- var balances = dailyBalanceRepository.findByIdPostingDateBetween(
533
- LocalDate.of(2024, 4, 1),
534
- LocalDate.of(2024, 4, 30)
535
- );
536
-
537
- // Then
538
- assertThat(balances).allMatch(b ->
539
- !b.getId().getPostingDate().isBefore(LocalDate.of(2024, 4, 1)) &&
540
- !b.getId().getPostingDate().isAfter(LocalDate.of(2024, 4, 30))
541
- );
542
- }
543
-
544
- @Test
545
- @DisplayName("勘定科目コードで日次残高を検索できる")
546
- void shouldFindBalancesByAccountCode() {
547
- // When
548
- var balances = dailyBalanceRepository.findByIdAccountCode("11110");
549
-
550
- // Then
551
- assertThat(balances).allMatch(b ->
552
- b.getId().getAccountCode().equals("11110")
553
- );
554
- }
555
- }
556
- }
557
- ```
558
-
559
- </details>
560
-
561
- ---
562
-
563
- ## 18.5 JpaRepository インターフェース
564
-
565
- ### 日次勘定科目残高 Repository
566
-
567
- <details>
568
- <summary>DailyAccountBalanceJpaRepository.java</summary>
569
-
570
- ```java
571
- package com.example.accounting.infrastructure.persistence.repository;
572
-
573
- import com.example.accounting.domain.model.balance.DailyAccountBalance;
574
- import com.example.accounting.domain.model.balance.DailyAccountBalanceId;
575
- import com.example.accounting.domain.model.balance.DailyReportLineProjection;
576
- import org.springframework.data.jpa.repository.JpaRepository;
577
- import org.springframework.data.jpa.repository.Modifying;
578
- import org.springframework.data.jpa.repository.Query;
579
- import org.springframework.data.repository.query.Param;
580
- import org.springframework.stereotype.Repository;
581
-
582
- import java.math.BigDecimal;
583
- import java.time.LocalDate;
584
- import java.util.List;
585
-
586
- /**
587
- * 日次勘定科目残高 JpaRepository
588
- *
589
- * JPA 版では JpaRepository を継承
590
- * 複合主キーは DailyAccountBalanceId として定義
591
- * 集計クエリは @Query + Projection で実装
592
- */
593
- @Repository
594
- public interface DailyAccountBalanceJpaRepository
595
- extends JpaRepository<DailyAccountBalance, DailyAccountBalanceId> {
596
-
597
- /**
598
- * 日付範囲で検索
599
- * メソッド名規約で自動生成
600
- */
601
- List<DailyAccountBalance> findByIdPostingDateBetween(
602
- LocalDate fromDate, LocalDate toDate);
603
-
604
- /**
605
- * 起票日で検索
606
- */
607
- List<DailyAccountBalance> findByIdPostingDate(LocalDate postingDate);
608
-
609
- /**
610
- * 勘定科目コードで検索
611
- */
612
- List<DailyAccountBalance> findByIdAccountCode(String accountCode);
613
-
614
- /**
615
- * 部門コードで検索
616
- */
617
- List<DailyAccountBalance> findByIdDepartmentCode(String departmentCode);
618
-
619
- /**
620
- * 日計表データ取得
621
- * Native Query で集計クエリを実行し、Projection にマッピング
622
- */
623
- @Query(value = """
624
- SELECT
625
- d."起票日" as reportDate,
626
- d."勘定科目コード" as accountCode,
627
- a."勘定科目名" as accountName,
628
- d."補助科目コード" as subAccountCode,
629
- '' as subAccountName,
630
- SUM(d."借方金額") as debitTotal,
631
- SUM(d."貸方金額") as creditTotal,
632
- CASE
633
- WHEN a."貸借区分" = '借方'
634
- THEN SUM(d."借方金額") - SUM(d."貸方金額")
635
- ELSE SUM(d."貸方金額") - SUM(d."借方金額")
636
- END as balance
637
- FROM "日次勘定科目残高" d
638
- JOIN "勘定科目マスタ" a ON d."勘定科目コード" = a."勘定科目コード"
639
- WHERE d."起票日" = :reportDate
640
- GROUP BY d."起票日", d."勘定科目コード", a."勘定科目名",
641
- d."補助科目コード", a."貸借区分"
642
- ORDER BY d."勘定科目コード", d."補助科目コード"
643
- """, nativeQuery = true)
644
- List<DailyReportLineProjection> getDailyReport(@Param("reportDate") LocalDate reportDate);
645
-
646
- /**
647
- * UPSERT 用のカスタムクエリ
648
- * PostgreSQL の ON CONFLICT を使用
649
- */
650
- @Modifying
651
- @Query(value = """
652
- INSERT INTO "日次勘定科目残高" (
653
- "起票日", "勘定科目コード", "補助科目コード",
654
- "部門コード", "プロジェクトコード", "決算仕訳フラグ",
655
- "借方金額", "貸方金額", "作成日時", "更新日時"
656
- ) VALUES (
657
- :postingDate, :accountCode, :subAccountCode,
658
- :departmentCode, :projectCode, :closingJournalFlag,
659
- :debitAmount, :creditAmount, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
660
- )
661
- ON CONFLICT (
662
- "起票日", "勘定科目コード", "補助科目コード",
663
- "部門コード", "プロジェクトコード", "決算仕訳フラグ"
664
- )
665
- DO UPDATE SET
666
- "借方金額" = "日次勘定科目残高"."借方金額" + EXCLUDED."借方金額",
667
- "貸方金額" = "日次勘定科目残高"."貸方金額" + EXCLUDED."貸方金額",
668
- "更新日時" = CURRENT_TIMESTAMP
669
- """, nativeQuery = true)
670
- void upsert(
671
- @Param("postingDate") LocalDate postingDate,
672
- @Param("accountCode") String accountCode,
673
- @Param("subAccountCode") String subAccountCode,
674
- @Param("departmentCode") String departmentCode,
675
- @Param("projectCode") String projectCode,
676
- @Param("closingJournalFlag") Boolean closingJournalFlag,
677
- @Param("debitAmount") BigDecimal debitAmount,
678
- @Param("creditAmount") BigDecimal creditAmount);
679
- }
680
- ```
681
-
682
- </details>
683
-
684
- ---
685
-
686
- ## 18.6 月次勘定科目残高の設計
687
-
688
- ### 月次残高管理の目的
689
-
690
- 月次勘定科目残高は、月単位での残高管理を行い、合計残高試算表や財務諸表の出力に使用します。
691
-
692
- ```plantuml
693
- @startuml
694
-
695
- title 月次残高管理の役割
696
-
697
- rectangle "日次処理" as daily {
698
- card "日次残高更新" as d1
699
- card "日計表" as d2
700
- }
701
-
702
- rectangle "月次処理" as monthly {
703
- card "月末残高確定" as m1
704
- card "月次残高更新" as m2
705
- card "繰越処理" as m3
706
- }
707
-
708
- rectangle "帳票・決算" as closing {
709
- card "合計残高試算表" as c1
710
- card "損益計算書" as c2
711
- card "貸借対照表" as c3
712
- card "決算仕訳" as c4
713
- }
714
-
715
- d1 --> m2 : 月末集計
716
- m2 --> m1
717
- m1 --> m3 : 翌月初
718
- m2 --> c1
719
- m2 --> c2
720
- m2 --> c3
721
- c4 --> m2
722
-
723
- note bottom of m2
724
- 月次勘定科目残高は
725
- ・月初残高
726
- ・当月借方・貸方
727
- ・月末残高
728
- を管理
729
- end note
730
-
731
- @enduml
732
- ```
733
-
734
- | 目的 | 説明 |
735
- |-----|------|
736
- | 合計残高試算表 | 月次の勘定科目別借方・貸方・残高の集計 |
737
- | 財務諸表出力 | 貸借対照表・損益計算書のデータソース |
738
- | 月次決算 | 月末残高の確定と繰越処理 |
739
- | 決算仕訳対応 | 通常仕訳と決算仕訳の分離管理 |
740
-
741
- ### 月次勘定科目残高テーブルの ER 図
742
-
743
- ```plantuml
744
- @startuml
745
-
746
- entity "月次勘定科目残高" as MonthlyBalance {
747
- * **決算期**: INTEGER <<PK>>
748
- * **月度**: SMALLINT <<PK>>
749
- * **勘定科目コード**: VARCHAR(5) <<PK>> <<FK>>
750
- * **補助科目コード**: VARCHAR(10) <<PK>>
751
- * **部門コード**: VARCHAR(5) <<PK>> <<FK>>
752
- * **プロジェクトコード**: VARCHAR(10) <<PK>>
753
- * **決算仕訳フラグ**: SMALLINT <<PK>>
754
- --
755
- * **月初残高**: DECIMAL(13,0)
756
- * **借方金額**: DECIMAL(14,2)
757
- * **貸方金額**: DECIMAL(14,2)
758
- * **月末残高**: DECIMAL(13,0)
759
- }
760
-
761
- entity "日次勘定科目残高" as DailyBalance {
762
- * **起票日** <<PK>>
763
- * **勘定科目コード** <<PK>>
764
- ...
765
- --
766
- 借方金額
767
- 貸方金額
768
- }
769
-
770
- DailyBalance ..> MonthlyBalance : 月末集計
771
-
772
- note right of MonthlyBalance
773
- 決算期・月度による期間管理
774
- 月初残高は前月末残高から繰越
775
- 月末残高 = 月初残高 + 借方金額 - 貸方金額
776
- (借方勘定の場合)
777
- end note
778
-
779
- @enduml
780
- ```
781
-
782
- ---
783
-
784
- ## 18.7 月次残高の JPA エンティティ
785
-
786
- ### 複合主キークラス
787
-
788
- <details>
789
- <summary>MonthlyAccountBalanceId.java</summary>
790
-
791
- ```java
792
- package com.example.accounting.domain.model.balance;
793
-
794
- import jakarta.persistence.Column;
795
- import jakarta.persistence.Embeddable;
796
- import lombok.*;
797
-
798
- import java.io.Serializable;
799
- import java.util.Objects;
800
-
801
- /**
802
- * 月次勘定科目残高の複合主キー
803
- */
804
- @Embeddable
805
- @Data
806
- @Builder
807
- @NoArgsConstructor
808
- @AllArgsConstructor
809
- public class MonthlyAccountBalanceId implements Serializable {
810
-
811
- @Column(name = "決算期", nullable = false)
812
- private Integer fiscalYear;
813
-
814
- @Column(name = "月度", nullable = false)
815
- private Integer month;
816
-
817
- @Column(name = "勘定科目コード", length = 5, nullable = false)
818
- private String accountCode;
819
-
820
- @Column(name = "補助科目コード", length = 10, nullable = false)
821
- private String subAccountCode;
822
-
823
- @Column(name = "部門コード", length = 5, nullable = false)
824
- private String departmentCode;
825
-
826
- @Column(name = "プロジェクトコード", length = 10, nullable = false)
827
- private String projectCode;
828
-
829
- @Column(name = "決算仕訳フラグ", nullable = false)
830
- private Boolean closingJournalFlag;
831
-
832
- @Override
833
- public boolean equals(Object o) {
834
- if (this == o) return true;
835
- if (o == null || getClass() != o.getClass()) return false;
836
- MonthlyAccountBalanceId that = (MonthlyAccountBalanceId) o;
837
- return Objects.equals(fiscalYear, that.fiscalYear) &&
838
- Objects.equals(month, that.month) &&
839
- Objects.equals(accountCode, that.accountCode) &&
840
- Objects.equals(subAccountCode, that.subAccountCode) &&
841
- Objects.equals(departmentCode, that.departmentCode) &&
842
- Objects.equals(projectCode, that.projectCode) &&
843
- Objects.equals(closingJournalFlag, that.closingJournalFlag);
844
- }
845
-
846
- @Override
847
- public int hashCode() {
848
- return Objects.hash(fiscalYear, month, accountCode, subAccountCode,
849
- departmentCode, projectCode, closingJournalFlag);
850
- }
851
- }
852
- ```
853
-
854
- </details>
855
-
856
- ### 月次勘定科目残高 Entity
857
-
858
- <details>
859
- <summary>MonthlyAccountBalance.java</summary>
860
-
861
- ```java
862
- package com.example.accounting.domain.model.balance;
863
-
864
- import com.example.accounting.domain.model.account.Account;
865
- import com.example.accounting.domain.model.department.Department;
866
- import jakarta.persistence.*;
867
- import lombok.*;
868
-
869
- import java.math.BigDecimal;
870
- import java.time.LocalDateTime;
871
-
872
- /**
873
- * 月次勘定科目残高 Entity
874
- */
875
- @Entity
876
- @Table(name = "月次勘定科目残高")
877
- @Data
878
- @Builder
879
- @NoArgsConstructor
880
- @AllArgsConstructor
881
- public class MonthlyAccountBalance {
882
-
883
- @EmbeddedId
884
- private MonthlyAccountBalanceId id;
885
-
886
- @ManyToOne(fetch = FetchType.LAZY)
887
- @JoinColumn(name = "勘定科目コード", referencedColumnName = "勘定科目コード",
888
- insertable = false, updatable = false)
889
- private Account account;
890
-
891
- @ManyToOne(fetch = FetchType.LAZY)
892
- @JoinColumn(name = "部門コード", referencedColumnName = "部門コード",
893
- insertable = false, updatable = false)
894
- private Department department;
895
-
896
- @Column(name = "月初残高", nullable = false, precision = 13)
897
- private BigDecimal openingBalance;
898
-
899
- @Column(name = "借方金額", nullable = false, precision = 14, scale = 2)
900
- private BigDecimal debitAmount;
901
-
902
- @Column(name = "貸方金額", nullable = false, precision = 14, scale = 2)
903
- private BigDecimal creditAmount;
904
-
905
- @Column(name = "月末残高", nullable = false, precision = 13)
906
- private BigDecimal closingBalance;
907
-
908
- @Column(name = "作成日時", nullable = false, updatable = false)
909
- private LocalDateTime createdAt;
910
-
911
- @Column(name = "更新日時", nullable = false)
912
- private LocalDateTime updatedAt;
913
-
914
- /**
915
- * 月末残高を計算する
916
- * @param isDebitAccount 借方勘定かどうか
917
- */
918
- public void calculateClosingBalance(boolean isDebitAccount) {
919
- if (isDebitAccount) {
920
- // 借方勘定:月初 + 借方 - 貸方
921
- this.closingBalance = openingBalance
922
- .add(debitAmount)
923
- .subtract(creditAmount);
924
- } else {
925
- // 貸方勘定:月初 + 貸方 - 借方
926
- this.closingBalance = openingBalance
927
- .add(creditAmount)
928
- .subtract(debitAmount);
929
- }
930
- }
931
-
932
- @PrePersist
933
- protected void onCreate() {
934
- LocalDateTime now = LocalDateTime.now();
935
- this.createdAt = now;
936
- this.updatedAt = now;
937
- initializeDefaults();
938
- }
939
-
940
- @PreUpdate
941
- protected void onUpdate() {
942
- this.updatedAt = LocalDateTime.now();
943
- }
944
-
945
- private void initializeDefaults() {
946
- if (this.openingBalance == null) this.openingBalance = BigDecimal.ZERO;
947
- if (this.debitAmount == null) this.debitAmount = BigDecimal.ZERO;
948
- if (this.creditAmount == null) this.creditAmount = BigDecimal.ZERO;
949
- if (this.closingBalance == null) this.closingBalance = BigDecimal.ZERO;
950
- }
951
- }
952
- ```
953
-
954
- </details>
955
-
956
- ### 合計残高試算表行用 Projection
957
-
958
- <details>
959
- <summary>TrialBalanceLineProjection.java と TrialBalanceLine.java</summary>
960
-
961
- ```java
962
- package com.example.accounting.domain.model.balance;
963
-
964
- import java.math.BigDecimal;
965
-
966
- /**
967
- * 合計残高試算表行の Projection インターフェース
968
- */
969
- public interface TrialBalanceLineProjection {
970
- Integer getFiscalYear();
971
- Integer getMonth();
972
- String getAccountCode();
973
- String getAccountName();
974
- String getBsplType();
975
- String getDebitCreditType();
976
- BigDecimal getOpeningBalance();
977
- BigDecimal getDebitTotal();
978
- BigDecimal getCreditTotal();
979
- BigDecimal getClosingBalance();
980
- }
981
- ```
982
-
983
- ```java
984
- package com.example.accounting.domain.model.balance;
985
-
986
- import lombok.AllArgsConstructor;
987
- import lombok.Builder;
988
- import lombok.Data;
989
- import lombok.NoArgsConstructor;
990
-
991
- import java.math.BigDecimal;
992
-
993
- /**
994
- * 合計残高試算表行 DTO
995
- */
996
- @Data
997
- @Builder
998
- @NoArgsConstructor
999
- @AllArgsConstructor
1000
- public class TrialBalanceLine {
1001
- private Integer fiscalYear; // 決算期
1002
- private Integer month; // 月度
1003
- private String accountCode; // 勘定科目コード
1004
- private String accountName; // 勘定科目名
1005
- private String bsplType; // BSPL区分
1006
- private String debitCreditType; // 貸借区分
1007
- private BigDecimal openingBalance; // 月初残高
1008
- private BigDecimal debitTotal; // 借方合計
1009
- private BigDecimal creditTotal; // 貸方合計
1010
- private BigDecimal closingBalance; // 月末残高
1011
-
1012
- /**
1013
- * Projection から DTO を生成
1014
- */
1015
- public static TrialBalanceLine fromProjection(TrialBalanceLineProjection projection) {
1016
- return TrialBalanceLine.builder()
1017
- .fiscalYear(projection.getFiscalYear())
1018
- .month(projection.getMonth())
1019
- .accountCode(projection.getAccountCode())
1020
- .accountName(projection.getAccountName())
1021
- .bsplType(projection.getBsplType())
1022
- .debitCreditType(projection.getDebitCreditType())
1023
- .openingBalance(projection.getOpeningBalance())
1024
- .debitTotal(projection.getDebitTotal())
1025
- .creditTotal(projection.getCreditTotal())
1026
- .closingBalance(projection.getClosingBalance())
1027
- .build();
1028
- }
1029
- }
1030
- ```
1031
-
1032
- </details>
1033
-
1034
- ---
1035
-
1036
- ## 18.8 残高更新サービスの実装
1037
-
1038
- <details>
1039
- <summary>BalanceUpdateService.java</summary>
1040
-
1041
- ```java
1042
- package com.example.accounting.application.service;
1043
-
1044
- import com.example.accounting.application.port.out.DailyAccountBalanceRepository;
1045
- import com.example.accounting.application.port.out.MonthlyAccountBalanceRepository;
1046
- import com.example.accounting.domain.model.journal.DebitCreditType;
1047
- import com.example.accounting.domain.model.journal.Journal;
1048
- import com.example.accounting.domain.model.journal.JournalDebitCreditDetail;
1049
- import lombok.RequiredArgsConstructor;
1050
- import lombok.extern.slf4j.Slf4j;
1051
- import org.springframework.stereotype.Service;
1052
- import org.springframework.transaction.annotation.Transactional;
1053
-
1054
- import java.math.BigDecimal;
1055
- import java.time.LocalDate;
1056
-
1057
- /**
1058
- * 残高更新サービス
1059
- *
1060
- * 仕訳登録時の残高更新を担当
1061
- * JPA 版でもビジネスロジックは MyBatis 版と同じ
1062
- */
1063
- @Service
1064
- @RequiredArgsConstructor
1065
- @Slf4j
1066
- public class BalanceUpdateService {
1067
-
1068
- private final DailyAccountBalanceRepository dailyBalanceRepository;
1069
- private final MonthlyAccountBalanceRepository monthlyBalanceRepository;
1070
-
1071
- /**
1072
- * 仕訳登録に伴う残高更新
1073
- */
1074
- @Transactional
1075
- public void updateBalancesForJournal(Journal journal) {
1076
- var postingDate = journal.getPostingDate();
1077
- var closingFlag = journal.getClosingEntryFlag() != null
1078
- ? journal.getClosingEntryFlag() : false;
1079
-
1080
- // 仕訳の各明細について残高を更新
1081
- for (var detail : journal.getDetails()) {
1082
- for (var dcDetail : detail.getDebitCreditDetails()) {
1083
- updateDailyBalance(postingDate, dcDetail, closingFlag);
1084
- }
1085
- }
1086
-
1087
- log.info("残高更新完了: 仕訳伝票番号={}, 起票日={}",
1088
- journal.getJournalVoucherNumber(), postingDate);
1089
- }
1090
-
1091
- /**
1092
- * 日次残高の更新
1093
- * JPA 版では upsert メソッドで Native Query を使用
1094
- */
1095
- private void updateDailyBalance(LocalDate postingDate,
1096
- JournalDebitCreditDetail dcDetail, boolean closingFlag) {
1097
- var debitAmount = dcDetail.getDebitCreditType() == DebitCreditType.DEBIT
1098
- ? dcDetail.getAmount() : BigDecimal.ZERO;
1099
- var creditAmount = dcDetail.getDebitCreditType() == DebitCreditType.CREDIT
1100
- ? dcDetail.getAmount() : BigDecimal.ZERO;
1101
-
1102
- dailyBalanceRepository.upsert(
1103
- postingDate,
1104
- dcDetail.getAccountCode(),
1105
- dcDetail.getSubAccountCode() != null ? dcDetail.getSubAccountCode() : "",
1106
- dcDetail.getDepartmentCode() != null ? dcDetail.getDepartmentCode() : "00000",
1107
- dcDetail.getProjectCode() != null ? dcDetail.getProjectCode() : "",
1108
- closingFlag,
1109
- debitAmount,
1110
- creditAmount
1111
- );
1112
- }
1113
-
1114
- /**
1115
- * 月次残高の集計
1116
- */
1117
- @Transactional
1118
- public int aggregateMonthlyBalance(int fiscalYear, int month) {
1119
- LocalDate fromDate = LocalDate.of(fiscalYear, month, 1);
1120
- LocalDate toDate = fromDate.withDayOfMonth(fromDate.lengthOfMonth());
1121
-
1122
- int count = monthlyBalanceRepository.aggregateFromDaily(
1123
- fiscalYear, month, fromDate, toDate);
1124
-
1125
- log.info("月次残高集計完了: 決算期={}, 月度={}, 件数={}",
1126
- fiscalYear, month, count);
1127
-
1128
- return count;
1129
- }
1130
-
1131
- /**
1132
- * 月次残高の繰越処理
1133
- */
1134
- @Transactional
1135
- public int carryForwardMonthlyBalance(int fiscalYear, int fromMonth, int toMonth) {
1136
- int count = monthlyBalanceRepository.carryForward(fiscalYear, fromMonth, toMonth);
1137
-
1138
- log.info("月次残高繰越完了: 決算期={}, {}月 → {}月, 件数={}",
1139
- fiscalYear, fromMonth, toMonth, count);
1140
-
1141
- return count;
1142
- }
1143
- }
1144
- ```
1145
-
1146
- </details>
1147
-
1148
- ---
1149
-
1150
- ## 18.9 まとめ:設計のポイント
1151
-
1152
- ### 複合主キーによる多次元管理
1153
-
1154
- 1. **日次残高**:起票日 + 勘定科目 + 補助科目 + 部門 + プロジェクト + 決算仕訳フラグ
1155
- 2. **月次残高**:決算期 + 月度 + 勘定科目 + 補助科目 + 部門 + プロジェクト + 決算仕訳フラグ
1156
- 3. JPA では @EmbeddedId + @Embeddable で複合主キーを表現
1157
-
1158
- ### UPSERT による効率的な残高更新
1159
-
1160
- - PostgreSQL の `INSERT ON CONFLICT DO UPDATE` を使用
1161
- - JPA では @Query + nativeQuery で Native SQL を実行
1162
- - 既存レコードがあれば金額を加算、なければ新規挿入
1163
-
1164
- ### Projection による集計結果のマッピング
1165
-
1166
- - Native Query の結果を Projection インターフェースで受け取り
1167
- - Projection から DTO への変換メソッドを用意
1168
- - 型安全な集計結果の取り扱いが可能
1169
-
1170
- ### MyBatis 版との比較
1171
-
1172
- | 観点 | MyBatis 版 | JPA 版 |
1173
- |------|-----------|--------|
1174
- | 複合主キー | Key 内部クラス | @EmbeddedId + @Embeddable |
1175
- | 集計結果マッピング | resultMap + DTO | Projection インターフェース |
1176
- | UPSERT | XML で INSERT ON CONFLICT | @Query + nativeQuery |
1177
- | テスト | @MybatisTest | @DataJpaTest |
1178
-
1179
- ---
1180
-
1181
- ## 次章予告
1182
-
1183
- [第19章](chapter19-orm.md)では、赤黒処理によるデータ訂正方式と、JPA Auditing を使用したログ管理の設計について解説します。
1
+ # 第18章:勘定科目残高の設計(ORM版)
2
+
3
+ 会計システムにおける残高管理の基盤となる「勘定科目別残高テーブル」を TDD で設計していきます。日次・月次の残高管理と、帳票出力に必要なテーブル構造を実装します。
4
+
5
+ JPA 版では、@EmbeddedId による複合主キー、@Query による集計クエリ、Projection インターフェースを活用します。
6
+
7
+ ---
8
+
9
+ ## 18.1 日次勘定科目残高の設計
10
+
11
+ ### 日次残高管理の目的
12
+
13
+ 日次勘定科目残高は、日々の仕訳処理に連動して更新される残高情報を管理します。日計表の出力やリアルタイムな残高把握に使用します。
14
+
15
+ ```plantuml
16
+ @startuml
17
+
18
+ title 日次残高管理の役割
19
+
20
+ rectangle "仕訳処理" as journal {
21
+ card "仕訳入力" as j1
22
+ card "仕訳承認" as j2
23
+ card "仕訳転記" as j3
24
+ }
25
+
26
+ rectangle "残高更新" as balance {
27
+ card "日次残高更新" as b1
28
+ card "月次残高更新" as b2
29
+ }
30
+
31
+ rectangle "帳票出力" as report {
32
+ card "日計表" as r1
33
+ card "合計残高試算表" as r2
34
+ card "財務諸表" as r3
35
+ }
36
+
37
+ j3 --> b1 : 即時更新
38
+ b1 --> b2 : 月末集計
39
+ b1 --> r1 : データ参照
40
+ b2 --> r2 : データ参照
41
+ b2 --> r3 : データ参照
42
+
43
+ note bottom of b1
44
+ 日次勘定科目残高は
45
+ 仕訳入力時に即座に更新
46
+ リアルタイムな残高把握を実現
47
+ end note
48
+
49
+ @enduml
50
+ ```
51
+
52
+ | 目的 | 説明 |
53
+ |-----|------|
54
+ | 日計表出力 | 日単位の勘定科目別借方・貸方合計の集計 |
55
+ | リアルタイム残高 | 仕訳入力と同時に残高を更新 |
56
+ | 監査証跡 | 日付別の取引履歴の保持 |
57
+ | 決算仕訳の区別 | 通常仕訳と決算仕訳の分離管理 |
58
+
59
+ ### 複合主キーによる多次元管理
60
+
61
+ 日次残高テーブルは、以下の6つのカラムで複合主キーを構成します。
62
+
63
+ | カラム | 説明 | 例 |
64
+ |--------|------|-----|
65
+ | 起票日 | 仕訳の起票日 | 2024-04-01 |
66
+ | 勘定科目コード | 勘定科目マスタのコード | 11110 |
67
+ | 補助科目コード | 補助的な分類(空文字可) | 空文字 |
68
+ | 部門コード | 部門マスタのコード | 10100 |
69
+ | プロジェクトコード | プロジェクト単位管理(空文字可) | P001 |
70
+ | 決算仕訳フラグ | 決算仕訳か否か | false |
71
+
72
+ この設計により、同じ勘定科目でも以下の粒度で残高を分けて管理できます。
73
+
74
+ - 部門別の売上高
75
+ - プロジェクト別の原価
76
+ - 通常仕訳と決算仕訳の分離
77
+
78
+ ---
79
+
80
+ ## 18.2 MyBatis 版との実装比較
81
+
82
+ ### データアクセス層の比較
83
+
84
+ | 機能 | MyBatis 版 | JPA 版 |
85
+ |-----|-----------|--------|
86
+ | 複合主キー | Key 内部クラス | @EmbeddedId + @Embeddable |
87
+ | 検索結果マッピング | resultMap + DTO | Projection インターフェース |
88
+ | UPSERT | XML で INSERT ON CONFLICT | @Query + nativeQuery |
89
+ | 集計クエリ | XML で GROUP BY | Native Query + Projection |
90
+ | 日計表出力 | resultMap でマッピング | Projection → DTO 変換 |
91
+
92
+ ### Flyway マイグレーション
93
+
94
+ <details>
95
+ <summary>V008__create_daily_account_balance_table.sql</summary>
96
+
97
+ ```sql
98
+ -- 日次勘定科目残高
99
+ CREATE TABLE "日次勘定科目残高" (
100
+ "起票日" DATE NOT NULL,
101
+ "勘定科目コード" VARCHAR(5) NOT NULL,
102
+ "補助科目コード" VARCHAR(10) NOT NULL DEFAULT '',
103
+ "部門コード" VARCHAR(5) NOT NULL DEFAULT '00000',
104
+ "プロジェクトコード" VARCHAR(10) NOT NULL DEFAULT '',
105
+ "決算仕訳フラグ" SMALLINT NOT NULL DEFAULT 0,
106
+ "借方金額" DECIMAL(14,2) NOT NULL DEFAULT 0,
107
+ "貸方金額" DECIMAL(14,2) NOT NULL DEFAULT 0,
108
+ "作成日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
109
+ "更新日時" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
110
+ PRIMARY KEY (
111
+ "起票日",
112
+ "勘定科目コード",
113
+ "補助科目コード",
114
+ "部門コード",
115
+ "プロジェクトコード",
116
+ "決算仕訳フラグ"
117
+ ),
118
+ CONSTRAINT "fk_日次残高_勘定科目"
119
+ FOREIGN KEY ("勘定科目コード") REFERENCES "勘定科目マスタ"("勘定科目コード"),
120
+ CONSTRAINT "fk_日次残高_部門"
121
+ FOREIGN KEY ("部門コード") REFERENCES "部門マスタ"("部門コード")
122
+ );
123
+
124
+ -- インデックス
125
+ CREATE INDEX "idx_日次残高_起票日" ON "日次勘定科目残高"("起票日");
126
+ CREATE INDEX "idx_日次残高_勘定科目" ON "日次勘定科目残高"("勘定科目コード");
127
+ CREATE INDEX "idx_日次残高_部門" ON "日次勘定科目残高"("部門コード");
128
+ ```
129
+
130
+ </details>
131
+
132
+ ---
133
+
134
+ ## 18.3 JPA エンティティの実装
135
+
136
+ ### 複合主キークラス(@Embeddable)
137
+
138
+ <details>
139
+ <summary>DailyAccountBalanceId.java</summary>
140
+
141
+ ```java
142
+ package com.example.accounting.domain.model.balance;
143
+
144
+ import jakarta.persistence.Column;
145
+ import jakarta.persistence.Embeddable;
146
+ import lombok.*;
147
+
148
+ import java.io.Serializable;
149
+ import java.time.LocalDate;
150
+ import java.util.Objects;
151
+
152
+ /**
153
+ * 日次勘定科目残高の複合主キー
154
+ *
155
+ * JPA では @EmbeddedId で複合主キーを表現
156
+ * MyBatis 版では Key 内部クラスを使用していたが、
157
+ * JPA 版では @Embeddable アノテーション付きクラスで実装
158
+ *
159
+ * 注意: equals() と hashCode() の実装が必須
160
+ */
161
+ @Embeddable
162
+ @Data
163
+ @Builder
164
+ @NoArgsConstructor
165
+ @AllArgsConstructor
166
+ public class DailyAccountBalanceId implements Serializable {
167
+
168
+ @Column(name = "起票日", nullable = false)
169
+ private LocalDate postingDate;
170
+
171
+ @Column(name = "勘定科目コード", length = 5, nullable = false)
172
+ private String accountCode;
173
+
174
+ @Column(name = "補助科目コード", length = 10, nullable = false)
175
+ private String subAccountCode;
176
+
177
+ @Column(name = "部門コード", length = 5, nullable = false)
178
+ private String departmentCode;
179
+
180
+ @Column(name = "プロジェクトコード", length = 10, nullable = false)
181
+ private String projectCode;
182
+
183
+ @Column(name = "決算仕訳フラグ", nullable = false)
184
+ private Boolean closingJournalFlag;
185
+
186
+ @Override
187
+ public boolean equals(Object o) {
188
+ if (this == o) return true;
189
+ if (o == null || getClass() != o.getClass()) return false;
190
+ DailyAccountBalanceId that = (DailyAccountBalanceId) o;
191
+ return Objects.equals(postingDate, that.postingDate) &&
192
+ Objects.equals(accountCode, that.accountCode) &&
193
+ Objects.equals(subAccountCode, that.subAccountCode) &&
194
+ Objects.equals(departmentCode, that.departmentCode) &&
195
+ Objects.equals(projectCode, that.projectCode) &&
196
+ Objects.equals(closingJournalFlag, that.closingJournalFlag);
197
+ }
198
+
199
+ @Override
200
+ public int hashCode() {
201
+ return Objects.hash(postingDate, accountCode, subAccountCode,
202
+ departmentCode, projectCode, closingJournalFlag);
203
+ }
204
+ }
205
+ ```
206
+
207
+ </details>
208
+
209
+ ### 日次勘定科目残高 Entity
210
+
211
+ <details>
212
+ <summary>DailyAccountBalance.java</summary>
213
+
214
+ ```java
215
+ package com.example.accounting.domain.model.balance;
216
+
217
+ import com.example.accounting.domain.model.account.Account;
218
+ import com.example.accounting.domain.model.department.Department;
219
+ import jakarta.persistence.*;
220
+ import lombok.*;
221
+
222
+ import java.math.BigDecimal;
223
+ import java.time.LocalDateTime;
224
+
225
+ /**
226
+ * 日次勘定科目残高 Entity
227
+ *
228
+ * JPA 版では @EmbeddedId で複合主キーを定義
229
+ * MyBatis 版では単純な POJO + Key 内部クラスだったが、
230
+ * JPA 版では Entity アノテーションと関連定義が必要
231
+ */
232
+ @Entity
233
+ @Table(name = "日次勘定科目残高")
234
+ @Data
235
+ @Builder
236
+ @NoArgsConstructor
237
+ @AllArgsConstructor
238
+ public class DailyAccountBalance {
239
+
240
+ /**
241
+ * 複合主キー
242
+ * @EmbeddedId で埋め込みIDを使用
243
+ */
244
+ @EmbeddedId
245
+ private DailyAccountBalanceId id;
246
+
247
+ /**
248
+ * 勘定科目マスタとの関連
249
+ */
250
+ @ManyToOne(fetch = FetchType.LAZY)
251
+ @JoinColumn(name = "勘定科目コード", referencedColumnName = "勘定科目コード",
252
+ insertable = false, updatable = false)
253
+ private Account account;
254
+
255
+ /**
256
+ * 部門マスタとの関連
257
+ */
258
+ @ManyToOne(fetch = FetchType.LAZY)
259
+ @JoinColumn(name = "部門コード", referencedColumnName = "部門コード",
260
+ insertable = false, updatable = false)
261
+ private Department department;
262
+
263
+ @Column(name = "借方金額", nullable = false, precision = 14, scale = 2)
264
+ private BigDecimal debitAmount;
265
+
266
+ @Column(name = "貸方金額", nullable = false, precision = 14, scale = 2)
267
+ private BigDecimal creditAmount;
268
+
269
+ @Column(name = "作成日時", nullable = false, updatable = false)
270
+ private LocalDateTime createdAt;
271
+
272
+ @Column(name = "更新日時", nullable = false)
273
+ private LocalDateTime updatedAt;
274
+
275
+ /**
276
+ * 残高を計算する(貸借区分に応じて)
277
+ * @param isDebitAccount 借方勘定かどうか
278
+ * @return 残高
279
+ */
280
+ public BigDecimal calculateBalance(boolean isDebitAccount) {
281
+ if (isDebitAccount) {
282
+ // 借方勘定:借方 - 貸方
283
+ return debitAmount.subtract(creditAmount);
284
+ } else {
285
+ // 貸方勘定:貸方 - 借方
286
+ return creditAmount.subtract(debitAmount);
287
+ }
288
+ }
289
+
290
+ /**
291
+ * 金額を加算する
292
+ */
293
+ public void addAmounts(BigDecimal debit, BigDecimal credit) {
294
+ this.debitAmount = this.debitAmount.add(debit);
295
+ this.creditAmount = this.creditAmount.add(credit);
296
+ this.updatedAt = LocalDateTime.now();
297
+ }
298
+
299
+ @PrePersist
300
+ protected void onCreate() {
301
+ LocalDateTime now = LocalDateTime.now();
302
+ this.createdAt = now;
303
+ this.updatedAt = now;
304
+ if (this.debitAmount == null) {
305
+ this.debitAmount = BigDecimal.ZERO;
306
+ }
307
+ if (this.creditAmount == null) {
308
+ this.creditAmount = BigDecimal.ZERO;
309
+ }
310
+ }
311
+
312
+ @PreUpdate
313
+ protected void onUpdate() {
314
+ this.updatedAt = LocalDateTime.now();
315
+ }
316
+ }
317
+ ```
318
+
319
+ </details>
320
+
321
+ ### 日計表行用 Projection インターフェース
322
+
323
+ <details>
324
+ <summary>DailyReportLineProjection.java と DailyReportLine.java</summary>
325
+
326
+ ```java
327
+ package com.example.accounting.domain.model.balance;
328
+
329
+ import java.math.BigDecimal;
330
+ import java.time.LocalDate;
331
+
332
+ /**
333
+ * 日計表行の Projection インターフェース
334
+ *
335
+ * JPA 版では Projection インターフェースを使用して
336
+ * 集計クエリの結果をマッピング
337
+ * MyBatis 版では resultMap で DTO にマッピングしていた
338
+ */
339
+ public interface DailyReportLineProjection {
340
+ LocalDate getReportDate();
341
+ String getAccountCode();
342
+ String getAccountName();
343
+ String getSubAccountCode();
344
+ String getSubAccountName();
345
+ BigDecimal getDebitTotal();
346
+ BigDecimal getCreditTotal();
347
+ BigDecimal getBalance();
348
+ }
349
+ ```
350
+
351
+ ```java
352
+ package com.example.accounting.domain.model.balance;
353
+
354
+ import lombok.AllArgsConstructor;
355
+ import lombok.Builder;
356
+ import lombok.Data;
357
+ import lombok.NoArgsConstructor;
358
+
359
+ import java.math.BigDecimal;
360
+ import java.time.LocalDate;
361
+
362
+ /**
363
+ * 日計表行 DTO
364
+ */
365
+ @Data
366
+ @Builder
367
+ @NoArgsConstructor
368
+ @AllArgsConstructor
369
+ public class DailyReportLine {
370
+ private LocalDate reportDate; // 対象日
371
+ private String accountCode; // 勘定科目コード
372
+ private String accountName; // 勘定科目名
373
+ private String subAccountCode; // 補助科目コード
374
+ private String subAccountName; // 補助科目名
375
+ private BigDecimal debitTotal; // 借方合計
376
+ private BigDecimal creditTotal; // 貸方合計
377
+ private BigDecimal balance; // 残高
378
+
379
+ /**
380
+ * Projection から DTO を生成
381
+ */
382
+ public static DailyReportLine fromProjection(DailyReportLineProjection projection) {
383
+ return DailyReportLine.builder()
384
+ .reportDate(projection.getReportDate())
385
+ .accountCode(projection.getAccountCode())
386
+ .accountName(projection.getAccountName())
387
+ .subAccountCode(projection.getSubAccountCode())
388
+ .subAccountName(projection.getSubAccountName())
389
+ .debitTotal(projection.getDebitTotal())
390
+ .creditTotal(projection.getCreditTotal())
391
+ .balance(projection.getBalance())
392
+ .build();
393
+ }
394
+ }
395
+ ```
396
+
397
+ </details>
398
+
399
+ ---
400
+
401
+ ## 18.4 TDD による日次残高テーブルの実装
402
+
403
+ ### リポジトリのテスト
404
+
405
+ <details>
406
+ <summary>DailyAccountBalanceRepositoryTest.java</summary>
407
+
408
+ ```java
409
+ package com.example.accounting.infrastructure.persistence;
410
+
411
+ import com.example.accounting.domain.model.balance.DailyAccountBalance;
412
+ import com.example.accounting.domain.model.balance.DailyAccountBalanceId;
413
+ import com.example.accounting.infrastructure.persistence.repository.DailyAccountBalanceJpaRepository;
414
+ import org.junit.jupiter.api.DisplayName;
415
+ import org.junit.jupiter.api.Nested;
416
+ import org.junit.jupiter.api.Test;
417
+ import org.springframework.beans.factory.annotation.Autowired;
418
+ import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
419
+ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
420
+ import org.springframework.test.context.DynamicPropertyRegistry;
421
+ import org.springframework.test.context.DynamicPropertySource;
422
+ import org.testcontainers.containers.PostgreSQLContainer;
423
+ import org.testcontainers.junit.jupiter.Container;
424
+ import org.testcontainers.junit.jupiter.Testcontainers;
425
+
426
+ import java.math.BigDecimal;
427
+ import java.time.LocalDate;
428
+
429
+ import static org.assertj.core.api.Assertions.*;
430
+
431
+ /**
432
+ * 日次勘定科目残高リポジトリのテスト
433
+ *
434
+ * JPA 版では @DataJpaTest を使用(MyBatis 版では @MybatisTest)
435
+ */
436
+ @DataJpaTest
437
+ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
438
+ @Testcontainers
439
+ @DisplayName("日次勘定科目残高リポジトリのテスト")
440
+ class DailyAccountBalanceRepositoryTest {
441
+
442
+ @Container
443
+ static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16")
444
+ .withDatabaseName("testdb")
445
+ .withUsername("test")
446
+ .withPassword("test");
447
+
448
+ @DynamicPropertySource
449
+ static void configureProperties(DynamicPropertyRegistry registry) {
450
+ registry.add("spring.datasource.url", postgres::getJdbcUrl);
451
+ registry.add("spring.datasource.username", postgres::getUsername);
452
+ registry.add("spring.datasource.password", postgres::getPassword);
453
+ }
454
+
455
+ @Autowired
456
+ private DailyAccountBalanceJpaRepository dailyBalanceRepository;
457
+
458
+ @Nested
459
+ @DisplayName("日次残高の登録・更新")
460
+ class DailyBalanceUpsertTest {
461
+
462
+ @Test
463
+ @DisplayName("新規の日次残高を登録できる")
464
+ void shouldInsertNewDailyBalance() {
465
+ // Given
466
+ var id = DailyAccountBalanceId.builder()
467
+ .postingDate(LocalDate.of(2024, 4, 1))
468
+ .accountCode("11110") // 現金
469
+ .subAccountCode("")
470
+ .departmentCode("10100")
471
+ .projectCode("")
472
+ .closingJournalFlag(false)
473
+ .build();
474
+
475
+ var balance = DailyAccountBalance.builder()
476
+ .id(id)
477
+ .debitAmount(new BigDecimal("100000"))
478
+ .creditAmount(BigDecimal.ZERO)
479
+ .build();
480
+
481
+ // When
482
+ dailyBalanceRepository.save(balance);
483
+
484
+ // Then
485
+ var saved = dailyBalanceRepository.findById(id);
486
+ assertThat(saved).isPresent();
487
+ assertThat(saved.get().getDebitAmount())
488
+ .isEqualByComparingTo("100000");
489
+ }
490
+
491
+ @Test
492
+ @DisplayName("既存の日次残高を更新できる")
493
+ void shouldUpdateExistingDailyBalance() {
494
+ // Given: 初回登録
495
+ var id = DailyAccountBalanceId.builder()
496
+ .postingDate(LocalDate.of(2024, 4, 1))
497
+ .accountCode("11110")
498
+ .subAccountCode("")
499
+ .departmentCode("10100")
500
+ .projectCode("")
501
+ .closingJournalFlag(false)
502
+ .build();
503
+
504
+ var balance1 = DailyAccountBalance.builder()
505
+ .id(id)
506
+ .debitAmount(new BigDecimal("100000"))
507
+ .creditAmount(BigDecimal.ZERO)
508
+ .build();
509
+ dailyBalanceRepository.save(balance1);
510
+
511
+ // When: 金額を追加
512
+ var saved = dailyBalanceRepository.findById(id).orElseThrow();
513
+ saved.addAmounts(new BigDecimal("50000"), BigDecimal.ZERO);
514
+ dailyBalanceRepository.save(saved);
515
+
516
+ // Then: 合算される
517
+ var updated = dailyBalanceRepository.findById(id);
518
+ assertThat(updated).isPresent();
519
+ assertThat(updated.get().getDebitAmount())
520
+ .isEqualByComparingTo("150000");
521
+ }
522
+ }
523
+
524
+ @Nested
525
+ @DisplayName("日次残高の検索")
526
+ class DailyBalanceSearchTest {
527
+
528
+ @Test
529
+ @DisplayName("日付範囲で日次残高を検索できる")
530
+ void shouldFindBalancesByDateRange() {
531
+ // When
532
+ var balances = dailyBalanceRepository.findByIdPostingDateBetween(
533
+ LocalDate.of(2024, 4, 1),
534
+ LocalDate.of(2024, 4, 30)
535
+ );
536
+
537
+ // Then
538
+ assertThat(balances).allMatch(b ->
539
+ !b.getId().getPostingDate().isBefore(LocalDate.of(2024, 4, 1)) &&
540
+ !b.getId().getPostingDate().isAfter(LocalDate.of(2024, 4, 30))
541
+ );
542
+ }
543
+
544
+ @Test
545
+ @DisplayName("勘定科目コードで日次残高を検索できる")
546
+ void shouldFindBalancesByAccountCode() {
547
+ // When
548
+ var balances = dailyBalanceRepository.findByIdAccountCode("11110");
549
+
550
+ // Then
551
+ assertThat(balances).allMatch(b ->
552
+ b.getId().getAccountCode().equals("11110")
553
+ );
554
+ }
555
+ }
556
+ }
557
+ ```
558
+
559
+ </details>
560
+
561
+ ---
562
+
563
+ ## 18.5 JpaRepository インターフェース
564
+
565
+ ### 日次勘定科目残高 Repository
566
+
567
+ <details>
568
+ <summary>DailyAccountBalanceJpaRepository.java</summary>
569
+
570
+ ```java
571
+ package com.example.accounting.infrastructure.persistence.repository;
572
+
573
+ import com.example.accounting.domain.model.balance.DailyAccountBalance;
574
+ import com.example.accounting.domain.model.balance.DailyAccountBalanceId;
575
+ import com.example.accounting.domain.model.balance.DailyReportLineProjection;
576
+ import org.springframework.data.jpa.repository.JpaRepository;
577
+ import org.springframework.data.jpa.repository.Modifying;
578
+ import org.springframework.data.jpa.repository.Query;
579
+ import org.springframework.data.repository.query.Param;
580
+ import org.springframework.stereotype.Repository;
581
+
582
+ import java.math.BigDecimal;
583
+ import java.time.LocalDate;
584
+ import java.util.List;
585
+
586
+ /**
587
+ * 日次勘定科目残高 JpaRepository
588
+ *
589
+ * JPA 版では JpaRepository を継承
590
+ * 複合主キーは DailyAccountBalanceId として定義
591
+ * 集計クエリは @Query + Projection で実装
592
+ */
593
+ @Repository
594
+ public interface DailyAccountBalanceJpaRepository
595
+ extends JpaRepository<DailyAccountBalance, DailyAccountBalanceId> {
596
+
597
+ /**
598
+ * 日付範囲で検索
599
+ * メソッド名規約で自動生成
600
+ */
601
+ List<DailyAccountBalance> findByIdPostingDateBetween(
602
+ LocalDate fromDate, LocalDate toDate);
603
+
604
+ /**
605
+ * 起票日で検索
606
+ */
607
+ List<DailyAccountBalance> findByIdPostingDate(LocalDate postingDate);
608
+
609
+ /**
610
+ * 勘定科目コードで検索
611
+ */
612
+ List<DailyAccountBalance> findByIdAccountCode(String accountCode);
613
+
614
+ /**
615
+ * 部門コードで検索
616
+ */
617
+ List<DailyAccountBalance> findByIdDepartmentCode(String departmentCode);
618
+
619
+ /**
620
+ * 日計表データ取得
621
+ * Native Query で集計クエリを実行し、Projection にマッピング
622
+ */
623
+ @Query(value = """
624
+ SELECT
625
+ d."起票日" as reportDate,
626
+ d."勘定科目コード" as accountCode,
627
+ a."勘定科目名" as accountName,
628
+ d."補助科目コード" as subAccountCode,
629
+ '' as subAccountName,
630
+ SUM(d."借方金額") as debitTotal,
631
+ SUM(d."貸方金額") as creditTotal,
632
+ CASE
633
+ WHEN a."貸借区分" = '借方'
634
+ THEN SUM(d."借方金額") - SUM(d."貸方金額")
635
+ ELSE SUM(d."貸方金額") - SUM(d."借方金額")
636
+ END as balance
637
+ FROM "日次勘定科目残高" d
638
+ JOIN "勘定科目マスタ" a ON d."勘定科目コード" = a."勘定科目コード"
639
+ WHERE d."起票日" = :reportDate
640
+ GROUP BY d."起票日", d."勘定科目コード", a."勘定科目名",
641
+ d."補助科目コード", a."貸借区分"
642
+ ORDER BY d."勘定科目コード", d."補助科目コード"
643
+ """, nativeQuery = true)
644
+ List<DailyReportLineProjection> getDailyReport(@Param("reportDate") LocalDate reportDate);
645
+
646
+ /**
647
+ * UPSERT 用のカスタムクエリ
648
+ * PostgreSQL の ON CONFLICT を使用
649
+ */
650
+ @Modifying
651
+ @Query(value = """
652
+ INSERT INTO "日次勘定科目残高" (
653
+ "起票日", "勘定科目コード", "補助科目コード",
654
+ "部門コード", "プロジェクトコード", "決算仕訳フラグ",
655
+ "借方金額", "貸方金額", "作成日時", "更新日時"
656
+ ) VALUES (
657
+ :postingDate, :accountCode, :subAccountCode,
658
+ :departmentCode, :projectCode, :closingJournalFlag,
659
+ :debitAmount, :creditAmount, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
660
+ )
661
+ ON CONFLICT (
662
+ "起票日", "勘定科目コード", "補助科目コード",
663
+ "部門コード", "プロジェクトコード", "決算仕訳フラグ"
664
+ )
665
+ DO UPDATE SET
666
+ "借方金額" = "日次勘定科目残高"."借方金額" + EXCLUDED."借方金額",
667
+ "貸方金額" = "日次勘定科目残高"."貸方金額" + EXCLUDED."貸方金額",
668
+ "更新日時" = CURRENT_TIMESTAMP
669
+ """, nativeQuery = true)
670
+ void upsert(
671
+ @Param("postingDate") LocalDate postingDate,
672
+ @Param("accountCode") String accountCode,
673
+ @Param("subAccountCode") String subAccountCode,
674
+ @Param("departmentCode") String departmentCode,
675
+ @Param("projectCode") String projectCode,
676
+ @Param("closingJournalFlag") Boolean closingJournalFlag,
677
+ @Param("debitAmount") BigDecimal debitAmount,
678
+ @Param("creditAmount") BigDecimal creditAmount);
679
+ }
680
+ ```
681
+
682
+ </details>
683
+
684
+ ---
685
+
686
+ ## 18.6 月次勘定科目残高の設計
687
+
688
+ ### 月次残高管理の目的
689
+
690
+ 月次勘定科目残高は、月単位での残高管理を行い、合計残高試算表や財務諸表の出力に使用します。
691
+
692
+ ```plantuml
693
+ @startuml
694
+
695
+ title 月次残高管理の役割
696
+
697
+ rectangle "日次処理" as daily {
698
+ card "日次残高更新" as d1
699
+ card "日計表" as d2
700
+ }
701
+
702
+ rectangle "月次処理" as monthly {
703
+ card "月末残高確定" as m1
704
+ card "月次残高更新" as m2
705
+ card "繰越処理" as m3
706
+ }
707
+
708
+ rectangle "帳票・決算" as closing {
709
+ card "合計残高試算表" as c1
710
+ card "損益計算書" as c2
711
+ card "貸借対照表" as c3
712
+ card "決算仕訳" as c4
713
+ }
714
+
715
+ d1 --> m2 : 月末集計
716
+ m2 --> m1
717
+ m1 --> m3 : 翌月初
718
+ m2 --> c1
719
+ m2 --> c2
720
+ m2 --> c3
721
+ c4 --> m2
722
+
723
+ note bottom of m2
724
+ 月次勘定科目残高は
725
+ ・月初残高
726
+ ・当月借方・貸方
727
+ ・月末残高
728
+ を管理
729
+ end note
730
+
731
+ @enduml
732
+ ```
733
+
734
+ | 目的 | 説明 |
735
+ |-----|------|
736
+ | 合計残高試算表 | 月次の勘定科目別借方・貸方・残高の集計 |
737
+ | 財務諸表出力 | 貸借対照表・損益計算書のデータソース |
738
+ | 月次決算 | 月末残高の確定と繰越処理 |
739
+ | 決算仕訳対応 | 通常仕訳と決算仕訳の分離管理 |
740
+
741
+ ### 月次勘定科目残高テーブルの ER 図
742
+
743
+ ```plantuml
744
+ @startuml
745
+
746
+ entity "月次勘定科目残高" as MonthlyBalance {
747
+ * **決算期**: INTEGER <<PK>>
748
+ * **月度**: SMALLINT <<PK>>
749
+ * **勘定科目コード**: VARCHAR(5) <<PK>> <<FK>>
750
+ * **補助科目コード**: VARCHAR(10) <<PK>>
751
+ * **部門コード**: VARCHAR(5) <<PK>> <<FK>>
752
+ * **プロジェクトコード**: VARCHAR(10) <<PK>>
753
+ * **決算仕訳フラグ**: SMALLINT <<PK>>
754
+ --
755
+ * **月初残高**: DECIMAL(13,0)
756
+ * **借方金額**: DECIMAL(14,2)
757
+ * **貸方金額**: DECIMAL(14,2)
758
+ * **月末残高**: DECIMAL(13,0)
759
+ }
760
+
761
+ entity "日次勘定科目残高" as DailyBalance {
762
+ * **起票日** <<PK>>
763
+ * **勘定科目コード** <<PK>>
764
+ ...
765
+ --
766
+ 借方金額
767
+ 貸方金額
768
+ }
769
+
770
+ DailyBalance ..> MonthlyBalance : 月末集計
771
+
772
+ note right of MonthlyBalance
773
+ 決算期・月度による期間管理
774
+ 月初残高は前月末残高から繰越
775
+ 月末残高 = 月初残高 + 借方金額 - 貸方金額
776
+ (借方勘定の場合)
777
+ end note
778
+
779
+ @enduml
780
+ ```
781
+
782
+ ---
783
+
784
+ ## 18.7 月次残高の JPA エンティティ
785
+
786
+ ### 複合主キークラス
787
+
788
+ <details>
789
+ <summary>MonthlyAccountBalanceId.java</summary>
790
+
791
+ ```java
792
+ package com.example.accounting.domain.model.balance;
793
+
794
+ import jakarta.persistence.Column;
795
+ import jakarta.persistence.Embeddable;
796
+ import lombok.*;
797
+
798
+ import java.io.Serializable;
799
+ import java.util.Objects;
800
+
801
+ /**
802
+ * 月次勘定科目残高の複合主キー
803
+ */
804
+ @Embeddable
805
+ @Data
806
+ @Builder
807
+ @NoArgsConstructor
808
+ @AllArgsConstructor
809
+ public class MonthlyAccountBalanceId implements Serializable {
810
+
811
+ @Column(name = "決算期", nullable = false)
812
+ private Integer fiscalYear;
813
+
814
+ @Column(name = "月度", nullable = false)
815
+ private Integer month;
816
+
817
+ @Column(name = "勘定科目コード", length = 5, nullable = false)
818
+ private String accountCode;
819
+
820
+ @Column(name = "補助科目コード", length = 10, nullable = false)
821
+ private String subAccountCode;
822
+
823
+ @Column(name = "部門コード", length = 5, nullable = false)
824
+ private String departmentCode;
825
+
826
+ @Column(name = "プロジェクトコード", length = 10, nullable = false)
827
+ private String projectCode;
828
+
829
+ @Column(name = "決算仕訳フラグ", nullable = false)
830
+ private Boolean closingJournalFlag;
831
+
832
+ @Override
833
+ public boolean equals(Object o) {
834
+ if (this == o) return true;
835
+ if (o == null || getClass() != o.getClass()) return false;
836
+ MonthlyAccountBalanceId that = (MonthlyAccountBalanceId) o;
837
+ return Objects.equals(fiscalYear, that.fiscalYear) &&
838
+ Objects.equals(month, that.month) &&
839
+ Objects.equals(accountCode, that.accountCode) &&
840
+ Objects.equals(subAccountCode, that.subAccountCode) &&
841
+ Objects.equals(departmentCode, that.departmentCode) &&
842
+ Objects.equals(projectCode, that.projectCode) &&
843
+ Objects.equals(closingJournalFlag, that.closingJournalFlag);
844
+ }
845
+
846
+ @Override
847
+ public int hashCode() {
848
+ return Objects.hash(fiscalYear, month, accountCode, subAccountCode,
849
+ departmentCode, projectCode, closingJournalFlag);
850
+ }
851
+ }
852
+ ```
853
+
854
+ </details>
855
+
856
+ ### 月次勘定科目残高 Entity
857
+
858
+ <details>
859
+ <summary>MonthlyAccountBalance.java</summary>
860
+
861
+ ```java
862
+ package com.example.accounting.domain.model.balance;
863
+
864
+ import com.example.accounting.domain.model.account.Account;
865
+ import com.example.accounting.domain.model.department.Department;
866
+ import jakarta.persistence.*;
867
+ import lombok.*;
868
+
869
+ import java.math.BigDecimal;
870
+ import java.time.LocalDateTime;
871
+
872
+ /**
873
+ * 月次勘定科目残高 Entity
874
+ */
875
+ @Entity
876
+ @Table(name = "月次勘定科目残高")
877
+ @Data
878
+ @Builder
879
+ @NoArgsConstructor
880
+ @AllArgsConstructor
881
+ public class MonthlyAccountBalance {
882
+
883
+ @EmbeddedId
884
+ private MonthlyAccountBalanceId id;
885
+
886
+ @ManyToOne(fetch = FetchType.LAZY)
887
+ @JoinColumn(name = "勘定科目コード", referencedColumnName = "勘定科目コード",
888
+ insertable = false, updatable = false)
889
+ private Account account;
890
+
891
+ @ManyToOne(fetch = FetchType.LAZY)
892
+ @JoinColumn(name = "部門コード", referencedColumnName = "部門コード",
893
+ insertable = false, updatable = false)
894
+ private Department department;
895
+
896
+ @Column(name = "月初残高", nullable = false, precision = 13)
897
+ private BigDecimal openingBalance;
898
+
899
+ @Column(name = "借方金額", nullable = false, precision = 14, scale = 2)
900
+ private BigDecimal debitAmount;
901
+
902
+ @Column(name = "貸方金額", nullable = false, precision = 14, scale = 2)
903
+ private BigDecimal creditAmount;
904
+
905
+ @Column(name = "月末残高", nullable = false, precision = 13)
906
+ private BigDecimal closingBalance;
907
+
908
+ @Column(name = "作成日時", nullable = false, updatable = false)
909
+ private LocalDateTime createdAt;
910
+
911
+ @Column(name = "更新日時", nullable = false)
912
+ private LocalDateTime updatedAt;
913
+
914
+ /**
915
+ * 月末残高を計算する
916
+ * @param isDebitAccount 借方勘定かどうか
917
+ */
918
+ public void calculateClosingBalance(boolean isDebitAccount) {
919
+ if (isDebitAccount) {
920
+ // 借方勘定:月初 + 借方 - 貸方
921
+ this.closingBalance = openingBalance
922
+ .add(debitAmount)
923
+ .subtract(creditAmount);
924
+ } else {
925
+ // 貸方勘定:月初 + 貸方 - 借方
926
+ this.closingBalance = openingBalance
927
+ .add(creditAmount)
928
+ .subtract(debitAmount);
929
+ }
930
+ }
931
+
932
+ @PrePersist
933
+ protected void onCreate() {
934
+ LocalDateTime now = LocalDateTime.now();
935
+ this.createdAt = now;
936
+ this.updatedAt = now;
937
+ initializeDefaults();
938
+ }
939
+
940
+ @PreUpdate
941
+ protected void onUpdate() {
942
+ this.updatedAt = LocalDateTime.now();
943
+ }
944
+
945
+ private void initializeDefaults() {
946
+ if (this.openingBalance == null) this.openingBalance = BigDecimal.ZERO;
947
+ if (this.debitAmount == null) this.debitAmount = BigDecimal.ZERO;
948
+ if (this.creditAmount == null) this.creditAmount = BigDecimal.ZERO;
949
+ if (this.closingBalance == null) this.closingBalance = BigDecimal.ZERO;
950
+ }
951
+ }
952
+ ```
953
+
954
+ </details>
955
+
956
+ ### 合計残高試算表行用 Projection
957
+
958
+ <details>
959
+ <summary>TrialBalanceLineProjection.java と TrialBalanceLine.java</summary>
960
+
961
+ ```java
962
+ package com.example.accounting.domain.model.balance;
963
+
964
+ import java.math.BigDecimal;
965
+
966
+ /**
967
+ * 合計残高試算表行の Projection インターフェース
968
+ */
969
+ public interface TrialBalanceLineProjection {
970
+ Integer getFiscalYear();
971
+ Integer getMonth();
972
+ String getAccountCode();
973
+ String getAccountName();
974
+ String getBsplType();
975
+ String getDebitCreditType();
976
+ BigDecimal getOpeningBalance();
977
+ BigDecimal getDebitTotal();
978
+ BigDecimal getCreditTotal();
979
+ BigDecimal getClosingBalance();
980
+ }
981
+ ```
982
+
983
+ ```java
984
+ package com.example.accounting.domain.model.balance;
985
+
986
+ import lombok.AllArgsConstructor;
987
+ import lombok.Builder;
988
+ import lombok.Data;
989
+ import lombok.NoArgsConstructor;
990
+
991
+ import java.math.BigDecimal;
992
+
993
+ /**
994
+ * 合計残高試算表行 DTO
995
+ */
996
+ @Data
997
+ @Builder
998
+ @NoArgsConstructor
999
+ @AllArgsConstructor
1000
+ public class TrialBalanceLine {
1001
+ private Integer fiscalYear; // 決算期
1002
+ private Integer month; // 月度
1003
+ private String accountCode; // 勘定科目コード
1004
+ private String accountName; // 勘定科目名
1005
+ private String bsplType; // BSPL区分
1006
+ private String debitCreditType; // 貸借区分
1007
+ private BigDecimal openingBalance; // 月初残高
1008
+ private BigDecimal debitTotal; // 借方合計
1009
+ private BigDecimal creditTotal; // 貸方合計
1010
+ private BigDecimal closingBalance; // 月末残高
1011
+
1012
+ /**
1013
+ * Projection から DTO を生成
1014
+ */
1015
+ public static TrialBalanceLine fromProjection(TrialBalanceLineProjection projection) {
1016
+ return TrialBalanceLine.builder()
1017
+ .fiscalYear(projection.getFiscalYear())
1018
+ .month(projection.getMonth())
1019
+ .accountCode(projection.getAccountCode())
1020
+ .accountName(projection.getAccountName())
1021
+ .bsplType(projection.getBsplType())
1022
+ .debitCreditType(projection.getDebitCreditType())
1023
+ .openingBalance(projection.getOpeningBalance())
1024
+ .debitTotal(projection.getDebitTotal())
1025
+ .creditTotal(projection.getCreditTotal())
1026
+ .closingBalance(projection.getClosingBalance())
1027
+ .build();
1028
+ }
1029
+ }
1030
+ ```
1031
+
1032
+ </details>
1033
+
1034
+ ---
1035
+
1036
+ ## 18.8 残高更新サービスの実装
1037
+
1038
+ <details>
1039
+ <summary>BalanceUpdateService.java</summary>
1040
+
1041
+ ```java
1042
+ package com.example.accounting.application.service;
1043
+
1044
+ import com.example.accounting.application.port.out.DailyAccountBalanceRepository;
1045
+ import com.example.accounting.application.port.out.MonthlyAccountBalanceRepository;
1046
+ import com.example.accounting.domain.model.journal.DebitCreditType;
1047
+ import com.example.accounting.domain.model.journal.Journal;
1048
+ import com.example.accounting.domain.model.journal.JournalDebitCreditDetail;
1049
+ import lombok.RequiredArgsConstructor;
1050
+ import lombok.extern.slf4j.Slf4j;
1051
+ import org.springframework.stereotype.Service;
1052
+ import org.springframework.transaction.annotation.Transactional;
1053
+
1054
+ import java.math.BigDecimal;
1055
+ import java.time.LocalDate;
1056
+
1057
+ /**
1058
+ * 残高更新サービス
1059
+ *
1060
+ * 仕訳登録時の残高更新を担当
1061
+ * JPA 版でもビジネスロジックは MyBatis 版と同じ
1062
+ */
1063
+ @Service
1064
+ @RequiredArgsConstructor
1065
+ @Slf4j
1066
+ public class BalanceUpdateService {
1067
+
1068
+ private final DailyAccountBalanceRepository dailyBalanceRepository;
1069
+ private final MonthlyAccountBalanceRepository monthlyBalanceRepository;
1070
+
1071
+ /**
1072
+ * 仕訳登録に伴う残高更新
1073
+ */
1074
+ @Transactional
1075
+ public void updateBalancesForJournal(Journal journal) {
1076
+ var postingDate = journal.getPostingDate();
1077
+ var closingFlag = journal.getClosingEntryFlag() != null
1078
+ ? journal.getClosingEntryFlag() : false;
1079
+
1080
+ // 仕訳の各明細について残高を更新
1081
+ for (var detail : journal.getDetails()) {
1082
+ for (var dcDetail : detail.getDebitCreditDetails()) {
1083
+ updateDailyBalance(postingDate, dcDetail, closingFlag);
1084
+ }
1085
+ }
1086
+
1087
+ log.info("残高更新完了: 仕訳伝票番号={}, 起票日={}",
1088
+ journal.getJournalVoucherNumber(), postingDate);
1089
+ }
1090
+
1091
+ /**
1092
+ * 日次残高の更新
1093
+ * JPA 版では upsert メソッドで Native Query を使用
1094
+ */
1095
+ private void updateDailyBalance(LocalDate postingDate,
1096
+ JournalDebitCreditDetail dcDetail, boolean closingFlag) {
1097
+ var debitAmount = dcDetail.getDebitCreditType() == DebitCreditType.DEBIT
1098
+ ? dcDetail.getAmount() : BigDecimal.ZERO;
1099
+ var creditAmount = dcDetail.getDebitCreditType() == DebitCreditType.CREDIT
1100
+ ? dcDetail.getAmount() : BigDecimal.ZERO;
1101
+
1102
+ dailyBalanceRepository.upsert(
1103
+ postingDate,
1104
+ dcDetail.getAccountCode(),
1105
+ dcDetail.getSubAccountCode() != null ? dcDetail.getSubAccountCode() : "",
1106
+ dcDetail.getDepartmentCode() != null ? dcDetail.getDepartmentCode() : "00000",
1107
+ dcDetail.getProjectCode() != null ? dcDetail.getProjectCode() : "",
1108
+ closingFlag,
1109
+ debitAmount,
1110
+ creditAmount
1111
+ );
1112
+ }
1113
+
1114
+ /**
1115
+ * 月次残高の集計
1116
+ */
1117
+ @Transactional
1118
+ public int aggregateMonthlyBalance(int fiscalYear, int month) {
1119
+ LocalDate fromDate = LocalDate.of(fiscalYear, month, 1);
1120
+ LocalDate toDate = fromDate.withDayOfMonth(fromDate.lengthOfMonth());
1121
+
1122
+ int count = monthlyBalanceRepository.aggregateFromDaily(
1123
+ fiscalYear, month, fromDate, toDate);
1124
+
1125
+ log.info("月次残高集計完了: 決算期={}, 月度={}, 件数={}",
1126
+ fiscalYear, month, count);
1127
+
1128
+ return count;
1129
+ }
1130
+
1131
+ /**
1132
+ * 月次残高の繰越処理
1133
+ */
1134
+ @Transactional
1135
+ public int carryForwardMonthlyBalance(int fiscalYear, int fromMonth, int toMonth) {
1136
+ int count = monthlyBalanceRepository.carryForward(fiscalYear, fromMonth, toMonth);
1137
+
1138
+ log.info("月次残高繰越完了: 決算期={}, {}月 → {}月, 件数={}",
1139
+ fiscalYear, fromMonth, toMonth, count);
1140
+
1141
+ return count;
1142
+ }
1143
+ }
1144
+ ```
1145
+
1146
+ </details>
1147
+
1148
+ ---
1149
+
1150
+ ## 18.9 まとめ:設計のポイント
1151
+
1152
+ ### 複合主キーによる多次元管理
1153
+
1154
+ 1. **日次残高**:起票日 + 勘定科目 + 補助科目 + 部門 + プロジェクト + 決算仕訳フラグ
1155
+ 2. **月次残高**:決算期 + 月度 + 勘定科目 + 補助科目 + 部門 + プロジェクト + 決算仕訳フラグ
1156
+ 3. JPA では @EmbeddedId + @Embeddable で複合主キーを表現
1157
+
1158
+ ### UPSERT による効率的な残高更新
1159
+
1160
+ - PostgreSQL の `INSERT ON CONFLICT DO UPDATE` を使用
1161
+ - JPA では @Query + nativeQuery で Native SQL を実行
1162
+ - 既存レコードがあれば金額を加算、なければ新規挿入
1163
+
1164
+ ### Projection による集計結果のマッピング
1165
+
1166
+ - Native Query の結果を Projection インターフェースで受け取り
1167
+ - Projection から DTO への変換メソッドを用意
1168
+ - 型安全な集計結果の取り扱いが可能
1169
+
1170
+ ### MyBatis 版との比較
1171
+
1172
+ | 観点 | MyBatis 版 | JPA 版 |
1173
+ |------|-----------|--------|
1174
+ | 複合主キー | Key 内部クラス | @EmbeddedId + @Embeddable |
1175
+ | 集計結果マッピング | resultMap + DTO | Projection インターフェース |
1176
+ | UPSERT | XML で INSERT ON CONFLICT | @Query + nativeQuery |
1177
+ | テスト | @MybatisTest | @DataJpaTest |
1178
+
1179
+ ---
1180
+
1181
+ ## 次章予告
1182
+
1183
+ [第19章](chapter19-orm.md)では、赤黒処理によるデータ訂正方式と、JPA Auditing を使用したログ管理の設計について解説します。