@tailor-platform/erp-kit 0.3.0 → 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 (616) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +35 -7
  3. package/dist/cli.mjs +779 -268
  4. package/package.json +5 -4
  5. package/skills/erp-kit-app-1-requirements/SKILL.md +8 -9
  6. package/skills/erp-kit-app-2-requirements-review/references/best-practices-check.md +4 -0
  7. package/skills/erp-kit-app-2-requirements-review/references/boundary-consistency-check.md +4 -0
  8. package/skills/erp-kit-app-3-plan/SKILL.md +27 -27
  9. package/skills/erp-kit-app-3-plan/references/resolver-extraction.md +21 -17
  10. package/skills/erp-kit-app-3-plan/references/screen-extraction.md +15 -1
  11. package/skills/erp-kit-app-3-plan/references/story-extraction.md +8 -2
  12. package/skills/erp-kit-app-5-impl-backend/SKILL.md +9 -11
  13. package/skills/erp-kit-app-5-impl-backend/references/app-config.md +1 -22
  14. package/skills/erp-kit-app-5-impl-backend/references/module-wiring.md +0 -1
  15. package/skills/erp-kit-app-5-impl-backend/references/resolver-patterns.md +13 -4
  16. package/skills/erp-kit-app-6-impl-frontend/SKILL.md +5 -0
  17. package/skills/erp-kit-app-6-impl-frontend/references/pages.md +16 -46
  18. package/skills/erp-kit-app-7-impl-review/SKILL.md +13 -11
  19. package/skills/erp-kit-app-7-impl-review/references/resolver-doc-code-parity.md +16 -17
  20. package/skills/erp-kit-module-1-requirements/SKILL.md +6 -12
  21. package/skills/erp-kit-module-2-requirements-review/SKILL.md +21 -5
  22. package/skills/erp-kit-module-2-requirements-review/references/requirements-report-format.md +19 -0
  23. package/skills/erp-kit-module-3-plan/SKILL.md +2 -4
  24. package/skills/erp-kit-module-4-plan-review/SKILL.md +21 -5
  25. package/skills/erp-kit-module-4-plan-review/references/parity-report-format.md +15 -0
  26. package/skills/erp-kit-module-6-impl-review/SKILL.md +21 -7
  27. package/skills/erp-kit-module-6-impl-review/references/impl-parity-report-format.md +15 -0
  28. package/skills/erp-kit-module-shared/SKILL.md +4 -0
  29. package/src/commands/app/index.ts +28 -17
  30. package/src/commands/check.test.ts +1 -1
  31. package/src/commands/check.ts +2 -35
  32. package/src/commands/doc/index.ts +83 -0
  33. package/src/commands/doc/module.test.ts +119 -0
  34. package/src/commands/doc/module.ts +114 -0
  35. package/src/commands/doc/modules.test.ts +103 -0
  36. package/src/commands/doc/modules.ts +98 -0
  37. package/src/commands/doc/search.test.ts +94 -0
  38. package/src/commands/doc/search.ts +111 -0
  39. package/src/commands/generate-doc.ts +17 -10
  40. package/src/commands/index.ts +20 -8
  41. package/src/commands/lib/command-result.ts +30 -0
  42. package/src/commands/lib/discovery.test.ts +74 -0
  43. package/src/commands/lib/discovery.ts +106 -0
  44. package/src/commands/lib/paths.ts +22 -0
  45. package/src/commands/lib/sync-check-source.test.ts +197 -0
  46. package/src/commands/lib/sync-check-source.ts +100 -0
  47. package/src/commands/lib/sync-check-tests.test.ts +178 -0
  48. package/src/commands/lib/sync-check-tests.ts +69 -0
  49. package/src/commands/mock/index.ts +11 -6
  50. package/src/commands/module/generate.ts +13 -8
  51. package/src/commands/module/index.ts +17 -21
  52. package/src/commands/parse-doc-test-cases.ts +13 -2
  53. package/src/commands/sync-check.test.ts +6 -364
  54. package/src/commands/sync-check.ts +7 -251
  55. package/src/generator/generate-app-code.test.ts +121 -0
  56. package/src/generator/generate-app-code.ts +51 -0
  57. package/src/generator/generate-code-boilerplate.test.ts +1 -1
  58. package/src/generator/generate-code.test.ts +33 -6
  59. package/src/generator/generate-code.ts +12 -226
  60. package/src/generator/generate-errors.ts +34 -0
  61. package/src/generator/generate-permissions.ts +12 -0
  62. package/src/generator/generate-shells.ts +28 -0
  63. package/src/generator/generate-stubs.ts +31 -0
  64. package/src/generator/parse-resolver-doc.test.ts +89 -0
  65. package/src/generator/parse-resolver-doc.ts +125 -0
  66. package/src/generator/scaffold.ts +57 -0
  67. package/src/generator/stub-templates.test.ts +55 -0
  68. package/src/generator/stub-templates.ts +145 -0
  69. package/src/modules/audit/README.md +46 -0
  70. package/src/modules/audit/command/activateAuditPolicy.generated.ts +6 -0
  71. package/src/modules/audit/command/activateAuditPolicy.test.ts +186 -0
  72. package/src/modules/audit/command/activateAuditPolicy.ts +97 -0
  73. package/src/modules/audit/command/createAuditPolicy.generated.ts +6 -0
  74. package/src/modules/audit/command/createAuditPolicy.test.ts +395 -0
  75. package/src/modules/audit/command/createAuditPolicy.ts +131 -0
  76. package/src/modules/audit/command/deactivateAuditPolicy.generated.ts +6 -0
  77. package/src/modules/audit/command/deactivateAuditPolicy.test.ts +138 -0
  78. package/src/modules/audit/command/deactivateAuditPolicy.ts +58 -0
  79. package/src/modules/audit/command/deleteAuditPolicy.generated.ts +6 -0
  80. package/src/modules/audit/command/deleteAuditPolicy.test.ts +121 -0
  81. package/src/modules/audit/command/deleteAuditPolicy.ts +52 -0
  82. package/src/modules/audit/command/logAuditEvent.generated.ts +6 -0
  83. package/src/modules/audit/command/logAuditEvent.test.ts +991 -0
  84. package/src/modules/audit/command/logAuditEvent.ts +357 -0
  85. package/src/modules/audit/command/reactivateAuditPolicy.generated.ts +6 -0
  86. package/src/modules/audit/command/reactivateAuditPolicy.test.ts +143 -0
  87. package/src/modules/audit/command/reactivateAuditPolicy.ts +79 -0
  88. package/src/modules/audit/command/registerAuditableEntity.generated.ts +6 -0
  89. package/src/modules/audit/command/registerAuditableEntity.test.ts +268 -0
  90. package/src/modules/audit/command/registerAuditableEntity.ts +94 -0
  91. package/src/modules/audit/command/replaceAuditPolicy.generated.ts +6 -0
  92. package/src/modules/audit/command/replaceAuditPolicy.test.ts +242 -0
  93. package/src/modules/audit/command/replaceAuditPolicy.ts +91 -0
  94. package/src/modules/audit/command/updateAuditPolicy.generated.ts +6 -0
  95. package/src/modules/audit/command/updateAuditPolicy.test.ts +284 -0
  96. package/src/modules/audit/command/updateAuditPolicy.ts +151 -0
  97. package/src/modules/audit/db/auditEntry.ts +47 -0
  98. package/src/modules/audit/db/auditPolicy.ts +33 -0
  99. package/src/modules/audit/db/auditableEntity.ts +22 -0
  100. package/src/modules/audit/db/changeDetail.ts +28 -0
  101. package/src/modules/audit/db/policyFieldRule.ts +23 -0
  102. package/src/modules/audit/docs/commands/ActivateAuditPolicy.md +69 -0
  103. package/src/modules/audit/docs/commands/CreateAuditPolicy.md +79 -0
  104. package/src/modules/audit/docs/commands/DeactivateAuditPolicy.md +55 -0
  105. package/src/modules/audit/docs/commands/DeleteAuditPolicy.md +55 -0
  106. package/src/modules/audit/docs/commands/LogAuditEvent.md +137 -0
  107. package/src/modules/audit/docs/commands/ReactivateAuditPolicy.md +58 -0
  108. package/src/modules/audit/docs/commands/RegisterAuditableEntity.md +62 -0
  109. package/src/modules/audit/docs/commands/ReplaceAuditPolicy.md +72 -0
  110. package/src/modules/audit/docs/commands/UpdateAuditPolicy.md +77 -0
  111. package/src/modules/audit/docs/features/audit-event-logging.md +126 -0
  112. package/src/modules/audit/docs/features/audit-policy-configuration.md +135 -0
  113. package/src/modules/audit/docs/features/field-level-change-tracking.md +95 -0
  114. package/src/modules/audit/docs/models/AuditEntry.md +55 -0
  115. package/src/modules/audit/docs/models/AuditPolicy.md +79 -0
  116. package/src/modules/audit/docs/models/AuditableEntity.md +38 -0
  117. package/src/modules/audit/docs/models/ChangeDetail.md +55 -0
  118. package/src/modules/audit/docs/models/PolicyFieldRule.md +45 -0
  119. package/src/modules/audit/docs/queries/GetAuditEntry.md +49 -0
  120. package/src/modules/audit/docs/queries/GetAuditPolicy.md +54 -0
  121. package/src/modules/audit/docs/queries/GetAuditSummary.md +84 -0
  122. package/src/modules/audit/docs/queries/GetChangeDetails.md +56 -0
  123. package/src/modules/audit/docs/queries/ListAuditPolicies.md +58 -0
  124. package/src/modules/audit/docs/queries/SearchAuditEntries.md +91 -0
  125. package/src/modules/audit/generated/kysely-tailordb.ts +92 -0
  126. package/src/modules/audit/index.ts +2 -0
  127. package/src/modules/audit/lib/_db_deps.ts +13 -0
  128. package/src/modules/audit/lib/errors.generated.ts +120 -0
  129. package/src/modules/audit/lib/permissions.generated.ts +14 -0
  130. package/src/modules/audit/lib/types.ts +28 -0
  131. package/src/modules/audit/module.ts +57 -0
  132. package/src/modules/audit/permissions.ts +39 -0
  133. package/src/modules/audit/query/getAuditEntry.generated.ts +5 -0
  134. package/src/modules/audit/query/getAuditEntry.test.ts +123 -0
  135. package/src/modules/audit/query/getAuditEntry.ts +36 -0
  136. package/src/modules/audit/query/getAuditPolicy.generated.ts +5 -0
  137. package/src/modules/audit/query/getAuditPolicy.test.ts +169 -0
  138. package/src/modules/audit/query/getAuditPolicy.ts +42 -0
  139. package/src/modules/audit/query/getAuditSummary.generated.ts +5 -0
  140. package/src/modules/audit/query/getAuditSummary.test.ts +632 -0
  141. package/src/modules/audit/query/getAuditSummary.ts +164 -0
  142. package/src/modules/audit/query/getChangeDetails.generated.ts +5 -0
  143. package/src/modules/audit/query/getChangeDetails.test.ts +195 -0
  144. package/src/modules/audit/query/getChangeDetails.ts +42 -0
  145. package/src/modules/audit/query/listAuditPolicies.generated.ts +5 -0
  146. package/src/modules/audit/query/listAuditPolicies.test.ts +239 -0
  147. package/src/modules/audit/query/listAuditPolicies.ts +100 -0
  148. package/src/modules/audit/query/searchAuditEntries.generated.ts +5 -0
  149. package/src/modules/audit/query/searchAuditEntries.test.ts +424 -0
  150. package/src/modules/audit/query/searchAuditEntries.ts +121 -0
  151. package/src/modules/audit/tailor.config.ts +13 -0
  152. package/src/modules/audit/tailor.d.ts +13 -0
  153. package/src/modules/audit/testing/fixtures.ts +215 -0
  154. package/src/modules/business-partner/README.md +60 -0
  155. package/src/modules/business-partner/command/.gitkeep +0 -0
  156. package/src/modules/business-partner/command/activatePartner.generated.ts +6 -0
  157. package/src/modules/business-partner/command/activatePartner.test.ts +59 -0
  158. package/src/modules/business-partner/command/activatePartner.ts +45 -0
  159. package/src/modules/business-partner/command/assignRoleToPartner.generated.ts +6 -0
  160. package/src/modules/business-partner/command/assignRoleToPartner.test.ts +113 -0
  161. package/src/modules/business-partner/command/assignRoleToPartner.ts +72 -0
  162. package/src/modules/business-partner/command/createContactPerson.generated.ts +6 -0
  163. package/src/modules/business-partner/command/createContactPerson.test.ts +193 -0
  164. package/src/modules/business-partner/command/createContactPerson.ts +98 -0
  165. package/src/modules/business-partner/command/createPartner.generated.ts +6 -0
  166. package/src/modules/business-partner/command/createPartner.test.ts +179 -0
  167. package/src/modules/business-partner/command/createPartner.ts +83 -0
  168. package/src/modules/business-partner/command/createPartnerAddress.generated.ts +6 -0
  169. package/src/modules/business-partner/command/createPartnerAddress.test.ts +195 -0
  170. package/src/modules/business-partner/command/createPartnerAddress.ts +119 -0
  171. package/src/modules/business-partner/command/createPartnerBankAccount.generated.ts +6 -0
  172. package/src/modules/business-partner/command/createPartnerBankAccount.test.ts +297 -0
  173. package/src/modules/business-partner/command/createPartnerBankAccount.ts +114 -0
  174. package/src/modules/business-partner/command/createPartnerIdentification.generated.ts +6 -0
  175. package/src/modules/business-partner/command/createPartnerIdentification.test.ts +255 -0
  176. package/src/modules/business-partner/command/createPartnerIdentification.ts +97 -0
  177. package/src/modules/business-partner/command/deactivateContactPerson.generated.ts +6 -0
  178. package/src/modules/business-partner/command/deactivateContactPerson.test.ts +70 -0
  179. package/src/modules/business-partner/command/deactivateContactPerson.ts +54 -0
  180. package/src/modules/business-partner/command/deactivatePartner.generated.ts +6 -0
  181. package/src/modules/business-partner/command/deactivatePartner.test.ts +59 -0
  182. package/src/modules/business-partner/command/deactivatePartner.ts +46 -0
  183. package/src/modules/business-partner/command/deleteContactPerson.generated.ts +6 -0
  184. package/src/modules/business-partner/command/deleteContactPerson.test.ts +61 -0
  185. package/src/modules/business-partner/command/deleteContactPerson.ts +48 -0
  186. package/src/modules/business-partner/command/deletePartner.generated.ts +6 -0
  187. package/src/modules/business-partner/command/deletePartner.test.ts +58 -0
  188. package/src/modules/business-partner/command/deletePartner.ts +46 -0
  189. package/src/modules/business-partner/command/deletePartnerAddress.generated.ts +6 -0
  190. package/src/modules/business-partner/command/deletePartnerAddress.test.ts +74 -0
  191. package/src/modules/business-partner/command/deletePartnerAddress.ts +52 -0
  192. package/src/modules/business-partner/command/deletePartnerBankAccount.generated.ts +6 -0
  193. package/src/modules/business-partner/command/deletePartnerBankAccount.test.ts +55 -0
  194. package/src/modules/business-partner/command/deletePartnerBankAccount.ts +36 -0
  195. package/src/modules/business-partner/command/deletePartnerIdentification.generated.ts +6 -0
  196. package/src/modules/business-partner/command/deletePartnerIdentification.test.ts +47 -0
  197. package/src/modules/business-partner/command/deletePartnerIdentification.ts +37 -0
  198. package/src/modules/business-partner/command/reactivateContactPerson.generated.ts +6 -0
  199. package/src/modules/business-partner/command/reactivateContactPerson.test.ts +48 -0
  200. package/src/modules/business-partner/command/reactivateContactPerson.ts +48 -0
  201. package/src/modules/business-partner/command/reactivatePartner.generated.ts +6 -0
  202. package/src/modules/business-partner/command/reactivatePartner.test.ts +59 -0
  203. package/src/modules/business-partner/command/reactivatePartner.ts +46 -0
  204. package/src/modules/business-partner/command/removeRoleFromPartner.generated.ts +6 -0
  205. package/src/modules/business-partner/command/removeRoleFromPartner.test.ts +82 -0
  206. package/src/modules/business-partner/command/removeRoleFromPartner.ts +73 -0
  207. package/src/modules/business-partner/command/setDefaultPartnerAddress.generated.ts +6 -0
  208. package/src/modules/business-partner/command/setDefaultPartnerAddress.test.ts +60 -0
  209. package/src/modules/business-partner/command/setDefaultPartnerAddress.ts +48 -0
  210. package/src/modules/business-partner/command/setDefaultPartnerBankAccount.generated.ts +6 -0
  211. package/src/modules/business-partner/command/setDefaultPartnerBankAccount.test.ts +56 -0
  212. package/src/modules/business-partner/command/setDefaultPartnerBankAccount.ts +51 -0
  213. package/src/modules/business-partner/command/setPrimaryContactPerson.generated.ts +6 -0
  214. package/src/modules/business-partner/command/setPrimaryContactPerson.test.ts +63 -0
  215. package/src/modules/business-partner/command/setPrimaryContactPerson.ts +55 -0
  216. package/src/modules/business-partner/command/updateContactPerson.generated.ts +6 -0
  217. package/src/modules/business-partner/command/updateContactPerson.test.ts +193 -0
  218. package/src/modules/business-partner/command/updateContactPerson.ts +92 -0
  219. package/src/modules/business-partner/command/updatePartner.generated.ts +6 -0
  220. package/src/modules/business-partner/command/updatePartner.test.ts +101 -0
  221. package/src/modules/business-partner/command/updatePartner.ts +76 -0
  222. package/src/modules/business-partner/command/updatePartnerAddress.generated.ts +6 -0
  223. package/src/modules/business-partner/command/updatePartnerAddress.test.ts +148 -0
  224. package/src/modules/business-partner/command/updatePartnerAddress.ts +64 -0
  225. package/src/modules/business-partner/command/updatePartnerBankAccount.generated.ts +6 -0
  226. package/src/modules/business-partner/command/updatePartnerBankAccount.test.ts +249 -0
  227. package/src/modules/business-partner/command/updatePartnerBankAccount.ts +109 -0
  228. package/src/modules/business-partner/command/updatePartnerIdentification.generated.ts +6 -0
  229. package/src/modules/business-partner/command/updatePartnerIdentification.test.ts +162 -0
  230. package/src/modules/business-partner/command/updatePartnerIdentification.ts +105 -0
  231. package/src/modules/business-partner/db/.gitkeep +0 -0
  232. package/src/modules/business-partner/db/businessPartner.ts +59 -0
  233. package/src/modules/business-partner/db/contactPerson.ts +49 -0
  234. package/src/modules/business-partner/db/partnerAddress.ts +45 -0
  235. package/src/modules/business-partner/db/partnerBankAccount.ts +53 -0
  236. package/src/modules/business-partner/db/partnerIdentification.ts +53 -0
  237. package/src/modules/business-partner/db/partnerRole.ts +43 -0
  238. package/src/modules/business-partner/docs/commands/ActivatePartner.md +39 -0
  239. package/src/modules/business-partner/docs/commands/AssignRoleToPartner.md +49 -0
  240. package/src/modules/business-partner/docs/commands/CreateContactPerson.md +59 -0
  241. package/src/modules/business-partner/docs/commands/CreatePartner.md +54 -0
  242. package/src/modules/business-partner/docs/commands/CreatePartnerAddress.md +60 -0
  243. package/src/modules/business-partner/docs/commands/CreatePartnerBankAccount.md +68 -0
  244. package/src/modules/business-partner/docs/commands/CreatePartnerIdentification.md +59 -0
  245. package/src/modules/business-partner/docs/commands/DeactivateContactPerson.md +42 -0
  246. package/src/modules/business-partner/docs/commands/DeactivatePartner.md +39 -0
  247. package/src/modules/business-partner/docs/commands/DeleteContactPerson.md +43 -0
  248. package/src/modules/business-partner/docs/commands/DeletePartner.md +40 -0
  249. package/src/modules/business-partner/docs/commands/DeletePartnerAddress.md +40 -0
  250. package/src/modules/business-partner/docs/commands/DeletePartnerBankAccount.md +35 -0
  251. package/src/modules/business-partner/docs/commands/DeletePartnerIdentification.md +33 -0
  252. package/src/modules/business-partner/docs/commands/ReactivateContactPerson.md +38 -0
  253. package/src/modules/business-partner/docs/commands/ReactivatePartner.md +39 -0
  254. package/src/modules/business-partner/docs/commands/RemoveRoleFromPartner.md +46 -0
  255. package/src/modules/business-partner/docs/commands/SetDefaultPartnerAddress.md +38 -0
  256. package/src/modules/business-partner/docs/commands/SetDefaultPartnerBankAccount.md +38 -0
  257. package/src/modules/business-partner/docs/commands/SetPrimaryContactPerson.md +43 -0
  258. package/src/modules/business-partner/docs/commands/UpdateContactPerson.md +66 -0
  259. package/src/modules/business-partner/docs/commands/UpdatePartner.md +48 -0
  260. package/src/modules/business-partner/docs/commands/UpdatePartnerAddress.md +46 -0
  261. package/src/modules/business-partner/docs/commands/UpdatePartnerBankAccount.md +64 -0
  262. package/src/modules/business-partner/docs/commands/UpdatePartnerIdentification.md +52 -0
  263. package/src/modules/business-partner/docs/features/contact-person-management.md +70 -0
  264. package/src/modules/business-partner/docs/features/partner-address-management.md +96 -0
  265. package/src/modules/business-partner/docs/features/partner-bank-account.md +70 -0
  266. package/src/modules/business-partner/docs/features/partner-identification.md +76 -0
  267. package/src/modules/business-partner/docs/features/partner-lifecycle.md +59 -0
  268. package/src/modules/business-partner/docs/features/partner-role-classification.md +73 -0
  269. package/src/modules/business-partner/docs/models/BusinessPartner.md +64 -0
  270. package/src/modules/business-partner/docs/models/ContactPerson.md +62 -0
  271. package/src/modules/business-partner/docs/models/PartnerAddress.md +52 -0
  272. package/src/modules/business-partner/docs/models/PartnerBankAccount.md +50 -0
  273. package/src/modules/business-partner/docs/models/PartnerIdentification.md +46 -0
  274. package/src/modules/business-partner/docs/models/PartnerRole.md +42 -0
  275. package/src/modules/business-partner/docs/queries/GetContactPerson.md +34 -0
  276. package/src/modules/business-partner/docs/queries/GetDefaultPartnerAddress.md +40 -0
  277. package/src/modules/business-partner/docs/queries/GetDefaultPartnerBankAccount.md +36 -0
  278. package/src/modules/business-partner/docs/queries/GetPartner.md +35 -0
  279. package/src/modules/business-partner/docs/queries/GetPartnerAddress.md +34 -0
  280. package/src/modules/business-partner/docs/queries/GetPartnerBankAccount.md +34 -0
  281. package/src/modules/business-partner/docs/queries/GetPartnerIdentification.md +34 -0
  282. package/src/modules/business-partner/docs/queries/GetPartnerRole.md +34 -0
  283. package/src/modules/business-partner/docs/queries/GetPrimaryContactPerson.md +36 -0
  284. package/src/modules/business-partner/docs/queries/ListContactPersonsByPartner.md +39 -0
  285. package/src/modules/business-partner/docs/queries/ListPartnerAddressesByPartner.md +41 -0
  286. package/src/modules/business-partner/docs/queries/ListPartnerBankAccountsByPartner.md +39 -0
  287. package/src/modules/business-partner/docs/queries/ListPartnerIdentificationsByPartner.md +41 -0
  288. package/src/modules/business-partner/docs/queries/ListPartnersByRole.md +47 -0
  289. package/src/modules/business-partner/executor/.gitkeep +0 -0
  290. package/src/modules/business-partner/generated/.gitkeep +0 -0
  291. package/src/modules/business-partner/generated/enums.ts +60 -0
  292. package/src/modules/business-partner/generated/kysely-tailordb.ts +114 -0
  293. package/src/modules/business-partner/index.ts +2 -0
  294. package/src/modules/business-partner/lib/_db_deps.ts +17 -0
  295. package/src/modules/business-partner/lib/errors.generated.ts +172 -0
  296. package/src/modules/business-partner/lib/errors.ts +2 -0
  297. package/src/modules/business-partner/lib/permissions.generated.ts +30 -0
  298. package/src/modules/business-partner/lib/types.ts +53 -0
  299. package/src/modules/business-partner/module.ts +181 -0
  300. package/src/modules/business-partner/permissions.ts +3 -0
  301. package/src/modules/business-partner/query/.gitkeep +0 -0
  302. package/src/modules/business-partner/query/getContactPerson.generated.ts +5 -0
  303. package/src/modules/business-partner/query/getContactPerson.test.ts +31 -0
  304. package/src/modules/business-partner/query/getContactPerson.ts +16 -0
  305. package/src/modules/business-partner/query/getDefaultPartnerAddress.generated.ts +5 -0
  306. package/src/modules/business-partner/query/getDefaultPartnerAddress.test.ts +45 -0
  307. package/src/modules/business-partner/query/getDefaultPartnerAddress.ts +30 -0
  308. package/src/modules/business-partner/query/getDefaultPartnerBankAccount.generated.ts +5 -0
  309. package/src/modules/business-partner/query/getDefaultPartnerBankAccount.test.ts +43 -0
  310. package/src/modules/business-partner/query/getDefaultPartnerBankAccount.ts +17 -0
  311. package/src/modules/business-partner/query/getPartner.generated.ts +5 -0
  312. package/src/modules/business-partner/query/getPartner.test.ts +31 -0
  313. package/src/modules/business-partner/query/getPartner.ts +16 -0
  314. package/src/modules/business-partner/query/getPartnerAddress.generated.ts +5 -0
  315. package/src/modules/business-partner/query/getPartnerAddress.test.ts +31 -0
  316. package/src/modules/business-partner/query/getPartnerAddress.ts +16 -0
  317. package/src/modules/business-partner/query/getPartnerBankAccount.generated.ts +5 -0
  318. package/src/modules/business-partner/query/getPartnerBankAccount.test.ts +31 -0
  319. package/src/modules/business-partner/query/getPartnerBankAccount.ts +16 -0
  320. package/src/modules/business-partner/query/getPartnerIdentification.generated.ts +5 -0
  321. package/src/modules/business-partner/query/getPartnerIdentification.test.ts +31 -0
  322. package/src/modules/business-partner/query/getPartnerIdentification.ts +16 -0
  323. package/src/modules/business-partner/query/getPartnerRole.generated.ts +5 -0
  324. package/src/modules/business-partner/query/getPartnerRole.test.ts +31 -0
  325. package/src/modules/business-partner/query/getPartnerRole.ts +19 -0
  326. package/src/modules/business-partner/query/getPrimaryContactPerson.generated.ts +5 -0
  327. package/src/modules/business-partner/query/getPrimaryContactPerson.test.ts +43 -0
  328. package/src/modules/business-partner/query/getPrimaryContactPerson.ts +17 -0
  329. package/src/modules/business-partner/query/listContactPersonsByPartner.generated.ts +5 -0
  330. package/src/modules/business-partner/query/listContactPersonsByPartner.test.ts +77 -0
  331. package/src/modules/business-partner/query/listContactPersonsByPartner.ts +32 -0
  332. package/src/modules/business-partner/query/listPartnerAddressesByPartner.generated.ts +5 -0
  333. package/src/modules/business-partner/query/listPartnerAddressesByPartner.test.ts +71 -0
  334. package/src/modules/business-partner/query/listPartnerAddressesByPartner.ts +37 -0
  335. package/src/modules/business-partner/query/listPartnerBankAccountsByPartner.generated.ts +5 -0
  336. package/src/modules/business-partner/query/listPartnerBankAccountsByPartner.test.ts +59 -0
  337. package/src/modules/business-partner/query/listPartnerBankAccountsByPartner.ts +32 -0
  338. package/src/modules/business-partner/query/listPartnerIdentificationsByPartner.generated.ts +5 -0
  339. package/src/modules/business-partner/query/listPartnerIdentificationsByPartner.test.ts +72 -0
  340. package/src/modules/business-partner/query/listPartnerIdentificationsByPartner.ts +40 -0
  341. package/src/modules/business-partner/query/listPartnersByRole.generated.ts +5 -0
  342. package/src/modules/business-partner/query/listPartnersByRole.test.ts +103 -0
  343. package/src/modules/business-partner/query/listPartnersByRole.ts +47 -0
  344. package/src/modules/business-partner/tailor.config.ts +13 -0
  345. package/src/modules/business-partner/tailor.d.ts +13 -0
  346. package/src/modules/business-partner/testing/fixtures.ts +204 -0
  347. package/src/modules/coa-management/README.md +61 -0
  348. package/src/modules/coa-management/command/.gitkeep +0 -0
  349. package/src/modules/coa-management/command/activateAccount.generated.ts +6 -0
  350. package/src/modules/coa-management/command/activateAccount.test.ts +125 -0
  351. package/src/modules/coa-management/command/activateAccount.ts +105 -0
  352. package/src/modules/coa-management/command/activateChartOfAccounts.generated.ts +6 -0
  353. package/src/modules/coa-management/command/activateChartOfAccounts.test.ts +113 -0
  354. package/src/modules/coa-management/command/activateChartOfAccounts.ts +104 -0
  355. package/src/modules/coa-management/command/createAccount.generated.ts +6 -0
  356. package/src/modules/coa-management/command/createAccount.test.ts +767 -0
  357. package/src/modules/coa-management/command/createAccount.ts +247 -0
  358. package/src/modules/coa-management/command/createAccountGroup.generated.ts +6 -0
  359. package/src/modules/coa-management/command/createAccountGroup.test.ts +494 -0
  360. package/src/modules/coa-management/command/createAccountGroup.ts +207 -0
  361. package/src/modules/coa-management/command/createChartOfAccounts.generated.ts +6 -0
  362. package/src/modules/coa-management/command/createChartOfAccounts.test.ts +502 -0
  363. package/src/modules/coa-management/command/createChartOfAccounts.ts +267 -0
  364. package/src/modules/coa-management/command/deactivateAccount.generated.ts +6 -0
  365. package/src/modules/coa-management/command/deactivateAccount.test.ts +199 -0
  366. package/src/modules/coa-management/command/deactivateAccount.ts +142 -0
  367. package/src/modules/coa-management/command/deactivateChartOfAccounts.generated.ts +6 -0
  368. package/src/modules/coa-management/command/deactivateChartOfAccounts.test.ts +91 -0
  369. package/src/modules/coa-management/command/deactivateChartOfAccounts.ts +88 -0
  370. package/src/modules/coa-management/command/deleteAccount.generated.ts +6 -0
  371. package/src/modules/coa-management/command/deleteAccount.test.ts +122 -0
  372. package/src/modules/coa-management/command/deleteAccount.ts +103 -0
  373. package/src/modules/coa-management/command/deleteAccountGroup.generated.ts +6 -0
  374. package/src/modules/coa-management/command/deleteAccountGroup.test.ts +120 -0
  375. package/src/modules/coa-management/command/deleteAccountGroup.ts +113 -0
  376. package/src/modules/coa-management/command/deleteChartOfAccounts.generated.ts +6 -0
  377. package/src/modules/coa-management/command/deleteChartOfAccounts.test.ts +154 -0
  378. package/src/modules/coa-management/command/deleteChartOfAccounts.ts +133 -0
  379. package/src/modules/coa-management/command/moveAccountGroup.generated.ts +6 -0
  380. package/src/modules/coa-management/command/moveAccountGroup.test.ts +199 -0
  381. package/src/modules/coa-management/command/moveAccountGroup.ts +145 -0
  382. package/src/modules/coa-management/command/reactivateAccount.generated.ts +6 -0
  383. package/src/modules/coa-management/command/reactivateAccount.test.ts +126 -0
  384. package/src/modules/coa-management/command/reactivateAccount.ts +123 -0
  385. package/src/modules/coa-management/command/updateAccount.generated.ts +6 -0
  386. package/src/modules/coa-management/command/updateAccount.test.ts +669 -0
  387. package/src/modules/coa-management/command/updateAccount.ts +370 -0
  388. package/src/modules/coa-management/command/updateAccountGroup.generated.ts +6 -0
  389. package/src/modules/coa-management/command/updateAccountGroup.test.ts +253 -0
  390. package/src/modules/coa-management/command/updateAccountGroup.ts +191 -0
  391. package/src/modules/coa-management/command/updateChartOfAccounts.generated.ts +6 -0
  392. package/src/modules/coa-management/command/updateChartOfAccounts.test.ts +153 -0
  393. package/src/modules/coa-management/command/updateChartOfAccounts.ts +133 -0
  394. package/src/modules/coa-management/db/.gitkeep +0 -0
  395. package/src/modules/coa-management/db/account.ts +119 -0
  396. package/src/modules/coa-management/db/accountGroup.ts +57 -0
  397. package/src/modules/coa-management/db/chartOfAccounts.ts +55 -0
  398. package/src/modules/coa-management/docs/commands/ActivateAccount.md +49 -0
  399. package/src/modules/coa-management/docs/commands/ActivateChartOfAccounts.md +47 -0
  400. package/src/modules/coa-management/docs/commands/CreateAccount.md +94 -0
  401. package/src/modules/coa-management/docs/commands/CreateAccountGroup.md +70 -0
  402. package/src/modules/coa-management/docs/commands/CreateChartOfAccounts.md +72 -0
  403. package/src/modules/coa-management/docs/commands/DeactivateAccount.md +65 -0
  404. package/src/modules/coa-management/docs/commands/DeactivateChartOfAccounts.md +44 -0
  405. package/src/modules/coa-management/docs/commands/DeleteAccount.md +52 -0
  406. package/src/modules/coa-management/docs/commands/DeleteAccountGroup.md +50 -0
  407. package/src/modules/coa-management/docs/commands/DeleteChartOfAccounts.md +48 -0
  408. package/src/modules/coa-management/docs/commands/MoveAccountGroup.md +57 -0
  409. package/src/modules/coa-management/docs/commands/ReactivateAccount.md +50 -0
  410. package/src/modules/coa-management/docs/commands/UpdateAccount.md +102 -0
  411. package/src/modules/coa-management/docs/commands/UpdateAccountGroup.md +62 -0
  412. package/src/modules/coa-management/docs/commands/UpdateChartOfAccounts.md +49 -0
  413. package/src/modules/coa-management/docs/features/account-group-hierarchy.md +81 -0
  414. package/src/modules/coa-management/docs/features/account-lifecycle.md +80 -0
  415. package/src/modules/coa-management/docs/features/account-management.md +114 -0
  416. package/src/modules/coa-management/docs/features/chart-of-accounts-setup.md +86 -0
  417. package/src/modules/coa-management/docs/models/Account.md +84 -0
  418. package/src/modules/coa-management/docs/models/AccountGroup.md +55 -0
  419. package/src/modules/coa-management/docs/models/ChartOfAccounts.md +65 -0
  420. package/src/modules/coa-management/docs/queries/DetectCircularReference.md +52 -0
  421. package/src/modules/coa-management/docs/queries/GetAccount.md +42 -0
  422. package/src/modules/coa-management/docs/queries/GetAccountGroup.md +42 -0
  423. package/src/modules/coa-management/docs/queries/GetChartOfAccounts.md +48 -0
  424. package/src/modules/coa-management/docs/queries/ListAccountGroups.md +42 -0
  425. package/src/modules/coa-management/docs/queries/ListAccounts.md +54 -0
  426. package/src/modules/coa-management/docs/queries/ListUnassignedAccounts.md +40 -0
  427. package/src/modules/coa-management/executor/.gitkeep +0 -0
  428. package/src/modules/coa-management/generated/.gitkeep +0 -0
  429. package/src/modules/coa-management/generated/enums.ts +45 -0
  430. package/src/modules/coa-management/generated/kysely-tailordb.ts +81 -0
  431. package/src/modules/coa-management/index.ts +2 -0
  432. package/src/modules/coa-management/lib/_db_deps.ts +17 -0
  433. package/src/modules/coa-management/lib/errors.generated.ts +162 -0
  434. package/src/modules/coa-management/lib/errors.ts +0 -0
  435. package/src/modules/coa-management/lib/permissions.generated.ts +20 -0
  436. package/src/modules/coa-management/lib/types.ts +22 -0
  437. package/src/modules/coa-management/module.ts +136 -0
  438. package/src/modules/coa-management/permissions.ts +3 -0
  439. package/src/modules/coa-management/query/.gitkeep +0 -0
  440. package/src/modules/coa-management/query/detectCircularReference.generated.ts +5 -0
  441. package/src/modules/coa-management/query/detectCircularReference.test.ts +88 -0
  442. package/src/modules/coa-management/query/detectCircularReference.ts +46 -0
  443. package/src/modules/coa-management/query/getAccount.generated.ts +5 -0
  444. package/src/modules/coa-management/query/getAccount.test.ts +55 -0
  445. package/src/modules/coa-management/query/getAccount.ts +25 -0
  446. package/src/modules/coa-management/query/getAccountGroup.generated.ts +5 -0
  447. package/src/modules/coa-management/query/getAccountGroup.test.ts +55 -0
  448. package/src/modules/coa-management/query/getAccountGroup.ts +25 -0
  449. package/src/modules/coa-management/query/getChartOfAccounts.generated.ts +5 -0
  450. package/src/modules/coa-management/query/getChartOfAccounts.test.ts +79 -0
  451. package/src/modules/coa-management/query/getChartOfAccounts.ts +28 -0
  452. package/src/modules/coa-management/query/listAccountGroups.generated.ts +5 -0
  453. package/src/modules/coa-management/query/listAccountGroups.test.ts +72 -0
  454. package/src/modules/coa-management/query/listAccountGroups.ts +49 -0
  455. package/src/modules/coa-management/query/listAccounts.generated.ts +5 -0
  456. package/src/modules/coa-management/query/listAccounts.test.ts +136 -0
  457. package/src/modules/coa-management/query/listAccounts.ts +82 -0
  458. package/src/modules/coa-management/query/listUnassignedAccounts.generated.ts +5 -0
  459. package/src/modules/coa-management/query/listUnassignedAccounts.test.ts +96 -0
  460. package/src/modules/coa-management/query/listUnassignedAccounts.ts +39 -0
  461. package/src/modules/coa-management/tailor.config.ts +13 -0
  462. package/src/modules/coa-management/tailor.d.ts +13 -0
  463. package/src/modules/coa-management/testing/fixtures.ts +201 -0
  464. package/src/modules/item-management/README.md +1 -1
  465. package/src/modules/organization/README.md +57 -0
  466. package/src/modules/organization/command/.gitkeep +0 -0
  467. package/src/modules/organization/command/activateCompany.generated.ts +6 -0
  468. package/src/modules/organization/command/activateCompany.test.ts +184 -0
  469. package/src/modules/organization/command/activateCompany.ts +92 -0
  470. package/src/modules/organization/command/createCompany.generated.ts +6 -0
  471. package/src/modules/organization/command/createCompany.test.ts +156 -0
  472. package/src/modules/organization/command/createCompany.ts +80 -0
  473. package/src/modules/organization/command/createDepartment.generated.ts +6 -0
  474. package/src/modules/organization/command/createDepartment.test.ts +239 -0
  475. package/src/modules/organization/command/createDepartment.ts +98 -0
  476. package/src/modules/organization/command/createSite.generated.ts +6 -0
  477. package/src/modules/organization/command/createSite.test.ts +262 -0
  478. package/src/modules/organization/command/createSite.ts +155 -0
  479. package/src/modules/organization/command/deactivateCompany.generated.ts +6 -0
  480. package/src/modules/organization/command/deactivateCompany.test.ts +58 -0
  481. package/src/modules/organization/command/deactivateCompany.ts +47 -0
  482. package/src/modules/organization/command/deactivateDepartment.generated.ts +6 -0
  483. package/src/modules/organization/command/deactivateDepartment.test.ts +115 -0
  484. package/src/modules/organization/command/deactivateDepartment.ts +63 -0
  485. package/src/modules/organization/command/deactivateSite.generated.ts +6 -0
  486. package/src/modules/organization/command/deactivateSite.test.ts +53 -0
  487. package/src/modules/organization/command/deactivateSite.ts +47 -0
  488. package/src/modules/organization/command/deleteCompany.generated.ts +6 -0
  489. package/src/modules/organization/command/deleteCompany.test.ts +99 -0
  490. package/src/modules/organization/command/deleteCompany.ts +66 -0
  491. package/src/modules/organization/command/reactivateCompany.generated.ts +6 -0
  492. package/src/modules/organization/command/reactivateCompany.test.ts +58 -0
  493. package/src/modules/organization/command/reactivateCompany.ts +47 -0
  494. package/src/modules/organization/command/reactivateDepartment.generated.ts +6 -0
  495. package/src/modules/organization/command/reactivateDepartment.test.ts +59 -0
  496. package/src/modules/organization/command/reactivateDepartment.ts +47 -0
  497. package/src/modules/organization/command/reactivateSite.generated.ts +6 -0
  498. package/src/modules/organization/command/reactivateSite.test.ts +53 -0
  499. package/src/modules/organization/command/reactivateSite.ts +47 -0
  500. package/src/modules/organization/command/updateCompany.generated.ts +6 -0
  501. package/src/modules/organization/command/updateCompany.test.ts +239 -0
  502. package/src/modules/organization/command/updateCompany.ts +127 -0
  503. package/src/modules/organization/command/updateDepartment.generated.ts +6 -0
  504. package/src/modules/organization/command/updateDepartment.test.ts +232 -0
  505. package/src/modules/organization/command/updateDepartment.ts +120 -0
  506. package/src/modules/organization/command/updateSite.generated.ts +6 -0
  507. package/src/modules/organization/command/updateSite.test.ts +274 -0
  508. package/src/modules/organization/command/updateSite.ts +176 -0
  509. package/src/modules/organization/db/.gitkeep +0 -0
  510. package/src/modules/organization/db/company.ts +44 -0
  511. package/src/modules/organization/db/department.ts +46 -0
  512. package/src/modules/organization/db/site.ts +44 -0
  513. package/src/modules/organization/docs/commands/ActivateCompany.md +62 -0
  514. package/src/modules/organization/docs/commands/CreateCompany.md +49 -0
  515. package/src/modules/organization/docs/commands/CreateDepartment.md +62 -0
  516. package/src/modules/organization/docs/commands/CreateSite.md +74 -0
  517. package/src/modules/organization/docs/commands/DeactivateCompany.md +40 -0
  518. package/src/modules/organization/docs/commands/DeactivateDepartment.md +44 -0
  519. package/src/modules/organization/docs/commands/DeactivateSite.md +38 -0
  520. package/src/modules/organization/docs/commands/DeleteCompany.md +50 -0
  521. package/src/modules/organization/docs/commands/ReactivateCompany.md +39 -0
  522. package/src/modules/organization/docs/commands/ReactivateDepartment.md +37 -0
  523. package/src/modules/organization/docs/commands/ReactivateSite.md +37 -0
  524. package/src/modules/organization/docs/commands/UpdateCompany.md +58 -0
  525. package/src/modules/organization/docs/commands/UpdateDepartment.md +64 -0
  526. package/src/modules/organization/docs/commands/UpdateSite.md +80 -0
  527. package/src/modules/organization/docs/features/company-lifecycle.md +76 -0
  528. package/src/modules/organization/docs/features/department-management.md +66 -0
  529. package/src/modules/organization/docs/features/site-management.md +86 -0
  530. package/src/modules/organization/docs/models/Company.md +60 -0
  531. package/src/modules/organization/docs/models/Department.md +57 -0
  532. package/src/modules/organization/docs/models/Site.md +57 -0
  533. package/src/modules/organization/docs/queries/DetectDepartmentCircularReference.md +50 -0
  534. package/src/modules/organization/docs/queries/GetCompany.md +40 -0
  535. package/src/modules/organization/docs/queries/GetDepartment.md +44 -0
  536. package/src/modules/organization/docs/queries/GetDepartmentChildren.md +40 -0
  537. package/src/modules/organization/docs/queries/GetSite.md +37 -0
  538. package/src/modules/organization/docs/queries/ListDepartmentsByCompany.md +54 -0
  539. package/src/modules/organization/docs/queries/ListSitesByCompany.md +54 -0
  540. package/src/modules/organization/executor/.gitkeep +0 -0
  541. package/src/modules/organization/generated/.gitkeep +0 -0
  542. package/src/modules/organization/generated/kysely-tailordb.ts +77 -0
  543. package/src/modules/organization/index.ts +2 -0
  544. package/src/modules/organization/lib/_db_deps.ts +10 -0
  545. package/src/modules/organization/lib/errors.generated.ts +117 -0
  546. package/src/modules/organization/lib/errors.ts +1 -0
  547. package/src/modules/organization/lib/permissions.generated.ts +19 -0
  548. package/src/modules/organization/lib/types.ts +16 -0
  549. package/src/modules/organization/module.ts +89 -0
  550. package/src/modules/organization/permissions.ts +3 -0
  551. package/src/modules/organization/query/.gitkeep +0 -0
  552. package/src/modules/organization/query/detectDepartmentCircularReference.generated.ts +5 -0
  553. package/src/modules/organization/query/detectDepartmentCircularReference.test.ts +102 -0
  554. package/src/modules/organization/query/detectDepartmentCircularReference.ts +27 -0
  555. package/src/modules/organization/query/getCompany.generated.ts +5 -0
  556. package/src/modules/organization/query/getCompany.test.ts +70 -0
  557. package/src/modules/organization/query/getCompany.ts +16 -0
  558. package/src/modules/organization/query/getDepartment.generated.ts +5 -0
  559. package/src/modules/organization/query/getDepartment.test.ts +85 -0
  560. package/src/modules/organization/query/getDepartment.ts +17 -0
  561. package/src/modules/organization/query/getDepartmentChildren.generated.ts +5 -0
  562. package/src/modules/organization/query/getDepartmentChildren.test.ts +75 -0
  563. package/src/modules/organization/query/getDepartmentChildren.ts +21 -0
  564. package/src/modules/organization/query/getSite.generated.ts +5 -0
  565. package/src/modules/organization/query/getSite.test.ts +55 -0
  566. package/src/modules/organization/query/getSite.ts +16 -0
  567. package/src/modules/organization/query/listDepartmentsByCompany.generated.ts +5 -0
  568. package/src/modules/organization/query/listDepartmentsByCompany.test.ts +124 -0
  569. package/src/modules/organization/query/listDepartmentsByCompany.ts +43 -0
  570. package/src/modules/organization/query/listSitesByCompany.generated.ts +5 -0
  571. package/src/modules/organization/query/listSitesByCompany.test.ts +126 -0
  572. package/src/modules/organization/query/listSitesByCompany.ts +41 -0
  573. package/src/modules/organization/tailor.config.ts +13 -0
  574. package/src/modules/organization/tailor.d.ts +13 -0
  575. package/src/modules/organization/testing/fixtures.ts +155 -0
  576. package/src/modules/primitives/README.md +1 -1
  577. package/src/modules/primitives/command/setBaseCurrency.test.ts +8 -64
  578. package/src/modules/primitives/command/setBaseCurrency.ts +6 -64
  579. package/src/modules/primitives/docs/commands/ActivateCategory.md +1 -1
  580. package/src/modules/primitives/docs/commands/ActivateCurrency.md +1 -1
  581. package/src/modules/primitives/docs/commands/ActivateUnit.md +1 -1
  582. package/src/modules/primitives/docs/commands/CreateExchangeRate.md +2 -2
  583. package/src/modules/primitives/docs/commands/CreateUnit.md +1 -1
  584. package/src/modules/primitives/docs/commands/DeactivateCategory.md +1 -1
  585. package/src/modules/primitives/docs/commands/DeactivateCurrency.md +1 -1
  586. package/src/modules/primitives/docs/commands/DeactivateUnit.md +1 -1
  587. package/src/modules/primitives/docs/commands/SetBaseCurrency.md +13 -23
  588. package/src/modules/primitives/docs/commands/SetReferenceUnit.md +1 -1
  589. package/src/modules/primitives/docs/features/currency-definitions.md +13 -14
  590. package/src/modules/primitives/docs/models/Currency.md +3 -4
  591. package/src/modules/primitives/docs/queries/ConvertAmount.md +2 -2
  592. package/src/modules/primitives/docs/queries/ConvertQuantity.md +2 -2
  593. package/src/modules/primitives/lib/errors.generated.ts +5 -0
  594. package/src/modules/product-management/README.md +1 -1
  595. package/src/modules/user-management/docs/commands/CreatePermission.md +3 -3
  596. package/src/modules/user-management/docs/commands/CreateRole.md +1 -1
  597. package/src/modules/user-management/docs/queries/ListRolePermissionsByRole.md +39 -0
  598. package/src/modules/user-management/docs/queries/ListUserRolesByUser.md +39 -0
  599. package/src/modules/user-management/generated/enums.ts +0 -15
  600. package/src/modules/user-management/generated/kysely-tailordb.ts +0 -11
  601. package/src/shared/createContext.ts +2 -1
  602. package/src/shared/defineQuery.ts +36 -1
  603. package/src/shared/requirePermission.ts +3 -3
  604. package/src/shared/types.ts +3 -0
  605. package/templates/scaffold/app/backend/package.json +4 -3
  606. package/templates/scaffold/app/frontend/eslint.config.js +12 -0
  607. package/templates/scaffold/app/frontend/package.json +10 -7
  608. package/templates/scaffold/app/frontend/src/hooks/use-toast.ts +30 -0
  609. package/templates/scaffold/app/frontend/src/pages/user-management/user/create/components/create-user-form.tsx +3 -2
  610. package/templates/scaffold/app/frontend/vite.config.ts +5 -5
  611. package/src/commands/module/list.test.ts +0 -57
  612. package/src/commands/module/list.ts +0 -64
  613. /package/src/modules/{accounting → audit/db}/.gitkeep +0 -0
  614. /package/src/modules/audit/{.gitkeep → executor/.gitkeep} +0 -0
  615. /package/src/modules/{coa-management/.gitkeep → audit/lib/errors.ts} +0 -0
  616. /package/src/modules/{supplier-management → business-partner}/.gitkeep +0 -0
