@tailor-platform/erp-kit 0.1.2 → 0.2.1

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 (330) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +80 -12
  3. package/dist/cli.js +1070 -450
  4. package/package.json +11 -8
  5. package/schemas/app-compose/business-flow.yml +3 -0
  6. package/schemas/app-compose/story.yml +1 -1
  7. package/schemas/module/model.yml +5 -0
  8. package/skills/{app-compose-1-requirement-analysis → erp-kit-app-1-requirements}/SKILL.md +8 -14
  9. package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/SKILL.md +6 -13
  10. package/skills/{app-compose-3-doc-review → erp-kit-app-3-doc-review}/SKILL.md +2 -6
  11. package/skills/{app-compose-6-implementation-spec → erp-kit-app-4-impl-spec}/SKILL.md +11 -22
  12. package/skills/erp-kit-app-5-implementation/SKILL.md +149 -0
  13. package/skills/erp-kit-app-5-implementation/references/backend.md +232 -0
  14. package/skills/erp-kit-app-5-implementation/references/frontend.md +242 -0
  15. package/skills/{mock-scenario → erp-kit-mock-scenario}/SKILL.md +1 -1
  16. package/skills/{1-module-docs → erp-kit-module-1-docs}/SKILL.md +2 -2
  17. package/skills/{2-module-feature-breakdown → erp-kit-module-2-feature-breakdown}/SKILL.md +13 -9
  18. package/skills/erp-kit-module-2-feature-breakdown/references/naming.md +59 -0
  19. package/skills/{3-module-doc-review → erp-kit-module-3-doc-review}/SKILL.md +83 -25
  20. package/skills/erp-kit-module-4-tdd/SKILL.md +94 -0
  21. package/skills/erp-kit-module-4-tdd/references/cross-module-dependency.md +133 -0
  22. package/skills/{4-module-tdd-implementation → erp-kit-module-4-tdd}/references/db-relations.md +5 -1
  23. package/skills/{4-module-tdd-implementation → erp-kit-module-4-tdd}/references/exports.md +1 -1
  24. package/skills/erp-kit-module-4-tdd/references/generated-code.md +32 -0
  25. package/skills/{5-module-implementation-review → erp-kit-module-5-impl-review}/SKILL.md +46 -44
  26. package/skills/erp-kit-module-5-impl-review/references/commands.md +62 -0
  27. package/skills/erp-kit-module-5-impl-review/references/errors.md +10 -0
  28. package/skills/{5-module-implementation-review → erp-kit-module-5-impl-review}/references/testing.md +1 -1
  29. package/skills/erp-kit-module-shared/SKILL.md +16 -0
  30. package/skills/erp-kit-module-shared/references/commands.md +203 -0
  31. package/skills/erp-kit-module-shared/references/errors.md +35 -0
  32. package/skills/erp-kit-module-shared/references/queries.md +168 -0
  33. package/skills/erp-kit-module-shared/references/structure.md +36 -0
  34. package/skills/{3-module-doc-review → erp-kit-module-shared}/references/testing.md +4 -3
  35. package/skills/erp-kit-update/SKILL.md +64 -0
  36. package/src/cli.doc.test.ts +65 -0
  37. package/src/cli.ts +3 -35
  38. package/src/commands/app/index.ts +3 -3
  39. package/src/commands/check.test.ts +1 -1
  40. package/src/commands/check.ts +2 -2
  41. package/src/commands/index.ts +73 -0
  42. package/src/commands/init.test.ts +22 -5
  43. package/src/commands/init.ts +25 -16
  44. package/src/commands/license.ts +193 -0
  45. package/src/commands/mock/index.ts +2 -2
  46. package/src/commands/mock/start.ts +1 -1
  47. package/src/commands/mock/validate.test.ts +1 -1
  48. package/src/commands/module/generate.ts +35 -0
  49. package/src/commands/module/index.ts +6 -4
  50. package/src/commands/module/list.test.ts +7 -12
  51. package/src/commands/module/list.ts +1 -1
  52. package/src/commands/scaffold-templates.ts +65 -0
  53. package/src/commands/scaffold.test.ts +92 -2
  54. package/src/commands/scaffold.ts +22 -2
  55. package/src/commands/sync-check.test.ts +60 -1
  56. package/src/commands/sync-check.ts +35 -2
  57. package/src/generator/generate-code.test.ts +200 -0
  58. package/src/generator/generate-code.ts +260 -0
  59. package/src/generator/parse-command-doc.test.ts +159 -0
  60. package/src/generator/parse-command-doc.ts +116 -0
  61. package/src/integration.test.ts +2 -2
  62. package/src/module.ts +44 -6
  63. package/src/modules/item-management/README.md +38 -0
  64. package/src/modules/item-management/command/activateItem.generated.ts +6 -0
  65. package/src/modules/item-management/command/activateItem.test.ts +76 -0
  66. package/src/modules/item-management/command/activateItem.ts +42 -0
  67. package/src/modules/item-management/command/assignItemToTaxonomy.generated.ts +6 -0
  68. package/src/modules/item-management/command/assignItemToTaxonomy.test.ts +88 -0
  69. package/src/modules/item-management/command/assignItemToTaxonomy.ts +63 -0
  70. package/src/modules/item-management/command/createItem.generated.ts +6 -0
  71. package/src/modules/item-management/command/createItem.test.ts +152 -0
  72. package/src/modules/item-management/command/createItem.ts +72 -0
  73. package/src/modules/item-management/command/createTaxonomyNode.generated.ts +6 -0
  74. package/src/modules/item-management/command/createTaxonomyNode.test.ts +126 -0
  75. package/src/modules/item-management/command/createTaxonomyNode.ts +70 -0
  76. package/src/modules/item-management/command/deactivateItem.generated.ts +6 -0
  77. package/src/modules/item-management/command/deactivateItem.test.ts +76 -0
  78. package/src/modules/item-management/command/deactivateItem.ts +42 -0
  79. package/src/modules/item-management/command/deleteItem.generated.ts +6 -0
  80. package/src/modules/item-management/command/deleteItem.test.ts +61 -0
  81. package/src/modules/item-management/command/deleteItem.ts +38 -0
  82. package/src/modules/item-management/command/deleteTaxonomyNode.generated.ts +6 -0
  83. package/src/modules/item-management/command/deleteTaxonomyNode.test.ts +73 -0
  84. package/src/modules/item-management/command/deleteTaxonomyNode.ts +50 -0
  85. package/src/modules/item-management/command/moveTaxonomyNode.generated.ts +6 -0
  86. package/src/modules/item-management/command/moveTaxonomyNode.test.ts +136 -0
  87. package/src/modules/item-management/command/moveTaxonomyNode.ts +85 -0
  88. package/src/modules/item-management/command/reactivateItem.generated.ts +6 -0
  89. package/src/modules/item-management/command/reactivateItem.test.ts +76 -0
  90. package/src/modules/item-management/command/reactivateItem.ts +42 -0
  91. package/src/modules/item-management/command/removeItemFromTaxonomy.generated.ts +6 -0
  92. package/src/modules/item-management/command/removeItemFromTaxonomy.test.ts +43 -0
  93. package/src/modules/item-management/command/removeItemFromTaxonomy.ts +30 -0
  94. package/src/modules/item-management/command/updateItem.generated.ts +6 -0
  95. package/src/modules/item-management/command/updateItem.test.ts +178 -0
  96. package/src/modules/item-management/command/updateItem.ts +103 -0
  97. package/src/modules/item-management/command/updateTaxonomyNode.generated.ts +6 -0
  98. package/src/modules/item-management/command/updateTaxonomyNode.test.ts +88 -0
  99. package/src/modules/item-management/command/updateTaxonomyNode.ts +62 -0
  100. package/src/modules/item-management/db/item.ts +47 -0
  101. package/src/modules/item-management/db/itemTaxonomyAssignment.ts +49 -0
  102. package/src/modules/item-management/db/taxonomyNode.ts +34 -0
  103. package/src/modules/item-management/docs/commands/ActivateItem.md +32 -0
  104. package/src/modules/item-management/docs/commands/AssignItemToTaxonomy.md +38 -0
  105. package/src/modules/item-management/docs/commands/CreateItem.md +44 -0
  106. package/src/modules/item-management/docs/commands/CreateTaxonomyNode.md +44 -0
  107. package/src/modules/item-management/docs/commands/DeactivateItem.md +34 -0
  108. package/src/modules/item-management/docs/commands/DeleteItem.md +35 -0
  109. package/src/modules/item-management/docs/commands/DeleteTaxonomyNode.md +39 -0
  110. package/src/modules/item-management/docs/commands/MoveTaxonomyNode.md +45 -0
  111. package/src/modules/item-management/docs/commands/ReactivateItem.md +34 -0
  112. package/src/modules/item-management/docs/commands/RemoveItemFromTaxonomy.md +30 -0
  113. package/src/modules/item-management/docs/commands/UpdateItem.md +55 -0
  114. package/src/modules/item-management/docs/commands/UpdateTaxonomyNode.md +36 -0
  115. package/src/modules/item-management/docs/features/item-lifecycle.md +60 -0
  116. package/src/modules/item-management/docs/features/item-taxonomy.md +65 -0
  117. package/src/modules/item-management/docs/models/ItemTaxonomyAssignment.md +36 -0
  118. package/src/modules/item-management/docs/models/TaxonomyNode.md +47 -0
  119. package/src/modules/item-management/docs/models/item.md +59 -0
  120. package/src/modules/item-management/docs/queries/CalculateNodeDepth.md +36 -0
  121. package/src/modules/item-management/docs/queries/CalculateSubtreeDepth.md +40 -0
  122. package/src/modules/item-management/docs/queries/DetectCircularReference.md +41 -0
  123. package/src/modules/item-management/docs/queries/GetItem.md +38 -0
  124. package/src/modules/item-management/docs/queries/GetItemTaxonomyAssignment.md +29 -0
  125. package/src/modules/item-management/docs/queries/GetTaxonomyNode.md +35 -0
  126. package/src/modules/item-management/docs/queries/GetTaxonomyNodeAssignments.md +29 -0
  127. package/src/modules/item-management/docs/queries/GetTaxonomyNodeChildren.md +29 -0
  128. package/src/modules/item-management/generated/enums.ts +9 -0
  129. package/src/modules/item-management/generated/kysely-tailordb.ts +62 -0
  130. package/src/modules/item-management/index.ts +53 -0
  131. package/src/modules/item-management/lib/_db_deps.ts +13 -0
  132. package/src/modules/item-management/lib/errors.generated.ts +117 -0
  133. package/src/modules/item-management/lib/permissions.generated.ts +17 -0
  134. package/src/modules/item-management/lib/types.ts +19 -0
  135. package/src/modules/item-management/module.ts +97 -0
  136. package/src/modules/item-management/query/calculateNodeDepth.generated.ts +5 -0
  137. package/src/modules/item-management/query/calculateNodeDepth.test.ts +56 -0
  138. package/src/modules/item-management/query/calculateNodeDepth.ts +28 -0
  139. package/src/modules/item-management/query/calculateSubtreeDepth.generated.ts +5 -0
  140. package/src/modules/item-management/query/calculateSubtreeDepth.test.ts +75 -0
  141. package/src/modules/item-management/query/calculateSubtreeDepth.ts +29 -0
  142. package/src/modules/item-management/query/detectCircularReference.generated.ts +5 -0
  143. package/src/modules/item-management/query/detectCircularReference.test.ts +61 -0
  144. package/src/modules/item-management/query/detectCircularReference.ts +32 -0
  145. package/src/modules/item-management/query/getItem.generated.ts +5 -0
  146. package/src/modules/item-management/query/getItem.test.ts +67 -0
  147. package/src/modules/item-management/query/getItem.ts +20 -0
  148. package/src/modules/item-management/query/getItemTaxonomyAssignment.generated.ts +5 -0
  149. package/src/modules/item-management/query/getItemTaxonomyAssignment.test.ts +25 -0
  150. package/src/modules/item-management/query/getItemTaxonomyAssignment.ts +18 -0
  151. package/src/modules/item-management/query/getTaxonomyNode.generated.ts +5 -0
  152. package/src/modules/item-management/query/getTaxonomyNode.test.ts +47 -0
  153. package/src/modules/item-management/query/getTaxonomyNode.ts +18 -0
  154. package/src/modules/item-management/query/getTaxonomyNodeAssignments.generated.ts +5 -0
  155. package/src/modules/item-management/query/getTaxonomyNodeAssignments.test.ts +25 -0
  156. package/src/modules/item-management/query/getTaxonomyNodeAssignments.ts +16 -0
  157. package/src/modules/item-management/query/getTaxonomyNodeChildren.generated.ts +5 -0
  158. package/src/modules/item-management/query/getTaxonomyNodeChildren.test.ts +34 -0
  159. package/src/modules/item-management/query/getTaxonomyNodeChildren.ts +16 -0
  160. package/src/modules/item-management/tailor.config.ts +11 -0
  161. package/src/modules/item-management/testing/fixtures.ts +81 -0
  162. package/src/modules/primitives/command/activateCategory.generated.ts +6 -0
  163. package/src/modules/primitives/command/activateCategory.test.ts +11 -29
  164. package/src/modules/primitives/command/activateCategory.ts +27 -34
  165. package/src/modules/primitives/command/activateCurrency.generated.ts +6 -0
  166. package/src/modules/primitives/command/activateCurrency.test.ts +11 -29
  167. package/src/modules/primitives/command/activateCurrency.ts +27 -34
  168. package/src/modules/primitives/command/activateUnit.generated.ts +6 -0
  169. package/src/modules/primitives/command/activateUnit.test.ts +11 -15
  170. package/src/modules/primitives/command/activateUnit.ts +27 -34
  171. package/src/modules/primitives/command/createCategory.generated.ts +6 -0
  172. package/src/modules/primitives/command/createCategory.test.ts +27 -39
  173. package/src/modules/primitives/command/createCategory.ts +53 -62
  174. package/src/modules/primitives/command/createCurrency.generated.ts +6 -0
  175. package/src/modules/primitives/command/createCurrency.test.ts +78 -71
  176. package/src/modules/primitives/command/createCurrency.ts +43 -48
  177. package/src/modules/primitives/command/createExchangeRate.generated.ts +6 -0
  178. package/src/modules/primitives/command/createExchangeRate.test.ts +101 -100
  179. package/src/modules/primitives/command/createExchangeRate.ts +50 -59
  180. package/src/modules/primitives/command/createUnit.generated.ts +6 -0
  181. package/src/modules/primitives/command/createUnit.test.ts +92 -95
  182. package/src/modules/primitives/command/createUnit.ts +54 -57
  183. package/src/modules/primitives/command/deactivateCategory.generated.ts +6 -0
  184. package/src/modules/primitives/command/deactivateCategory.test.ts +27 -28
  185. package/src/modules/primitives/command/deactivateCategory.ts +43 -50
  186. package/src/modules/primitives/command/deactivateCurrency.generated.ts +6 -0
  187. package/src/modules/primitives/command/deactivateCurrency.test.ts +23 -38
  188. package/src/modules/primitives/command/deactivateCurrency.ts +31 -38
  189. package/src/modules/primitives/command/deactivateUnit.generated.ts +6 -0
  190. package/src/modules/primitives/command/deactivateUnit.test.ts +27 -23
  191. package/src/modules/primitives/command/deactivateUnit.ts +39 -49
  192. package/src/modules/primitives/command/setBaseCurrency.generated.ts +6 -0
  193. package/src/modules/primitives/command/setBaseCurrency.test.ts +40 -33
  194. package/src/modules/primitives/command/setBaseCurrency.ts +43 -50
  195. package/src/modules/primitives/command/setReferenceUnit.generated.ts +6 -0
  196. package/src/modules/primitives/command/setReferenceUnit.test.ts +39 -35
  197. package/src/modules/primitives/command/setReferenceUnit.ts +46 -59
  198. package/src/modules/primitives/db/unit.ts +13 -3
  199. package/src/modules/primitives/docs/commands/ActivateCategory.md +1 -2
  200. package/src/modules/primitives/docs/commands/ActivateCurrency.md +1 -2
  201. package/src/modules/primitives/docs/commands/ActivateUnit.md +1 -2
  202. package/src/modules/primitives/docs/commands/CreateCategory.md +1 -4
  203. package/src/modules/primitives/docs/commands/CreateCurrency.md +3 -4
  204. package/src/modules/primitives/docs/commands/CreateExchangeRate.md +4 -5
  205. package/src/modules/primitives/docs/commands/CreateUnit.md +5 -5
  206. package/src/modules/primitives/docs/commands/DeactivateCategory.md +2 -3
  207. package/src/modules/primitives/docs/commands/DeactivateCurrency.md +2 -3
  208. package/src/modules/primitives/docs/commands/DeactivateUnit.md +2 -3
  209. package/src/modules/primitives/docs/commands/SetBaseCurrency.md +2 -3
  210. package/src/modules/primitives/docs/commands/SetReferenceUnit.md +2 -3
  211. package/src/modules/primitives/docs/queries/ConvertAmount.md +3 -5
  212. package/src/modules/primitives/docs/queries/ConvertQuantity.md +3 -5
  213. package/src/modules/primitives/docs/queries/GetBaseCurrency.md +32 -0
  214. package/src/modules/primitives/docs/queries/GetCurrency.md +36 -0
  215. package/src/modules/primitives/docs/queries/GetUnit.md +36 -0
  216. package/src/modules/primitives/docs/queries/GetUoMCategory.md +36 -0
  217. package/src/modules/primitives/docs/queries/ListUnitsByCategory.md +26 -0
  218. package/src/modules/primitives/generated/kysely-tailordb.ts +24 -45
  219. package/src/modules/primitives/index.ts +15 -4
  220. package/src/modules/primitives/lib/errors.generated.ts +112 -0
  221. package/src/modules/primitives/{permissions.ts → lib/permissions.generated.ts} +9 -8
  222. package/src/modules/primitives/module.ts +37 -27
  223. package/src/modules/primitives/query/convertAmount.generated.ts +5 -0
  224. package/src/modules/primitives/query/convertAmount.test.ts +2 -2
  225. package/src/modules/primitives/query/convertAmount.ts +27 -28
  226. package/src/modules/primitives/query/convertQuantity.generated.ts +5 -0
  227. package/src/modules/primitives/query/convertQuantity.test.ts +6 -2
  228. package/src/modules/primitives/query/convertQuantity.ts +49 -57
  229. package/src/modules/primitives/query/getBaseCurrency.generated.ts +5 -0
  230. package/src/modules/primitives/query/getBaseCurrency.test.ts +28 -0
  231. package/src/modules/primitives/query/getBaseCurrency.ts +16 -0
  232. package/src/modules/primitives/query/getCurrency.generated.ts +5 -0
  233. package/src/modules/primitives/query/getCurrency.test.ts +47 -0
  234. package/src/modules/primitives/query/getCurrency.ts +18 -0
  235. package/src/modules/primitives/query/getUnit.generated.ts +5 -0
  236. package/src/modules/primitives/query/getUnit.test.ts +47 -0
  237. package/src/modules/primitives/query/getUnit.ts +18 -0
  238. package/src/modules/primitives/query/getUoMCategory.generated.ts +5 -0
  239. package/src/modules/primitives/query/getUoMCategory.test.ts +47 -0
  240. package/src/modules/primitives/query/getUoMCategory.ts +18 -0
  241. package/src/modules/primitives/query/listUnitsByCategory.generated.ts +5 -0
  242. package/src/modules/primitives/query/listUnitsByCategory.ts +16 -0
  243. package/src/modules/primitives/tailor.config.ts +3 -3
  244. package/src/modules/shared/defineCommand.test.ts +23 -10
  245. package/src/modules/shared/defineCommand.ts +23 -10
  246. package/src/modules/shared/internal.ts +1 -0
  247. package/src/modules/shared/requirePermission.test.ts +22 -21
  248. package/src/modules/shared/requirePermission.ts +8 -2
  249. package/src/modules/shared/result.ts +12 -0
  250. package/src/modules/testing/index.ts +36 -11
  251. package/src/modules/user-management/command/activateUser.generated.ts +6 -0
  252. package/src/modules/user-management/command/activateUser.test.ts +27 -27
  253. package/src/modules/user-management/command/activateUser.ts +40 -48
  254. package/src/modules/user-management/command/assignPermissionToRole.generated.ts +6 -0
  255. package/src/modules/user-management/command/assignPermissionToRole.test.ts +42 -43
  256. package/src/modules/user-management/command/assignPermissionToRole.ts +59 -62
  257. package/src/modules/user-management/command/assignRoleToUser.generated.ts +6 -0
  258. package/src/modules/user-management/command/assignRoleToUser.test.ts +70 -63
  259. package/src/modules/user-management/command/assignRoleToUser.ts +63 -66
  260. package/src/modules/user-management/command/createPermission.generated.ts +6 -0
  261. package/src/modules/user-management/command/createPermission.test.ts +45 -38
  262. package/src/modules/user-management/command/createPermission.ts +42 -46
  263. package/src/modules/user-management/command/createRole.generated.ts +6 -0
  264. package/src/modules/user-management/command/createRole.test.ts +30 -29
  265. package/src/modules/user-management/command/createRole.ts +33 -33
  266. package/src/modules/user-management/command/createUser.generated.ts +6 -0
  267. package/src/modules/user-management/command/createUser.test.ts +64 -42
  268. package/src/modules/user-management/command/createUser.ts +54 -56
  269. package/src/modules/user-management/command/deactivateUser.generated.ts +6 -0
  270. package/src/modules/user-management/command/deactivateUser.test.ts +27 -27
  271. package/src/modules/user-management/command/deactivateUser.ts +40 -48
  272. package/src/modules/user-management/command/logAuditEvent.generated.ts +6 -0
  273. package/src/modules/user-management/command/logAuditEvent.test.ts +50 -42
  274. package/src/modules/user-management/command/logAuditEvent.ts +25 -28
  275. package/src/modules/user-management/command/reactivateUser.generated.ts +6 -0
  276. package/src/modules/user-management/command/reactivateUser.test.ts +31 -27
  277. package/src/modules/user-management/command/reactivateUser.ts +40 -48
  278. package/src/modules/user-management/command/revokePermissionFromRole.generated.ts +6 -0
  279. package/src/modules/user-management/command/revokePermissionFromRole.test.ts +52 -51
  280. package/src/modules/user-management/command/revokePermissionFromRole.ts +60 -57
  281. package/src/modules/user-management/command/revokeRoleFromUser.generated.ts +6 -0
  282. package/src/modules/user-management/command/revokeRoleFromUser.test.ts +53 -48
  283. package/src/modules/user-management/command/revokeRoleFromUser.ts +58 -57
  284. package/src/modules/user-management/docs/commands/CreatePermission.md +2 -2
  285. package/src/modules/user-management/docs/commands/CreateRole.md +1 -1
  286. package/src/modules/user-management/generated/enums.ts +11 -11
  287. package/src/modules/user-management/generated/kysely-tailordb.ts +27 -56
  288. package/src/modules/user-management/index.ts +2 -2
  289. package/src/modules/user-management/lib/errors.generated.ts +67 -0
  290. package/src/modules/user-management/{permissions.ts → lib/permissions.generated.ts} +8 -7
  291. package/src/modules/user-management/module.ts +22 -22
  292. package/src/modules/user-management/tailor.config.ts +3 -3
  293. package/src/schemas.ts +1 -1
  294. package/skills/1-module-docs/references/structure.md +0 -22
  295. package/skills/2-module-feature-breakdown/references/commands.md +0 -48
  296. package/skills/2-module-feature-breakdown/references/structure.md +0 -22
  297. package/skills/3-module-doc-review/references/commands.md +0 -54
  298. package/skills/3-module-doc-review/references/models.md +0 -29
  299. package/skills/4-module-tdd-implementation/SKILL.md +0 -74
  300. package/skills/4-module-tdd-implementation/references/commands.md +0 -45
  301. package/skills/4-module-tdd-implementation/references/errors.md +0 -7
  302. package/skills/4-module-tdd-implementation/references/models.md +0 -30
  303. package/skills/4-module-tdd-implementation/references/structure.md +0 -22
  304. package/skills/4-module-tdd-implementation/references/testing.md +0 -37
  305. package/skills/5-module-implementation-review/references/commands.md +0 -45
  306. package/skills/5-module-implementation-review/references/errors.md +0 -7
  307. package/skills/5-module-implementation-review/references/exports.md +0 -8
  308. package/skills/5-module-implementation-review/references/models.md +0 -30
  309. package/skills/app-compose-1-requirement-analysis/references/structure.md +0 -27
  310. package/skills/app-compose-2-requirements-breakdown/references/screen-detailview.md +0 -106
  311. package/skills/app-compose-2-requirements-breakdown/references/screen-form.md +0 -139
  312. package/skills/app-compose-2-requirements-breakdown/references/screen-listview.md +0 -153
  313. package/skills/app-compose-2-requirements-breakdown/references/structure.md +0 -27
  314. package/skills/app-compose-3-doc-review/references/structure.md +0 -27
  315. package/skills/app-compose-4-design-mock/SKILL.md +0 -256
  316. package/skills/app-compose-4-design-mock/references/component.md +0 -50
  317. package/skills/app-compose-4-design-mock/references/screen-detailview.md +0 -106
  318. package/skills/app-compose-4-design-mock/references/screen-form.md +0 -139
  319. package/skills/app-compose-4-design-mock/references/screen-listview.md +0 -153
  320. package/skills/app-compose-4-design-mock/references/structure.md +0 -27
  321. package/skills/app-compose-5-design-mock-review/SKILL.md +0 -290
  322. package/skills/app-compose-5-design-mock-review/references/component.md +0 -50
  323. package/skills/app-compose-5-design-mock-review/references/screen-detailview.md +0 -106
  324. package/skills/app-compose-5-design-mock-review/references/screen-form.md +0 -139
  325. package/skills/app-compose-5-design-mock-review/references/screen-listview.md +0 -153
  326. package/skills/app-compose-6-implementation-spec/references/auth.md +0 -72
  327. package/skills/app-compose-6-implementation-spec/references/structure.md +0 -27
  328. package/src/modules/primitives/lib/errors.ts +0 -138
  329. package/src/modules/user-management/lib/errors.ts +0 -81
  330. /package/skills/{2-module-feature-breakdown → erp-kit-module-4-tdd}/references/models.md +0 -0
