@tailor-platform/erp-kit 0.1.2 → 0.2.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 (325) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +81 -12
  3. package/dist/cli.js +1070 -450
  4. package/package.json +11 -8
  5. package/schemas/module/model.yml +5 -0
  6. package/skills/{app-compose-1-requirement-analysis → erp-kit-app-1-requirements}/SKILL.md +2 -2
  7. package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/SKILL.md +3 -3
  8. package/skills/{app-compose-3-doc-review → erp-kit-app-3-doc-review}/SKILL.md +2 -2
  9. package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/SKILL.md +3 -3
  10. package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/SKILL.md +4 -4
  11. package/skills/{app-compose-6-implementation-spec → erp-kit-app-6-impl-spec}/SKILL.md +3 -3
  12. package/skills/{mock-scenario → erp-kit-mock-scenario}/SKILL.md +1 -1
  13. package/skills/{1-module-docs → erp-kit-module-1-docs}/SKILL.md +2 -2
  14. package/skills/{2-module-feature-breakdown → erp-kit-module-2-feature-breakdown}/SKILL.md +13 -9
  15. package/skills/erp-kit-module-2-feature-breakdown/references/naming.md +59 -0
  16. package/skills/{3-module-doc-review → erp-kit-module-3-doc-review}/SKILL.md +83 -25
  17. package/skills/erp-kit-module-4-tdd/SKILL.md +94 -0
  18. package/skills/erp-kit-module-4-tdd/references/cross-module-dependency.md +133 -0
  19. package/skills/{4-module-tdd-implementation → erp-kit-module-4-tdd}/references/db-relations.md +5 -1
  20. package/skills/{4-module-tdd-implementation → erp-kit-module-4-tdd}/references/exports.md +1 -1
  21. package/skills/erp-kit-module-4-tdd/references/generated-code.md +32 -0
  22. package/skills/{5-module-implementation-review → erp-kit-module-5-impl-review}/SKILL.md +46 -44
  23. package/skills/erp-kit-module-5-impl-review/references/commands.md +62 -0
  24. package/skills/erp-kit-module-5-impl-review/references/errors.md +10 -0
  25. package/skills/{5-module-implementation-review → erp-kit-module-5-impl-review}/references/testing.md +1 -1
  26. package/skills/erp-kit-module-shared/SKILL.md +16 -0
  27. package/skills/erp-kit-module-shared/references/commands.md +203 -0
  28. package/skills/erp-kit-module-shared/references/errors.md +35 -0
  29. package/skills/erp-kit-module-shared/references/queries.md +168 -0
  30. package/skills/erp-kit-module-shared/references/structure.md +36 -0
  31. package/skills/{3-module-doc-review → erp-kit-module-shared}/references/testing.md +4 -3
  32. package/skills/erp-kit-update/SKILL.md +64 -0
  33. package/src/cli.doc.test.ts +65 -0
  34. package/src/cli.ts +3 -35
  35. package/src/commands/app/index.ts +3 -3
  36. package/src/commands/check.test.ts +1 -1
  37. package/src/commands/check.ts +2 -2
  38. package/src/commands/index.ts +73 -0
  39. package/src/commands/init.test.ts +22 -5
  40. package/src/commands/init.ts +25 -16
  41. package/src/commands/license.ts +193 -0
  42. package/src/commands/mock/index.ts +2 -2
  43. package/src/commands/mock/start.ts +1 -1
  44. package/src/commands/mock/validate.test.ts +1 -1
  45. package/src/commands/module/generate.ts +35 -0
  46. package/src/commands/module/index.ts +6 -4
  47. package/src/commands/module/list.test.ts +7 -12
  48. package/src/commands/module/list.ts +1 -1
  49. package/src/commands/scaffold-templates.ts +65 -0
  50. package/src/commands/scaffold.test.ts +92 -2
  51. package/src/commands/scaffold.ts +22 -2
  52. package/src/commands/sync-check.test.ts +60 -1
  53. package/src/commands/sync-check.ts +35 -2
  54. package/src/generator/generate-code.test.ts +200 -0
  55. package/src/generator/generate-code.ts +260 -0
  56. package/src/generator/parse-command-doc.test.ts +159 -0
  57. package/src/generator/parse-command-doc.ts +116 -0
  58. package/src/integration.test.ts +2 -2
  59. package/src/module.ts +6 -6
  60. package/src/modules/item-management/README.md +38 -0
  61. package/src/modules/item-management/command/activateItem.generated.ts +6 -0
  62. package/src/modules/item-management/command/activateItem.test.ts +76 -0
  63. package/src/modules/item-management/command/activateItem.ts +42 -0
  64. package/src/modules/item-management/command/assignItemToTaxonomy.generated.ts +6 -0
  65. package/src/modules/item-management/command/assignItemToTaxonomy.test.ts +88 -0
  66. package/src/modules/item-management/command/assignItemToTaxonomy.ts +63 -0
  67. package/src/modules/item-management/command/createItem.generated.ts +6 -0
  68. package/src/modules/item-management/command/createItem.test.ts +152 -0
  69. package/src/modules/item-management/command/createItem.ts +72 -0
  70. package/src/modules/item-management/command/createTaxonomyNode.generated.ts +6 -0
  71. package/src/modules/item-management/command/createTaxonomyNode.test.ts +126 -0
  72. package/src/modules/item-management/command/createTaxonomyNode.ts +70 -0
  73. package/src/modules/item-management/command/deactivateItem.generated.ts +6 -0
  74. package/src/modules/item-management/command/deactivateItem.test.ts +76 -0
  75. package/src/modules/item-management/command/deactivateItem.ts +42 -0
  76. package/src/modules/item-management/command/deleteItem.generated.ts +6 -0
  77. package/src/modules/item-management/command/deleteItem.test.ts +61 -0
  78. package/src/modules/item-management/command/deleteItem.ts +38 -0
  79. package/src/modules/item-management/command/deleteTaxonomyNode.generated.ts +6 -0
  80. package/src/modules/item-management/command/deleteTaxonomyNode.test.ts +73 -0
  81. package/src/modules/item-management/command/deleteTaxonomyNode.ts +50 -0
  82. package/src/modules/item-management/command/moveTaxonomyNode.generated.ts +6 -0
  83. package/src/modules/item-management/command/moveTaxonomyNode.test.ts +136 -0
  84. package/src/modules/item-management/command/moveTaxonomyNode.ts +85 -0
  85. package/src/modules/item-management/command/reactivateItem.generated.ts +6 -0
  86. package/src/modules/item-management/command/reactivateItem.test.ts +76 -0
  87. package/src/modules/item-management/command/reactivateItem.ts +42 -0
  88. package/src/modules/item-management/command/removeItemFromTaxonomy.generated.ts +6 -0
  89. package/src/modules/item-management/command/removeItemFromTaxonomy.test.ts +43 -0
  90. package/src/modules/item-management/command/removeItemFromTaxonomy.ts +30 -0
  91. package/src/modules/item-management/command/updateItem.generated.ts +6 -0
  92. package/src/modules/item-management/command/updateItem.test.ts +178 -0
  93. package/src/modules/item-management/command/updateItem.ts +103 -0
  94. package/src/modules/item-management/command/updateTaxonomyNode.generated.ts +6 -0
  95. package/src/modules/item-management/command/updateTaxonomyNode.test.ts +88 -0
  96. package/src/modules/item-management/command/updateTaxonomyNode.ts +62 -0
  97. package/src/modules/item-management/db/item.ts +47 -0
  98. package/src/modules/item-management/db/itemTaxonomyAssignment.ts +49 -0
  99. package/src/modules/item-management/db/taxonomyNode.ts +34 -0
  100. package/src/modules/item-management/docs/commands/ActivateItem.md +32 -0
  101. package/src/modules/item-management/docs/commands/AssignItemToTaxonomy.md +38 -0
  102. package/src/modules/item-management/docs/commands/CreateItem.md +44 -0
  103. package/src/modules/item-management/docs/commands/CreateTaxonomyNode.md +44 -0
  104. package/src/modules/item-management/docs/commands/DeactivateItem.md +34 -0
  105. package/src/modules/item-management/docs/commands/DeleteItem.md +35 -0
  106. package/src/modules/item-management/docs/commands/DeleteTaxonomyNode.md +39 -0
  107. package/src/modules/item-management/docs/commands/MoveTaxonomyNode.md +45 -0
  108. package/src/modules/item-management/docs/commands/ReactivateItem.md +34 -0
  109. package/src/modules/item-management/docs/commands/RemoveItemFromTaxonomy.md +30 -0
  110. package/src/modules/item-management/docs/commands/UpdateItem.md +55 -0
  111. package/src/modules/item-management/docs/commands/UpdateTaxonomyNode.md +36 -0
  112. package/src/modules/item-management/docs/features/item-lifecycle.md +60 -0
  113. package/src/modules/item-management/docs/features/item-taxonomy.md +65 -0
  114. package/src/modules/item-management/docs/models/ItemTaxonomyAssignment.md +36 -0
  115. package/src/modules/item-management/docs/models/TaxonomyNode.md +47 -0
  116. package/src/modules/item-management/docs/models/item.md +59 -0
  117. package/src/modules/item-management/docs/queries/CalculateNodeDepth.md +36 -0
  118. package/src/modules/item-management/docs/queries/CalculateSubtreeDepth.md +40 -0
  119. package/src/modules/item-management/docs/queries/DetectCircularReference.md +41 -0
  120. package/src/modules/item-management/docs/queries/GetItem.md +38 -0
  121. package/src/modules/item-management/docs/queries/GetItemTaxonomyAssignment.md +29 -0
  122. package/src/modules/item-management/docs/queries/GetTaxonomyNode.md +35 -0
  123. package/src/modules/item-management/docs/queries/GetTaxonomyNodeAssignments.md +29 -0
  124. package/src/modules/item-management/docs/queries/GetTaxonomyNodeChildren.md +29 -0
  125. package/src/modules/item-management/generated/enums.ts +9 -0
  126. package/src/modules/item-management/generated/kysely-tailordb.ts +62 -0
  127. package/src/modules/item-management/index.ts +53 -0
  128. package/src/modules/item-management/lib/_db_deps.ts +13 -0
  129. package/src/modules/item-management/lib/errors.generated.ts +117 -0
  130. package/src/modules/item-management/lib/permissions.generated.ts +17 -0
  131. package/src/modules/item-management/lib/types.ts +19 -0
  132. package/src/modules/item-management/module.ts +97 -0
  133. package/src/modules/item-management/query/calculateNodeDepth.generated.ts +5 -0
  134. package/src/modules/item-management/query/calculateNodeDepth.test.ts +56 -0
  135. package/src/modules/item-management/query/calculateNodeDepth.ts +28 -0
  136. package/src/modules/item-management/query/calculateSubtreeDepth.generated.ts +5 -0
  137. package/src/modules/item-management/query/calculateSubtreeDepth.test.ts +75 -0
  138. package/src/modules/item-management/query/calculateSubtreeDepth.ts +29 -0
  139. package/src/modules/item-management/query/detectCircularReference.generated.ts +5 -0
  140. package/src/modules/item-management/query/detectCircularReference.test.ts +61 -0
  141. package/src/modules/item-management/query/detectCircularReference.ts +32 -0
  142. package/src/modules/item-management/query/getItem.generated.ts +5 -0
  143. package/src/modules/item-management/query/getItem.test.ts +67 -0
  144. package/src/modules/item-management/query/getItem.ts +20 -0
  145. package/src/modules/item-management/query/getItemTaxonomyAssignment.generated.ts +5 -0
  146. package/src/modules/item-management/query/getItemTaxonomyAssignment.test.ts +25 -0
  147. package/src/modules/item-management/query/getItemTaxonomyAssignment.ts +18 -0
  148. package/src/modules/item-management/query/getTaxonomyNode.generated.ts +5 -0
  149. package/src/modules/item-management/query/getTaxonomyNode.test.ts +47 -0
  150. package/src/modules/item-management/query/getTaxonomyNode.ts +18 -0
  151. package/src/modules/item-management/query/getTaxonomyNodeAssignments.generated.ts +5 -0
  152. package/src/modules/item-management/query/getTaxonomyNodeAssignments.test.ts +25 -0
  153. package/src/modules/item-management/query/getTaxonomyNodeAssignments.ts +16 -0
  154. package/src/modules/item-management/query/getTaxonomyNodeChildren.generated.ts +5 -0
  155. package/src/modules/item-management/query/getTaxonomyNodeChildren.test.ts +34 -0
  156. package/src/modules/item-management/query/getTaxonomyNodeChildren.ts +16 -0
  157. package/src/modules/item-management/tailor.config.ts +11 -0
  158. package/src/modules/item-management/testing/fixtures.ts +81 -0
  159. package/src/modules/primitives/command/activateCategory.generated.ts +6 -0
  160. package/src/modules/primitives/command/activateCategory.test.ts +11 -29
  161. package/src/modules/primitives/command/activateCategory.ts +27 -34
  162. package/src/modules/primitives/command/activateCurrency.generated.ts +6 -0
  163. package/src/modules/primitives/command/activateCurrency.test.ts +11 -29
  164. package/src/modules/primitives/command/activateCurrency.ts +27 -34
  165. package/src/modules/primitives/command/activateUnit.generated.ts +6 -0
  166. package/src/modules/primitives/command/activateUnit.test.ts +11 -15
  167. package/src/modules/primitives/command/activateUnit.ts +27 -34
  168. package/src/modules/primitives/command/createCategory.generated.ts +6 -0
  169. package/src/modules/primitives/command/createCategory.test.ts +27 -39
  170. package/src/modules/primitives/command/createCategory.ts +53 -62
  171. package/src/modules/primitives/command/createCurrency.generated.ts +6 -0
  172. package/src/modules/primitives/command/createCurrency.test.ts +78 -71
  173. package/src/modules/primitives/command/createCurrency.ts +43 -48
  174. package/src/modules/primitives/command/createExchangeRate.generated.ts +6 -0
  175. package/src/modules/primitives/command/createExchangeRate.test.ts +101 -100
  176. package/src/modules/primitives/command/createExchangeRate.ts +50 -59
  177. package/src/modules/primitives/command/createUnit.generated.ts +6 -0
  178. package/src/modules/primitives/command/createUnit.test.ts +92 -95
  179. package/src/modules/primitives/command/createUnit.ts +54 -57
  180. package/src/modules/primitives/command/deactivateCategory.generated.ts +6 -0
  181. package/src/modules/primitives/command/deactivateCategory.test.ts +27 -28
  182. package/src/modules/primitives/command/deactivateCategory.ts +43 -50
  183. package/src/modules/primitives/command/deactivateCurrency.generated.ts +6 -0
  184. package/src/modules/primitives/command/deactivateCurrency.test.ts +23 -38
  185. package/src/modules/primitives/command/deactivateCurrency.ts +31 -38
  186. package/src/modules/primitives/command/deactivateUnit.generated.ts +6 -0
  187. package/src/modules/primitives/command/deactivateUnit.test.ts +27 -23
  188. package/src/modules/primitives/command/deactivateUnit.ts +39 -49
  189. package/src/modules/primitives/command/setBaseCurrency.generated.ts +6 -0
  190. package/src/modules/primitives/command/setBaseCurrency.test.ts +40 -33
  191. package/src/modules/primitives/command/setBaseCurrency.ts +43 -50
  192. package/src/modules/primitives/command/setReferenceUnit.generated.ts +6 -0
  193. package/src/modules/primitives/command/setReferenceUnit.test.ts +39 -35
  194. package/src/modules/primitives/command/setReferenceUnit.ts +46 -59
  195. package/src/modules/primitives/db/unit.ts +13 -3
  196. package/src/modules/primitives/docs/commands/ActivateCategory.md +1 -2
  197. package/src/modules/primitives/docs/commands/ActivateCurrency.md +1 -2
  198. package/src/modules/primitives/docs/commands/ActivateUnit.md +1 -2
  199. package/src/modules/primitives/docs/commands/CreateCategory.md +1 -4
  200. package/src/modules/primitives/docs/commands/CreateCurrency.md +3 -4
  201. package/src/modules/primitives/docs/commands/CreateExchangeRate.md +4 -5
  202. package/src/modules/primitives/docs/commands/CreateUnit.md +5 -5
  203. package/src/modules/primitives/docs/commands/DeactivateCategory.md +2 -3
  204. package/src/modules/primitives/docs/commands/DeactivateCurrency.md +2 -3
  205. package/src/modules/primitives/docs/commands/DeactivateUnit.md +2 -3
  206. package/src/modules/primitives/docs/commands/SetBaseCurrency.md +2 -3
  207. package/src/modules/primitives/docs/commands/SetReferenceUnit.md +2 -3
  208. package/src/modules/primitives/docs/queries/ConvertAmount.md +3 -5
  209. package/src/modules/primitives/docs/queries/ConvertQuantity.md +3 -5
  210. package/src/modules/primitives/docs/queries/GetBaseCurrency.md +32 -0
  211. package/src/modules/primitives/docs/queries/GetCurrency.md +36 -0
  212. package/src/modules/primitives/docs/queries/GetUnit.md +36 -0
  213. package/src/modules/primitives/docs/queries/GetUoMCategory.md +36 -0
  214. package/src/modules/primitives/docs/queries/ListUnitsByCategory.md +26 -0
  215. package/src/modules/primitives/generated/kysely-tailordb.ts +24 -45
  216. package/src/modules/primitives/index.ts +15 -4
  217. package/src/modules/primitives/lib/errors.generated.ts +112 -0
  218. package/src/modules/primitives/{permissions.ts → lib/permissions.generated.ts} +9 -8
  219. package/src/modules/primitives/module.ts +37 -27
  220. package/src/modules/primitives/query/convertAmount.generated.ts +5 -0
  221. package/src/modules/primitives/query/convertAmount.test.ts +2 -2
  222. package/src/modules/primitives/query/convertAmount.ts +27 -28
  223. package/src/modules/primitives/query/convertQuantity.generated.ts +5 -0
  224. package/src/modules/primitives/query/convertQuantity.test.ts +6 -2
  225. package/src/modules/primitives/query/convertQuantity.ts +49 -57
  226. package/src/modules/primitives/query/getBaseCurrency.generated.ts +5 -0
  227. package/src/modules/primitives/query/getBaseCurrency.test.ts +28 -0
  228. package/src/modules/primitives/query/getBaseCurrency.ts +16 -0
  229. package/src/modules/primitives/query/getCurrency.generated.ts +5 -0
  230. package/src/modules/primitives/query/getCurrency.test.ts +47 -0
  231. package/src/modules/primitives/query/getCurrency.ts +18 -0
  232. package/src/modules/primitives/query/getUnit.generated.ts +5 -0
  233. package/src/modules/primitives/query/getUnit.test.ts +47 -0
  234. package/src/modules/primitives/query/getUnit.ts +18 -0
  235. package/src/modules/primitives/query/getUoMCategory.generated.ts +5 -0
  236. package/src/modules/primitives/query/getUoMCategory.test.ts +47 -0
  237. package/src/modules/primitives/query/getUoMCategory.ts +18 -0
  238. package/src/modules/primitives/query/listUnitsByCategory.generated.ts +5 -0
  239. package/src/modules/primitives/query/listUnitsByCategory.ts +16 -0
  240. package/src/modules/primitives/tailor.config.ts +3 -3
  241. package/src/modules/shared/defineCommand.test.ts +23 -10
  242. package/src/modules/shared/defineCommand.ts +23 -10
  243. package/src/modules/shared/internal.ts +1 -0
  244. package/src/modules/shared/requirePermission.test.ts +22 -21
  245. package/src/modules/shared/requirePermission.ts +8 -2
  246. package/src/modules/shared/result.ts +12 -0
  247. package/src/modules/testing/index.ts +36 -11
  248. package/src/modules/user-management/command/activateUser.generated.ts +6 -0
  249. package/src/modules/user-management/command/activateUser.test.ts +27 -27
  250. package/src/modules/user-management/command/activateUser.ts +40 -48
  251. package/src/modules/user-management/command/assignPermissionToRole.generated.ts +6 -0
  252. package/src/modules/user-management/command/assignPermissionToRole.test.ts +42 -43
  253. package/src/modules/user-management/command/assignPermissionToRole.ts +59 -62
  254. package/src/modules/user-management/command/assignRoleToUser.generated.ts +6 -0
  255. package/src/modules/user-management/command/assignRoleToUser.test.ts +70 -63
  256. package/src/modules/user-management/command/assignRoleToUser.ts +63 -66
  257. package/src/modules/user-management/command/createPermission.generated.ts +6 -0
  258. package/src/modules/user-management/command/createPermission.test.ts +45 -38
  259. package/src/modules/user-management/command/createPermission.ts +42 -46
  260. package/src/modules/user-management/command/createRole.generated.ts +6 -0
  261. package/src/modules/user-management/command/createRole.test.ts +30 -29
  262. package/src/modules/user-management/command/createRole.ts +33 -33
  263. package/src/modules/user-management/command/createUser.generated.ts +6 -0
  264. package/src/modules/user-management/command/createUser.test.ts +64 -42
  265. package/src/modules/user-management/command/createUser.ts +54 -56
  266. package/src/modules/user-management/command/deactivateUser.generated.ts +6 -0
  267. package/src/modules/user-management/command/deactivateUser.test.ts +27 -27
  268. package/src/modules/user-management/command/deactivateUser.ts +40 -48
  269. package/src/modules/user-management/command/logAuditEvent.generated.ts +6 -0
  270. package/src/modules/user-management/command/logAuditEvent.test.ts +50 -42
  271. package/src/modules/user-management/command/logAuditEvent.ts +25 -28
  272. package/src/modules/user-management/command/reactivateUser.generated.ts +6 -0
  273. package/src/modules/user-management/command/reactivateUser.test.ts +31 -27
  274. package/src/modules/user-management/command/reactivateUser.ts +40 -48
  275. package/src/modules/user-management/command/revokePermissionFromRole.generated.ts +6 -0
  276. package/src/modules/user-management/command/revokePermissionFromRole.test.ts +52 -51
  277. package/src/modules/user-management/command/revokePermissionFromRole.ts +60 -57
  278. package/src/modules/user-management/command/revokeRoleFromUser.generated.ts +6 -0
  279. package/src/modules/user-management/command/revokeRoleFromUser.test.ts +53 -48
  280. package/src/modules/user-management/command/revokeRoleFromUser.ts +58 -57
  281. package/src/modules/user-management/docs/commands/CreatePermission.md +2 -2
  282. package/src/modules/user-management/docs/commands/CreateRole.md +1 -1
  283. package/src/modules/user-management/generated/enums.ts +11 -11
  284. package/src/modules/user-management/generated/kysely-tailordb.ts +27 -56
  285. package/src/modules/user-management/index.ts +2 -2
  286. package/src/modules/user-management/lib/errors.generated.ts +67 -0
  287. package/src/modules/user-management/{permissions.ts → lib/permissions.generated.ts} +8 -7
  288. package/src/modules/user-management/module.ts +22 -22
  289. package/src/modules/user-management/tailor.config.ts +3 -3
  290. package/src/schemas.ts +1 -1
  291. package/skills/1-module-docs/references/structure.md +0 -22
  292. package/skills/2-module-feature-breakdown/references/commands.md +0 -48
  293. package/skills/2-module-feature-breakdown/references/structure.md +0 -22
  294. package/skills/3-module-doc-review/references/commands.md +0 -54
  295. package/skills/3-module-doc-review/references/models.md +0 -29
  296. package/skills/4-module-tdd-implementation/SKILL.md +0 -74
  297. package/skills/4-module-tdd-implementation/references/commands.md +0 -45
  298. package/skills/4-module-tdd-implementation/references/errors.md +0 -7
  299. package/skills/4-module-tdd-implementation/references/models.md +0 -30
  300. package/skills/4-module-tdd-implementation/references/structure.md +0 -22
  301. package/skills/4-module-tdd-implementation/references/testing.md +0 -37
  302. package/skills/5-module-implementation-review/references/commands.md +0 -45
  303. package/skills/5-module-implementation-review/references/errors.md +0 -7
  304. package/skills/5-module-implementation-review/references/exports.md +0 -8
  305. package/skills/5-module-implementation-review/references/models.md +0 -30
  306. package/src/modules/primitives/lib/errors.ts +0 -138
  307. package/src/modules/user-management/lib/errors.ts +0 -81
  308. /package/skills/{app-compose-1-requirement-analysis → erp-kit-app-1-requirements}/references/structure.md +0 -0
  309. /package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/references/screen-detailview.md +0 -0
  310. /package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/references/screen-form.md +0 -0
  311. /package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/references/screen-listview.md +0 -0
  312. /package/skills/{app-compose-2-requirements-breakdown → erp-kit-app-2-breakdown}/references/structure.md +0 -0
  313. /package/skills/{app-compose-3-doc-review → erp-kit-app-3-doc-review}/references/structure.md +0 -0
  314. /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/component.md +0 -0
  315. /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/screen-detailview.md +0 -0
  316. /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/screen-form.md +0 -0
  317. /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/screen-listview.md +0 -0
  318. /package/skills/{app-compose-4-design-mock → erp-kit-app-4-design}/references/structure.md +0 -0
  319. /package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/references/component.md +0 -0
  320. /package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/references/screen-detailview.md +0 -0
  321. /package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/references/screen-form.md +0 -0
  322. /package/skills/{app-compose-5-design-mock-review → erp-kit-app-5-design-review}/references/screen-listview.md +0 -0
  323. /package/skills/{app-compose-6-implementation-spec → erp-kit-app-6-impl-spec}/references/auth.md +0 -0
  324. /package/skills/{app-compose-6-implementation-spec → erp-kit-app-6-impl-spec}/references/structure.md +0 -0
  325. /package/skills/{2-module-feature-breakdown → erp-kit-module-4-tdd}/references/models.md +0 -0