@@ -0,0 +1,125 @@
1
+ import { fromMarkdown } from "mdast-util-from-markdown";
2
+ import { toString } from "mdast-util-to-string";
3
+ import type { Heading, RootContent, Root } from "mdast";
4
+
5
+ export interface ParsedModuleCommand {
6
+ module: string;
7
+ command: string;
8
+ }
9
+
10
+ export interface ParsedResolverError {
11
+ code: string;
12
+ description: string;
13
+ }
14
+
15
+ export interface ParsedResolverDoc {
16
+ resolverName: string;
17
+ moduleCommands: ParsedModuleCommand[];
18
+ errors: ParsedResolverError[];
19
+ }
20
+
21
+ const MODULE_COMMAND_PATTERN = /([a-z][\w-]*)\.(\w+)/;
22
+ const TABLE_ROW_PATTERN = /^\|(.+)\|(.+)\|$/;
23
+
24
+ export function parseResolverDoc(fileName: string, markdown: string): ParsedResolverDoc {
25
+ const resolverName = fileName.charAt(0).toLowerCase() + fileName.slice(1);
26
+ const tree = fromMarkdown(markdown);
27
+
28
+ return {
29
+ resolverName,
30
+ moduleCommands: parseModuleCommands(tree),
31
+ errors: parseExceptionHandlingFromRaw(markdown),
32
+ };
33
+ }
34
+
35
+ function isHeading(node: RootContent): node is Heading {
36
+ return node.type === "heading";
37
+ }
38
+
39
+ function getNodesUnderHeading(tree: Root, headingText: string): RootContent[] {
40
+ const nodes: RootContent[] = [];
41
+ let collecting = false;
42
+
43
+ for (const node of tree.children) {
44
+ if (isHeading(node)) {
45
+ if (collecting) break;
46
+ if (node.depth === 2 && toString(node) === headingText) {
47
+ collecting = true;
48
+ continue;
49
+ }
50
+ }
51
+ if (collecting) {
52
+ nodes.push(node);
53
+ }
54
+ }
55
+
56
+ return nodes;
57
+ }
58
+
59
+ function parseModuleCommands(tree: Root): ParsedModuleCommand[] {
60
+ const nodes = getNodesUnderHeading(tree, "Modules Commands Used");
61
+ const commands: ParsedModuleCommand[] = [];
62
+
63
+ for (const node of nodes) {
64
+ if (node.type !== "list") continue;
65
+
66
+ for (const item of node.children) {
67
+ const text = toString(item);
68
+ const match = MODULE_COMMAND_PATTERN.exec(text);
69
+ if (match) {
70
+ commands.push({ module: match[1], command: match[2] });
71
+ }
72
+ }
73
+ }
74
+
75
+ return commands;
76
+ }
77
+
78
+ function parseExceptionHandlingFromRaw(markdown: string): ParsedResolverError[] {
79
+ const lines = markdown.split("\n");
80
+ const errors: ParsedResolverError[] = [];
81
+
82
+ // Find the "## Exception Handling" heading
83
+ let inSection = false;
84
+ let headerSkipped = false;
85
+ let separatorSkipped = false;
86
+
87
+ for (const line of lines) {
88
+ const trimmed = line.trim();
89
+
90
+ if (trimmed.startsWith("## Exception Handling")) {
91
+ inSection = true;
92
+ continue;
93
+ }
94
+
95
+ if (!inSection) continue;
96
+
97
+ // Stop at next heading
98
+ if (trimmed.startsWith("#")) break;
99
+
100
+ // Skip empty lines
101
+ if (!trimmed) continue;
102
+
103
+ // Parse table rows
104
+ const match = TABLE_ROW_PATTERN.exec(trimmed);
105
+ if (!match) continue;
106
+
107
+ // Skip header row and separator row
108
+ if (!headerSkipped) {
109
+ headerSkipped = true;
110
+ continue;
111
+ }
112
+ if (!separatorSkipped) {
113
+ separatorSkipped = true;
114
+ continue;
115
+ }
116
+
117
+ const code = match[1].trim();
118
+ const description = match[2].trim();
119
+ if (code) {
120
+ errors.push({ code, description });
121
+ }
122
+ }
123
+
124
+ return errors;
125
+ }
@@ -0,0 +1,57 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { PACKAGE_ROOT, readErpKitVersion } from "../util";
4
+
5
+ // npm renames .gitignore during pack (npm/cli#5756).
6
+ // prepack copies .gitignore to __dot__gitignore to preserve it.
7
+ export function copyTemplateDir(
8
+ srcDir: string,
9
+ destDir: string,
10
+ replacements: Record<string, string>,
11
+ placeholderFiles: Set<string>,
12
+ ): void {
13
+ for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
14
+ const srcPath = path.join(srcDir, entry.name);
15
+ const destName = entry.name === "__dot__gitignore" ? ".gitignore" : entry.name;
16
+ const destPath = path.join(destDir, destName);
17
+
18
+ if (entry.name === "node_modules") continue;
19
+
20
+ if (entry.isDirectory()) {
21
+ fs.mkdirSync(destPath, { recursive: true });
22
+ copyTemplateDir(srcPath, destPath, replacements, placeholderFiles);
23
+ } else {
24
+ if (fs.existsSync(destPath)) continue;
25
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
26
+ if (placeholderFiles.has(entry.name)) {
27
+ let content = fs.readFileSync(srcPath, "utf-8");
28
+ for (const [from, to] of Object.entries(replacements)) {
29
+ content = content.replaceAll(from, to);
30
+ }
31
+ fs.writeFileSync(destPath, content);
32
+ } else {
33
+ fs.copyFileSync(srcPath, destPath);
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ export function scaffoldModuleBoilerplate(moduleDir: string, moduleName: string): void {
40
+ const templateDir = path.join(PACKAGE_ROOT, "templates", "scaffold", "module");
41
+ const replacements = { "template-module": moduleName };
42
+ const placeholderFiles = new Set(["permissions.ts", "tailor.config.ts"]);
43
+ copyTemplateDir(templateDir, moduleDir, replacements, placeholderFiles);
44
+ }
45
+
46
+ export function scaffoldAppBoilerplate(appDir: string, appName: string): void {
47
+ const templateDir = path.join(PACKAGE_ROOT, "templates", "scaffold", "app");
48
+ const erpKitVersion = readErpKitVersion();
49
+ const replacements = {
50
+ "template-app-frontend": `${appName}-frontend`,
51
+ "template-app-backend": appName,
52
+ "template-app": appName,
53
+ '"workspace:*"': `"${erpKitVersion}"`,
54
+ };
55
+ const placeholderFiles = new Set(["package.json", "tailor.config.ts", "index.html"]);
56
+ copyTemplateDir(templateDir, appDir, replacements, placeholderFiles);
57
+ }
@@ -0,0 +1,55 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { renderStub } from "./stub-templates";
3
+
4
+ describe("renderStub", () => {
5
+ it("command: generates input interface and run function", () => {
6
+ const result = renderStub("command", "createItem");
7
+ expect(result).toContain("export interface CreateItemInput");
8
+ expect(result).toContain(
9
+ "export async function run(db: Transaction, input: CreateItemInput, ctx: CommandContext)",
10
+ );
11
+ expect(result).toContain("return ok({})");
12
+ });
13
+
14
+ it("commandTest: generates test with createMockDb", () => {
15
+ const result = renderStub("commandTest", "createItem");
16
+ expect(result).toContain('describe("createItem - test scenario"');
17
+ expect(result).toContain("createMockDb<Transaction>()");
18
+ expect(result).toContain("CreateItemInput");
19
+ });
20
+
21
+ it("query: generates ReadonlyDB-based stub", () => {
22
+ const result = renderStub("query", "getProduct");
23
+ expect(result).toContain("export interface GetProductInput");
24
+ expect(result).toContain("ReadonlyDB<DB>");
25
+ });
26
+
27
+ it("queryTest: generates test with DB type", () => {
28
+ const result = renderStub("queryTest", "getProduct");
29
+ expect(result).toContain('describe("getProduct"');
30
+ expect(result).toContain("createMockDb<DB>()");
31
+ expect(result).toContain("type GetProductInput");
32
+ });
33
+
34
+ it("db: generates model type definition", () => {
35
+ const result = renderStub("db", "item");
36
+ expect(result).toContain("export const item = db");
37
+ expect(result).toContain('.type("Item"');
38
+ expect(result).toContain("unsafeAllowAllTypePermission");
39
+ });
40
+
41
+ it("resolver: generates createResolver stub with SDK imports", () => {
42
+ const result = renderStub("resolver", "createItem");
43
+ expect(result).toContain("createResolver");
44
+ expect(result).toContain('name: "createItem"');
45
+ expect(result).toContain('operation: "mutation"');
46
+ expect(result).toContain('getDB("main-db")');
47
+ });
48
+
49
+ it("resolverTest: generates test that imports resolver", () => {
50
+ const result = renderStub("resolverTest", "createItem");
51
+ expect(result).toContain('describe("createItem"');
52
+ expect(result).toContain('import("./createItem")');
53
+ expect(result).toContain("resolver.default");
54
+ });
55
+ });
@@ -0,0 +1,145 @@
1
+ function toPascal(name: string): string {
2
+ return name.charAt(0).toUpperCase() + name.slice(1);
3
+ }
4
+
5
+ const templates = {
6
+ command: {
7
+ render: (name: string) => {
8
+ const inputType = `${toPascal(name)}Input`;
9
+ return `import { ok, type CommandContext } from "../../../shared";
10
+ import type { Transaction } from "../generated/kysely-tailordb";
11
+
12
+ export interface ${inputType} {
13
+ // TODO: define input fields
14
+ }
15
+
16
+ export async function run(db: Transaction, input: ${inputType}, ctx: CommandContext) {
17
+ // TODO: implement
18
+ return ok({});
19
+ }
20
+ `;
21
+ },
22
+ },
23
+ commandTest: {
24
+ render: (name: string) => {
25
+ const pascal = toPascal(name);
26
+ return `import { describe, expect, it } from "vitest";
27
+ import { createMockDb } from "../../../testing/index";
28
+ import type { CommandContext } from "../../../shared";
29
+ import type { Transaction } from "../generated/kysely-tailordb";
30
+ import { run, ${pascal}Input } from "./${name}";
31
+
32
+ describe("${name} - test scenario", () => {
33
+ const ctx: CommandContext = {
34
+ actorId: "test-actor",
35
+ permissions: ["TODO:${name}"],
36
+ };
37
+
38
+ it("should be implemented", async () => {
39
+ const { db } = createMockDb<Transaction>();
40
+ const result = await run(db, {} as ${pascal}Input, ctx);
41
+ expect(result.ok).toBe(true);
42
+ });
43
+ });
44
+ `;
45
+ },
46
+ },
47
+ query: {
48
+ render: (name: string) => {
49
+ const inputType = `${toPascal(name)}Input`;
50
+ return `import type { ReadonlyDB } from "../../../shared";
51
+ import type { DB } from "../generated/kysely-tailordb";
52
+
53
+ export interface ${inputType} {
54
+ // TODO: define input fields
55
+ }
56
+
57
+ export async function run(db: ReadonlyDB<DB>, input: ${inputType}) {
58
+ // TODO: implement
59
+ return {};
60
+ }
61
+ `;
62
+ },
63
+ },
64
+ queryTest: {
65
+ render: (name: string) => {
66
+ const pascal = toPascal(name);
67
+ const inputType = `${pascal}Input`;
68
+ return `import { describe, expect, it } from "vitest";
69
+ import { createMockDb } from "../../../testing/index";
70
+ import type { DB } from "../generated/kysely-tailordb";
71
+ import { run, type ${inputType} } from "./${name}";
72
+
73
+ describe("${name}", () => {
74
+ it("should be implemented", async () => {
75
+ const { db } = createMockDb<DB>();
76
+ const result = await run(db, {} as ${inputType});
77
+ expect(result).toBeDefined();
78
+ });
79
+ });
80
+ `;
81
+ },
82
+ },
83
+ db: {
84
+ render: (name: string) => {
85
+ return `import { db, unsafeAllowAllGqlPermission, unsafeAllowAllTypePermission } from "@tailor-platform/sdk";
86
+
87
+ export const ${name} = db
88
+ .type("${toPascal(name)}", {
89
+ // TODO: define fields
90
+ ...db.fields.timestamps(),
91
+ })
92
+ .permission(unsafeAllowAllTypePermission)
93
+ .gqlPermission(unsafeAllowAllGqlPermission);
94
+ `;
95
+ },
96
+ },
97
+ resolver: {
98
+ render: (name: string) => {
99
+ return `import { createResolver, t } from "@tailor-platform/sdk";
100
+ import { createContext } from "@tailor-platform/erp-kit/app";
101
+ import { getDB } from "@/generated/kysely-tailordb";
102
+
103
+ export default createResolver({
104
+ name: "${name}",
105
+ operation: "mutation",
106
+ input: {
107
+ // TODO: define input fields
108
+ },
109
+ body: async (context) => {
110
+ const db = getDB("main-db");
111
+ return db.transaction().execute(async (trx) => {
112
+ // TODO: implement
113
+ return {};
114
+ });
115
+ },
116
+ output: t
117
+ .object({
118
+ // TODO: define output fields
119
+ })
120
+ .description("${toPascal(name)} response"),
121
+ });
122
+ `;
123
+ },
124
+ },
125
+ resolverTest: {
126
+ render: (name: string) => {
127
+ return `import { describe, expect, it } from "vitest";
128
+
129
+ describe("${name}", () => {
130
+ it("should be implemented", async () => {
131
+ const resolver = await import("./${name}");
132
+ expect(resolver.default).toBeDefined();
133
+ expect(resolver.default.name).toBe("${name}");
134
+ });
135
+ });
136
+ `;
137
+ },
138
+ },
139
+ } as const;
140
+
141
+ export type StubType = keyof typeof templates;
142
+
143
+ export function renderStub(type: StubType, name: string): string {
144
+ return templates[type].render(name);
145
+ }
@@ -0,0 +1,46 @@
1
+ # README
2
+
3
+ ## Overview
4
+
5
+ The Audit module provides a centralized, append-only audit trail for tracking data changes across all ERP modules. It records who or what performed an action, when it occurred, and what data changed — capturing both the old and new values at the field level. The module is designed as cross-cutting infrastructure: other modules emit structured audit events that the Audit module stores, indexes, and exposes for query. All audit entries are append-only and immutable once written, ensuring that stored records cannot be retroactively altered or deleted. Note: because ingestion is eventually consistent and decoupled from the emitting module's transaction, the module provides best-effort delivery — it does not guarantee that every mutation is captured (see [Audit Event Logging](docs/features/audit-event-logging.md) for the ingestion contract and failure semantics).
6
+
7
+ The module supports both company-scoped entities (e.g., sales orders, invoices) and global entities (e.g., user accounts, currencies) — entries for global entities omit companyId and are queryable without company scope.
8
+
9
+ Access to audit data and policy management is controlled by explicit permissions. Because audit entries can contain sensitive before/after values, viewing and administering the audit trail requires dedicated privileges separate from the permissions on the audited entities themselves. The module defines four coarse permissions: `viewAuditHistory` (query audit entries and change details), `viewAuditSummary` (view aggregated audit summaries without field-level details), `manageAuditPolicies` (create, update, activate, deactivate, delete audit policies, query policies, and register auditable entities), and `logAuditEvent` (ingest audit events from emitting modules). At runtime, command shells enforce per-command permission keys (e.g., `audit:createAuditPolicy`, `audit:registerAuditableEntity`), and policy query endpoints (`getAuditPolicy`, `listAuditPolicies`) require the coarse `audit:manageAuditPolicies` key directly. The `manageAuditPolicies` alias (defined in `permissions.ts`) expands to both the coarse `manageAuditPolicies` key itself and all per-command keys; the application's RBAC layer should use this alias when populating `ctx.permissions` to ensure both command and query authorization work correctly. Each permission is company-scoped — holders can only access entries and policies for their assigned companies — or global-scoped for company-unscoped entries and policies. The audit module does not define its own roles; it exposes permissions that the application's role-based access control system assigns to roles as needed.
10
+
11
+ ## Key Features
12
+
13
+ - **Audit Event Logging** — Captures create, update, and delete operations as immutable audit entries with unique eventId, optional correlationId for operation grouping, actor identity (actorType + actorId), timestamp, entity reference, and operation type
14
+ - **Field-Level Change Tracking** — Records old and new values for each changed field within an audit entry, with configurable sensitivity modes (capture, mask, hash, exclude) to protect sensitive data
15
+ - **Audit Policy Configuration** — Allows administrators to define which entities, fields, and operation types are audited, controlling granularity, sensitivity handling, and performance impact
16
+
17
+ ## Module Scope
18
+
19
+ ### In Scope
20
+
21
+ - Immutable storage of audit log entries (append-only, no update or delete)
22
+ - Field-level change detail recording (old value / new value pairs) with sensitivity-aware value processing
23
+ - Configurable audit policies at entity and field granularity with sensitivity modes
24
+ - Query and filtering of audit logs by actor, entity, record, operation type, and date range
25
+ - Record-level change history retrieval
26
+ - Actor identity capture supporting multiple actor types (USER, SYSTEM, SERVICE) with optional delegation (onBehalfOf)
27
+ - Company-scoped and global (company-unscoped) audit entries
28
+ - Permission-based access control for audit viewing and policy administration
29
+
30
+ ### Out of Scope
31
+
32
+ - User authentication and session tracking (owned by user-management / infrastructure layer)
33
+ - Compliance framework mapping and automated evidence collection (application-level concern)
34
+ - Anomaly detection, alerting, and real-time notifications
35
+ - Log archival, long-term retention policies, and storage tiering
36
+ - Dashboard visualizations and audit analytics
37
+
38
+ ### Scope Decision Rationale
39
+
40
+ The module focuses on the foundational audit trail capabilities that all ERP deployments require: capturing changes, storing them immutably once written, and making them queryable. The ingestion contract is best-effort — applications that require guaranteed delivery for strict compliance scenarios should layer an outbox or replay mechanism on top of this module. Authentication logging is excluded because it belongs to the identity/infrastructure layer, not the domain data change layer. Compliance framework mapping, anomaly detection, and retention management are excluded as application-level or operational concerns that can be layered on top of the core audit trail. This separation keeps the module focused, testable, and reusable across different compliance contexts.
41
+
42
+ ## Module Dependencies
43
+
44
+ - **user-management** — References userId as one type of actorId on audit entries (data reference only; no domain logic dependency)
45
+ - **organization** — References companyId for multi-company scoping of company-bound audit entries (data reference only; companyId is optional for global entities)
46
+ - **all emitting modules** (reverse dependency) — The audit module is cross-cutting: other modules depend on it, not the other way around. Emitting modules register their auditable entities (name, scope, field list) at initialization time and submit structured audit event payloads (including a unique `eventId` for idempotency) after committing their own transactions. The ingestion contract is idempotent on `eventId` for safe retries, and the audit module does not participate in the emitting module's transaction (eventually consistent). See the [Audit Event Logging](docs/features/audit-event-logging.md) feature documentation for the full ingestion contract.
@@ -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 "./activateAuditPolicy";
5
+
6
+ export const activateAuditPolicy = defineCommand(permissions.activateAuditPolicy, run);
@@ -0,0 +1,186 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import { type CommandContext, InsufficientPermissionError } from "../../../shared";
4
+ import type { Transaction } from "../generated/kysely-tailordb";
5
+ import {
6
+ PolicyNotFoundError,
7
+ InvalidStateError,
8
+ IncompletePolicyError,
9
+ ConflictingActivePolicyError,
10
+ EntityTypeNotRegisteredError,
11
+ UnauthorizedError,
12
+ } from "../lib/errors.generated";
13
+ import { draftPolicy, activePolicy, inactivePolicy, companyBoundEntity } from "../testing/fixtures";
14
+ import { run } from "./activateAuditPolicy";
15
+ import { activateAuditPolicy } from "./activateAuditPolicy.generated";
16
+
17
+ const ctx: CommandContext = {
18
+ actorId: "test-actor",
19
+ permissions: ["audit:activateAuditPolicy"],
20
+ };
21
+
22
+ describe("activateAuditPolicy", () => {
23
+ it("activates DRAFT policy to ACTIVE", async () => {
24
+ const { db, spies } = createMockDb<Transaction>();
25
+ spies.select.mockReturnValueOnce(draftPolicy); // policy lookup
26
+ spies.select.mockReturnValueOnce(companyBoundEntity); // entity registration check
27
+ spies.select.mockReturnValueOnce(undefined); // no conflicting policy
28
+ spies.update.mockReturnValue({ ...draftPolicy, status: "ACTIVE" });
29
+
30
+ const result = await run(db, { policyId: "policy-1" }, ctx);
31
+
32
+ expect(result.ok).toBe(true);
33
+ if (result.ok) {
34
+ expect(result.value.policy.status).toBe("ACTIVE");
35
+ }
36
+ });
37
+
38
+ it("begins audit capture after activation", async () => {
39
+ const { db, spies } = createMockDb<Transaction>();
40
+ spies.select.mockReturnValueOnce(draftPolicy);
41
+ spies.select.mockReturnValueOnce(companyBoundEntity); // entity registration check
42
+ spies.select.mockReturnValueOnce(undefined);
43
+ spies.update.mockReturnValue({ ...draftPolicy, status: "ACTIVE" });
44
+
45
+ const result = await run(db, { policyId: "policy-1" }, ctx);
46
+
47
+ expect(result.ok).toBe(true);
48
+ if (result.ok) {
49
+ expect(result.value.policy.status).toBe("ACTIVE");
50
+ }
51
+ // Verify that the DB update sets status to ACTIVE, which is the gate for logAuditEvent to capture events
52
+ expect(spies.set).toHaveBeenCalledWith(expect.objectContaining({ status: "ACTIVE" }));
53
+ expect(spies.update).toHaveBeenCalledTimes(1);
54
+ });
55
+
56
+ it("rejects activation of ACTIVE policy", async () => {
57
+ const { db, spies } = createMockDb<Transaction>();
58
+ spies.select.mockReturnValueOnce(activePolicy);
59
+
60
+ const result = await run(db, { policyId: activePolicy.id }, ctx);
61
+
62
+ expect(result.ok).toBe(false);
63
+ if (!result.ok) {
64
+ expect(result.error).toBeInstanceOf(InvalidStateError);
65
+ }
66
+ });
67
+
68
+ it("rejects activation of INACTIVE policy", async () => {
69
+ const { db, spies } = createMockDb<Transaction>();
70
+ spies.select.mockReturnValueOnce(inactivePolicy);
71
+
72
+ const result = await run(db, { policyId: inactivePolicy.id }, ctx);
73
+
74
+ expect(result.ok).toBe(false);
75
+ if (!result.ok) {
76
+ expect(result.error).toBeInstanceOf(InvalidStateError);
77
+ }
78
+ });
79
+
80
+ it("rejects activation when conflicting ACTIVE policy exists", async () => {
81
+ const { db, spies } = createMockDb<Transaction>();
82
+ spies.select.mockReturnValueOnce(draftPolicy); // policy lookup
83
+ spies.select.mockReturnValueOnce(companyBoundEntity); // entity registration check
84
+ spies.select.mockReturnValueOnce(activePolicy); // conflicting policy
85
+
86
+ const result = await run(db, { policyId: "policy-1" }, ctx);
87
+
88
+ expect(result.ok).toBe(false);
89
+ if (!result.ok) {
90
+ expect(result.error).toBeInstanceOf(ConflictingActivePolicyError);
91
+ }
92
+ });
93
+
94
+ it("rejects activation when entity name is missing", async () => {
95
+ const { db, spies } = createMockDb<Transaction>();
96
+ const policyNoEntity = { ...draftPolicy, entityName: "" };
97
+ spies.select.mockReturnValueOnce(policyNoEntity);
98
+
99
+ const result = await run(db, { policyId: "policy-1" }, ctx);
100
+
101
+ expect(result.ok).toBe(false);
102
+ if (!result.ok) {
103
+ expect(result.error).toBeInstanceOf(IncompletePolicyError);
104
+ }
105
+ });
106
+
107
+ it("rejects activation when operation type is missing", async () => {
108
+ const { db, spies } = createMockDb<Transaction>();
109
+ const policyNoOp = { ...draftPolicy, operationType: "" };
110
+ spies.select.mockReturnValueOnce(policyNoOp);
111
+
112
+ const result = await run(db, { policyId: "policy-1" }, ctx);
113
+
114
+ expect(result.ok).toBe(false);
115
+ if (!result.ok) {
116
+ expect(result.error).toBeInstanceOf(IncompletePolicyError);
117
+ }
118
+ });
119
+
120
+ it("rejects when policy does not exist", async () => {
121
+ const { db, spies } = createMockDb<Transaction>();
122
+ spies.select.mockReturnValueOnce(undefined);
123
+
124
+ const result = await run(db, { policyId: "nonexistent" }, ctx);
125
+
126
+ expect(result.ok).toBe(false);
127
+ if (!result.ok) {
128
+ expect(result.error).toBeInstanceOf(PolicyNotFoundError);
129
+ }
130
+ });
131
+
132
+ it("rejects when caller lacks manageAuditPolicies permission", async () => {
133
+ const { db } = createMockDb<Transaction>();
134
+ const command = activateAuditPolicy();
135
+ const noPermCtx: CommandContext = {
136
+ actorId: "test-actor",
137
+ permissions: [],
138
+ };
139
+
140
+ const result = await command(db, { policyId: "policy-1" }, noPermCtx);
141
+
142
+ expect(result.ok).toBe(false);
143
+ if (!result.ok) {
144
+ expect(result.error).toBeInstanceOf(InsufficientPermissionError);
145
+ }
146
+ });
147
+
148
+ it("rejects when company-scoped caller activates policy for a different company", async () => {
149
+ const { db, spies } = createMockDb<Transaction>();
150
+ spies.select.mockReturnValueOnce(draftPolicy); // policy with companyId: "company-1"
151
+ const scopedCtx = { ...ctx, companyId: "company-2" };
152
+
153
+ const result = await run(db, { policyId: "policy-1" }, scopedCtx);
154
+
155
+ expect(result.ok).toBe(false);
156
+ if (!result.ok) {
157
+ expect(result.error).toBeInstanceOf(UnauthorizedError);
158
+ }
159
+ });
160
+
161
+ it("rejects when global-scoped caller activates company-scoped policy", async () => {
162
+ const { db, spies } = createMockDb<Transaction>();
163
+ spies.select.mockReturnValueOnce(draftPolicy); // policy with companyId: "company-1"
164
+ const globalCtx = { ...ctx, companyId: null };
165
+
166
+ const result = await run(db, { policyId: "policy-1" }, globalCtx);
167
+
168
+ expect(result.ok).toBe(false);
169
+ if (!result.ok) {
170
+ expect(result.error).toBeInstanceOf(UnauthorizedError);
171
+ }
172
+ });
173
+
174
+ it("rejects when target entity is no longer registered", async () => {
175
+ const { db, spies } = createMockDb<Transaction>();
176
+ spies.select.mockReturnValueOnce(draftPolicy); // policy lookup
177
+ spies.select.mockReturnValueOnce(undefined); // entity not found
178
+
179
+ const result = await run(db, { policyId: "policy-1" }, ctx);
180
+
181
+ expect(result.ok).toBe(false);
182
+ if (!result.ok) {
183
+ expect(result.error).toBeInstanceOf(EntityTypeNotRegisteredError);
184
+ }
185
+ });
186
+ });