@@ -1,19 +1,15 @@
1
1
  import {
2
- type ColumnType,
3
- Kysely,
4
- type KyselyConfig,
5
- type Transaction as KyselyTransaction,
6
- type Insertable as KyselyInsertable,
7
- type Selectable as KyselySelectable,
8
- type Updateable as KyselyUpdateable,
9
- } from "kysely";
10
- import { TailordbDialect } from "@tailor-platform/function-kysely-tailordb";
11
-
12
- type Timestamp = ColumnType<Date, Date | string, Date | string>;
13
- type Generated<T> =
14
- T extends ColumnType<infer S, infer I, infer U>
15
- ? ColumnType<S, I | undefined, U>
16
- : ColumnType<T, T | undefined, T>;
2
+ createGetDB,
3
+ type Generated,
4
+ type Timestamp,
5
+ type NamespaceDB,
6
+ type NamespaceInsertable,
7
+ type NamespaceSelectable,
8
+ type NamespaceTable,
9
+ type NamespaceTableName,
10
+ type NamespaceTransaction,
11
+ type NamespaceUpdateable,
12
+ } from "@tailor-platform/sdk/kysely";
17
13
 
18
14
  export interface Namespace {
19
15
  "main-db": {
@@ -27,7 +23,7 @@ export interface Namespace {
27
23
  isActive: boolean;
28
24
  createdAt: Generated<Timestamp>;
29
25
  updatedAt: Timestamp | null;
30
- };
26
+ }
31
27
 
32
28
  ExchangeRate: {
33
29
  id: Generated<string>;
@@ -37,7 +33,7 @@ export interface Namespace {
37
33
  effectiveDate: Timestamp;
38
34
  createdAt: Generated<Timestamp>;
39
35
  updatedAt: Timestamp | null;
40
- };
36
+ }
41
37
 
42
38
  Unit: {
43
39
  id: Generated<string>;
@@ -49,7 +45,7 @@ export interface Namespace {
49
45
  isActive: boolean;
50
46
  createdAt: Generated<Timestamp>;
51
47
  updatedAt: Timestamp | null;
52
- };
48
+ }
53
49
 
54
50
  UoMCategory: {
55
51
  id: Generated<string>;
@@ -59,37 +55,20 @@ export interface Namespace {
59
55
  isActive: boolean;
60
56
  createdAt: Generated<Timestamp>;
61
57
  updatedAt: Timestamp | null;
62
- };
63
- };
58
+ }
59
+ }
64
60
  }