@@ -1,40 +1,28 @@
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": {
20
16
  AuditEvent: {
21
17
  id: Generated<string>;
22
- eventType:
23
- | "USER_CREATED"
24
- | "USER_ACTIVATED"
25
- | "USER_DEACTIVATED"
26
- | "USER_REACTIVATED"
27
- | "ROLE_ASSIGNED"
28
- | "ROLE_REVOKED"
29
- | "PERMISSION_ASSIGNED"
30
- | "PERMISSION_REVOKED";
18
+ eventType: "USER_CREATED" | "USER_ACTIVATED" | "USER_DEACTIVATED" | "USER_REACTIVATED" | "ROLE_ASSIGNED" | "ROLE_REVOKED" | "PERMISSION_ASSIGNED" | "PERMISSION_REVOKED";
31
19
  actorId: string;
32
20
  targetId: string | null;
33
21
  targetType: string | null;
34
22
  payload: string | null;
35
23
  createdAt: Generated<Timestamp>;
36
24
  updatedAt: Timestamp | null;
37
- };
25
+ }
38
26
 
39
27
  Permission: {
40
28
  id: Generated<string>;
@@ -42,7 +30,7 @@ export interface Namespace {
42
30
  description: string | null;
43
31
  createdAt: Generated<Timestamp>;
44
32
  updatedAt: Timestamp | null;
45
- };
33
+ }
46
34
 
