@tailor-platform/erp-kit 0.2.2 → 0.4.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 (639) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +193 -69
  3. package/dist/cli.mjs +1038 -398
  4. package/package.json +7 -5
  5. package/skills/erp-kit-app-1-requirements/SKILL.md +27 -17
  6. package/skills/erp-kit-app-2-requirements-review/SKILL.md +5 -4
  7. package/skills/erp-kit-app-2-requirements-review/references/best-practices-check.md +10 -1
  8. package/skills/erp-kit-app-2-requirements-review/references/boundary-consistency-check.md +10 -1
  9. package/skills/erp-kit-app-3-plan/SKILL.md +31 -34
  10. package/skills/erp-kit-app-3-plan/references/resolver-extraction.md +22 -36
  11. package/skills/erp-kit-app-3-plan/references/screen-extraction.md +15 -1
  12. package/skills/erp-kit-app-3-plan/references/story-extraction.md +8 -2
  13. package/skills/erp-kit-app-4-plan-review/SKILL.md +1 -10
  14. package/skills/erp-kit-app-5-impl-backend/SKILL.md +10 -19
  15. package/skills/erp-kit-app-5-impl-backend/references/app-config.md +1 -22
  16. package/skills/erp-kit-app-5-impl-backend/references/module-wiring.md +0 -1
  17. package/skills/erp-kit-app-5-impl-backend/references/resolver-patterns.md +13 -4
  18. package/skills/erp-kit-app-6-impl-frontend/SKILL.md +5 -0
  19. package/skills/erp-kit-app-6-impl-frontend/references/pages.md +16 -46
  20. package/skills/erp-kit-app-7-impl-review/SKILL.md +13 -11
  21. package/skills/erp-kit-app-7-impl-review/references/resolver-doc-code-parity.md +16 -17
  22. package/skills/erp-kit-app-shared/SKILL.md +15 -0
  23. package/skills/erp-kit-app-shared/references/link-format-reference.md +13 -0
  24. package/skills/erp-kit-app-shared/references/naming-conventions.md +21 -0
  25. package/skills/erp-kit-app-shared/references/resolver-classification.md +23 -0
  26. package/skills/erp-kit-app-shared/references/schema-constraints.md +25 -0
  27. package/skills/erp-kit-module-1-requirements/SKILL.md +7 -13
  28. package/skills/erp-kit-module-1-requirements/references/feature-doc.md +1 -1
  29. package/skills/erp-kit-module-2-requirements-review/SKILL.md +21 -5
  30. package/skills/erp-kit-module-2-requirements-review/references/requirements-report-format.md +19 -0
  31. package/skills/erp-kit-module-3-plan/SKILL.md +6 -8
  32. package/skills/erp-kit-module-3-plan/references/naming.md +15 -1
  33. package/skills/erp-kit-module-4-plan-review/SKILL.md +21 -5
  34. package/skills/erp-kit-module-4-plan-review/references/parity-report-format.md +15 -0
  35. package/skills/erp-kit-module-5-impl/SKILL.md +12 -10
  36. package/skills/erp-kit-module-5-impl/references/generated-code.md +2 -2
  37. package/skills/erp-kit-module-6-impl-review/SKILL.md +21 -7
  38. package/skills/erp-kit-module-6-impl-review/references/error-implementation-parity.md +1 -1
  39. package/skills/erp-kit-module-6-impl-review/references/errors.md +1 -1
  40. package/skills/erp-kit-module-6-impl-review/references/impl-parity-report-format.md +15 -0
  41. package/skills/erp-kit-module-shared/SKILL.md +4 -0
  42. package/skills/erp-kit-module-shared/references/errors.md +1 -1
  43. package/skills/erp-kit-module-shared/references/queries.md +1 -1
  44. package/skills/erp-kit-module-shared/references/structure.md +1 -1
  45. package/skills/erp-kit-update/SKILL.md +2 -2
  46. package/src/commands/app/index.ts +75 -31
  47. package/src/commands/check.test.ts +1 -1
  48. package/src/commands/check.ts +2 -35
  49. package/src/commands/doc/index.ts +83 -0
  50. package/src/commands/doc/module.test.ts +119 -0
  51. package/src/commands/doc/module.ts +114 -0
  52. package/src/commands/doc/modules.test.ts +103 -0
  53. package/src/commands/doc/modules.ts +98 -0
  54. package/src/commands/doc/search.test.ts +94 -0
  55. package/src/commands/doc/search.ts +111 -0
  56. package/src/commands/generate-doc.test.ts +63 -0
  57. package/src/commands/generate-doc.ts +105 -0
  58. package/src/commands/index.ts +20 -8
  59. package/src/commands/init-module.test.ts +43 -0
  60. package/src/commands/init-module.ts +74 -0
  61. package/src/commands/lib/command-result.ts +30 -0
  62. package/src/commands/lib/discovery.test.ts +74 -0
  63. package/src/commands/lib/discovery.ts +106 -0
  64. package/src/commands/lib/paths.ts +22 -0
  65. package/src/commands/lib/sync-check-source.test.ts +197 -0
  66. package/src/commands/lib/sync-check-source.ts +100 -0
  67. package/src/commands/lib/sync-check-tests.test.ts +178 -0
  68. package/src/commands/lib/sync-check-tests.ts +69 -0
  69. package/src/commands/mock/index.ts +11 -6
  70. package/src/commands/module/generate.ts +39 -14
  71. package/src/commands/module/index.ts +31 -45
  72. package/src/commands/parse-doc-test-cases.ts +13 -2
  73. package/src/commands/sync-check.test.ts +6 -364
  74. package/src/commands/sync-check.ts +7 -251
  75. package/src/generator/generate-app-code.test.ts +121 -0
  76. package/src/generator/generate-app-code.ts +51 -0
  77. package/src/{commands/scaffold.test.ts → generator/generate-code-boilerplate.test.ts} +19 -89
  78. package/src/generator/generate-code.test.ts +57 -6
  79. package/src/generator/generate-code.ts +40 -157
  80. package/src/generator/generate-errors.ts +34 -0
  81. package/src/generator/generate-permissions.ts +12 -0
  82. package/src/generator/generate-shells.ts +28 -0
  83. package/src/generator/generate-stubs.ts +31 -0
  84. package/src/generator/parse-resolver-doc.test.ts +89 -0
  85. package/src/generator/parse-resolver-doc.ts +125 -0
  86. package/src/generator/scaffold.ts +57 -0
  87. package/src/generator/stub-templates.test.ts +55 -0
  88. package/src/generator/stub-templates.ts +145 -0
  89. package/src/integration.test.ts +2 -2
  90. package/src/modules/audit/README.md +46 -0
  91. package/src/modules/audit/command/activateAuditPolicy.generated.ts +6 -0
  92. package/src/modules/audit/command/activateAuditPolicy.test.ts +186 -0
  93. package/src/modules/audit/command/activateAuditPolicy.ts +97 -0
  94. package/src/modules/audit/command/createAuditPolicy.generated.ts +6 -0
  95. package/src/modules/audit/command/createAuditPolicy.test.ts +395 -0
  96. package/src/modules/audit/command/createAuditPolicy.ts +131 -0
  97. package/src/modules/audit/command/deactivateAuditPolicy.generated.ts +6 -0
  98. package/src/modules/audit/command/deactivateAuditPolicy.test.ts +138 -0
  99. package/src/modules/audit/command/deactivateAuditPolicy.ts +58 -0
  100. package/src/modules/audit/command/deleteAuditPolicy.generated.ts +6 -0
  101. package/src/modules/audit/command/deleteAuditPolicy.test.ts +121 -0
  102. package/src/modules/audit/command/deleteAuditPolicy.ts +52 -0
  103. package/src/modules/audit/command/logAuditEvent.generated.ts +6 -0
  104. package/src/modules/audit/command/logAuditEvent.test.ts +991 -0
  105. package/src/modules/audit/command/logAuditEvent.ts +357 -0
  106. package/src/modules/audit/command/reactivateAuditPolicy.generated.ts +6 -0
  107. package/src/modules/audit/command/reactivateAuditPolicy.test.ts +143 -0
  108. package/src/modules/audit/command/reactivateAuditPolicy.ts +79 -0
  109. package/src/modules/audit/command/registerAuditableEntity.generated.ts +6 -0
  110. package/src/modules/audit/command/registerAuditableEntity.test.ts +268 -0
  111. package/src/modules/audit/command/registerAuditableEntity.ts +94 -0
  112. package/src/modules/audit/command/replaceAuditPolicy.generated.ts +6 -0
  113. package/src/modules/audit/command/replaceAuditPolicy.test.ts +242 -0
  114. package/src/modules/audit/command/replaceAuditPolicy.ts +91 -0
  115. package/src/modules/audit/command/updateAuditPolicy.generated.ts +6 -0
  116. package/src/modules/audit/command/updateAuditPolicy.test.ts +284 -0
  117. package/src/modules/audit/command/updateAuditPolicy.ts +151 -0
  118. package/src/modules/audit/db/auditEntry.ts +47 -0
  119. package/src/modules/audit/db/auditPolicy.ts +33 -0
  120. package/src/modules/audit/db/auditableEntity.ts +22 -0
  121. package/src/modules/audit/db/changeDetail.ts +28 -0
  122. package/src/modules/audit/db/policyFieldRule.ts +23 -0
  123. package/src/modules/audit/docs/commands/ActivateAuditPolicy.md +69 -0
  124. package/src/modules/audit/docs/commands/CreateAuditPolicy.md +79 -0
  125. package/src/modules/audit/docs/commands/DeactivateAuditPolicy.md +55 -0
  126. package/src/modules/audit/docs/commands/DeleteAuditPolicy.md +55 -0
  127. package/src/modules/audit/docs/commands/LogAuditEvent.md +137 -0
  128. package/src/modules/audit/docs/commands/ReactivateAuditPolicy.md +58 -0
  129. package/src/modules/audit/docs/commands/RegisterAuditableEntity.md +62 -0
  130. package/src/modules/audit/docs/commands/ReplaceAuditPolicy.md +72 -0
  131. package/src/modules/audit/docs/commands/UpdateAuditPolicy.md +77 -0
  132. package/src/modules/audit/docs/features/audit-event-logging.md +126 -0
  133. package/src/modules/audit/docs/features/audit-policy-configuration.md +135 -0
  134. package/src/modules/audit/docs/features/field-level-change-tracking.md +95 -0
  135. package/src/modules/audit/docs/models/AuditEntry.md +55 -0
  136. package/src/modules/audit/docs/models/AuditPolicy.md +79 -0
  137. package/src/modules/audit/docs/models/AuditableEntity.md +38 -0
  138. package/src/modules/audit/docs/models/ChangeDetail.md +55 -0
  139. package/src/modules/audit/docs/models/PolicyFieldRule.md +45 -0
  140. package/src/modules/audit/docs/queries/GetAuditEntry.md +49 -0
  141. package/src/modules/audit/docs/queries/GetAuditPolicy.md +54 -0
  142. package/src/modules/audit/docs/queries/GetAuditSummary.md +84 -0
  143. package/src/modules/audit/docs/queries/GetChangeDetails.md +56 -0
  144. package/src/modules/audit/docs/queries/ListAuditPolicies.md +58 -0
  145. package/src/modules/audit/docs/queries/SearchAuditEntries.md +91 -0
  146. package/src/modules/audit/generated/kysely-tailordb.ts +92 -0
  147. package/src/modules/audit/index.ts +2 -0
  148. package/src/modules/audit/lib/_db_deps.ts +13 -0
  149. package/src/modules/audit/lib/errors.generated.ts +120 -0
  150. package/src/modules/audit/lib/permissions.generated.ts +14 -0
  151. package/src/modules/audit/lib/types.ts +28 -0
  152. package/src/modules/audit/module.ts +57 -0
  153. package/src/modules/audit/permissions.ts +39 -0
  154. package/src/modules/audit/query/getAuditEntry.generated.ts +5 -0
  155. package/src/modules/audit/query/getAuditEntry.test.ts +123 -0
  156. package/src/modules/audit/query/getAuditEntry.ts +36 -0
  157. package/src/modules/audit/query/getAuditPolicy.generated.ts +5 -0
  158. package/src/modules/audit/query/getAuditPolicy.test.ts +169 -0
  159. package/src/modules/audit/query/getAuditPolicy.ts +42 -0
  160. package/src/modules/audit/query/getAuditSummary.generated.ts +5 -0
  161. package/src/modules/audit/query/getAuditSummary.test.ts +632 -0
  162. package/src/modules/audit/query/getAuditSummary.ts +164 -0
  163. package/src/modules/audit/query/getChangeDetails.generated.ts +5 -0
  164. package/src/modules/audit/query/getChangeDetails.test.ts +195 -0
  165. package/src/modules/audit/query/getChangeDetails.ts +42 -0
  166. package/src/modules/audit/query/listAuditPolicies.generated.ts +5 -0
  167. package/src/modules/audit/query/listAuditPolicies.test.ts +239 -0
  168. package/src/modules/audit/query/listAuditPolicies.ts +100 -0
  169. package/src/modules/audit/query/searchAuditEntries.generated.ts +5 -0
  170. package/src/modules/audit/query/searchAuditEntries.test.ts +424 -0
  171. package/src/modules/audit/query/searchAuditEntries.ts +121 -0
  172. package/src/modules/audit/tailor.config.ts +13 -0
  173. package/src/modules/audit/tailor.d.ts +13 -0
  174. package/src/modules/audit/testing/fixtures.ts +215 -0
  175. package/src/modules/business-partner/README.md +60 -0
  176. package/src/modules/business-partner/command/.gitkeep +0 -0
  177. package/src/modules/business-partner/command/activatePartner.generated.ts +6 -0
  178. package/src/modules/business-partner/command/activatePartner.test.ts +59 -0
  179. package/src/modules/business-partner/command/activatePartner.ts +45 -0
  180. package/src/modules/business-partner/command/assignRoleToPartner.generated.ts +6 -0
  181. package/src/modules/business-partner/command/assignRoleToPartner.test.ts +113 -0
  182. package/src/modules/business-partner/command/assignRoleToPartner.ts +72 -0
  183. package/src/modules/business-partner/command/createContactPerson.generated.ts +6 -0
  184. package/src/modules/business-partner/command/createContactPerson.test.ts +193 -0
  185. package/src/modules/business-partner/command/createContactPerson.ts +98 -0
  186. package/src/modules/business-partner/command/createPartner.generated.ts +6 -0
  187. package/src/modules/business-partner/command/createPartner.test.ts +179 -0
  188. package/src/modules/business-partner/command/createPartner.ts +83 -0
  189. package/src/modules/business-partner/command/createPartnerAddress.generated.ts +6 -0
  190. package/src/modules/business-partner/command/createPartnerAddress.test.ts +195 -0
  191. package/src/modules/business-partner/command/createPartnerAddress.ts +119 -0
  192. package/src/modules/business-partner/command/createPartnerBankAccount.generated.ts +6 -0
  193. package/src/modules/business-partner/command/createPartnerBankAccount.test.ts +297 -0
  194. package/src/modules/business-partner/command/createPartnerBankAccount.ts +114 -0
  195. package/src/modules/business-partner/command/createPartnerIdentification.generated.ts +6 -0
  196. package/src/modules/business-partner/command/createPartnerIdentification.test.ts +255 -0
  197. package/src/modules/business-partner/command/createPartnerIdentification.ts +97 -0
  198. package/src/modules/business-partner/command/deactivateContactPerson.generated.ts +6 -0
  199. package/src/modules/business-partner/command/deactivateContactPerson.test.ts +70 -0
  200. package/src/modules/business-partner/command/deactivateContactPerson.ts +54 -0
  201. package/src/modules/business-partner/command/deactivatePartner.generated.ts +6 -0
  202. package/src/modules/business-partner/command/deactivatePartner.test.ts +59 -0
  203. package/src/modules/business-partner/command/deactivatePartner.ts +46 -0
  204. package/src/modules/business-partner/command/deleteContactPerson.generated.ts +6 -0
  205. package/src/modules/business-partner/command/deleteContactPerson.test.ts +61 -0
  206. package/src/modules/business-partner/command/deleteContactPerson.ts +48 -0
  207. package/src/modules/business-partner/command/deletePartner.generated.ts +6 -0
  208. package/src/modules/business-partner/command/deletePartner.test.ts +58 -0
  209. package/src/modules/business-partner/command/deletePartner.ts +46 -0
  210. package/src/modules/business-partner/command/deletePartnerAddress.generated.ts +6 -0
  211. package/src/modules/business-partner/command/deletePartnerAddress.test.ts +74 -0
  212. package/src/modules/business-partner/command/deletePartnerAddress.ts +52 -0
  213. package/src/modules/business-partner/command/deletePartnerBankAccount.generated.ts +6 -0
  214. package/src/modules/business-partner/command/deletePartnerBankAccount.test.ts +55 -0
  215. package/src/modules/business-partner/command/deletePartnerBankAccount.ts +36 -0
  216. package/src/modules/business-partner/command/deletePartnerIdentification.generated.ts +6 -0
  217. package/src/modules/business-partner/command/deletePartnerIdentification.test.ts +47 -0
  218. package/src/modules/business-partner/command/deletePartnerIdentification.ts +37 -0
  219. package/src/modules/business-partner/command/reactivateContactPerson.generated.ts +6 -0
  220. package/src/modules/business-partner/command/reactivateContactPerson.test.ts +48 -0
  221. package/src/modules/business-partner/command/reactivateContactPerson.ts +48 -0
  222. package/src/modules/business-partner/command/reactivatePartner.generated.ts +6 -0
  223. package/src/modules/business-partner/command/reactivatePartner.test.ts +59 -0
  224. package/src/modules/business-partner/command/reactivatePartner.ts +46 -0
  225. package/src/modules/business-partner/command/removeRoleFromPartner.generated.ts +6 -0
  226. package/src/modules/business-partner/command/removeRoleFromPartner.test.ts +82 -0
  227. package/src/modules/business-partner/command/removeRoleFromPartner.ts +73 -0
  228. package/src/modules/business-partner/command/setDefaultPartnerAddress.generated.ts +6 -0
  229. package/src/modules/business-partner/command/setDefaultPartnerAddress.test.ts +60 -0
  230. package/src/modules/business-partner/command/setDefaultPartnerAddress.ts +48 -0
  231. package/src/modules/business-partner/command/setDefaultPartnerBankAccount.generated.ts +6 -0
  232. package/src/modules/business-partner/command/setDefaultPartnerBankAccount.test.ts +56 -0
  233. package/src/modules/business-partner/command/setDefaultPartnerBankAccount.ts +51 -0
  234. package/src/modules/business-partner/command/setPrimaryContactPerson.generated.ts +6 -0
  235. package/src/modules/business-partner/command/setPrimaryContactPerson.test.ts +63 -0
  236. package/src/modules/business-partner/command/setPrimaryContactPerson.ts +55 -0
  237. package/src/modules/business-partner/command/updateContactPerson.generated.ts +6 -0
  238. package/src/modules/business-partner/command/updateContactPerson.test.ts +193 -0
  239. package/src/modules/business-partner/command/updateContactPerson.ts +92 -0
  240. package/src/modules/business-partner/command/updatePartner.generated.ts +6 -0
  241. package/src/modules/business-partner/command/updatePartner.test.ts +101 -0
  242. package/src/modules/business-partner/command/updatePartner.ts +76 -0
  243. package/src/modules/business-partner/command/updatePartnerAddress.generated.ts +6 -0
  244. package/src/modules/business-partner/command/updatePartnerAddress.test.ts +148 -0
  245. package/src/modules/business-partner/command/updatePartnerAddress.ts +64 -0
  246. package/src/modules/business-partner/command/updatePartnerBankAccount.generated.ts +6 -0
  247. package/src/modules/business-partner/command/updatePartnerBankAccount.test.ts +249 -0
  248. package/src/modules/business-partner/command/updatePartnerBankAccount.ts +109 -0
  249. package/src/modules/business-partner/command/updatePartnerIdentification.generated.ts +6 -0
  250. package/src/modules/business-partner/command/updatePartnerIdentification.test.ts +162 -0
  251. package/src/modules/business-partner/command/updatePartnerIdentification.ts +105 -0
  252. package/src/modules/business-partner/db/.gitkeep +0 -0
  253. package/src/modules/business-partner/db/businessPartner.ts +59 -0
  254. package/src/modules/business-partner/db/contactPerson.ts +49 -0
  255. package/src/modules/business-partner/db/partnerAddress.ts +45 -0
  256. package/src/modules/business-partner/db/partnerBankAccount.ts +53 -0
  257. package/src/modules/business-partner/db/partnerIdentification.ts +53 -0
  258. package/src/modules/business-partner/db/partnerRole.ts +43 -0
  259. package/src/modules/business-partner/docs/commands/ActivatePartner.md +39 -0
  260. package/src/modules/business-partner/docs/commands/AssignRoleToPartner.md +49 -0
  261. package/src/modules/business-partner/docs/commands/CreateContactPerson.md +59 -0
  262. package/src/modules/business-partner/docs/commands/CreatePartner.md +54 -0
  263. package/src/modules/business-partner/docs/commands/CreatePartnerAddress.md +60 -0
  264. package/src/modules/business-partner/docs/commands/CreatePartnerBankAccount.md +68 -0
  265. package/src/modules/business-partner/docs/commands/CreatePartnerIdentification.md +59 -0
  266. package/src/modules/business-partner/docs/commands/DeactivateContactPerson.md +42 -0
  267. package/src/modules/business-partner/docs/commands/DeactivatePartner.md +39 -0
  268. package/src/modules/business-partner/docs/commands/DeleteContactPerson.md +43 -0
  269. package/src/modules/business-partner/docs/commands/DeletePartner.md +40 -0
  270. package/src/modules/business-partner/docs/commands/DeletePartnerAddress.md +40 -0
  271. package/src/modules/business-partner/docs/commands/DeletePartnerBankAccount.md +35 -0
  272. package/src/modules/business-partner/docs/commands/DeletePartnerIdentification.md +33 -0
  273. package/src/modules/business-partner/docs/commands/ReactivateContactPerson.md +38 -0
  274. package/src/modules/business-partner/docs/commands/ReactivatePartner.md +39 -0
  275. package/src/modules/business-partner/docs/commands/RemoveRoleFromPartner.md +46 -0
  276. package/src/modules/business-partner/docs/commands/SetDefaultPartnerAddress.md +38 -0
  277. package/src/modules/business-partner/docs/commands/SetDefaultPartnerBankAccount.md +38 -0
  278. package/src/modules/business-partner/docs/commands/SetPrimaryContactPerson.md +43 -0
  279. package/src/modules/business-partner/docs/commands/UpdateContactPerson.md +66 -0
  280. package/src/modules/business-partner/docs/commands/UpdatePartner.md +48 -0
  281. package/src/modules/business-partner/docs/commands/UpdatePartnerAddress.md +46 -0
  282. package/src/modules/business-partner/docs/commands/UpdatePartnerBankAccount.md +64 -0
  283. package/src/modules/business-partner/docs/commands/UpdatePartnerIdentification.md +52 -0
  284. package/src/modules/business-partner/docs/features/contact-person-management.md +70 -0
  285. package/src/modules/business-partner/docs/features/partner-address-management.md +96 -0
  286. package/src/modules/business-partner/docs/features/partner-bank-account.md +70 -0
  287. package/src/modules/business-partner/docs/features/partner-identification.md +76 -0
  288. package/src/modules/business-partner/docs/features/partner-lifecycle.md +59 -0
  289. package/src/modules/business-partner/docs/features/partner-role-classification.md +73 -0
  290. package/src/modules/business-partner/docs/models/BusinessPartner.md +64 -0
  291. package/src/modules/business-partner/docs/models/ContactPerson.md +62 -0
  292. package/src/modules/business-partner/docs/models/PartnerAddress.md +52 -0
  293. package/src/modules/business-partner/docs/models/PartnerBankAccount.md +50 -0
  294. package/src/modules/business-partner/docs/models/PartnerIdentification.md +46 -0
  295. package/src/modules/business-partner/docs/models/PartnerRole.md +42 -0
  296. package/src/modules/business-partner/docs/queries/GetContactPerson.md +34 -0
  297. package/src/modules/business-partner/docs/queries/GetDefaultPartnerAddress.md +40 -0
  298. package/src/modules/business-partner/docs/queries/GetDefaultPartnerBankAccount.md +36 -0
  299. package/src/modules/business-partner/docs/queries/GetPartner.md +35 -0
  300. package/src/modules/business-partner/docs/queries/GetPartnerAddress.md +34 -0
  301. package/src/modules/business-partner/docs/queries/GetPartnerBankAccount.md +34 -0
  302. package/src/modules/business-partner/docs/queries/GetPartnerIdentification.md +34 -0
  303. package/src/modules/business-partner/docs/queries/GetPartnerRole.md +34 -0
  304. package/src/modules/business-partner/docs/queries/GetPrimaryContactPerson.md +36 -0
  305. package/src/modules/business-partner/docs/queries/ListContactPersonsByPartner.md +39 -0
  306. package/src/modules/business-partner/docs/queries/ListPartnerAddressesByPartner.md +41 -0
  307. package/src/modules/business-partner/docs/queries/ListPartnerBankAccountsByPartner.md +39 -0
  308. package/src/modules/business-partner/docs/queries/ListPartnerIdentificationsByPartner.md +41 -0
  309. package/src/modules/business-partner/docs/queries/ListPartnersByRole.md +47 -0
  310. package/src/modules/business-partner/executor/.gitkeep +0 -0
  311. package/src/modules/business-partner/generated/.gitkeep +0 -0
  312. package/src/modules/business-partner/generated/enums.ts +60 -0
  313. package/src/modules/business-partner/generated/kysely-tailordb.ts +114 -0
  314. package/src/modules/business-partner/index.ts +2 -0
  315. package/src/modules/business-partner/lib/_db_deps.ts +17 -0
  316. package/src/modules/business-partner/lib/errors.generated.ts +172 -0
  317. package/src/modules/business-partner/lib/errors.ts +2 -0
  318. package/src/modules/business-partner/lib/permissions.generated.ts +30 -0
  319. package/src/modules/business-partner/lib/types.ts +53 -0
  320. package/src/modules/business-partner/module.ts +181 -0
  321. package/src/modules/business-partner/permissions.ts +3 -0
  322. package/src/modules/business-partner/query/.gitkeep +0 -0
  323. package/src/modules/business-partner/query/getContactPerson.generated.ts +5 -0
  324. package/src/modules/business-partner/query/getContactPerson.test.ts +31 -0
  325. package/src/modules/business-partner/query/getContactPerson.ts +16 -0
  326. package/src/modules/business-partner/query/getDefaultPartnerAddress.generated.ts +5 -0
  327. package/src/modules/business-partner/query/getDefaultPartnerAddress.test.ts +45 -0
  328. package/src/modules/business-partner/query/getDefaultPartnerAddress.ts +30 -0
  329. package/src/modules/business-partner/query/getDefaultPartnerBankAccount.generated.ts +5 -0
  330. package/src/modules/business-partner/query/getDefaultPartnerBankAccount.test.ts +43 -0
  331. package/src/modules/business-partner/query/getDefaultPartnerBankAccount.ts +17 -0
  332. package/src/modules/business-partner/query/getPartner.generated.ts +5 -0
  333. package/src/modules/business-partner/query/getPartner.test.ts +31 -0
  334. package/src/modules/business-partner/query/getPartner.ts +16 -0
  335. package/src/modules/business-partner/query/getPartnerAddress.generated.ts +5 -0
  336. package/src/modules/business-partner/query/getPartnerAddress.test.ts +31 -0
  337. package/src/modules/business-partner/query/getPartnerAddress.ts +16 -0
  338. package/src/modules/business-partner/query/getPartnerBankAccount.generated.ts +5 -0
  339. package/src/modules/business-partner/query/getPartnerBankAccount.test.ts +31 -0
  340. package/src/modules/business-partner/query/getPartnerBankAccount.ts +16 -0
  341. package/src/modules/business-partner/query/getPartnerIdentification.generated.ts +5 -0
  342. package/src/modules/business-partner/query/getPartnerIdentification.test.ts +31 -0
  343. package/src/modules/business-partner/query/getPartnerIdentification.ts +16 -0
  344. package/src/modules/business-partner/query/getPartnerRole.generated.ts +5 -0
  345. package/src/modules/business-partner/query/getPartnerRole.test.ts +31 -0
  346. package/src/modules/business-partner/query/getPartnerRole.ts +19 -0
  347. package/src/modules/business-partner/query/getPrimaryContactPerson.generated.ts +5 -0
  348. package/src/modules/business-partner/query/getPrimaryContactPerson.test.ts +43 -0
  349. package/src/modules/business-partner/query/getPrimaryContactPerson.ts +17 -0
  350. package/src/modules/business-partner/query/listContactPersonsByPartner.generated.ts +5 -0
  351. package/src/modules/business-partner/query/listContactPersonsByPartner.test.ts +77 -0
  352. package/src/modules/business-partner/query/listContactPersonsByPartner.ts +32 -0
  353. package/src/modules/business-partner/query/listPartnerAddressesByPartner.generated.ts +5 -0
  354. package/src/modules/business-partner/query/listPartnerAddressesByPartner.test.ts +71 -0
  355. package/src/modules/business-partner/query/listPartnerAddressesByPartner.ts +37 -0
  356. package/src/modules/business-partner/query/listPartnerBankAccountsByPartner.generated.ts +5 -0
  357. package/src/modules/business-partner/query/listPartnerBankAccountsByPartner.test.ts +59 -0
  358. package/src/modules/business-partner/query/listPartnerBankAccountsByPartner.ts +32 -0
  359. package/src/modules/business-partner/query/listPartnerIdentificationsByPartner.generated.ts +5 -0
  360. package/src/modules/business-partner/query/listPartnerIdentificationsByPartner.test.ts +72 -0
  361. package/src/modules/business-partner/query/listPartnerIdentificationsByPartner.ts +40 -0
  362. package/src/modules/business-partner/query/listPartnersByRole.generated.ts +5 -0
  363. package/src/modules/business-partner/query/listPartnersByRole.test.ts +103 -0
  364. package/src/modules/business-partner/query/listPartnersByRole.ts +47 -0
  365. package/src/modules/business-partner/tailor.config.ts +13 -0
  366. package/src/modules/business-partner/tailor.d.ts +13 -0
  367. package/src/modules/business-partner/testing/fixtures.ts +204 -0
  368. package/src/modules/coa-management/README.md +61 -0
  369. package/src/modules/coa-management/command/.gitkeep +0 -0
  370. package/src/modules/coa-management/command/activateAccount.generated.ts +6 -0
  371. package/src/modules/coa-management/command/activateAccount.test.ts +125 -0
  372. package/src/modules/coa-management/command/activateAccount.ts +105 -0
  373. package/src/modules/coa-management/command/activateChartOfAccounts.generated.ts +6 -0
  374. package/src/modules/coa-management/command/activateChartOfAccounts.test.ts +113 -0
  375. package/src/modules/coa-management/command/activateChartOfAccounts.ts +104 -0
  376. package/src/modules/coa-management/command/createAccount.generated.ts +6 -0
  377. package/src/modules/coa-management/command/createAccount.test.ts +767 -0
  378. package/src/modules/coa-management/command/createAccount.ts +247 -0
  379. package/src/modules/coa-management/command/createAccountGroup.generated.ts +6 -0
  380. package/src/modules/coa-management/command/createAccountGroup.test.ts +494 -0
  381. package/src/modules/coa-management/command/createAccountGroup.ts +207 -0
  382. package/src/modules/coa-management/command/createChartOfAccounts.generated.ts +6 -0
  383. package/src/modules/coa-management/command/createChartOfAccounts.test.ts +502 -0
  384. package/src/modules/coa-management/command/createChartOfAccounts.ts +267 -0
  385. package/src/modules/coa-management/command/deactivateAccount.generated.ts +6 -0
  386. package/src/modules/coa-management/command/deactivateAccount.test.ts +199 -0
  387. package/src/modules/coa-management/command/deactivateAccount.ts +142 -0
  388. package/src/modules/coa-management/command/deactivateChartOfAccounts.generated.ts +6 -0
  389. package/src/modules/coa-management/command/deactivateChartOfAccounts.test.ts +91 -0
  390. package/src/modules/coa-management/command/deactivateChartOfAccounts.ts +88 -0
  391. package/src/modules/coa-management/command/deleteAccount.generated.ts +6 -0
  392. package/src/modules/coa-management/command/deleteAccount.test.ts +122 -0
  393. package/src/modules/coa-management/command/deleteAccount.ts +103 -0
  394. package/src/modules/coa-management/command/deleteAccountGroup.generated.ts +6 -0
  395. package/src/modules/coa-management/command/deleteAccountGroup.test.ts +120 -0
  396. package/src/modules/coa-management/command/deleteAccountGroup.ts +113 -0
  397. package/src/modules/coa-management/command/deleteChartOfAccounts.generated.ts +6 -0
  398. package/src/modules/coa-management/command/deleteChartOfAccounts.test.ts +154 -0
  399. package/src/modules/coa-management/command/deleteChartOfAccounts.ts +133 -0
  400. package/src/modules/coa-management/command/moveAccountGroup.generated.ts +6 -0
  401. package/src/modules/coa-management/command/moveAccountGroup.test.ts +199 -0
  402. package/src/modules/coa-management/command/moveAccountGroup.ts +145 -0
  403. package/src/modules/coa-management/command/reactivateAccount.generated.ts +6 -0
  404. package/src/modules/coa-management/command/reactivateAccount.test.ts +126 -0
  405. package/src/modules/coa-management/command/reactivateAccount.ts +123 -0
  406. package/src/modules/coa-management/command/updateAccount.generated.ts +6 -0
  407. package/src/modules/coa-management/command/updateAccount.test.ts +669 -0
  408. package/src/modules/coa-management/command/updateAccount.ts +370 -0
  409. package/src/modules/coa-management/command/updateAccountGroup.generated.ts +6 -0
  410. package/src/modules/coa-management/command/updateAccountGroup.test.ts +253 -0
  411. package/src/modules/coa-management/command/updateAccountGroup.ts +191 -0
  412. package/src/modules/coa-management/command/updateChartOfAccounts.generated.ts +6 -0
  413. package/src/modules/coa-management/command/updateChartOfAccounts.test.ts +153 -0
  414. package/src/modules/coa-management/command/updateChartOfAccounts.ts +133 -0
  415. package/src/modules/coa-management/db/.gitkeep +0 -0
  416. package/src/modules/coa-management/db/account.ts +119 -0
  417. package/src/modules/coa-management/db/accountGroup.ts +57 -0
  418. package/src/modules/coa-management/db/chartOfAccounts.ts +55 -0
  419. package/src/modules/coa-management/docs/commands/ActivateAccount.md +49 -0
  420. package/src/modules/coa-management/docs/commands/ActivateChartOfAccounts.md +47 -0
  421. package/src/modules/coa-management/docs/commands/CreateAccount.md +94 -0
  422. package/src/modules/coa-management/docs/commands/CreateAccountGroup.md +70 -0
  423. package/src/modules/coa-management/docs/commands/CreateChartOfAccounts.md +72 -0
  424. package/src/modules/coa-management/docs/commands/DeactivateAccount.md +65 -0
  425. package/src/modules/coa-management/docs/commands/DeactivateChartOfAccounts.md +44 -0
  426. package/src/modules/coa-management/docs/commands/DeleteAccount.md +52 -0
  427. package/src/modules/coa-management/docs/commands/DeleteAccountGroup.md +50 -0
  428. package/src/modules/coa-management/docs/commands/DeleteChartOfAccounts.md +48 -0
  429. package/src/modules/coa-management/docs/commands/MoveAccountGroup.md +57 -0
  430. package/src/modules/coa-management/docs/commands/ReactivateAccount.md +50 -0
  431. package/src/modules/coa-management/docs/commands/UpdateAccount.md +102 -0
  432. package/src/modules/coa-management/docs/commands/UpdateAccountGroup.md +62 -0
  433. package/src/modules/coa-management/docs/commands/UpdateChartOfAccounts.md +49 -0
  434. package/src/modules/coa-management/docs/features/account-group-hierarchy.md +81 -0
  435. package/src/modules/coa-management/docs/features/account-lifecycle.md +80 -0
  436. package/src/modules/coa-management/docs/features/account-management.md +114 -0
  437. package/src/modules/coa-management/docs/features/chart-of-accounts-setup.md +86 -0
  438. package/src/modules/coa-management/docs/models/Account.md +84 -0
  439. package/src/modules/coa-management/docs/models/AccountGroup.md +55 -0
  440. package/src/modules/coa-management/docs/models/ChartOfAccounts.md +65 -0
  441. package/src/modules/coa-management/docs/queries/DetectCircularReference.md +52 -0
  442. package/src/modules/coa-management/docs/queries/GetAccount.md +42 -0
  443. package/src/modules/coa-management/docs/queries/GetAccountGroup.md +42 -0
  444. package/src/modules/coa-management/docs/queries/GetChartOfAccounts.md +48 -0
  445. package/src/modules/coa-management/docs/queries/ListAccountGroups.md +42 -0
  446. package/src/modules/coa-management/docs/queries/ListAccounts.md +54 -0
  447. package/src/modules/coa-management/docs/queries/ListUnassignedAccounts.md +40 -0
  448. package/src/modules/coa-management/executor/.gitkeep +0 -0
  449. package/src/modules/coa-management/generated/.gitkeep +0 -0
  450. package/src/modules/coa-management/generated/enums.ts +45 -0
  451. package/src/modules/coa-management/generated/kysely-tailordb.ts +81 -0
  452. package/src/modules/coa-management/index.ts +2 -0
  453. package/src/modules/coa-management/lib/_db_deps.ts +17 -0
  454. package/src/modules/coa-management/lib/errors.generated.ts +162 -0
  455. package/src/modules/coa-management/lib/errors.ts +0 -0
  456. package/src/modules/coa-management/lib/permissions.generated.ts +20 -0
  457. package/src/modules/coa-management/lib/types.ts +22 -0
  458. package/src/modules/coa-management/module.ts +136 -0
  459. package/src/modules/coa-management/permissions.ts +3 -0
  460. package/src/modules/coa-management/query/.gitkeep +0 -0
  461. package/src/modules/coa-management/query/detectCircularReference.generated.ts +5 -0
  462. package/src/modules/coa-management/query/detectCircularReference.test.ts +88 -0
  463. package/src/modules/coa-management/query/detectCircularReference.ts +46 -0
  464. package/src/modules/coa-management/query/getAccount.generated.ts +5 -0
  465. package/src/modules/coa-management/query/getAccount.test.ts +55 -0
  466. package/src/modules/coa-management/query/getAccount.ts +25 -0
  467. package/src/modules/coa-management/query/getAccountGroup.generated.ts +5 -0
  468. package/src/modules/coa-management/query/getAccountGroup.test.ts +55 -0
  469. package/src/modules/coa-management/query/getAccountGroup.ts +25 -0
  470. package/src/modules/coa-management/query/getChartOfAccounts.generated.ts +5 -0
  471. package/src/modules/coa-management/query/getChartOfAccounts.test.ts +79 -0
  472. package/src/modules/coa-management/query/getChartOfAccounts.ts +28 -0
  473. package/src/modules/coa-management/query/listAccountGroups.generated.ts +5 -0
  474. package/src/modules/coa-management/query/listAccountGroups.test.ts +72 -0
  475. package/src/modules/coa-management/query/listAccountGroups.ts +49 -0
  476. package/src/modules/coa-management/query/listAccounts.generated.ts +5 -0
  477. package/src/modules/coa-management/query/listAccounts.test.ts +136 -0
  478. package/src/modules/coa-management/query/listAccounts.ts +82 -0
  479. package/src/modules/coa-management/query/listUnassignedAccounts.generated.ts +5 -0
  480. package/src/modules/coa-management/query/listUnassignedAccounts.test.ts +96 -0
  481. package/src/modules/coa-management/query/listUnassignedAccounts.ts +39 -0
  482. package/src/modules/coa-management/tailor.config.ts +13 -0
  483. package/src/modules/coa-management/tailor.d.ts +13 -0
  484. package/src/modules/coa-management/testing/fixtures.ts +201 -0
  485. package/src/modules/item-management/README.md +1 -1
  486. package/src/modules/organization/README.md +57 -0
  487. package/src/modules/organization/command/.gitkeep +0 -0
  488. package/src/modules/organization/command/activateCompany.generated.ts +6 -0
  489. package/src/modules/organization/command/activateCompany.test.ts +184 -0
  490. package/src/modules/organization/command/activateCompany.ts +92 -0
  491. package/src/modules/organization/command/createCompany.generated.ts +6 -0
  492. package/src/modules/organization/command/createCompany.test.ts +156 -0
  493. package/src/modules/organization/command/createCompany.ts +80 -0
  494. package/src/modules/organization/command/createDepartment.generated.ts +6 -0
  495. package/src/modules/organization/command/createDepartment.test.ts +239 -0
  496. package/src/modules/organization/command/createDepartment.ts +98 -0
  497. package/src/modules/organization/command/createSite.generated.ts +6 -0
  498. package/src/modules/organization/command/createSite.test.ts +262 -0
  499. package/src/modules/organization/command/createSite.ts +155 -0
  500. package/src/modules/organization/command/deactivateCompany.generated.ts +6 -0
  501. package/src/modules/organization/command/deactivateCompany.test.ts +58 -0
  502. package/src/modules/organization/command/deactivateCompany.ts +47 -0
  503. package/src/modules/organization/command/deactivateDepartment.generated.ts +6 -0
  504. package/src/modules/organization/command/deactivateDepartment.test.ts +115 -0
  505. package/src/modules/organization/command/deactivateDepartment.ts +63 -0
  506. package/src/modules/organization/command/deactivateSite.generated.ts +6 -0
  507. package/src/modules/organization/command/deactivateSite.test.ts +53 -0
  508. package/src/modules/organization/command/deactivateSite.ts +47 -0
  509. package/src/modules/organization/command/deleteCompany.generated.ts +6 -0
  510. package/src/modules/organization/command/deleteCompany.test.ts +99 -0
  511. package/src/modules/organization/command/deleteCompany.ts +66 -0
  512. package/src/modules/organization/command/reactivateCompany.generated.ts +6 -0
  513. package/src/modules/organization/command/reactivateCompany.test.ts +58 -0
  514. package/src/modules/organization/command/reactivateCompany.ts +47 -0
  515. package/src/modules/organization/command/reactivateDepartment.generated.ts +6 -0
  516. package/src/modules/organization/command/reactivateDepartment.test.ts +59 -0
  517. package/src/modules/organization/command/reactivateDepartment.ts +47 -0
  518. package/src/modules/organization/command/reactivateSite.generated.ts +6 -0
  519. package/src/modules/organization/command/reactivateSite.test.ts +53 -0
  520. package/src/modules/organization/command/reactivateSite.ts +47 -0
  521. package/src/modules/organization/command/updateCompany.generated.ts +6 -0
  522. package/src/modules/organization/command/updateCompany.test.ts +239 -0
  523. package/src/modules/organization/command/updateCompany.ts +127 -0
  524. package/src/modules/organization/command/updateDepartment.generated.ts +6 -0
  525. package/src/modules/organization/command/updateDepartment.test.ts +232 -0
  526. package/src/modules/organization/command/updateDepartment.ts +120 -0
  527. package/src/modules/organization/command/updateSite.generated.ts +6 -0
  528. package/src/modules/organization/command/updateSite.test.ts +274 -0
  529. package/src/modules/organization/command/updateSite.ts +176 -0
  530. package/src/modules/organization/db/.gitkeep +0 -0
  531. package/src/modules/organization/db/company.ts +44 -0
  532. package/src/modules/organization/db/department.ts +46 -0
  533. package/src/modules/organization/db/site.ts +44 -0
  534. package/src/modules/organization/docs/commands/ActivateCompany.md +62 -0
  535. package/src/modules/organization/docs/commands/CreateCompany.md +49 -0
  536. package/src/modules/organization/docs/commands/CreateDepartment.md +62 -0
  537. package/src/modules/organization/docs/commands/CreateSite.md +74 -0
  538. package/src/modules/organization/docs/commands/DeactivateCompany.md +40 -0
  539. package/src/modules/organization/docs/commands/DeactivateDepartment.md +44 -0
  540. package/src/modules/organization/docs/commands/DeactivateSite.md +38 -0
  541. package/src/modules/organization/docs/commands/DeleteCompany.md +50 -0
  542. package/src/modules/organization/docs/commands/ReactivateCompany.md +39 -0
  543. package/src/modules/organization/docs/commands/ReactivateDepartment.md +37 -0
  544. package/src/modules/organization/docs/commands/ReactivateSite.md +37 -0
  545. package/src/modules/organization/docs/commands/UpdateCompany.md +58 -0
  546. package/src/modules/organization/docs/commands/UpdateDepartment.md +64 -0
  547. package/src/modules/organization/docs/commands/UpdateSite.md +80 -0
  548. package/src/modules/organization/docs/features/company-lifecycle.md +76 -0
  549. package/src/modules/organization/docs/features/department-management.md +66 -0
  550. package/src/modules/organization/docs/features/site-management.md +86 -0
  551. package/src/modules/organization/docs/models/Company.md +60 -0
  552. package/src/modules/organization/docs/models/Department.md +57 -0
  553. package/src/modules/organization/docs/models/Site.md +57 -0
  554. package/src/modules/organization/docs/queries/DetectDepartmentCircularReference.md +50 -0
  555. package/src/modules/organization/docs/queries/GetCompany.md +40 -0
  556. package/src/modules/organization/docs/queries/GetDepartment.md +44 -0
  557. package/src/modules/organization/docs/queries/GetDepartmentChildren.md +40 -0
  558. package/src/modules/organization/docs/queries/GetSite.md +37 -0
  559. package/src/modules/organization/docs/queries/ListDepartmentsByCompany.md +54 -0
  560. package/src/modules/organization/docs/queries/ListSitesByCompany.md +54 -0
  561. package/src/modules/organization/executor/.gitkeep +0 -0
  562. package/src/modules/organization/generated/.gitkeep +0 -0
  563. package/src/modules/organization/generated/kysely-tailordb.ts +77 -0
  564. package/src/modules/organization/index.ts +2 -0
  565. package/src/modules/organization/lib/_db_deps.ts +10 -0
  566. package/src/modules/organization/lib/errors.generated.ts +117 -0
  567. package/src/modules/organization/lib/errors.ts +1 -0
  568. package/src/modules/organization/lib/permissions.generated.ts +19 -0
  569. package/src/modules/organization/lib/types.ts +16 -0
  570. package/src/modules/organization/module.ts +89 -0
  571. package/src/modules/organization/permissions.ts +3 -0
  572. package/src/modules/organization/query/.gitkeep +0 -0
  573. package/src/modules/organization/query/detectDepartmentCircularReference.generated.ts +5 -0
  574. package/src/modules/organization/query/detectDepartmentCircularReference.test.ts +102 -0
  575. package/src/modules/organization/query/detectDepartmentCircularReference.ts +27 -0
  576. package/src/modules/organization/query/getCompany.generated.ts +5 -0
  577. package/src/modules/organization/query/getCompany.test.ts +70 -0
  578. package/src/modules/organization/query/getCompany.ts +16 -0
  579. package/src/modules/organization/query/getDepartment.generated.ts +5 -0
  580. package/src/modules/organization/query/getDepartment.test.ts +85 -0
  581. package/src/modules/organization/query/getDepartment.ts +17 -0
  582. package/src/modules/organization/query/getDepartmentChildren.generated.ts +5 -0
  583. package/src/modules/organization/query/getDepartmentChildren.test.ts +75 -0
  584. package/src/modules/organization/query/getDepartmentChildren.ts +21 -0
  585. package/src/modules/organization/query/getSite.generated.ts +5 -0
  586. package/src/modules/organization/query/getSite.test.ts +55 -0
  587. package/src/modules/organization/query/getSite.ts +16 -0
  588. package/src/modules/organization/query/listDepartmentsByCompany.generated.ts +5 -0
  589. package/src/modules/organization/query/listDepartmentsByCompany.test.ts +124 -0
  590. package/src/modules/organization/query/listDepartmentsByCompany.ts +43 -0
  591. package/src/modules/organization/query/listSitesByCompany.generated.ts +5 -0
  592. package/src/modules/organization/query/listSitesByCompany.test.ts +126 -0
  593. package/src/modules/organization/query/listSitesByCompany.ts +41 -0
  594. package/src/modules/organization/tailor.config.ts +13 -0
  595. package/src/modules/organization/tailor.d.ts +13 -0
  596. package/src/modules/organization/testing/fixtures.ts +155 -0
  597. package/src/modules/primitives/README.md +1 -1
  598. package/src/modules/primitives/command/setBaseCurrency.test.ts +8 -64
  599. package/src/modules/primitives/command/setBaseCurrency.ts +6 -64
  600. package/src/modules/primitives/docs/commands/ActivateCategory.md +1 -1
  601. package/src/modules/primitives/docs/commands/ActivateCurrency.md +1 -1
  602. package/src/modules/primitives/docs/commands/ActivateUnit.md +1 -1
  603. package/src/modules/primitives/docs/commands/CreateExchangeRate.md +2 -2
  604. package/src/modules/primitives/docs/commands/CreateUnit.md +1 -1
  605. package/src/modules/primitives/docs/commands/DeactivateCategory.md +1 -1
  606. package/src/modules/primitives/docs/commands/DeactivateCurrency.md +1 -1
  607. package/src/modules/primitives/docs/commands/DeactivateUnit.md +1 -1
  608. package/src/modules/primitives/docs/commands/SetBaseCurrency.md +13 -23
  609. package/src/modules/primitives/docs/commands/SetReferenceUnit.md +1 -1
  610. package/src/modules/primitives/docs/features/currency-definitions.md +13 -14
  611. package/src/modules/primitives/docs/models/Currency.md +3 -4
  612. package/src/modules/primitives/docs/queries/ConvertAmount.md +2 -2
  613. package/src/modules/primitives/docs/queries/ConvertQuantity.md +2 -2
  614. package/src/modules/primitives/lib/errors.generated.ts +5 -0
  615. package/src/modules/product-management/README.md +1 -1
  616. package/src/modules/user-management/docs/commands/CreatePermission.md +3 -3
  617. package/src/modules/user-management/docs/commands/CreateRole.md +1 -1
  618. package/src/modules/user-management/docs/queries/ListRolePermissionsByRole.md +39 -0
  619. package/src/modules/user-management/docs/queries/ListUserRolesByUser.md +39 -0
  620. package/src/modules/user-management/generated/enums.ts +0 -15
  621. package/src/modules/user-management/generated/kysely-tailordb.ts +0 -11
  622. package/src/shared/createContext.ts +2 -1
  623. package/src/shared/defineQuery.ts +36 -1
  624. package/src/shared/requirePermission.ts +3 -3
  625. package/src/shared/types.ts +3 -0
  626. package/templates/scaffold/app/backend/package.json +8 -7
  627. package/templates/scaffold/app/frontend/eslint.config.js +12 -0
  628. package/templates/scaffold/app/frontend/package.json +19 -16
  629. package/templates/scaffold/app/frontend/src/hooks/use-toast.ts +30 -0
  630. package/templates/scaffold/app/frontend/src/pages/user-management/user/create/components/create-user-form.tsx +3 -2
  631. package/templates/scaffold/app/frontend/vite.config.ts +5 -5
  632. package/templates/workflows/erp-kit-check.yml +2 -2
  633. package/src/commands/module/list.test.ts +0 -57
  634. package/src/commands/module/list.ts +0 -64
  635. package/src/commands/scaffold.ts +0 -176
  636. /package/src/modules/{accounting → audit/db}/.gitkeep +0 -0
  637. /package/src/modules/audit/{.gitkeep → executor/.gitkeep} +0 -0
  638. /package/src/modules/{coa-management/.gitkeep → audit/lib/errors.ts} +0 -0
  639. /package/src/modules/{supplier-management → business-partner}/.gitkeep +0 -0