65
61
 
66
- export function getDB<const N extends keyof Namespace>(
67
- namespace: N,
68
- kyselyConfig?: Omit<KyselyConfig, "dialect">,
69
- ): Kysely<Namespace[N]> {
70
- const client = new tailordb.Client({ namespace });
71
- return new Kysely<Namespace[N]>({
72
- dialect: new TailordbDialect(client),
73
- ...kyselyConfig,
74
- });
75
- }
62
+ export const getDB = createGetDB<Namespace>();
76
63
 
77
- export type DB<N extends keyof Namespace = keyof Namespace> = ReturnType<typeof getDB<N>>;
64
+ export type DB<N extends keyof Namespace = keyof Namespace> = NamespaceDB<Namespace, N>;
78
65
 
79
66
  export type Transaction<K extends keyof Namespace | DB = keyof Namespace> =
80
- K extends DB<infer N>
81
- ? KyselyTransaction<Namespace[N]>
82
- : K extends keyof Namespace
83
- ? KyselyTransaction<Namespace[K]>
84
- : never;
67
+ NamespaceTransaction<Namespace, K>;
85
68
 
86
- type TableName = {
87
- [N in keyof Namespace]: keyof Namespace[N];
88
- }[keyof Namespace];
89
- export type Table<T extends TableName> = {
90
- [N in keyof Namespace]: T extends keyof Namespace[N] ? Namespace[N][T] : never;
91
- }[keyof Namespace];
69
+ type TableName = NamespaceTableName<Namespace>;
70
+ export type Table<T extends TableName> = NamespaceTable<Namespace, T>;
92
71
 