47
35
  Role: {
48
36
  id: Generated<string>;
@@ -50,7 +38,7 @@ export interface Namespace {
50
38
  description: string | null;
51
39
  createdAt: Generated<Timestamp>;
52
40
  updatedAt: Timestamp | null;
53
- };
41
+ }
54
42
 
55
43
  RolePermission: {
56
44
  id: Generated<string>;
@@ -58,7 +46,7 @@ export interface Namespace {
58
46
  permissionId: string;
59
47
  createdAt: Generated<Timestamp>;
60
48
  updatedAt: Timestamp | null;
61
- };
49
+ }
62
50
 
63
51
  User: {
64
52
  id: Generated<string>;
@@ -68,7 +56,7 @@ export interface Namespace {
68
56
  permissions: string[] | null;
69
57
  createdAt: Generated<Timestamp>;
70
58
  updatedAt: Timestamp | null;
71
- };
59
+ }
72
60
 
73
61
  UserRole: {
74
62
  id: Generated<string>;
@@ -76,37 +64,20 @@ export interface Namespace {
76
64
  roleId: string;
77
65
  createdAt: Generated<Timestamp>;
78
66
  updatedAt: Timestamp | null;
79
- };
80
- };
67
+ }
68
+ }
81
69
  }
82
70
 
83
- export function getDB<const N extends keyof Namespace>(
84
- namespace: N,
85
- kyselyConfig?: Omit<KyselyConfig, "dialect">,
86
- ): Kysely<Namespace[N]> {
87
- const client = new tailordb.Client({ namespace });
88
- return new Kysely<Namespace[N]>({
89
- dialect: new TailordbDialect(client),
90
- ...kyselyConfig,
91
- });
92
- }
71
+ export const getDB = createGetDB<Namespace>();
93
72
 