@@ -0,0 +1,215 @@
1
+ import type {
2
+ AuditableEntity,
3
+ AuditPolicy,
4
+ PolicyFieldRule,
5
+ AuditEntry,
6
+ ChangeDetail,
7
+ Schema,
8
+ } from "../lib/types";
9
+
10
+ // AuditableEntity fixtures
11
+ export const companyBoundEntity = {
12
+ id: "entity-1",
13
+ entityName: "SalesOrder",
14
+ entityScope: "COMPANY_BOUND",
15
+ auditableFields: JSON.stringify([
16
+ { fieldName: "amount", fieldType: "scalar" },
17
+ { fieldName: "status", fieldType: "scalar" },
18
+ { fieldName: "customerId", fieldType: "relation" },
19
+ ]),
20
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
21
+ updatedAt: null,
22
+ } as const satisfies AuditableEntity<Schema>;
23
+
24
+ export const globalEntity = {
25
+ id: "entity-2",
26
+ entityName: "User",
27
+ entityScope: "GLOBAL",
28
+ auditableFields: JSON.stringify([
29
+ { fieldName: "email", fieldType: "scalar" },
30
+ { fieldName: "role", fieldType: "scalar" },
31
+ { fieldName: "isActive", fieldType: "scalar" },
32
+ ]),
33
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
34
+ updatedAt: null,
35
+ } as const satisfies AuditableEntity<Schema>;
36
+
37
+ // AuditPolicy fixtures
38
+ export const draftPolicy = {
39
+ id: "policy-1",
40
+ entityName: "SalesOrder",
41
+ companyId: "company-1",
42
+ operationType: "UPDATE",
43
+ status: "DRAFT",
44
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
45
+ updatedAt: null,
46
+ } as const satisfies AuditPolicy<Schema>;
47
+
48
+ export const activePolicy = {
49
+ id: "policy-2",
50
+ entityName: "SalesOrder",
51
+ companyId: "company-1",
52
+ operationType: "UPDATE",
53
+ status: "ACTIVE",
54
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
55
+ updatedAt: null,
56
+ } as const satisfies AuditPolicy<Schema>;
57
+
58
+ export const inactivePolicy = {
59
+ id: "policy-3",
60
+ entityName: "SalesOrder",
61
+ companyId: "company-1",
62
+ operationType: "UPDATE",
63
+ status: "INACTIVE",
64
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
65
+ updatedAt: null,
66
+ } as const satisfies AuditPolicy<Schema>;
67
+
68
+ export const globalDraftPolicy = {
69
+ id: "policy-4",
70
+ entityName: "User",
71
+ companyId: null,
72
+ operationType: "CREATE",
73
+ status: "DRAFT",
74
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
75
+ updatedAt: null,
76
+ } as const satisfies AuditPolicy<Schema>;
77
+
78
+ export const globalActivePolicy = {
79
+ id: "policy-5",
80
+ entityName: "User",
81
+ companyId: null,
82
+ operationType: "CREATE",
83
+ status: "ACTIVE",
84
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
85
+ updatedAt: null,
86
+ } as const satisfies AuditPolicy<Schema>;
87
+
88
+ export const draftReplacementPolicy = {
89
+ id: "policy-6",
90
+ entityName: "SalesOrder",
91
+ companyId: "company-1",
92
+ operationType: "UPDATE",
93
+ status: "DRAFT",
94
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
95
+ updatedAt: null,
96
+ } as const satisfies AuditPolicy<Schema>;
97
+
98
+ // PolicyFieldRule fixtures
99
+ export const captureFieldRule = {
100
+ id: "rule-1",
101
+ auditPolicyId: "policy-2",
102
+ fieldName: "amount",
103
+ sensitivityMode: "CAPTURE",
104
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
105
+ updatedAt: null,
106
+ } as const satisfies PolicyFieldRule<Schema>;
107
+
108
+ export const maskFieldRule = {
109
+ id: "rule-2",
110
+ auditPolicyId: "policy-2",
111
+ fieldName: "customerId",
112
+ sensitivityMode: "MASK",
113
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
114
+ updatedAt: null,
115
+ } as const satisfies PolicyFieldRule<Schema>;
116
+
117
+ export const hashFieldRule = {
118
+ id: "rule-3",
119
+ auditPolicyId: "policy-2",
120
+ fieldName: "status",
121
+ sensitivityMode: "HASH",
122
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
123
+ updatedAt: null,
124
+ } as const satisfies PolicyFieldRule<Schema>;
125
+
126
+ export const excludeFieldRule = {
127
+ id: "rule-4",
128
+ auditPolicyId: "policy-2",
129
+ fieldName: "amount",
130
+ sensitivityMode: "EXCLUDE",
131
+ createdAt: new Date("2024-01-01T00:00:00.000Z"),
132
+ updatedAt: null,
133
+ } as const satisfies PolicyFieldRule<Schema>;
134
+
135
+ // AuditEntry fixtures
136
+ export const baseAuditEntry = {
137
+ id: "entry-1",
138
+ eventId: "event-uuid-1",
139
+ actorType: "USER",
140
+ actorId: "user-1",
141
+ entityType: "SalesOrder",
142
+ entityId: "so-1",
143
+ operationType: "UPDATE",
144
+ companyId: "company-1",
145
+ correlationId: null,
146
+ ipAddress: null,
147
+ userAgent: null,
148
+ sessionId: null,
149
+ requestId: null,
150
+ onBehalfOf: null,
151
+ timestamp: new Date("2024-01-15T10:30:00.000Z"),
152
+ createdAt: new Date("2024-01-15T10:30:00.000Z"),
153
+ updatedAt: null,
154
+ } as const satisfies AuditEntry<Schema>;
155
+
156
+ export const globalAuditEntry = {
157
+ id: "entry-2",
158
+ eventId: "event-uuid-2",
159
+ actorType: "SYSTEM",
160
+ actorId: "system-job-1",
161
+ entityType: "User",
162
+ entityId: "user-2",
163
+ operationType: "CREATE",
164
+ companyId: null,
165
+ correlationId: "corr-uuid-1",
166
+ ipAddress: "192.168.1.1",
167
+ userAgent: "AuditBot/1.0",
168
+ sessionId: "session-1",
169
+ requestId: "req-1",
170
+ onBehalfOf: "user-3",
171
+ timestamp: new Date("2024-01-16T12:00:00.000Z"),
172
+ createdAt: new Date("2024-01-16T12:00:00.000Z"),
173
+ updatedAt: null,
174
+ } as const satisfies AuditEntry<Schema>;
175
+
176
+ // ChangeDetail fixtures
177
+ export const baseChangeDetail = {
178
+ id: "detail-1",
179
+ auditEntryId: "entry-1",
180
+ fieldName: "amount",
181
+ oldValue: "100.00",
182
+ newValue: "95.00",
183
+ createdAt: new Date("2024-01-15T10:30:00.000Z"),
184
+ updatedAt: null,
185
+ } as const satisfies ChangeDetail<Schema>;
186
+
187
+ export const maskedChangeDetail = {
188
+ id: "detail-2",
189
+ auditEntryId: "entry-1",
190
+ fieldName: "customerId",
191
+ oldValue: "***",
192
+ newValue: "***",
193
+ createdAt: new Date("2024-01-15T10:30:00.000Z"),
194
+ updatedAt: null,
195
+ } as const satisfies ChangeDetail<Schema>;
196
+
197
+ export const excludedChangeDetail = {
198
+ id: "detail-3",
199
+ auditEntryId: "entry-1",
200
+ fieldName: "amount",
201
+ oldValue: null,
202
+ newValue: null,
203
+ createdAt: new Date("2024-01-15T10:30:00.000Z"),
204
+ updatedAt: null,
205
+ } as const satisfies ChangeDetail<Schema>;
206
+
207
+ export const createChangeDetail = {
208
+ id: "detail-4",
209
+ auditEntryId: "entry-2",
210
+ fieldName: "email",
211
+ oldValue: null,
212
+ newValue: "user@example.com",
213
+ createdAt: new Date("2024-01-16T12:00:00.000Z"),
214
+ updatedAt: null,
215
+ } as const satisfies ChangeDetail<Schema>;
@@ -0,0 +1,60 @@
1
+ # README
2
+
3
+ ## Overview
4
+
5
+ The Business Partner module manages the master data for all external parties the organization transacts with — suppliers, customers, or both. It provides a unified business partner entity following SAP's Business Partner model, where a single record can hold multiple roles (CUSTOMER, SUPPLIER) without duplication. Each partner is classified by type (ORGANIZATION or INDIVIDUAL), carries its own lifecycle state machine (DRAFT → ACTIVE ↔ INACTIVE), and is scoped to a company.
6
+
7
+ Partners serve as the authoritative counterparty reference for all downstream transactional modules. Sales orders reference a partner as the customer; purchase orders reference a partner as the supplier; accounting entries reference partners for accounts payable and receivable. The module also manages partner-owned sub-entities: addresses (billing, shipping, registered), contact persons (individuals at an organization), bank accounts (for AP/AR payments), and identification documents (tax IDs, VAT numbers, DUNS).
8
+
9
+ ## Key Features
10
+
11
+ - **[Partner Lifecycle](docs/features/partner-lifecycle.md)**: Unified business partner entity with type distinction (ORGANIZATION/INDIVIDUAL), lifecycle state machine (DRAFT → ACTIVE ↔ INACTIVE), and core master data. The central entity that all downstream modules reference as the counterparty
12
+ - **[Partner Address Management](docs/features/partner-address-management.md)**: Multiple addresses per partner with type classification (BILLING, SHIPPING, REGISTERED, OTHER). Structured address format consistent with organization's Site addresses but separately owned for external parties
13
+ - **[Contact Person Management](docs/features/contact-person-management.md)**: Link individual contacts to their parent organization with name, email, phone, job title, and primary contact designation. Contact persons are sub-entities of ORGANIZATION-type partners, distinct from user-management login accounts
14
+ - **[Partner Role Classification](docs/features/partner-role-classification.md)**: Assign roles (CUSTOMER, SUPPLIER) to a partner additively. A single partner can serve multiple roles without record duplication, following SAP's unified BP model
15
+ - **[Partner Bank Account](docs/features/partner-bank-account.md)**: Store partner banking details (bank name, account number, routing, IBAN/SWIFT) for AP/AR payments. Multiple accounts per partner with default designation and currency reference
16
+ - **[Partner Identification](docs/features/partner-identification.md)**: Store tax IDs, VAT numbers, DUNS, company registry numbers, and other identification documents per partner. Supports multiple identification types with optional validity periods
17
+
18
+ ## Module Scope
19
+
20
+ ### In Scope
21
+
22
+ - Business partner master data management (create, update, delete, status transitions)
23
+ - Partner type distinction (ORGANIZATION and INDIVIDUAL)
24
+ - Partner lifecycle state machine (DRAFT → ACTIVE ↔ INACTIVE)
25
+ - Company-scoped partner records (each partner belongs to a company)
26
+ - Multiple addresses per partner with type classification and default designation
27
+ - Contact person management for ORGANIZATION-type partners
28
+ - Role classification (CUSTOMER, SUPPLIER) with additive assignment
29
+ - Bank account storage with default designation and currency reference
30
+ - Identification document storage (tax IDs, VAT, DUNS, etc.) with uniqueness enforcement
31
+
32
+ ### Out of Scope
33
+
34
+ - Customer relationship management and sales pipeline (CRM module)
35
+ - Lead/prospect qualification and conversion workflows (CRM module)
36
+ - Supplier onboarding workflows with approval gates (`purchase` module)
37
+ - Supplier qualification, certification, and performance scoring (`purchase` module)
38
+ - Supplier catalog — linking suppliers to items they supply (`purchase` module)
39
+ - Payment terms and pricing rules (`payment-terms` module)
40
+ - Duplicate detection and automated merge (future enhancement)
41
+ - Partner portal and self-service capabilities (future enhancement)
42
+ - Activity logging — calls, emails, meetings, notes (CRM module)
43
+ - Know Your Customer (KYC) and sanctions screening workflows (compliance module)
44
+
45
+ ### Scope Decision Rationale
46
+
47
+ Business-partner is scoped to **external party master data** — the "who we transact with" foundation. It owns the identity, classification, and contact details of every customer, supplier, or dual-role partner the organization deals with. This is separated from internal organizational structure (organization module) because external parties have fundamentally different lifecycles, data requirements, and access patterns than internal entities like companies, departments, and sites.
48
+
49
+ The unified partner model (one entity with role classification rather than separate Customer and Supplier entities) follows the SAP Business Partner pattern. This prevents duplicate records when the same company is both a customer and a supplier, simplifies address and contact management, and provides a single reference point for downstream modules.
50
+
51
+ Addresses are included here rather than in the organization module because partner addresses belong to external parties (billing/shipping for customers and suppliers), while organization's Site addresses belong to company-owned facilities. The address structure is consistent across both modules, but ownership and semantics differ.
52
+
53
+ Contact persons are included because knowing who to communicate with at a partner organization is core master data, not a CRM concern. However, activity tracking (logging calls, meetings, emails) is excluded as CRM functionality.
54
+
55
+ Supplier catalog (which suppliers provide which items), payment terms, and pricing are excluded because they involve transactional business rules that change at different rates than partner master data. A supplier catalog naturally fits in a purchasing module where it integrates with PO workflows. Payment terms belong in pricing/accounting where they interact with discount rules and installment plans.
56
+
57
+ ## Module Dependencies
58
+
59
+ - [organization](../organization/README.md) — Company reference for partner scoping (each partner belongs to a company)
60
+ - [primitives](../primitives/README.md) — Currency definitions for bank account currency assignment
File without changes
@@ -0,0 +1,6 @@
1
+ // @generated — do not edit
2
+ import { defineCommand } from "../../../shared";
3
+ import { permissions } from "../lib/permissions.generated";
4
+ import { run } from "./activatePartner";
5
+
6
+ export const activatePartner = defineCommand(permissions.activatePartner, run);
@@ -0,0 +1,59 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { Transaction } from "../generated/kysely-tailordb";
4
+ import { InvalidStateTransitionError, PartnerNotFoundError } from "../lib/errors.generated";
5
+ import { baseActivePartner, baseDraftPartner, baseInactivePartner } from "../testing/fixtures";
6
+ import { run } from "./activatePartner";
7
+
8
+ describe("activatePartner", () => {
9
+ it("activates a DRAFT partner", async () => {
10
+ const { db, spies } = createMockDb<Transaction>();
11
+ const activatedPartner = { ...baseDraftPartner, status: "ACTIVE" };
12
+ spies.select.mockReturnValueOnce(baseDraftPartner);
13
+ spies.update.mockReturnValue(activatedPartner);
14
+
15
+ const result = await run(db, { id: baseDraftPartner.id });
16
+
17
+ expect(result.ok).toBe(true);
18
+ if (result.ok) {
19
+ expect(result.value.partner.status).toBe("ACTIVE");
20
+ }
21
+ expect(spies.update).toHaveBeenCalled();
22
+ });
23
+
24
+ it("returns error when partner not found", async () => {
25
+ const { db, spies } = createMockDb<Transaction>();
26
+ spies.select.mockReturnValue(undefined);
27
+
28
+ const result = await run(db, { id: "nonexistent" });
29
+
30
+ expect(result.ok).toBe(false);
31
+ if (!result.ok) {
32
+ expect(result.error).toBeInstanceOf(PartnerNotFoundError);
33
+ }
34
+ });
35
+
36
+ it("returns error when partner is ACTIVE", async () => {
37
+ const { db, spies } = createMockDb<Transaction>();
38
+ spies.select.mockReturnValueOnce(baseActivePartner);
39
+
40
+ const result = await run(db, { id: baseActivePartner.id });
41
+
42
+ expect(result.ok).toBe(false);
43
+ if (!result.ok) {
44
+ expect(result.error).toBeInstanceOf(InvalidStateTransitionError);
45
+ }
46
+ });
47
+
48
+ it("returns error when partner is INACTIVE", async () => {
49
+ const { db, spies } = createMockDb<Transaction>();
50
+ spies.select.mockReturnValueOnce(baseInactivePartner);
51
+
52
+ const result = await run(db, { id: baseInactivePartner.id });
53
+
54
+ expect(result.ok).toBe(false);
55
+ if (!result.ok) {
56
+ expect(result.error).toBeInstanceOf(InvalidStateTransitionError);
57
+ }
58
+ });
59
+ });
@@ -0,0 +1,45 @@
1
+ import { ok, err } from "../../../shared";
2
+ import type { Transaction } from "../generated/kysely-tailordb";
3
+ import { InvalidStateTransitionError, PartnerNotFoundError } from "../lib/errors.generated";
4
+
5
+ export interface ActivatePartnerInput {
6
+ id: string;
7
+ from?: string[];
8
+ }
9
+
10
+ /**
11
+ * Function: activatePartner
12
+ *
13
+ * Transitions a business partner from DRAFT to ACTIVE status.
14
+ */
15
+ export async function run(db: Transaction, input: ActivatePartnerInput) {
16
+ const { id, from } = input;
17
+
18
+ // 1. Check partner exists
19
+ const partner = await db
20
+ .selectFrom("BusinessPartner")
21
+ .selectAll()
22
+ .where("id", "=", id)
23
+ .forUpdate()
24
+ .executeTakeFirst();
25
+
26
+ if (!partner) {
27
+ return err(new PartnerNotFoundError(id));
28
+ }
29
+
30
+ // 2. Check status is valid for activation
31
+ const validFromStatuses = from ?? ["DRAFT"];
32
+ if (!validFromStatuses.includes(partner.status)) {
33
+ return err(new InvalidStateTransitionError(`${partner.status} to ACTIVE`));
34
+ }
35
+
36
+ // 3. Update status to ACTIVE
37
+ const activatedPartner = await db
38
+ .updateTable("BusinessPartner")
39
+ .set({ status: "ACTIVE", updatedAt: new Date() })
40
+ .where("id", "=", id)
41
+ .returningAll()
42
+ .executeTakeFirstOrThrow();
43
+
44
+ return ok({ partner: activatedPartner });
45
+ }
@@ -0,0 +1,6 @@
1
+ // @generated — do not edit
2
+ import { defineCommand } from "../../../shared";
3
+ import { permissions } from "../lib/permissions.generated";
4
+ import { run } from "./assignRoleToPartner";
5
+
6
+ export const assignRoleToPartner = defineCommand(permissions.assignRoleToPartner, run);
@@ -0,0 +1,113 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { CommandContext } from "../../../shared";
4
+ import type { Transaction } from "../generated/kysely-tailordb";
5
+ import {
6
+ PartnerNotFoundError,
7
+ PartnerNotActiveError,
8
+ InvalidRoleError,
9
+ } from "../lib/errors.generated";
10
+ import {
11
+ baseActivePartner,
12
+ baseDraftPartner,
13
+ baseInactivePartner,
14
+ baseCustomerRole,
15
+ baseSupplierRole,
16
+ } from "../testing/fixtures";
17
+ import { run } from "./assignRoleToPartner";
18
+
19
+ const ctx: CommandContext = {
20
+ actorId: "test-actor",
21
+ permissions: ["business-partner:assignRoleToPartner"],
22
+ };
23
+
24
+ describe("assignRoleToPartner", () => {
25
+ it("assigns CUSTOMER to partner with no roles", async () => {
26
+ const { db, spies } = createMockDb<Transaction>();
27
+ spies.select.mockReturnValueOnce(baseActivePartner); // partner lookup
28
+ spies.select.mockReturnValueOnce(undefined); // no existing role
29
+ spies.insert.mockReturnValue({ ...baseCustomerRole, id: "role-new" });
30
+
31
+ const result = await run(db, { partnerId: "partner-2", role: "CUSTOMER" }, ctx);
32
+
33
+ expect(result.ok).toBe(true);
34
+ if (result.ok) {
35
+ expect(result.value.partnerRole).toBeDefined();
36
+ }
37
+ });
38
+
39
+ it("assigns SUPPLIER to partner that already holds CUSTOMER", async () => {
40
+ const { db, spies } = createMockDb<Transaction>();
41
+ spies.select.mockReturnValueOnce(baseActivePartner); // partner lookup
42
+ spies.select.mockReturnValueOnce(undefined); // no existing SUPPLIER role
43
+ spies.insert.mockReturnValue({ ...baseSupplierRole, id: "role-new" });
44
+
45
+ const result = await run(db, { partnerId: "partner-2", role: "SUPPLIER" }, ctx);
46
+
47
+ expect(result.ok).toBe(true);
48
+ if (result.ok) {
49
+ expect(result.value.partnerRole).toBeDefined();
50
+ }
51
+ });
52
+
53
+ it("idempotent when role already assigned", async () => {
54
+ const { db, spies } = createMockDb<Transaction>();
55
+ spies.select.mockReturnValueOnce(baseActivePartner); // partner lookup
56
+ spies.select.mockReturnValueOnce(baseCustomerRole); // existing role found
57
+
58
+ const result = await run(db, { partnerId: "partner-2", role: "CUSTOMER" }, ctx);
59
+
60
+ expect(result.ok).toBe(true);
61
+ if (result.ok) {
62
+ expect(result.value.partnerRole).toEqual(baseCustomerRole);
63
+ }
64
+ expect(spies.insert).not.toHaveBeenCalled();
65
+ });
66
+
67
+ it("returns error when partner not found", async () => {
68
+ const { db, spies } = createMockDb<Transaction>();
69
+ spies.select.mockReturnValueOnce(undefined); // partner not found
70
+
71
+ const result = await run(db, { partnerId: "nonexistent", role: "CUSTOMER" }, ctx);
72
+
73
+ expect(result.ok).toBe(false);
74
+ if (!result.ok) {
75
+ expect(result.error).toBeInstanceOf(PartnerNotFoundError);
76
+ }
77
+ });
78
+
79
+ it("returns error when partner is INACTIVE", async () => {
80
+ const { db, spies } = createMockDb<Transaction>();
81
+ spies.select.mockReturnValueOnce(baseInactivePartner); // partner in INACTIVE
82
+
83
+ const result = await run(db, { partnerId: "partner-3", role: "CUSTOMER" }, ctx);
84
+
85
+ expect(result.ok).toBe(false);
86
+ if (!result.ok) {
87
+ expect(result.error).toBeInstanceOf(PartnerNotActiveError);
88
+ }
89
+ });
90
+
91
+ it("returns error when partner is DRAFT", async () => {
92
+ const { db, spies } = createMockDb<Transaction>();
93
+ spies.select.mockReturnValueOnce(baseDraftPartner); // partner in DRAFT
94
+
95
+ const result = await run(db, { partnerId: "partner-1", role: "CUSTOMER" }, ctx);
96
+
97
+ expect(result.ok).toBe(false);
98
+ if (!result.ok) {
99
+ expect(result.error).toBeInstanceOf(PartnerNotActiveError);
100
+ }
101
+ });
102
+
103
+ it("returns error when role is invalid", async () => {
104
+ const { db } = createMockDb<Transaction>();
105
+
106
+ const result = await run(db, { partnerId: "partner-2", role: "INVALID_ROLE" }, ctx);
107
+
108
+ expect(result.ok).toBe(false);
109
+ if (!result.ok) {
110
+ expect(result.error).toBeInstanceOf(InvalidRoleError);
111
+ }
112
+ });
113
+ });
@@ -0,0 +1,72 @@
1
+ import { ok, err, type CommandContext } from "../../../shared";
2
+ import type { Transaction } from "../generated/kysely-tailordb";
3
+ import {
4
+ PartnerNotFoundError,
5
+ PartnerNotActiveError,
6
+ InvalidRoleError,
7
+ } from "../lib/errors.generated";
8
+
9
+ type ValidRole = "CUSTOMER" | "SUPPLIER";
10
+ const VALID_ROLES: readonly ValidRole[] = ["CUSTOMER", "SUPPLIER"] as const;
11
+
12
+ export interface AssignRoleToPartnerInput {
13
+ partnerId: string;
14
+ role: string;
15
+ }
16
+
17
+ /**
18
+ * Function: assignRoleToPartner
19
+ *
20
+ * Assigns a CUSTOMER or SUPPLIER role to an ACTIVE partner. Idempotent —
21
+ * returns the existing role if already assigned.
22
+ */
23
+ export async function run(db: Transaction, input: AssignRoleToPartnerInput, _ctx: CommandContext) {
24
+ const { partnerId, role } = input;
25
+
26
+ // 1. Validate role
27
+ if (!VALID_ROLES.includes(role as ValidRole)) {
28
+ return err(new InvalidRoleError(role ?? ""));
29
+ }
30
+ const validRole = role as ValidRole;
31
+
32
+ // 2. Check partner exists and is ACTIVE
33
+ const partner = await db
34
+ .selectFrom("BusinessPartner")
35
+ .selectAll()
36
+ .where("id", "=", partnerId)
37
+ .forUpdate()
38
+ .executeTakeFirst();
39
+
40
+ if (!partner) {
41
+ return err(new PartnerNotFoundError(partnerId));
42
+ }
43
+
44
+ if (partner.status !== "ACTIVE") {
45
+ return err(new PartnerNotActiveError(partnerId));
46
+ }
47
+
48
+ // 3. Check if role already assigned (idempotent)
49
+ const existingRole = await db
50
+ .selectFrom("PartnerRole")
51
+ .selectAll()
52
+ .where("partnerId", "=", partnerId)
53
+ .where("role", "=", validRole)
54
+ .executeTakeFirst();
55
+
56
+ if (existingRole) {
57
+ return ok({ partnerRole: existingRole });
58
+ }
59
+
60
+ // 4. Create new role
61
+ const partnerRole = await db
62
+ .insertInto("PartnerRole")
63
+ .values({
64
+ partnerId,
65
+ role: validRole,
66
+ updatedAt: null,
67
+ })
68
+ .returningAll()
69
+ .executeTakeFirst();
70
+
71
+ return ok({ partnerRole: partnerRole! });
72
+ }
@@ -0,0 +1,6 @@
1
+ // @generated — do not edit
2
+ import { defineCommand } from "../../../shared";
3
+ import { permissions } from "../lib/permissions.generated";
4
+ import { run } from "./createContactPerson";
5
+
6
+ export const createContactPerson = defineCommand(permissions.createContactPerson, run);