93
- export type Insertable<T extends keyof Namespace[keyof Namespace]> = KyselyInsertable<Table<T>>;
94
- export type Selectable<T extends keyof Namespace[keyof Namespace]> = KyselySelectable<Table<T>>;
95
- export type Updateable<T extends keyof Namespace[keyof Namespace]> = KyselyUpdateable<Table<T>>;
72
+ export type Insertable<T extends TableName> = NamespaceInsertable<Namespace, T>;
73
+ export type Selectable<T extends TableName> = NamespaceSelectable<Namespace, T>;
74
+ export type Updateable<T extends TableName> = NamespaceUpdateable<Namespace, T>;
@@ -1,9 +1,9 @@
1
1
  export { defineModule } from "./module";
2
- export { permissions, own, all } from "./permissions";
2
+ export { permissions, own, all } from "./lib/permissions.generated";
3
3
 
4
4
  // errors
5
5
  export {
6
- UoMCategoryNotFoundError,
6
+ UomCategoryNotFoundError,
7
7
  UnitNotFoundError,
8
8
  IncompatibleUnitsError,
9
9
  InactiveUnitError,
@@ -18,16 +18,27 @@ export {
18
18
  DuplicateCategoryNameError,
19
19
  CategoryHasActiveUnitsError,
20
20
  UnitNotInCategoryError,
21
- InvalidISOCodeError,
21
+ InvalidIsoCodeError,
22
22
  DuplicateCurrencyCodeError,
23
23
  InvalidDecimalPlacesError,
24
24
  CannotDeactivateBaseCurrencyError,
25
25
  CannotSetInactiveAsBaseCurrencyError,
26
26
  SameCurrencyPairError,
27
27
  InvalidExchangeRateError,
28
- } from "./lib/errors";
28
+ } from "./lib/errors.generated";
29
+
30
+ // queries
31
+ export { getUnit } from "./query/getUnit.generated";
32
+ export { getCurrency } from "./query/getCurrency.generated";
33
+ export { getUoMCategory } from "./query/getUoMCategory.generated";
34
+ export { getBaseCurrency } from "./query/getBaseCurrency.generated";
35
+ export { listUnitsByCategory } from "./query/listUnitsByCategory.generated";
29
36
 