94
- export type DB<N extends keyof Namespace = keyof Namespace> = ReturnType<typeof getDB<N>>;
73
+ export type DB<N extends keyof Namespace = keyof Namespace> = NamespaceDB<Namespace, N>;
95
74
 
96
75
  export type Transaction<K extends keyof Namespace | DB = keyof Namespace> =
97
- K extends DB<infer N>
98
- ? KyselyTransaction<Namespace[N]>
99
- : K extends keyof Namespace
100
- ? KyselyTransaction<Namespace[K]>
101
- : never;
76
+ NamespaceTransaction<Namespace, K>;
102
77
 
103
- type TableName = {
104
- [N in keyof Namespace]: keyof Namespace[N];
105
- }[keyof Namespace];
106
- export type Table<T extends TableName> = {
107
- [N in keyof Namespace]: T extends keyof Namespace[N] ? Namespace[N][T] : never;
108
- }[keyof Namespace];
78
+ type TableName = NamespaceTableName<Namespace>;
79
+ export type Table<T extends TableName> = NamespaceTable<Namespace, T>;
109
80
 
110
- export type Insertable<T extends keyof Namespace[keyof Namespace]> = KyselyInsertable<Table<T>>;
111
- export type Selectable<T extends keyof Namespace[keyof Namespace]> = KyselySelectable<Table<T>>;
112
- export type Updateable<T extends keyof Namespace[keyof Namespace]> = KyselyUpdateable<Table<T>>;
81
+ export type Insertable<T extends TableName> = NamespaceInsertable<Namespace, T>;
82
+ export type Selectable<T extends TableName> = NamespaceSelectable<Namespace, T>;
83
+ export type Updateable<T extends TableName> = NamespaceUpdateable<Namespace, T>;
@@ -1,5 +1,5 @@
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
  // generated types