30
37
  // input types
38
+ export { type GetUnitInput } from "./query/getUnit";
39
+ export { type GetCurrencyInput } from "./query/getCurrency";
40
+ export { type GetUoMCategoryInput } from "./query/getUoMCategory";
41
+ export { type ListUnitsByCategoryInput } from "./query/listUnitsByCategory";
31
42
  export { type ConvertQuantityInput } from "./query/convertQuantity";
32
43
  export { type ActivateCategoryInput } from "./command/activateCategory";
33
44
  export { type DeactivateCategoryInput } from "./command/deactivateCategory";
@@ -0,0 +1,112 @@
1
+ // @generated — do not edit
2
+ import { createDomainError } from "../../shared/internal";
3
+
4
+ export const UomCategoryNotFoundError = createDomainError(
5
+ "UomCategoryNotFoundError", "UOM_CATEGORY_NOT_FOUND",
6
+ (identifier: string) => `Specified category ID does not exist: ${identifier}`,
7
+ );
8
+
9
+ export const CurrencyNotFoundError = createDomainError(
10
+ "CurrencyNotFoundError", "CURRENCY_NOT_FOUND",
11
+ (identifier: string) => `Specified currency ID does not exist: ${identifier}`,
12
+ );
13
+
14
+ export const UnitNotFoundError = createDomainError(
15
+ "UnitNotFoundError", "UNIT_NOT_FOUND",
16
+ (identifier: string) => `Specified unit ID does not exist: ${identifier}`,
17
+ );
18
+
19
+ export const DuplicateCategoryNameError = createDomainError(
20
+ "DuplicateCategoryNameError", "DUPLICATE_CATEGORY_NAME",
21
+ (identifier: string) => `Category with same name already exists: ${identifier}`,
22
+ );
23
+
24
+ export const InvalidIsoCodeError = createDomainError(
25
+ "InvalidIsoCodeError", "INVALID_ISO_CODE",
26
+ (identifier: string) => `Code is not exactly 3 uppercase letters: ${identifier}`,
27
+ );
28
+
29
+ export const DuplicateCurrencyCodeError = createDomainError(
30
+ "DuplicateCurrencyCodeError", "DUPLICATE_CURRENCY_CODE",
31
+ (identifier: string) => `Currency with same code already exists: ${identifier}`,
32
+ );
33
+
34
+ export const InvalidDecimalPlacesError = createDomainError(
35
+ "InvalidDecimalPlacesError", "INVALID_DECIMAL_PLACES",
36
+ (identifier: string) => `Value is negative or exceeds maximum (typically 4): ${identifier}`,
37
+ );
38
+
39
+ export const InactiveCurrencyError = createDomainError(
40
+ "InactiveCurrencyError", "INACTIVE_CURRENCY",
41
+ (identifier: string) => `Source or target currency is inactive: ${identifier}`,
42
+ );
43
+
44
+ export const SameCurrencyPairError = createDomainError(
45
+ "SameCurrencyPairError", "SAME_CURRENCY_PAIR",
46
+ (identifier: string) => `Source and target currencies are the same: ${identifier}`,
47
+ );
48
+
49
+ export const InvalidExchangeRateError = createDomainError(
50
+ "InvalidExchangeRateError", "INVALID_EXCHANGE_RATE",
51
+ (identifier: string) => `Rate is zero, negative, or not a valid number: ${identifier}`,
52
+ );
53
+
54
+ export const CategoryNotActiveError = createDomainError(
55
+ "CategoryNotActiveError", "CATEGORY_NOT_ACTIVE",
56
+ (identifier: string) => `Category is inactive: ${identifier}`,
57
+ );
58
+
59
+ export const DuplicateUnitSymbolError = createDomainError(
60
+ "DuplicateUnitSymbolError", "DUPLICATE_UNIT_SYMBOL",
61
+ (identifier: string) => `Unit with same symbol already exists in category: ${identifier}`,
62
+ );
63
+
64
+ export const InvalidConversionFactorError = createDomainError(
65
+ "InvalidConversionFactorError", "INVALID_CONVERSION_FACTOR",
66
+ (identifier: string) => `Factor is zero, negative, or not a valid number: ${identifier}`,
67
+ );
68
+
69
+ export const InvalidRoundingPrecisionError = createDomainError(
70
+ "InvalidRoundingPrecisionError", "INVALID_ROUNDING_PRECISION",
71
+ (identifier: string) => `Precision is negative: ${identifier}`,
72
+ );
73
+
74
+ export const CategoryHasActiveUnitsError = createDomainError(
75
+ "CategoryHasActiveUnitsError", "CATEGORY_HAS_ACTIVE_UNITS",
76
+ (identifier: string) => `Category still contains active units that must be deactivated first: ${identifier}`,
77
+ );
78
+
79
+ export const CannotDeactivateBaseCurrencyError = createDomainError(
80
+ "CannotDeactivateBaseCurrencyError", "CANNOT_DEACTIVATE_BASE_CURRENCY",
81
+ (identifier: string) => `Attempting to deactivate the base currency, must change base currency first: ${identifier}`,
82
+ );
83
+
84
+ export const CannotDeactivateReferenceUnitError = createDomainError(
85
+ "CannotDeactivateReferenceUnitError", "CANNOT_DEACTIVATE_REFERENCE_UNIT",
86
+ (identifier: string) => `Attempting to deactivate the category's reference unit, must change reference unit first: ${identifier}`,
87
+ );
88
+
89
+ export const CannotSetInactiveAsBaseCurrencyError = createDomainError(
90
+ "CannotSetInactiveAsBaseCurrencyError", "CANNOT_SET_INACTIVE_AS_BASE_CURRENCY",
91
+ (identifier: string) => `Target currency is not in Active status, must be activated first: ${identifier}`,
92
+ );
93
+
94
+ export const UnitNotInCategoryError = createDomainError(
95
+ "UnitNotInCategoryError", "UNIT_NOT_IN_CATEGORY",
96
+ (identifier: string) => `Unit belongs to a different category than specified: ${identifier}`,
97
+ );
98
+
99
+ export const ExchangeRateNotFoundError = createDomainError(
100
+ "ExchangeRateNotFoundError", "EXCHANGE_RATE_NOT_FOUND",
101
+ (identifier: string) => `No rate found for the currency pair on or before the specified date: ${identifier}`,
102
+ );
103
+
104
+ export const IncompatibleUnitsError = createDomainError(
105
+ "IncompatibleUnitsError", "INCOMPATIBLE_UNITS",
106
+ (identifier: string) => `Source and target units belong to different categories: ${identifier}`,
107
+ );
108
+
109
+ export const InactiveUnitError = createDomainError(
110
+ "InactiveUnitError", "INACTIVE_UNIT",
111
+ (identifier: string) => `Either source or target unit is inactive: ${identifier}`,
112
+ );
@@ -1,16 +1,17 @@
1
- import { definePermissions } from "../shared/internal";
1
+ // @generated do not edit
2
+ import { definePermissions } from "../../shared/internal";
2
3
 