5
5
  export { AuditEventEventType, UserStatus } from "./generated/enums";
@@ -19,7 +19,7 @@ export {
19
19
  DuplicateRoleNameError,
20
20
  AssignmentNotFoundError,
21
21
  InvalidEventTypeError,
22
- } from "./lib/errors";
22
+ } from "./lib/errors.generated";
23
23
 
24
24
  // input types
25
25
  export { type ActivateUserInput } from "./command/activateUser";
@@ -0,0 +1,67 @@
1
+ // @generated — do not edit
2
+ import { createDomainError } from "../../shared/internal";
3
+
4
+ export const UserNotFoundError = createDomainError(
5
+ "UserNotFoundError", "USER_NOT_FOUND",
6
+ (identifier: string) => `User ID does not exist in the system - return not found error with the provided ID: ${identifier}`,
7
+ );
8
+
9
+ export const InvalidStatusTransitionError = createDomainError(
10
+ "InvalidStatusTransitionError", "INVALID_STATUS_TRANSITION",
11
+ (identifier: string) => `User is not in PENDING status (already ACTIVE or INACTIVE) - return error with current status and valid transitions: ${identifier}`,
12
+ );
13
+
14
+ export const RoleNotFoundError = createDomainError(
15
+ "RoleNotFoundError", "ROLE_NOT_FOUND",
16
+ (identifier: string) => `Role ID does not exist in the system - return not found error with the provided role ID: ${identifier}`,
17
+ );
18
+
19
+ export const PermissionNotFoundError = createDomainError(
20
+ "PermissionNotFoundError", "PERMISSION_NOT_FOUND",
21
+ (identifier: string) => `Permission ID does not exist in the system - return not found error with the provided permission ID: ${identifier}`,
22
+ );
23
+
24
+ export const UserNotActiveError = createDomainError(
25
+ "UserNotActiveError", "USER_NOT_ACTIVE",
26
+ (identifier: string) => `User is in PENDING or INACTIVE status - return error indicating only ACTIVE users can receive role assignments: ${identifier}`,
27
+ );
28
+
29
+ export const InvalidPermissionKeyFormatError = createDomainError(
30
+ "InvalidPermissionKeyFormatError", "INVALID_PERMISSION_KEY_FORMAT",
31
+ (identifier: string) => `Key does not match resource:action pattern: ${identifier}`,
32
+ );
33
+
34
+ export const DuplicatePermissionKeyError = createDomainError(
35
+ "DuplicatePermissionKeyError", "DUPLICATE_PERMISSION_KEY",
36
+ (identifier: string) => `Permission with the same key already exists: ${identifier}`,
37
+ );
38
+
39
+ export const MissingRequiredFieldError = createDomainError(
40
+ "MissingRequiredFieldError", "MISSING_REQUIRED_FIELD",
41
+ (identifier: string) => `Role name not provided - return validation error indicating name is required: ${identifier}`,
42
+ );
43
+
44
+ export const DuplicateRoleNameError = createDomainError(
45
+ "DuplicateRoleNameError", "DUPLICATE_ROLE_NAME",
46
+ (identifier: string) => `Role with the same name already exists: ${identifier}`,
47
+ );
48
+
49
+ export const UserAlreadyExistsError = createDomainError(
50
+ "UserAlreadyExistsError", "USER_ALREADY_EXISTS",
51
+ (identifier: string) => `Email address is already registered in the system - return conflict error with message indicating email is taken: ${identifier}`,
52
+ );
53
+
54
+ export const InvalidEmailError = createDomainError(
55
+ "InvalidEmailError", "INVALID_EMAIL",
56
+ (identifier: string) => `Email does not follow valid email format - return validation error with format requirements: ${identifier}`,
57
+ );
58
+
59
+ export const InvalidEventTypeError = createDomainError(
60
+ "InvalidEventTypeError", "INVALID_EVENT_TYPE",
61
+ (identifier: string) => `Event type is not one of the recognized types - return validation error with list of valid event types: ${identifier}`,
62
+ );
63
+
64
+ export const AssignmentNotFoundError = createDomainError(
65
+ "AssignmentNotFoundError", "ASSIGNMENT_NOT_FOUND",
66
+ (identifier: string) => `Role does not have this permission assigned - return not found error indicating the association does not exist: ${identifier}`,
67
+ );
@@ -1,15 +1,16 @@
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("user-management", [
4
- "createUser",
5
5
  "activateUser",
6
- "deactivateUser",
7
- "reactivateUser",
6
+ "assignPermissionToRole",
7
+ "assignRoleToUser",
8
8
  "createPermission",
9
9
  "createRole",
10
- "assignPermissionToRole",
10
+ "createUser",
11
+ "deactivateUser",
12
+ "logAuditEvent",
13
+ "reactivateUser",
11
14
  "revokePermissionFromRole",
12
- "assignRoleToUser",
13
15
  "revokeRoleFromUser",
14
- "logAuditEvent",
15
16
  ] as const);