3
4
  export const { permissions, own, all } = definePermissions("primitives", [
4
- "createCategory",
5
5
  "activateCategory",
6
- "deactivateCategory",
7
- "setReferenceUnit",
8
- "createUnit",
6
+ "activateCurrency",
9
7
  "activateUnit",
10
- "deactivateUnit",
8
+ "createCategory",
11
9
  "createCurrency",
12
- "activateCurrency",
10
+ "createExchangeRate",
11
+ "createUnit",
12
+ "deactivateCategory",
13
13
  "deactivateCurrency",
14
+ "deactivateUnit",
14
15
  "setBaseCurrency",
15
- "createExchangeRate",
16
+ "setReferenceUnit",
16
17
  ] as const);
@@ -1,19 +1,24 @@
1
1
  import { type TailorAnyDBField } from "@tailor-platform/sdk";
2
2
  import { type EmptyFields, type FieldsToInsertable } from "../shared/internal";
3
- import { makeCreateCategory } from "./command/createCategory";
4
- import { makeCreateCurrency } from "./command/createCurrency";
5
- import { makeCreateUnit } from "./command/createUnit";
6
- import { makeCreateExchangeRate } from "./command/createExchangeRate";
7
- import { activateCategory } from "./command/activateCategory";
8
- import { deactivateCategory } from "./command/deactivateCategory";
9
- import { activateUnit } from "./command/activateUnit";
10
- import { deactivateUnit } from "./command/deactivateUnit";
11
- import { setReferenceUnit } from "./command/setReferenceUnit";
12
- import { convertQuantity } from "./query/convertQuantity";
13
- import { activateCurrency } from "./command/activateCurrency";
14
- import { deactivateCurrency } from "./command/deactivateCurrency";
15
- import { setBaseCurrency } from "./command/setBaseCurrency";
16
- import { convertAmount } from "./query/convertAmount";
3
+ import { createCategory } from "./command/createCategory.generated";
4
+ import { createCurrency } from "./command/createCurrency.generated";
5
+ import { createUnit } from "./command/createUnit.generated";
6
+ import { createExchangeRate } from "./command/createExchangeRate.generated";
7
+ import { activateCategory } from "./command/activateCategory.generated";
8
+ import { deactivateCategory } from "./command/deactivateCategory.generated";
9
+ import { activateUnit } from "./command/activateUnit.generated";
10
+ import { deactivateUnit } from "./command/deactivateUnit.generated";
11
+ import { setReferenceUnit } from "./command/setReferenceUnit.generated";
12
+ import { convertQuantity } from "./query/convertQuantity.generated";
13
+ import { getUnit } from "./query/getUnit.generated";
14
+ import { getCurrency } from "./query/getCurrency.generated";
15
+ import { getUoMCategory } from "./query/getUoMCategory.generated";
16
+ import { getBaseCurrency } from "./query/getBaseCurrency.generated";
17
+ import { listUnitsByCategory } from "./query/listUnitsByCategory.generated";
18
+ import { activateCurrency } from "./command/activateCurrency.generated";
19
+ import { deactivateCurrency } from "./command/deactivateCurrency.generated";
20
+ import { setBaseCurrency } from "./command/setBaseCurrency.generated";
21
+ import { convertAmount } from "./query/convertAmount.generated";
17
22
  import { createUoMCategoryType, CreateUoMCategoryTypeParams } from "./db/uomCategory";