@@ -1,16 +1,16 @@
1
1
  import { type TailorAnyDBField } from "@tailor-platform/sdk";
2
2
  import { type EmptyFields, type FieldsToInsertable } from "../shared/internal";
3
- import { makeCreateUser } from "./command/createUser";
4
- import { makeCreateRole } from "./command/createRole";
5
- import { makeCreatePermission } from "./command/createPermission";
6
- import { activateUser } from "./command/activateUser";
7
- import { deactivateUser } from "./command/deactivateUser";
8
- import { reactivateUser } from "./command/reactivateUser";
9
- import { assignPermissionToRole } from "./command/assignPermissionToRole";
10
- import { revokePermissionFromRole } from "./command/revokePermissionFromRole";
11
- import { assignRoleToUser } from "./command/assignRoleToUser";
12
- import { revokeRoleFromUser } from "./command/revokeRoleFromUser";
13
- import { logAuditEvent } from "./command/logAuditEvent";
3
+ import { createUser } from "./command/createUser.generated";
4
+ import { createRole } from "./command/createRole.generated";
5
+ import { createPermission } from "./command/createPermission.generated";
6
+ import { activateUser } from "./command/activateUser.generated";
7
+ import { deactivateUser } from "./command/deactivateUser.generated";
8
+ import { reactivateUser } from "./command/reactivateUser.generated";
9
+ import { assignPermissionToRole } from "./command/assignPermissionToRole.generated";
10
+ import { revokePermissionFromRole } from "./command/revokePermissionFromRole.generated";
11
+ import { assignRoleToUser } from "./command/assignRoleToUser.generated";
12
+ import { revokeRoleFromUser } from "./command/revokeRoleFromUser.generated";
13
+ import { logAuditEvent } from "./command/logAuditEvent.generated";
14
14
  import { createAuditEventType, CreateAuditEventTypeParams } from "./db/auditEvent";
15
15
  import { createPermissionType, CreatePermissionTypeParams } from "./db/permission";
16
16
  import { createRoleType, CreateRoleTypeParams } from "./db/role";
@@ -61,17 +61,17 @@ export const defineModule = <
61
61
  db: { user, permission, role, userRole, rolePermission, auditEvent },
62
62
  executors: { rolePermissionCreated, rolePermissionDeleted },
63
63
  commands: {
64
- createUser: makeCreateUser<FieldsToInsertable<UF>>(),
65
- createRole: makeCreateRole<FieldsToInsertable<RF>>(),
66
- createPermission: makeCreatePermission<FieldsToInsertable<PF>>(),
67
- activateUser,
68
- deactivateUser,
69
- reactivateUser,
70
- assignPermissionToRole,
71
- revokePermissionFromRole,
72
- assignRoleToUser,
73
- revokeRoleFromUser,
74
- logAuditEvent,
64
+ createUser: createUser<FieldsToInsertable<UF>>(),
65
+ createRole: createRole<FieldsToInsertable<RF>>(),
66
+ createPermission: createPermission<FieldsToInsertable<PF>>(),
67
+ activateUser: activateUser(),
68
+ deactivateUser: deactivateUser(),
69
+ reactivateUser: reactivateUser(),
70
+ assignPermissionToRole: assignPermissionToRole(),
71
+ revokePermissionFromRole: revokePermissionFromRole(),
72
+ assignRoleToUser: assignRoleToUser(),
73
+ revokeRoleFromUser: revokeRoleFromUser(),
74
+ logAuditEvent: logAuditEvent(),
75
75
  },
76
76
  };
77
77
  };
@@ -2,10 +2,10 @@ import { defineConfig, defineGenerators } from "@tailor-platform/sdk";
2
2
 
3
3
  export default defineConfig({
4
4
  name: "user-management",
5
- db: { "main-db": { files: [`./src/db/*.ts`] } },
5
+ db: { "main-db": { files: [`./db/*.ts`] } },
6
6
  });
7
7
 
8
8
  export const generators = defineGenerators(
9
- ["@tailor-platform/kysely-type", { distPath: `./src/generated/kysely-tailordb.ts` }],
10
- ["@tailor-platform/enum-constants", { distPath: "./src/generated/enums.ts" }],
9
+ ["@tailor-platform/kysely-type", { distPath: `./generated/kysely-tailordb.ts` }],
10
+ ["@tailor-platform/enum-constants", { distPath: "./generated/enums.ts" }],
11
11
  );
package/src/schemas.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { PACKAGE_ROOT } from "./util.js";
2
+ import { PACKAGE_ROOT } from "./util";
3
3
 
4
4
  const SCHEMAS_ROOT = path.join(PACKAGE_ROOT, "schemas");
5
5
 