18
23
  import { createUnitType, CreateUnitTypeParams } from "./db/unit";
19
24
  import { createCurrencyType, CreateCurrencyTypeParams } from "./db/currency";
@@ -40,27 +45,32 @@ export const defineModule = <
40
45
  params: DefineModuleParams<CatF, UnitF, CurF, ERF>,
41
46
  ) => {
42
47
  const uomCategory = createUoMCategoryType(params.uomCategory ?? {});
43
- const unit = createUnitType(params.unit ?? {});
48
+ const unit = createUnitType({ ...params.unit, uomCategoryType: uomCategory });
44
49
  const currency = createCurrencyType(params.currency ?? {});
45
50
  const exchangeRate = createExchangeRateType(params.exchangeRate ?? {});
46
51
 
47
52
  return {
48
53
  db: { uomCategory, unit, currency, exchangeRate },
49
54
  commands: {
50
- createCategory: makeCreateCategory<FieldsToInsertable<CatF>, FieldsToInsertable<UnitF>>(),
51
- createCurrency: makeCreateCurrency<FieldsToInsertable<CurF>>(),
52
- createUnit: makeCreateUnit<FieldsToInsertable<UnitF>>(),
53
- createExchangeRate: makeCreateExchangeRate<FieldsToInsertable<ERF>>(),
54
- activateCategory,
55
- deactivateCategory,
56
- activateUnit,
57
- deactivateUnit,
58
- setReferenceUnit,
59
- activateCurrency,
60
- deactivateCurrency,
61
- setBaseCurrency,
55
+ createCategory: createCategory<FieldsToInsertable<CatF>, FieldsToInsertable<UnitF>>(),
56
+ createCurrency: createCurrency<FieldsToInsertable<CurF>>(),
57
+ createUnit: createUnit<FieldsToInsertable<UnitF>>(),
58
+ createExchangeRate: createExchangeRate<FieldsToInsertable<ERF>>(),
59
+ activateCategory: activateCategory(),
60
+ deactivateCategory: deactivateCategory(),
61
+ activateUnit: activateUnit(),
62
+ deactivateUnit: deactivateUnit(),
63
+ setReferenceUnit: setReferenceUnit(),
64
+ activateCurrency: activateCurrency(),
65
+ deactivateCurrency: deactivateCurrency(),
66
+ setBaseCurrency: setBaseCurrency(),
62
67
  },
63
68
  queries: {
69
+ getUnit,
70
+ getCurrency,
71
+ getUoMCategory,
72
+ getBaseCurrency,
73
+ listUnitsByCategory,
64
74
  convertQuantity,
65
75
  convertAmount,
66
76
  },
@@ -0,0 +1,5 @@
1
+ // @generated — do not edit
2
+ import { defineQuery } from "../../shared/internal";
3
+ import { run } from "./convertAmount";
4
+
5
+ export const convertAmount = defineQuery(run);
@@ -6,7 +6,7 @@ import {
6
6
  CurrencyNotFoundError,
7
7
  ExchangeRateNotFoundError,
8
8
  InactiveCurrencyError,
9
- } from "../lib/errors";
9
+ } from "../lib/errors.generated";
10
10
  import {
11
11
  baseCurrencyEUR,
12
12
  baseCurrencyJPY,
@@ -16,7 +16,7 @@ import {
16
16
  inactiveCurrency,
17
17
  olderExchangeRateUSDtoEUR,
18
18
  } from "../testing/fixtures";
19
- import { convertAmount } from "./convertAmount";
19
+ import { convertAmount } from "./convertAmount.generated";
20
20
 
21
21
  describe("convertAmount", () => {
22
22
  const ctx: QueryContext = { actorId: "test-actor" };
@@ -1,10 +1,11 @@
1
- import { defineQuery, type ReadonlyDB } from "../../shared/internal";
1
+ import type { ReadonlyDB, QueryContext } from "../../shared/internal";
2
2
  import type { DB } from "../generated/kysely-tailordb";
3
3
  import {
4
4
  CurrencyNotFoundError,
5
5
  ExchangeRateNotFoundError,
6
6
  InactiveCurrencyError,
7
- } from "../lib/errors";
7
+ } from "../lib/errors.generated";
8
+ import { getCurrency } from "./getCurrency.generated";
8
9
 
9
10
  export interface ConvertAmountInput {
10
11
  amount: number;
@@ -14,38 +15,40 @@ export interface ConvertAmountInput {
14
15
  }
15
16
 
16
17
  /**
17
- * Function: convertAmount
18
- *
19
18
  * Converts a monetary amount from one currency to another using the applicable
20
19
  * exchange rate for a given date. Currencies are identified by their ISO 4217
21
20
  * code (e.g., "USD", "EUR", "JPY"). The function looks up the most recent exchange
22
21
  * rate on or before the specified date. If no direct rate exists, it calculates
23
22
  * the inverse rate. Result is rounded to the target currency's decimal precision.
24
23
  */
25
- export const convertAmount = defineQuery(async (db: ReadonlyDB<DB>, input: ConvertAmountInput) => {
26
- // 1. Validate source currency exists
27
- const sourceCurrency = await db
28
- .selectFrom("Currency")
29
- .selectAll()
30
- .where("code", "=", input.sourceCurrencyCode)
31
- .executeTakeFirst();
24
+ export async function run(db: ReadonlyDB<DB>, input: ConvertAmountInput, ctx: QueryContext) {
25
+ // Validate source currency exists
26
+ const { currency: sourceCurrency } = await getCurrency(
27
+ db,
28
+ {
29
+ code: input.sourceCurrencyCode,
30
+ },
31
+ ctx,
32
+ );
32
33
 
33
34
  if (!sourceCurrency) {
34
35
  throw new CurrencyNotFoundError(input.sourceCurrencyCode);
35
36
  }
36
37
 
37
- // 2. Validate target currency exists
38
- const targetCurrency = await db
39
- .selectFrom("Currency")
40
- .selectAll()
41
- .where("code", "=", input.targetCurrencyCode)
42
- .executeTakeFirst();
38
+ // Validate target currency exists
39
+ const { currency: targetCurrency } = await getCurrency(
40
+ db,
41
+ {
42
+ code: input.targetCurrencyCode,
43
+ },
44
+ ctx,
45
+ );
43
46
 
44
47
  if (!targetCurrency) {
45
48
  throw new CurrencyNotFoundError(input.targetCurrencyCode);
46
49
  }
47
50
 
48
- // 3. Validate both currencies are active
51
+ // Validate both currencies are active
49
52
  if (!sourceCurrency.isActive) {
50
53
  throw new InactiveCurrencyError(input.sourceCurrencyCode);
51
54
  }
@@ -54,7 +57,7 @@ export const convertAmount = defineQuery(async (db: ReadonlyDB<DB>, input: Conve
54
57
  throw new InactiveCurrencyError(input.targetCurrencyCode);
55
58
  }
56
59
 
57
- // 4. Same currency - return original amount
60
+ // Same currency - return original amount
58
61
  if (sourceCurrency.id === targetCurrency.id) {
59
62
  return {
60
63
  convertedAmount: input.amount,
@@ -65,7 +68,7 @@ export const convertAmount = defineQuery(async (db: ReadonlyDB<DB>, input: Conve
65
68
  };
66
69
  }
67
70
 
68
- // 5. Find direct exchange rate (most recent on or before conversion date)
71
+ // Find direct exchange rate (most recent on or before conversion date)
69
72
  const conversionDate = new Date(input.conversionDate);
70
73
  const directRate = await db
71
74
  .selectFrom("ExchangeRate")
@@ -83,7 +86,7 @@ export const convertAmount = defineQuery(async (db: ReadonlyDB<DB>, input: Conve
83
86
  exchangeRate = directRate.rate;
84
87
  exchangeRateRecord = directRate;
85
88
  } else {
86
- // 6. Try inverse rate
89
+ // Try inverse rate
87
90
  const inverseRate = await db
88
91
  .selectFrom("ExchangeRate")
89
92
  .selectAll()
@@ -95,9 +98,7 @@ export const convertAmount = defineQuery(async (db: ReadonlyDB<DB>, input: Conve
95
98
 
96
99
  if (!inverseRate) {
97
100
  throw new ExchangeRateNotFoundError(
98
- input.sourceCurrencyCode,
99
- input.targetCurrencyCode,
100
- input.conversionDate,
101
+ `${input.sourceCurrencyCode} to ${input.targetCurrencyCode} on ${input.conversionDate}`,
101
102
  );
102
103
  }
103
104
 
@@ -105,10 +106,8 @@ export const convertAmount = defineQuery(async (db: ReadonlyDB<DB>, input: Conve
105
106
  exchangeRateRecord = inverseRate;
106
107
  }
107
108
 
108
- // 7. Calculate converted amount
109
+ // Calculate converted amount, rounded to target currency's decimal places
109
110
  const rawResult = input.amount * exchangeRate;
110
-
111
- // 8. Round to target currency's decimal places
112
111
  const roundingFactor = Math.pow(10, targetCurrency.decimalPlaces);
113
112
  const convertedAmount = Math.round(rawResult * roundingFactor) / roundingFactor;
114
113
 
@@ -119,4 +118,4 @@ export const convertAmount = defineQuery(async (db: ReadonlyDB<DB>, input: Conve
119
118
  targetCurrency,
120
119
  exchangeRateRecord,
121
120
  };
122
- });
121
+ }
@@ -0,0 +1,5 @@
1
+ // @generated — do not edit
2
+ import { defineQuery } from "../../shared/internal";
3
+ import { run } from "./convertQuantity";
4
+
5
+ export const convertQuantity = defineQuery(run);
@@ -2,7 +2,11 @@ import { describe, expect, it } from "vitest";
2
2
  import { createMockDb } from "../../testing/index";
3
3
  import { DB } from "../generated/kysely-tailordb";
4
4
  import type { QueryContext } from "../../shared/internal";
5
- import { InactiveUnitError, IncompatibleUnitsError, UnitNotFoundError } from "../lib/errors";
5
+ import {
6
+ InactiveUnitError,
7
+ IncompatibleUnitsError,
8
+ UnitNotFoundError,
9
+ } from "../lib/errors.generated";
6
10
  import {
7
11
  baseUnitGram,
8
12
  baseUnitKg,
@@ -10,7 +14,7 @@ import {
10
14
  baseUnitPound,
11
15
  inactiveUnit,
12
16
  } from "../testing/fixtures";
13
- import { convertQuantity } from "./convertQuantity";
17
+ import { convertQuantity } from "./convertQuantity.generated";
14
18
 
15
19
  describe("convertQuantity", () => {
16
20
  const ctx: QueryContext = { actorId: "test-actor" };