@@ -1,22 +0,0 @@
1
- # Module Directory Structure
2
-
3
- ```
4
- src/
5
- ├── db/ # Database models (one file per model)
6
- ├── executor/ # Async executors (record triggers, job functions)
7
- ├── command/ # Domain commands + tests (*.test.ts co-located)
8
- ├── lib/ # Internal shared code (errors.ts, types.ts)
9
- ├── testing/ # Test fixtures and helpers
10
- ├── generated/ # Auto-generated code (do not edit)
11
- ├── index.ts # Public exports
12
- └── module.ts # Module definition
13
- ```
14
-
15
- ## Rules
16
-
17
- - `db/`: Only documentable model definitions, no helpers
18
- - `executor/`: Async executors as factory functions (see executors.md)
19
- - `command/`: Domain commands + co-located tests, no utilities
20
- - `lib/`: Internal errors and types (not documented)
21
- - `testing/`: Fixtures for tests only
22
- - Run `pnpm generate` after modifying `db/` models
@@ -1,48 +0,0 @@
1
- # Command Implementation
2
-
3
- ## defineCommand Pattern
4
-
5
- Commands that don't need custom fields use `defineCommand` directly:
6
-
7
- ```typescript
8
- export const myCommand = defineCommand(permissions.myCommand, async (db: DB, input: Input) => { ... });
9
- ```
10
-
11
- ## Factory Function Pattern (custom fields)
12
-
13
- Commands that insert into a table with user-extensible fields use a `makeCreateX<CF>()` factory:
14
-
15
- - Export only `makeCreateX` — no default instance
16
- - Generic `CF extends Record<string, unknown>` for custom fields
17
- - Input type: `CreateXInput & CF`
18
- - Destructure known fields, rest-spread custom fields into `.values()` before known fields
19
- - Cast custom fields: `...(customFields as Record<string, unknown>)`
20
- - `module.ts` wires with `makeCreateX<FieldsToInsertable<F>>()`
21
-
22
- ## Implementation Considerations
23
-
24
- - **Validation**: Check referenced entities exist before operating
25
- - **Idempotency**: For assign/revoke, return existing instead of throwing
26
- - **Return format**: Wrap in object `{ entity }` not just `entity`
27
-
28
- ## Conventions
29
-
30
- - Input types: exported interfaces (`export interface MyFunctionInput`)
31
- - Use `.executeTakeFirst()` for single results
32
- - Include JSDoc: `/** Function: name \n Description */`
33
-
34
- ## State Transitions
35
-
36
- For commands that transition between statuses, accept `from?: string[]` with a default:
37
-
38
- ```typescript
39
- from?: string[]; // Default: ["ACTIVE"]
40
-
41
- const validFromStatuses = input.from ?? ["ACTIVE"];
42
- if (!validFromStatuses.includes(user.status)) {
43
- throw new InvalidStatusTransitionError(user.status, targetStatus);
44
- }
45
- ```
46
-
47
- - Default `from` contains the base valid source status
48
- - Parent modules can override to allow transitions from additional statuses
@@ -1,22 +0,0 @@
1
- # Module Directory Structure
2
-
3
- ```
4
- src/
5
- ├── db/ # Database models (one file per model)
6
- ├── executor/ # Async executors (record triggers, job functions)
7
- ├── command/ # Domain commands + tests (*.test.ts co-located)
8
- ├── lib/ # Internal shared code (errors.ts, types.ts)
9
- ├── testing/ # Test fixtures and helpers
10
- ├── generated/ # Auto-generated code (do not edit)
11
- ├── index.ts # Public exports
12
- └── module.ts # Module definition
13
- ```
14
-
15
- ## Rules
16
-
17
- - `db/`: Only documentable model definitions, no helpers
18
- - `executor/`: Async executors as factory functions (see executors.md)
19
- - `command/`: Domain commands + co-located tests, no utilities
20
- - `lib/`: Internal errors and types (not documented)
21
- - `testing/`: Fixtures for tests only
22
- - Run `pnpm generate` after modifying `db/` models
@@ -1,54 +0,0 @@
1
- ---
2
- paths:
3
- - "packages/erp-kit/src/modules/*/command/*.ts"
4
- - "!packages/erp-kit/src/modules/*/command/*.test.ts"
5
- ---
6
-
7
- # Command Implementation
8
-
9
- ## defineCommand Pattern
10
-
11
- Commands that don't need custom fields use `defineCommand` directly:
12
-
13
- ```typescript
14
- export const myCommand = defineCommand(permissions.myCommand, async (db: DB, input: Input) => { ... });
15
- ```
16
-
17
- ## Factory Function Pattern (custom fields)
18
-
19
- Commands that insert into a table with user-extensible fields use a `makeCreateX<CF>()` factory:
20
-
21
- - Export only `makeCreateX` — no default instance
22
- - Generic `CF extends Record<string, unknown>` for custom fields
23
- - Input type: `CreateXInput & CF`
24
- - Destructure known fields, rest-spread custom fields into `.values()` before known fields
25
- - Cast custom fields: `...(customFields as Record<string, unknown>)`
26
- - `module.ts` wires with `makeCreateX<FieldsToInsertable<F>>()`
27
-
28
- ## Implementation Considerations
29
-
30
- - **Validation**: Check referenced entities exist before operating
31
- - **Idempotency**: For assign/revoke, return existing instead of throwing
32
- - **Return format**: Wrap in object `{ entity }` not just `entity`
33
-
34
- ## Conventions
35
-
36
- - Input types: exported interfaces (`export interface MyFunctionInput`)
37
- - Use `.executeTakeFirst()` for single results
38
- - Include JSDoc: `/** Function: name \n Description */`
39
-
40
- ## State Transitions
41
-
42
- For commands that transition between statuses, accept `from?: string[]` with a default:
43
-
44
- ```typescript
45
- from?: string[]; // Default: ["ACTIVE"]
46
-
47
- const validFromStatuses = input.from ?? ["ACTIVE"];
48
- if (!validFromStatuses.includes(user.status)) {
49
- throw new InvalidStatusTransitionError(user.status, targetStatus);
50
- }
51
- ```
52
-
53
- - Default `from` contains the base valid source status
54
- - Parent modules can override to allow transitions from additional statuses
@@ -1,29 +0,0 @@
1
- # Database Models
2
-
3
- ## Factory Function Pattern
4
-
5
- Each model is a `createXType<const F>(params)` factory:
6
-
7
- - Params interface generic: `F extends Record<string, TailorAnyDBField>`
8
- - `fields?: F` — optional custom fields from parent modules
9
- - Spread as `...(params.fields ?? {}) as F` to preserve type information
10
- - Include `...db.fields.timestamps()`
11
- - Use `.description()` for field docs
12
- - Apply permissions at model level
13
- - Export a default instance: `export const x = createXType({})`
14
-
15
- ## Stateful Model Enums
16
-
17
- Status enums are tied to the module's state machine. Base module defines core statuses; parent callers can only **extend, not replace**.
18
-
19
- ```typescript
20
- // Good: extension only
21
- const BASE_STATUSES = ["PENDING", "ACTIVE", "INACTIVE"] as const;
22
- const statuses = [...BASE_STATUSES, ...(params.additionalStatuses ?? [])];
23
-
24
- // Bad: allows replacement
25
- const statuses = params.statuses ?? ["PENDING", "ACTIVE", "INACTIVE"];
26
- ```
27
-
28
- - Name parameter `additionalX` to signal extension-only
29
- - Parent modules handle their additional status transitions
@@ -1,74 +0,0 @@
1
- ---
2
- name: 4-module-tdd-implementation
3
- description: Use when implementing features in any module under modules/. Triggers on TDD workflow, domain command implementation, adding new database models, creating test fixtures, or implementing business logic commands.
4
- ---
5
-
6
- # TDD Implementation for Module Development
7
-
8
- Guide for implementing features in modules using Test-Driven Development.
9
-
10
- ## When to Use
11
-
12
- - Implementing new domain commands in any module
13
- - Adding database models with `@tailor-platform/sdk`
14
- - Creating tests with `@tailor-platform/erp-kit` testing utilities
15
- - Implementing business logic (CRUD, state transitions, relationships)
16
-
17
- ## Workflow
18
-
19
- ```
20
- MODELS → ERRORS → FIXTURES → TESTS → IMPLEMENT → EXPORT → VERIFY
21
- ```
22
-
23
- ## Step-by-Step
24
-
25
- ### 1. Database Models (`src/db/`)
26
-
27
- **Read [models rules](references/models.md) and [db-relations rules](references/db-relations.md) before writing any model.**
28
-
29
- Key patterns: factory function, `db.fields.timestamps()`, `.description()` on fields, `.relation()` for foreign keys.
30
-
31
- ### 2. Error Classes (`src/lib/errors.ts`)
32
-
33
- **Read [errors rules](references/errors.md) before defining errors.**
34
-
35
- Key patterns: `name` as const = class name, `code` as const = SCREAMING_SNAKE_CASE.
36
-
37
- ### 3. Test Fixtures (`src/testing/fixtures.ts`)
38
-
39
- **Read [testing rules](references/testing.md) before writing fixtures or tests.**
40
-
41
- ### 4. Write Tests First (`src/command/*.test.ts`)
42
-
43
- Same reference: [testing rules](references/testing.md).
44
-
45
- Key patterns: `createMockDb<DB>()`, fixed IDs `"entity-1"`, cover all doc branches.
46
-
47
- ### 5. Implement Commands (`src/command/*.ts`)
48
-
49
- **Read [commands rules](references/commands.md) before implementing.**
50
-
51
- Key patterns: dual function (`_fn` internal + `fn<T>` public), validate → query → mutate.
52
-
53
- ### 6. Export (`src/index.ts`)
54
-
55
- **Read [exports rules](references/exports.md) for export order.**
56
-
57
- ### 7. Verify
58
-
59
- ```bash
60
- pnpm generate # Regenerate types if models changed
61
- pnpm lint # Check code style
62
- pnpm typecheck # Verify TypeScript types
63
- pnpm test # Run all tests
64
- ```
65
-
66
- ## References
67
-
68
- - [Module structure](references/structure.md)
69
- - [Model patterns](references/models.md)
70
- - [Database relations](references/db-relations.md)
71
- - [Command patterns](references/commands.md)
72
- - [Error patterns](references/errors.md)
73
- - [Testing patterns](references/testing.md)
74
- - [Export order](references/exports.md)
@@ -1,45 +0,0 @@
1
- # Command Implementation
2
-
3
- ## Dual Function Pattern
4
-
5
- Two functions per operation: internal `_fn` and public `fn`.
6
-
7
- **Internal function (`_myFunction`):**
8
-
9
- - Takes concrete `DB` type from `generated/kysely-tailordb`
10
- - Return type uses `Schema` from `lib/types`: `Promise<{ entity: Entity<Schema> }>`
11
- - Contains actual implementation
12
-
13
- **Public function (`myFunction`):**
14
-
15
- - Generic signature: `<T extends { Entity: object }>(db: Kysely<T>, ...)`
16
- - Return type uses generic `T`: `Promise<{ entity: Entity<T> }>`
17
- - Delegates to internal with type casting: `_fn(db as unknown as DB, ...) as unknown as Result`
18
-
19
- ## Implementation Considerations
20
-
21
- - **Validation**: Check referenced entities exist before operating
22
- - **Idempotency**: For assign/revoke, return existing instead of throwing
23
- - **Return format**: Wrap in object `{ entity }` not just `entity`
24
-
25
- ## Conventions
26
-
27
- - Input types: exported interfaces (`export interface MyFunctionInput`)
28
- - Use `.executeTakeFirst()` for single results
29
- - Include JSDoc: `/** Function: name \n Description */`
30
-
31
- ## State Transitions
32
-
33
- For commands that transition between statuses, accept `from?: string[]` with a default:
34
-
35
- ```typescript
36
- from?: string[]; // Default: ["ACTIVE"]
37
-
38
- const validFromStatuses = input.from ?? ["ACTIVE"];
39
- if (!validFromStatuses.includes(user.status)) {
40
- throw new InvalidStatusTransitionError(user.status, targetStatus);
41
- }
42
- ```
43
-
44
- - Default `from` contains the base valid source status
45
- - Parent modules can override to allow transitions from additional statuses
@@ -1,7 +0,0 @@
1
- # Error Classes
2
-
3
- Naming convention:
4
-
5
- - `name`: Class name exactly, `as const`
6
- - `code`: SCREAMING_SNAKE_CASE, `as const`
7
- - Constructor includes context (IDs, values)
@@ -1,30 +0,0 @@
1
- # Database Models
2
-
3
- ## Factory Function Pattern
4
-
5
- ```typescript
6
- export function createEntityType(params: {
7
- fields?: Record<string, unknown>;
8
- additionalStatuses?: string[];
9
- });
10
- ```
11
-
12
- - Include `...db.fields.timestamps()`
13
- - Use `.description()` for field docs
14
- - Apply permissions at model level
15
-
16
- ## Stateful Model Enums
17
-
18
- Status enums are tied to the module's state machine. Base module defines core statuses; parent callers can only **extend, not replace**.
19
-
20
- ```typescript
21
- // Good: extension only
22
- const BASE_STATUSES = ["PENDING", "ACTIVE", "INACTIVE"] as const;
23
- const statuses = [...BASE_STATUSES, ...(params.additionalStatuses ?? [])];
24
-
25
- // Bad: allows replacement
26
- const statuses = params.statuses ?? ["PENDING", "ACTIVE", "INACTIVE"];
27
- ```
28
-
29
- - Name parameter `additionalX` to signal extension-only
30
- - Parent modules handle their additional status transitions