@tailor-platform/erp-kit 0.2.0 → 0.2.2

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 (637) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +3 -26
  3. package/dist/cli.mjs +1613 -0
  4. package/package.json +14 -13
  5. package/schemas/app-compose/business-flow.yml +3 -0
  6. package/schemas/app-compose/story.yml +13 -1
  7. package/schemas/module/command.yml +9 -0
  8. package/schemas/module/module.yml +4 -0
  9. package/schemas/module/query.yml +9 -0
  10. package/skills/erp-kit-app-1-requirements/SKILL.md +8 -14
  11. package/skills/erp-kit-app-2-requirements-review/SKILL.md +102 -0
  12. package/skills/erp-kit-app-2-requirements-review/references/best-practices-check.md +66 -0
  13. package/skills/erp-kit-app-2-requirements-review/references/boundary-consistency-check.md +69 -0
  14. package/skills/erp-kit-app-2-requirements-review/references/requirements-report-format.md +25 -0
  15. package/skills/erp-kit-app-3-plan/SKILL.md +157 -0
  16. package/skills/erp-kit-app-3-plan/references/resolver-extraction.md +107 -0
  17. package/skills/erp-kit-app-3-plan/references/screen-extraction.md +74 -0
  18. package/skills/erp-kit-app-3-plan/references/story-extraction.md +86 -0
  19. package/skills/erp-kit-app-4-plan-review/SKILL.md +177 -0
  20. package/skills/erp-kit-app-4-plan-review/references/actor-flow-parity.md +73 -0
  21. package/skills/erp-kit-app-4-plan-review/references/business-flow-story-parity.md +86 -0
  22. package/skills/erp-kit-app-4-plan-review/references/orphan-detection.md +69 -0
  23. package/skills/erp-kit-app-4-plan-review/references/parity-report-format.md +52 -0
  24. package/skills/erp-kit-app-4-plan-review/references/story-resolver-parity.md +83 -0
  25. package/skills/erp-kit-app-4-plan-review/references/story-screen-parity.md +73 -0
  26. package/skills/erp-kit-app-5-impl-backend/SKILL.md +105 -0
  27. package/skills/erp-kit-app-5-impl-backend/references/app-config.md +38 -0
  28. package/skills/erp-kit-app-5-impl-backend/references/module-wiring.md +48 -0
  29. package/skills/erp-kit-app-5-impl-backend/references/resolver-patterns.md +68 -0
  30. package/skills/erp-kit-app-6-impl-frontend/SKILL.md +74 -0
  31. package/skills/erp-kit-app-6-impl-frontend/references/pages.md +160 -0
  32. package/skills/erp-kit-app-7-impl-review/SKILL.md +176 -0
  33. package/skills/erp-kit-app-7-impl-review/references/impl-parity-report-format.md +52 -0
  34. package/skills/erp-kit-app-7-impl-review/references/module-wiring-parity.md +84 -0
  35. package/skills/erp-kit-app-7-impl-review/references/resolver-doc-code-parity.md +86 -0
  36. package/skills/erp-kit-app-7-impl-review/references/screen-doc-code-parity.md +86 -0
  37. package/skills/erp-kit-module-1-requirements/SKILL.md +126 -0
  38. package/skills/erp-kit-module-1-requirements/references/boundary-analysis.md +51 -0
  39. package/skills/erp-kit-module-1-requirements/references/erp-research.md +57 -0
  40. package/skills/erp-kit-module-1-requirements/references/feature-doc.md +61 -0
  41. package/skills/erp-kit-module-2-requirements-review/SKILL.md +112 -0
  42. package/skills/erp-kit-module-2-requirements-review/references/best-practices-check.md +79 -0
  43. package/skills/erp-kit-module-2-requirements-review/references/boundary-consistency-check.md +70 -0
  44. package/skills/erp-kit-module-2-requirements-review/references/requirements-report-format.md +25 -0
  45. package/skills/erp-kit-module-3-plan/SKILL.md +107 -0
  46. package/skills/erp-kit-module-3-plan/references/command-extraction.md +87 -0
  47. package/skills/erp-kit-module-3-plan/references/model-extraction.md +72 -0
  48. package/skills/erp-kit-module-3-plan/references/query-extraction.md +59 -0
  49. package/skills/erp-kit-module-4-plan-review/SKILL.md +158 -0
  50. package/skills/erp-kit-module-4-plan-review/references/command-model-consistency.md +46 -0
  51. package/skills/erp-kit-module-4-plan-review/references/feature-command-parity.md +97 -0
  52. package/skills/erp-kit-module-4-plan-review/references/feature-model-parity.md +47 -0
  53. package/skills/erp-kit-module-4-plan-review/references/feature-query-parity.md +70 -0
  54. package/skills/erp-kit-module-4-plan-review/references/parity-report-format.md +52 -0
  55. package/skills/erp-kit-module-5-impl/SKILL.md +118 -0
  56. package/skills/erp-kit-module-5-impl/references/command-impl.md +68 -0
  57. package/skills/erp-kit-module-5-impl/references/exports.md +10 -0
  58. package/skills/erp-kit-module-5-impl/references/model-impl.md +45 -0
  59. package/skills/erp-kit-module-5-impl/references/query-impl.md +53 -0
  60. package/skills/erp-kit-module-6-impl-review/SKILL.md +187 -0
  61. package/skills/erp-kit-module-6-impl-review/references/command-doc-code-parity.md +92 -0
  62. package/skills/erp-kit-module-6-impl-review/references/command-doc-test-parity.md +93 -0
  63. package/skills/erp-kit-module-6-impl-review/references/error-implementation-parity.md +95 -0
  64. package/skills/{erp-kit-module-5-impl-review → erp-kit-module-6-impl-review}/references/errors.md +1 -1
  65. package/skills/erp-kit-module-6-impl-review/references/impl-parity-report-format.md +52 -0
  66. package/skills/erp-kit-module-6-impl-review/references/model-doc-code-parity.md +80 -0
  67. package/skills/erp-kit-module-shared/SKILL.md +1 -1
  68. package/skills/erp-kit-module-shared/references/commands.md +1 -1
  69. package/skills/erp-kit-module-shared/references/errors.md +12 -9
  70. package/skills/erp-kit-module-shared/references/queries.md +109 -36
  71. package/skills/erp-kit-module-shared/references/testing.md +10 -0
  72. package/skills/erp-kit-update/SKILL.md +2 -2
  73. package/src/app.ts +1 -1
  74. package/src/commands/check.ts +1 -1
  75. package/src/commands/index.ts +16 -5
  76. package/src/commands/init.test.ts +22 -69
  77. package/src/commands/init.ts +28 -115
  78. package/src/commands/lib/distribute.test.ts +126 -0
  79. package/src/commands/lib/distribute.ts +129 -0
  80. package/src/commands/parse-doc-test-cases.ts +55 -0
  81. package/src/commands/scaffold.test.ts +74 -33
  82. package/src/commands/scaffold.ts +54 -18
  83. package/src/commands/sync-check.test.ts +173 -0
  84. package/src/commands/sync-check.ts +103 -2
  85. package/src/commands/update.test.ts +87 -0
  86. package/src/commands/update.ts +41 -0
  87. package/src/generator/generate-code.test.ts +23 -12
  88. package/src/generator/generate-code.ts +22 -16
  89. package/src/integration.test.ts +1 -1
  90. package/src/module.ts +20 -65
  91. package/src/modules/item-management/README.md +8 -0
  92. package/src/modules/item-management/command/activateItem.generated.ts +1 -1
  93. package/src/modules/item-management/command/activateItem.test.ts +12 -18
  94. package/src/modules/item-management/command/activateItem.ts +9 -5
  95. package/src/modules/item-management/command/assignItemToTaxonomy.generated.ts +1 -1
  96. package/src/modules/item-management/command/assignItemToTaxonomy.test.ts +10 -24
  97. package/src/modules/item-management/command/assignItemToTaxonomy.ts +19 -16
  98. package/src/modules/item-management/command/createItem.generated.ts +1 -1
  99. package/src/modules/item-management/command/createItem.test.ts +11 -11
  100. package/src/modules/item-management/command/createItem.ts +16 -7
  101. package/src/modules/item-management/command/createTaxonomyNode.generated.ts +1 -1
  102. package/src/modules/item-management/command/createTaxonomyNode.test.ts +9 -9
  103. package/src/modules/item-management/command/createTaxonomyNode.ts +33 -14
  104. package/src/modules/item-management/command/deactivateItem.generated.ts +1 -1
  105. package/src/modules/item-management/command/deactivateItem.test.ts +12 -18
  106. package/src/modules/item-management/command/deactivateItem.ts +9 -5
  107. package/src/modules/item-management/command/deleteItem.generated.ts +1 -1
  108. package/src/modules/item-management/command/deleteItem.test.ts +10 -16
  109. package/src/modules/item-management/command/deleteItem.ts +9 -5
  110. package/src/modules/item-management/command/deleteTaxonomyNode.generated.ts +1 -1
  111. package/src/modules/item-management/command/deleteTaxonomyNode.test.ts +10 -16
  112. package/src/modules/item-management/command/deleteTaxonomyNode.ts +22 -12
  113. package/src/modules/item-management/command/moveTaxonomyNode.generated.ts +1 -1
  114. package/src/modules/item-management/command/moveTaxonomyNode.test.ts +10 -10
  115. package/src/modules/item-management/command/moveTaxonomyNode.ts +63 -19
  116. package/src/modules/item-management/command/reactivateItem.generated.ts +1 -1
  117. package/src/modules/item-management/command/reactivateItem.test.ts +12 -18
  118. package/src/modules/item-management/command/reactivateItem.ts +9 -5
  119. package/src/modules/item-management/command/removeItemFromTaxonomy.generated.ts +1 -1
  120. package/src/modules/item-management/command/removeItemFromTaxonomy.test.ts +9 -16
  121. package/src/modules/item-management/command/removeItemFromTaxonomy.ts +11 -6
  122. package/src/modules/item-management/command/updateItem.generated.ts +1 -1
  123. package/src/modules/item-management/command/updateItem.test.ts +16 -16
  124. package/src/modules/item-management/command/updateItem.ts +11 -6
  125. package/src/modules/item-management/command/updateTaxonomyNode.generated.ts +1 -1
  126. package/src/modules/item-management/command/updateTaxonomyNode.test.ts +14 -20
  127. package/src/modules/item-management/command/updateTaxonomyNode.ts +9 -6
  128. package/src/modules/item-management/docs/commands/ActivateItem.md +8 -0
  129. package/src/modules/item-management/docs/commands/AssignItemToTaxonomy.md +7 -0
  130. package/src/modules/item-management/docs/commands/CreateItem.md +10 -0
  131. package/src/modules/item-management/docs/commands/CreateTaxonomyNode.md +9 -0
  132. package/src/modules/item-management/docs/commands/DeactivateItem.md +8 -0
  133. package/src/modules/item-management/docs/commands/DeleteItem.md +7 -0
  134. package/src/modules/item-management/docs/commands/DeleteTaxonomyNode.md +7 -0
  135. package/src/modules/item-management/docs/commands/MoveTaxonomyNode.md +10 -0
  136. package/src/modules/item-management/docs/commands/ReactivateItem.md +8 -0
  137. package/src/modules/item-management/docs/commands/RemoveItemFromTaxonomy.md +5 -0
  138. package/src/modules/item-management/docs/commands/UpdateItem.md +15 -0
  139. package/src/modules/item-management/docs/commands/UpdateTaxonomyNode.md +9 -0
  140. package/src/modules/item-management/docs/queries/CalculateNodeDepth.md +8 -0
  141. package/src/modules/item-management/docs/queries/CalculateSubtreeDepth.md +7 -0
  142. package/src/modules/item-management/docs/queries/DetectCircularReference.md +9 -0
  143. package/src/modules/item-management/docs/queries/GetItem.md +9 -0
  144. package/src/modules/item-management/docs/queries/GetItemTaxonomyAssignment.md +5 -0
  145. package/src/modules/item-management/docs/queries/GetTaxonomyNode.md +7 -0
  146. package/src/modules/item-management/docs/queries/GetTaxonomyNodeAssignments.md +5 -0
  147. package/src/modules/item-management/docs/queries/GetTaxonomyNodeChildren.md +6 -0
  148. package/src/modules/item-management/index.ts +0 -51
  149. package/src/modules/item-management/lib/errors.generated.ts +24 -24
  150. package/src/modules/item-management/lib/permissions.generated.ts +1 -1
  151. package/src/modules/item-management/lib/types.ts +1 -1
  152. package/src/modules/item-management/module.ts +1 -1
  153. package/src/modules/item-management/query/calculateNodeDepth.generated.ts +1 -1
  154. package/src/modules/item-management/query/calculateNodeDepth.test.ts +21 -6
  155. package/src/modules/item-management/query/calculateNodeDepth.ts +2 -2
  156. package/src/modules/item-management/query/calculateSubtreeDepth.generated.ts +1 -1
  157. package/src/modules/item-management/query/calculateSubtreeDepth.test.ts +17 -5
  158. package/src/modules/item-management/query/calculateSubtreeDepth.ts +2 -2
  159. package/src/modules/item-management/query/detectCircularReference.generated.ts +1 -1
  160. package/src/modules/item-management/query/detectCircularReference.test.ts +25 -7
  161. package/src/modules/item-management/query/detectCircularReference.ts +4 -4
  162. package/src/modules/item-management/query/getItem.generated.ts +1 -1
  163. package/src/modules/item-management/query/getItem.test.ts +25 -7
  164. package/src/modules/item-management/query/getItem.ts +2 -2
  165. package/src/modules/item-management/query/getItemTaxonomyAssignment.generated.ts +1 -1
  166. package/src/modules/item-management/query/getItemTaxonomyAssignment.test.ts +9 -3
  167. package/src/modules/item-management/query/getItemTaxonomyAssignment.ts +2 -2
  168. package/src/modules/item-management/query/getTaxonomyNode.generated.ts +1 -1
  169. package/src/modules/item-management/query/getTaxonomyNode.test.ts +17 -5
  170. package/src/modules/item-management/query/getTaxonomyNode.ts +2 -2
  171. package/src/modules/item-management/query/getTaxonomyNodeAssignments.generated.ts +1 -1
  172. package/src/modules/item-management/query/getTaxonomyNodeAssignments.test.ts +9 -3
  173. package/src/modules/item-management/query/getTaxonomyNodeAssignments.ts +2 -2
  174. package/src/modules/item-management/query/getTaxonomyNodeChildren.generated.ts +1 -1
  175. package/src/modules/item-management/query/getTaxonomyNodeChildren.test.ts +13 -4
  176. package/src/modules/item-management/query/getTaxonomyNodeChildren.ts +2 -2
  177. package/src/modules/item-management/tailor.config.ts +6 -4
  178. package/src/modules/item-management/tailor.d.ts +13 -0
  179. package/src/modules/primitives/README.md +8 -0
  180. package/src/modules/primitives/command/activateCategory.generated.ts +1 -1
  181. package/src/modules/primitives/command/activateCategory.test.ts +8 -18
  182. package/src/modules/primitives/command/activateCategory.ts +9 -5
  183. package/src/modules/primitives/command/activateCurrency.generated.ts +1 -1
  184. package/src/modules/primitives/command/activateCurrency.test.ts +8 -18
  185. package/src/modules/primitives/command/activateCurrency.ts +9 -5
  186. package/src/modules/primitives/command/activateUnit.generated.ts +1 -1
  187. package/src/modules/primitives/command/activateUnit.test.ts +8 -15
  188. package/src/modules/primitives/command/activateUnit.ts +9 -5
  189. package/src/modules/primitives/command/createCategory.generated.ts +1 -1
  190. package/src/modules/primitives/command/createCategory.test.ts +29 -44
  191. package/src/modules/primitives/command/createCategory.ts +9 -5
  192. package/src/modules/primitives/command/createCurrency.generated.ts +1 -1
  193. package/src/modules/primitives/command/createCurrency.test.ts +53 -78
  194. package/src/modules/primitives/command/createCurrency.ts +9 -6
  195. package/src/modules/primitives/command/createExchangeRate.generated.ts +1 -1
  196. package/src/modules/primitives/command/createExchangeRate.test.ts +59 -97
  197. package/src/modules/primitives/command/createExchangeRate.ts +13 -7
  198. package/src/modules/primitives/command/createUnit.generated.ts +1 -1
  199. package/src/modules/primitives/command/createUnit.test.ts +59 -90
  200. package/src/modules/primitives/command/createUnit.ts +9 -6
  201. package/src/modules/primitives/command/deactivateCategory.generated.ts +1 -1
  202. package/src/modules/primitives/command/deactivateCategory.test.ts +15 -33
  203. package/src/modules/primitives/command/deactivateCategory.ts +9 -5
  204. package/src/modules/primitives/command/deactivateCurrency.generated.ts +1 -1
  205. package/src/modules/primitives/command/deactivateCurrency.test.ts +12 -26
  206. package/src/modules/primitives/command/deactivateCurrency.ts +9 -5
  207. package/src/modules/primitives/command/deactivateUnit.generated.ts +1 -1
  208. package/src/modules/primitives/command/deactivateUnit.test.ts +15 -30
  209. package/src/modules/primitives/command/deactivateUnit.ts +14 -7
  210. package/src/modules/primitives/command/setBaseCurrency.generated.ts +1 -1
  211. package/src/modules/primitives/command/setBaseCurrency.test.ts +18 -40
  212. package/src/modules/primitives/command/setBaseCurrency.ts +15 -7
  213. package/src/modules/primitives/command/setReferenceUnit.generated.ts +1 -1
  214. package/src/modules/primitives/command/setReferenceUnit.test.ts +22 -44
  215. package/src/modules/primitives/command/setReferenceUnit.ts +21 -9
  216. package/src/modules/primitives/docs/commands/ActivateCategory.md +6 -0
  217. package/src/modules/primitives/docs/commands/ActivateCurrency.md +6 -0
  218. package/src/modules/primitives/docs/commands/ActivateUnit.md +6 -0
  219. package/src/modules/primitives/docs/commands/CreateCategory.md +6 -0
  220. package/src/modules/primitives/docs/commands/CreateCurrency.md +10 -0
  221. package/src/modules/primitives/docs/commands/CreateExchangeRate.md +11 -0
  222. package/src/modules/primitives/docs/commands/CreateUnit.md +10 -0
  223. package/src/modules/primitives/docs/commands/DeactivateCategory.md +7 -0
  224. package/src/modules/primitives/docs/commands/DeactivateCurrency.md +7 -0
  225. package/src/modules/primitives/docs/commands/DeactivateUnit.md +7 -0
  226. package/src/modules/primitives/docs/commands/SetBaseCurrency.md +7 -0
  227. package/src/modules/primitives/docs/commands/SetReferenceUnit.md +7 -0
  228. package/src/modules/primitives/docs/queries/ConvertAmount.md +14 -0
  229. package/src/modules/primitives/docs/queries/ConvertQuantity.md +13 -0
  230. package/src/modules/primitives/docs/queries/GetBaseCurrency.md +5 -0
  231. package/src/modules/primitives/docs/queries/GetCurrency.md +7 -0
  232. package/src/modules/primitives/docs/queries/GetUnit.md +7 -0
  233. package/src/modules/primitives/docs/queries/GetUoMCategory.md +7 -0
  234. package/src/modules/primitives/docs/queries/ListUnitsByCategory.md +15 -5
  235. package/src/modules/primitives/index.ts +0 -49
  236. package/src/modules/primitives/lib/errors.generated.ts +23 -23
  237. package/src/modules/primitives/lib/permissions.generated.ts +1 -1
  238. package/src/modules/primitives/lib/types.ts +1 -1
  239. package/src/modules/primitives/module.ts +1 -1
  240. package/src/modules/primitives/query/convertAmount.generated.ts +1 -1
  241. package/src/modules/primitives/query/convertAmount.test.ts +110 -77
  242. package/src/modules/primitives/query/convertAmount.ts +61 -47
  243. package/src/modules/primitives/query/convertQuantity.generated.ts +1 -1
  244. package/src/modules/primitives/query/convertQuantity.test.ts +99 -69
  245. package/src/modules/primitives/query/convertQuantity.ts +12 -10
  246. package/src/modules/primitives/query/getBaseCurrency.generated.ts +1 -1
  247. package/src/modules/primitives/query/getBaseCurrency.test.ts +10 -4
  248. package/src/modules/primitives/query/getBaseCurrency.ts +2 -2
  249. package/src/modules/primitives/query/getCurrency.generated.ts +1 -1
  250. package/src/modules/primitives/query/getCurrency.test.ts +17 -5
  251. package/src/modules/primitives/query/getCurrency.ts +2 -2
  252. package/src/modules/primitives/query/getUnit.generated.ts +1 -1
  253. package/src/modules/primitives/query/getUnit.test.ts +17 -5
  254. package/src/modules/primitives/query/getUnit.ts +2 -2
  255. package/src/modules/primitives/query/getUoMCategory.generated.ts +1 -1
  256. package/src/modules/primitives/query/getUoMCategory.test.ts +17 -5
  257. package/src/modules/primitives/query/getUoMCategory.ts +2 -2
  258. package/src/modules/primitives/query/listUnitsByCategory.generated.ts +1 -1
  259. package/src/modules/primitives/query/listUnitsByCategory.test.ts +80 -0
  260. package/src/modules/primitives/query/listUnitsByCategory.ts +19 -3
  261. package/src/modules/primitives/tailor.config.ts +6 -4
  262. package/src/modules/primitives/tailor.d.ts +13 -0
  263. package/src/modules/product-management/README.md +52 -0
  264. package/src/modules/product-management/command/activateProduct.generated.ts +6 -0
  265. package/src/modules/product-management/command/activateProduct.test.ts +40 -0
  266. package/src/modules/product-management/command/activateProduct.ts +42 -0
  267. package/src/modules/product-management/command/assignProductToCategory.generated.ts +6 -0
  268. package/src/modules/product-management/command/assignProductToCategory.test.ts +90 -0
  269. package/src/modules/product-management/command/assignProductToCategory.ts +62 -0
  270. package/src/modules/product-management/command/createProduct.generated.ts +6 -0
  271. package/src/modules/product-management/command/createProduct.test.ts +149 -0
  272. package/src/modules/product-management/command/createProduct.ts +73 -0
  273. package/src/modules/product-management/command/createProductAttribute.generated.ts +6 -0
  274. package/src/modules/product-management/command/createProductAttribute.test.ts +70 -0
  275. package/src/modules/product-management/command/createProductAttribute.ts +53 -0
  276. package/src/modules/product-management/command/createProductAttributeValue.generated.ts +6 -0
  277. package/src/modules/product-management/command/createProductAttributeValue.test.ts +68 -0
  278. package/src/modules/product-management/command/createProductAttributeValue.ts +63 -0
  279. package/src/modules/product-management/command/createProductCategory.generated.ts +6 -0
  280. package/src/modules/product-management/command/createProductCategory.test.ts +135 -0
  281. package/src/modules/product-management/command/createProductCategory.ts +82 -0
  282. package/src/modules/product-management/command/deactivateProduct.generated.ts +6 -0
  283. package/src/modules/product-management/command/deactivateProduct.test.ts +40 -0
  284. package/src/modules/product-management/command/deactivateProduct.ts +42 -0
  285. package/src/modules/product-management/command/deleteProduct.generated.ts +6 -0
  286. package/src/modules/product-management/command/deleteProduct.test.ts +42 -0
  287. package/src/modules/product-management/command/deleteProduct.ts +42 -0
  288. package/src/modules/product-management/command/deleteProductAttribute.generated.ts +6 -0
  289. package/src/modules/product-management/command/deleteProductAttribute.test.ts +49 -0
  290. package/src/modules/product-management/command/deleteProductAttribute.ts +45 -0
  291. package/src/modules/product-management/command/deleteProductAttributeValue.generated.ts +6 -0
  292. package/src/modules/product-management/command/deleteProductAttributeValue.test.ts +71 -0
  293. package/src/modules/product-management/command/deleteProductAttributeValue.ts +68 -0
  294. package/src/modules/product-management/command/deleteProductCategory.generated.ts +6 -0
  295. package/src/modules/product-management/command/deleteProductCategory.test.ts +74 -0
  296. package/src/modules/product-management/command/deleteProductCategory.ts +53 -0
  297. package/src/modules/product-management/command/generateVariants.generated.ts +6 -0
  298. package/src/modules/product-management/command/generateVariants.test.ts +365 -0
  299. package/src/modules/product-management/command/generateVariants.ts +168 -0
  300. package/src/modules/product-management/command/moveProductCategory.generated.ts +6 -0
  301. package/src/modules/product-management/command/moveProductCategory.test.ts +170 -0
  302. package/src/modules/product-management/command/moveProductCategory.ts +124 -0
  303. package/src/modules/product-management/command/reactivateProduct.generated.ts +6 -0
  304. package/src/modules/product-management/command/reactivateProduct.test.ts +40 -0
  305. package/src/modules/product-management/command/reactivateProduct.ts +42 -0
  306. package/src/modules/product-management/command/removeProductFromCategory.generated.ts +6 -0
  307. package/src/modules/product-management/command/removeProductFromCategory.test.ts +42 -0
  308. package/src/modules/product-management/command/removeProductFromCategory.ts +32 -0
  309. package/src/modules/product-management/command/setProductAttributeAssignment.generated.ts +6 -0
  310. package/src/modules/product-management/command/setProductAttributeAssignment.test.ts +206 -0
  311. package/src/modules/product-management/command/setProductAttributeAssignment.ts +102 -0
  312. package/src/modules/product-management/command/updateProduct.generated.ts +6 -0
  313. package/src/modules/product-management/command/updateProduct.test.ts +168 -0
  314. package/src/modules/product-management/command/updateProduct.ts +95 -0
  315. package/src/modules/product-management/command/updateProductAttribute.generated.ts +6 -0
  316. package/src/modules/product-management/command/updateProductAttribute.test.ts +101 -0
  317. package/src/modules/product-management/command/updateProductAttribute.ts +68 -0
  318. package/src/modules/product-management/command/updateProductAttributeValue.generated.ts +6 -0
  319. package/src/modules/product-management/command/updateProductAttributeValue.test.ts +80 -0
  320. package/src/modules/product-management/command/updateProductAttributeValue.ts +58 -0
  321. package/src/modules/product-management/command/updateProductCategory.generated.ts +6 -0
  322. package/src/modules/product-management/command/updateProductCategory.test.ts +80 -0
  323. package/src/modules/product-management/command/updateProductCategory.ts +66 -0
  324. package/src/modules/product-management/db/product.ts +47 -0
  325. package/src/modules/product-management/db/productAttribute.ts +26 -0
  326. package/src/modules/product-management/db/productAttributeAssignment.ts +58 -0
  327. package/src/modules/product-management/db/productAttributeValue.ts +39 -0
  328. package/src/modules/product-management/db/productCategory.ts +34 -0
  329. package/src/modules/product-management/db/productCategoryAssignment.ts +49 -0
  330. package/src/modules/product-management/db/productVariant.ts +52 -0
  331. package/src/modules/product-management/docs/commands/ActivateProduct.md +39 -0
  332. package/src/modules/product-management/docs/commands/AssignProductToCategory.md +43 -0
  333. package/src/modules/product-management/docs/commands/CreateProduct.md +48 -0
  334. package/src/modules/product-management/docs/commands/CreateProductAttribute.md +39 -0
  335. package/src/modules/product-management/docs/commands/CreateProductAttributeValue.md +42 -0
  336. package/src/modules/product-management/docs/commands/CreateProductCategory.md +54 -0
  337. package/src/modules/product-management/docs/commands/DeactivateProduct.md +39 -0
  338. package/src/modules/product-management/docs/commands/DeleteProduct.md +42 -0
  339. package/src/modules/product-management/docs/commands/DeleteProductAttribute.md +39 -0
  340. package/src/modules/product-management/docs/commands/DeleteProductAttributeValue.md +42 -0
  341. package/src/modules/product-management/docs/commands/DeleteProductCategory.md +43 -0
  342. package/src/modules/product-management/docs/commands/GenerateVariants.md +68 -0
  343. package/src/modules/product-management/docs/commands/MoveProductCategory.md +54 -0
  344. package/src/modules/product-management/docs/commands/ReactivateProduct.md +38 -0
  345. package/src/modules/product-management/docs/commands/RemoveProductFromCategory.md +34 -0
  346. package/src/modules/product-management/docs/commands/SetProductAttributeAssignment.md +62 -0
  347. package/src/modules/product-management/docs/commands/UpdateProduct.md +61 -0
  348. package/src/modules/product-management/docs/commands/UpdateProductAttribute.md +46 -0
  349. package/src/modules/product-management/docs/commands/UpdateProductAttributeValue.md +47 -0
  350. package/src/modules/product-management/docs/commands/UpdateProductCategory.md +46 -0
  351. package/src/modules/product-management/docs/features/attribute-management.md +48 -0
  352. package/src/modules/product-management/docs/features/product-category.md +71 -0
  353. package/src/modules/product-management/docs/features/product-lifecycle.md +66 -0
  354. package/src/modules/product-management/docs/features/variant-generation.md +77 -0
  355. package/src/modules/product-management/docs/models/Product.md +58 -0
  356. package/src/modules/product-management/docs/models/ProductAttribute.md +37 -0
  357. package/src/modules/product-management/docs/models/ProductAttributeAssignment.md +41 -0
  358. package/src/modules/product-management/docs/models/ProductAttributeValue.md +40 -0
  359. package/src/modules/product-management/docs/models/ProductCategory.md +46 -0
  360. package/src/modules/product-management/docs/models/ProductCategoryAssignment.md +37 -0
  361. package/src/modules/product-management/docs/models/ProductVariant.md +41 -0
  362. package/src/modules/product-management/docs/queries/CalculateCategoryDepth.md +47 -0
  363. package/src/modules/product-management/docs/queries/DetectCategoryCircularReference.md +51 -0
  364. package/src/modules/product-management/docs/queries/GetProduct.md +42 -0
  365. package/src/modules/product-management/docs/queries/GetProductAttribute.md +42 -0
  366. package/src/modules/product-management/docs/queries/GetProductAttributeAssignment.md +34 -0
  367. package/src/modules/product-management/docs/queries/GetProductAttributeValue.md +40 -0
  368. package/src/modules/product-management/docs/queries/GetProductCategory.md +42 -0
  369. package/src/modules/product-management/docs/queries/GetProductCategoryAssignment.md +34 -0
  370. package/src/modules/product-management/docs/queries/GetProductVariant.md +41 -0
  371. package/src/modules/product-management/docs/queries/ListAttributeAssignmentsByAttribute.md +34 -0
  372. package/src/modules/product-management/docs/queries/ListCategoryAssignmentsByProduct.md +35 -0
  373. package/src/modules/product-management/docs/queries/ListProductAttributeAssignments.md +34 -0
  374. package/src/modules/product-management/docs/queries/ListProductAttributeValues.md +36 -0
  375. package/src/modules/product-management/docs/queries/ListProductCategoryAssignments.md +34 -0
  376. package/src/modules/product-management/docs/queries/ListProductCategoryChildren.md +34 -0
  377. package/src/modules/product-management/docs/queries/ListProductVariants.md +34 -0
  378. package/src/modules/product-management/generated/enums.ts +9 -0
  379. package/src/modules/product-management/generated/kysely-tailordb.ts +100 -0
  380. package/src/modules/product-management/index.ts +2 -0
  381. package/src/modules/product-management/lib/_db_deps.ts +17 -0
  382. package/src/modules/product-management/lib/errors.generated.ts +152 -0
  383. package/src/modules/product-management/lib/permissions.generated.ts +25 -0
  384. package/src/modules/product-management/lib/types.ts +51 -0
  385. package/src/modules/product-management/module.ts +201 -0
  386. package/src/modules/product-management/query/calculateCategoryDepth.generated.ts +5 -0
  387. package/src/modules/product-management/query/calculateCategoryDepth.test.ts +72 -0
  388. package/src/modules/product-management/query/calculateCategoryDepth.ts +37 -0
  389. package/src/modules/product-management/query/detectCategoryCircularReference.generated.ts +5 -0
  390. package/src/modules/product-management/query/detectCategoryCircularReference.test.ts +72 -0
  391. package/src/modules/product-management/query/detectCategoryCircularReference.ts +44 -0
  392. package/src/modules/product-management/query/getProduct.generated.ts +5 -0
  393. package/src/modules/product-management/query/getProduct.test.ts +59 -0
  394. package/src/modules/product-management/query/getProduct.ts +18 -0
  395. package/src/modules/product-management/query/getProductAttribute.generated.ts +5 -0
  396. package/src/modules/product-management/query/getProductAttribute.test.ts +59 -0
  397. package/src/modules/product-management/query/getProductAttribute.ts +18 -0
  398. package/src/modules/product-management/query/getProductAttributeAssignment.generated.ts +5 -0
  399. package/src/modules/product-management/query/getProductAttributeAssignment.test.ts +37 -0
  400. package/src/modules/product-management/query/getProductAttributeAssignment.ts +18 -0
  401. package/src/modules/product-management/query/getProductAttributeValue.generated.ts +5 -0
  402. package/src/modules/product-management/query/getProductAttributeValue.test.ts +31 -0
  403. package/src/modules/product-management/query/getProductAttributeValue.ts +16 -0
  404. package/src/modules/product-management/query/getProductCategory.generated.ts +5 -0
  405. package/src/modules/product-management/query/getProductCategory.test.ts +59 -0
  406. package/src/modules/product-management/query/getProductCategory.ts +18 -0
  407. package/src/modules/product-management/query/getProductCategoryAssignment.generated.ts +5 -0
  408. package/src/modules/product-management/query/getProductCategoryAssignment.test.ts +37 -0
  409. package/src/modules/product-management/query/getProductCategoryAssignment.ts +18 -0
  410. package/src/modules/product-management/query/getProductVariant.generated.ts +5 -0
  411. package/src/modules/product-management/query/getProductVariant.test.ts +43 -0
  412. package/src/modules/product-management/query/getProductVariant.ts +20 -0
  413. package/src/modules/product-management/query/listAttributeAssignmentsByAttribute.generated.ts +5 -0
  414. package/src/modules/product-management/query/listAttributeAssignmentsByAttribute.test.ts +31 -0
  415. package/src/modules/product-management/query/listAttributeAssignmentsByAttribute.ts +16 -0
  416. package/src/modules/product-management/query/listCategoryAssignmentsByProduct.generated.ts +5 -0
  417. package/src/modules/product-management/query/listCategoryAssignmentsByProduct.test.ts +31 -0
  418. package/src/modules/product-management/query/listCategoryAssignmentsByProduct.ts +16 -0
  419. package/src/modules/product-management/query/listProductAttributeAssignments.generated.ts +5 -0
  420. package/src/modules/product-management/query/listProductAttributeAssignments.test.ts +31 -0
  421. package/src/modules/product-management/query/listProductAttributeAssignments.ts +16 -0
  422. package/src/modules/product-management/query/listProductAttributeValues.generated.ts +5 -0
  423. package/src/modules/product-management/query/listProductAttributeValues.test.ts +31 -0
  424. package/src/modules/product-management/query/listProductAttributeValues.ts +17 -0
  425. package/src/modules/product-management/query/listProductCategoryAssignments.generated.ts +5 -0
  426. package/src/modules/product-management/query/listProductCategoryAssignments.test.ts +31 -0
  427. package/src/modules/product-management/query/listProductCategoryAssignments.ts +16 -0
  428. package/src/modules/product-management/query/listProductCategoryChildren.generated.ts +5 -0
  429. package/src/modules/product-management/query/listProductCategoryChildren.test.ts +31 -0
  430. package/src/modules/product-management/query/listProductCategoryChildren.ts +16 -0
  431. package/src/modules/product-management/query/listProductVariants.generated.ts +5 -0
  432. package/src/modules/product-management/query/listProductVariants.test.ts +31 -0
  433. package/src/modules/product-management/query/listProductVariants.ts +16 -0
  434. package/src/modules/product-management/tailor.config.ts +13 -0
  435. package/src/modules/product-management/tailor.d.ts +13 -0
  436. package/src/modules/product-management/testing/fixtures.ts +151 -0
  437. package/src/modules/user-management/README.md +9 -3
  438. package/src/modules/user-management/command/activateUser.generated.ts +1 -1
  439. package/src/modules/user-management/command/activateUser.test.ts +12 -65
  440. package/src/modules/user-management/command/activateUser.ts +5 -20
  441. package/src/modules/user-management/command/assignPermissionToRole.generated.ts +1 -1
  442. package/src/modules/user-management/command/assignPermissionToRole.test.ts +25 -60
  443. package/src/modules/user-management/command/assignPermissionToRole.ts +5 -24
  444. package/src/modules/user-management/command/assignRoleToUser.generated.ts +1 -1
  445. package/src/modules/user-management/command/assignRoleToUser.test.ts +35 -87
  446. package/src/modules/user-management/command/assignRoleToUser.ts +5 -24
  447. package/src/modules/user-management/command/createPermission.generated.ts +1 -1
  448. package/src/modules/user-management/command/createPermission.test.ts +23 -33
  449. package/src/modules/user-management/command/createPermission.ts +4 -5
  450. package/src/modules/user-management/command/createRole.generated.ts +1 -1
  451. package/src/modules/user-management/command/createRole.test.ts +17 -27
  452. package/src/modules/user-management/command/createRole.ts +4 -5
  453. package/src/modules/user-management/command/createUser.generated.ts +1 -1
  454. package/src/modules/user-management/command/createUser.test.ts +31 -118
  455. package/src/modules/user-management/command/createUser.ts +7 -25
  456. package/src/modules/user-management/command/deactivateUser.generated.ts +1 -1
  457. package/src/modules/user-management/command/deactivateUser.test.ts +12 -65
  458. package/src/modules/user-management/command/deactivateUser.ts +6 -21
  459. package/src/modules/user-management/command/reactivateUser.generated.ts +1 -1
  460. package/src/modules/user-management/command/reactivateUser.test.ts +13 -66
  461. package/src/modules/user-management/command/reactivateUser.ts +5 -20
  462. package/src/modules/user-management/command/revokePermissionFromRole.generated.ts +1 -1
  463. package/src/modules/user-management/command/revokePermissionFromRole.test.ts +24 -62
  464. package/src/modules/user-management/command/revokePermissionFromRole.ts +5 -24
  465. package/src/modules/user-management/command/revokeRoleFromUser.generated.ts +1 -1
  466. package/src/modules/user-management/command/revokeRoleFromUser.test.ts +24 -60
  467. package/src/modules/user-management/command/revokeRoleFromUser.ts +5 -24
  468. package/src/modules/user-management/docs/commands/ActivateUser.md +7 -0
  469. package/src/modules/user-management/docs/commands/AssignPermissionToRole.md +7 -0
  470. package/src/modules/user-management/docs/commands/AssignRoleToUser.md +9 -0
  471. package/src/modules/user-management/docs/commands/CreatePermission.md +12 -0
  472. package/src/modules/user-management/docs/commands/CreateRole.md +9 -0
  473. package/src/modules/user-management/docs/commands/CreateUser.md +11 -0
  474. package/src/modules/user-management/docs/commands/DeactivateUser.md +7 -0
  475. package/src/modules/user-management/docs/commands/ReactivateUser.md +7 -0
  476. package/src/modules/user-management/docs/commands/RevokePermissionFromRole.md +7 -0
  477. package/src/modules/user-management/docs/commands/RevokeRoleFromUser.md +7 -0
  478. package/src/modules/user-management/index.ts +0 -30
  479. package/src/modules/user-management/lib/errors.generated.ts +14 -14
  480. package/src/modules/user-management/lib/permissions.generated.ts +1 -2
  481. package/src/modules/user-management/lib/recomputeUserPermissions.ts +4 -3
  482. package/src/modules/user-management/lib/types.ts +1 -1
  483. package/src/modules/user-management/module.ts +2 -7
  484. package/src/modules/user-management/tailor.config.ts +6 -4
  485. package/src/modules/user-management/tailor.d.ts +13 -0
  486. package/src/modules/user-management/testing/fixtures.ts +1 -20
  487. package/src/schemas.ts +1 -1
  488. package/src/{modules/shared → shared}/defineCommand.test.ts +23 -7
  489. package/src/{modules/shared → shared}/defineCommand.ts +19 -10
  490. package/src/{modules/shared/internal.ts → shared/index.ts} +9 -1
  491. package/src/shared/pagination.test.ts +43 -0
  492. package/src/shared/pagination.ts +22 -0
  493. package/src/{modules/shared → shared}/types.ts +13 -0
  494. package/src/{modules/testing → testing}/index.ts +14 -7
  495. package/src/testing.ts +1 -1
  496. package/src/util.ts +8 -0
  497. package/templates/config/license.config.json +4 -0
  498. package/templates/scaffold/app/backend/.env.example +1 -0
  499. package/templates/scaffold/app/backend/__dot__gitignore +4 -0
  500. package/templates/scaffold/app/backend/eslint.config.js +32 -0
  501. package/templates/scaffold/app/backend/package.json +31 -0
  502. package/templates/scaffold/app/backend/seed/data/AuditEvent.jsonl +0 -0
  503. package/templates/scaffold/app/backend/seed/data/Permission.jsonl +0 -0
  504. package/templates/scaffold/app/backend/seed/data/Permission.schema.ts +20 -0
  505. package/templates/scaffold/app/backend/seed/data/Role.jsonl +0 -0
  506. package/templates/scaffold/app/backend/seed/data/Role.schema.ts +20 -0
  507. package/templates/scaffold/app/backend/seed/data/RolePermission.jsonl +0 -0
  508. package/templates/scaffold/app/backend/seed/data/RolePermission.schema.ts +24 -0
  509. package/templates/scaffold/app/backend/seed/data/User.jsonl +1 -0
  510. package/templates/scaffold/app/backend/seed/data/User.schema.ts +20 -0
  511. package/templates/scaffold/app/backend/seed/data/UserRole.jsonl +0 -0
  512. package/templates/scaffold/app/backend/seed/data/UserRole.schema.ts +24 -0
  513. package/templates/scaffold/app/backend/seed/data/_User.jsonl +1 -0
  514. package/templates/scaffold/app/backend/seed/data/_User.schema.ts +30 -0
  515. package/templates/scaffold/app/backend/seed/exec.mjs +659 -0
  516. package/templates/scaffold/app/backend/src/executors/permissionCreated.ts +3 -0
  517. package/templates/scaffold/app/backend/src/executors/permissionDeleted.ts +3 -0
  518. package/templates/scaffold/app/backend/src/generated/kysely-tailordb.ts +83 -0
  519. package/templates/scaffold/app/backend/src/modules.ts +9 -0
  520. package/templates/scaffold/app/backend/src/resolvers/createUser.ts +46 -0
  521. package/templates/scaffold/app/backend/tailor.config.ts +68 -0
  522. package/templates/scaffold/app/backend/tailor.d.ts +15 -0
  523. package/templates/scaffold/app/backend/tsconfig.json +19 -0
  524. package/templates/scaffold/app/docs/actors/.gitkeep +0 -0
  525. package/templates/scaffold/app/docs/business-flow/.gitkeep +0 -0
  526. package/templates/scaffold/app/docs/resolver/.gitkeep +0 -0
  527. package/templates/scaffold/app/docs/screen/.gitkeep +0 -0
  528. package/templates/scaffold/app/frontend/.env.example +2 -0
  529. package/templates/scaffold/app/frontend/__dot__gitignore +3 -0
  530. package/templates/scaffold/app/frontend/components.json +23 -0
  531. package/templates/scaffold/app/frontend/eslint.config.js +48 -0
  532. package/templates/scaffold/app/frontend/index.html +13 -0
  533. package/templates/scaffold/app/frontend/package.json +53 -0
  534. package/templates/scaffold/app/frontend/scripts/generate-graphql.mjs +6 -0
  535. package/templates/scaffold/app/frontend/src/App.tsx +58 -0
  536. package/templates/scaffold/app/frontend/src/components/composed/empty-state.tsx +26 -0
  537. package/templates/scaffold/app/frontend/src/components/composed/error-fallback.tsx +28 -0
  538. package/templates/scaffold/app/frontend/src/components/composed/loading.tsx +13 -0
  539. package/templates/scaffold/app/frontend/src/components/ui/badge.tsx +39 -0
  540. package/templates/scaffold/app/frontend/src/components/ui/button.tsx +60 -0
  541. package/templates/scaffold/app/frontend/src/components/ui/card.tsx +75 -0
  542. package/templates/scaffold/app/frontend/src/components/ui/form.tsx +152 -0
  543. package/templates/scaffold/app/frontend/src/components/ui/input.tsx +21 -0
  544. package/templates/scaffold/app/frontend/src/components/ui/label.tsx +21 -0
  545. package/templates/scaffold/app/frontend/src/components/ui/spinner.tsx +16 -0
  546. package/templates/scaffold/app/frontend/src/components/ui/table.tsx +90 -0
  547. package/templates/scaffold/app/frontend/src/graphql/generated/graphql-env.d.ts +103 -0
  548. package/templates/scaffold/app/frontend/src/graphql/generated/schema.graphql +1235 -0
  549. package/templates/scaffold/app/frontend/src/graphql/index.ts +15 -0
  550. package/templates/scaffold/app/frontend/src/index.css +5 -0
  551. package/templates/scaffold/app/frontend/src/lib/auth-client.ts +17 -0
  552. package/templates/scaffold/app/frontend/src/lib/utils.ts +6 -0
  553. package/templates/scaffold/app/frontend/src/main.tsx +10 -0
  554. package/templates/scaffold/app/frontend/src/pages/page.tsx +20 -0
  555. package/templates/scaffold/app/frontend/src/pages/user-management/page.tsx +19 -0
  556. package/templates/scaffold/app/frontend/src/pages/user-management/profile/page.tsx +97 -0
  557. package/templates/scaffold/app/frontend/src/pages/user-management/user/[id]/components/user-detail.tsx +58 -0
  558. package/templates/scaffold/app/frontend/src/pages/user-management/user/[id]/page.tsx +51 -0
  559. package/templates/scaffold/app/frontend/src/pages/user-management/user/components/users-table.tsx +101 -0
  560. package/templates/scaffold/app/frontend/src/pages/user-management/user/create/components/create-user-form.tsx +99 -0
  561. package/templates/scaffold/app/frontend/src/pages/user-management/user/create/page.tsx +19 -0
  562. package/templates/scaffold/app/frontend/src/pages/user-management/user/page.tsx +61 -0
  563. package/templates/scaffold/app/frontend/src/providers/graphql-provider.tsx +21 -0
  564. package/templates/scaffold/app/frontend/tsconfig.app.json +35 -0
  565. package/templates/scaffold/app/frontend/tsconfig.json +16 -0
  566. package/templates/scaffold/app/frontend/tsconfig.node.json +23 -0
  567. package/templates/scaffold/app/frontend/vite.config.ts +23 -0
  568. package/templates/scaffold/module/command/.gitkeep +0 -0
  569. package/templates/scaffold/module/db/.gitkeep +0 -0
  570. package/templates/scaffold/module/executor/.gitkeep +0 -0
  571. package/templates/scaffold/module/generated/.gitkeep +0 -0
  572. package/templates/scaffold/module/index.ts +2 -0
  573. package/templates/scaffold/module/lib/errors.ts +1 -0
  574. package/templates/scaffold/module/lib/types.ts +4 -0
  575. package/templates/scaffold/module/module.ts +7 -0
  576. package/templates/scaffold/module/permissions.ts +3 -0
  577. package/templates/scaffold/module/query/.gitkeep +0 -0
  578. package/templates/scaffold/module/tailor.config.ts +13 -0
  579. package/templates/scaffold/module/testing/fixtures.ts +1 -0
  580. package/templates/workflows/erp-kit-check.yml +37 -0
  581. package/dist/cli.js +0 -1654
  582. package/skills/erp-kit-app-1-requirements/references/structure.md +0 -27
  583. package/skills/erp-kit-app-2-breakdown/SKILL.md +0 -95
  584. package/skills/erp-kit-app-2-breakdown/references/screen-detailview.md +0 -106
  585. package/skills/erp-kit-app-2-breakdown/references/screen-form.md +0 -139
  586. package/skills/erp-kit-app-2-breakdown/references/screen-listview.md +0 -153
  587. package/skills/erp-kit-app-2-breakdown/references/structure.md +0 -27
  588. package/skills/erp-kit-app-3-doc-review/SKILL.md +0 -116
  589. package/skills/erp-kit-app-3-doc-review/references/structure.md +0 -27
  590. package/skills/erp-kit-app-4-design/SKILL.md +0 -256
  591. package/skills/erp-kit-app-4-design/references/component.md +0 -50
  592. package/skills/erp-kit-app-4-design/references/screen-detailview.md +0 -106
  593. package/skills/erp-kit-app-4-design/references/screen-form.md +0 -139
  594. package/skills/erp-kit-app-4-design/references/screen-listview.md +0 -153
  595. package/skills/erp-kit-app-4-design/references/structure.md +0 -27
  596. package/skills/erp-kit-app-5-design-review/SKILL.md +0 -290
  597. package/skills/erp-kit-app-5-design-review/references/component.md +0 -50
  598. package/skills/erp-kit-app-5-design-review/references/screen-detailview.md +0 -106
  599. package/skills/erp-kit-app-5-design-review/references/screen-form.md +0 -139
  600. package/skills/erp-kit-app-5-design-review/references/screen-listview.md +0 -153
  601. package/skills/erp-kit-app-6-impl-spec/SKILL.md +0 -127
  602. package/skills/erp-kit-app-6-impl-spec/references/auth.md +0 -72
  603. package/skills/erp-kit-app-6-impl-spec/references/structure.md +0 -27
  604. package/skills/erp-kit-module-1-docs/SKILL.md +0 -111
  605. package/skills/erp-kit-module-2-feature-breakdown/SKILL.md +0 -76
  606. package/skills/erp-kit-module-3-doc-review/SKILL.md +0 -294
  607. package/skills/erp-kit-module-4-tdd/SKILL.md +0 -94
  608. package/skills/erp-kit-module-4-tdd/references/exports.md +0 -8
  609. package/skills/erp-kit-module-5-impl-review/SKILL.md +0 -410
  610. package/src/commands/scaffold-templates.ts +0 -65
  611. package/src/modules/shared/index.ts +0 -1
  612. package/src/modules/user-management/command/logAuditEvent.generated.ts +0 -6
  613. package/src/modules/user-management/command/logAuditEvent.test.ts +0 -187
  614. package/src/modules/user-management/command/logAuditEvent.ts +0 -56
  615. package/src/modules/user-management/db/auditEvent.ts +0 -47
  616. package/src/modules/user-management/docs/commands/LogAuditEvent.md +0 -37
  617. package/src/modules/user-management/docs/features/audit-trail.md +0 -80
  618. package/src/modules/user-management/docs/models/AuditEvent.md +0 -36
  619. /package/skills/{erp-kit-module-2-feature-breakdown → erp-kit-module-3-plan}/references/naming.md +0 -0
  620. /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/cross-module-dependency.md +0 -0
  621. /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/db-relations.md +0 -0
  622. /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/generated-code.md +0 -0
  623. /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/models.md +0 -0
  624. /package/skills/{erp-kit-module-5-impl-review → erp-kit-module-6-impl-review}/references/commands.md +0 -0
  625. /package/skills/{erp-kit-module-5-impl-review → erp-kit-module-6-impl-review}/references/testing.md +0 -0
  626. /package/src/modules/{product-management → audit}/.gitkeep +0 -0
  627. /package/src/{modules/shared → shared}/createContext.test.ts +0 -0
  628. /package/src/{modules/shared → shared}/createContext.ts +0 -0
  629. /package/src/{modules/shared → shared}/definePermissions.test.ts +0 -0
  630. /package/src/{modules/shared → shared}/definePermissions.ts +0 -0
  631. /package/src/{modules/shared → shared}/defineQuery.test.ts +0 -0
  632. /package/src/{modules/shared → shared}/defineQuery.ts +0 -0
  633. /package/src/{modules/shared → shared}/entityTypes.ts +0 -0
  634. /package/src/{modules/shared → shared}/errors.ts +0 -0
  635. /package/src/{modules/shared → shared}/requirePermission.test.ts +0 -0
  636. /package/src/{modules/shared → shared}/requirePermission.ts +0 -0
  637. /package/src/{modules/shared → shared}/result.ts +0 -0
@@ -8,7 +8,7 @@ Run `erp-kit module generate code` to generate query shells from `docs/queries/*
8
8
 
9
9
  ```typescript
10
10
  // @generated — do not edit
11
- import { defineQuery } from "../../shared/internal";
11
+ import { defineQuery } from "../../../shared";
12
12
  import { run } from "./getItem";
13
13
 
14
14
  export const getItem = defineQuery(run);
@@ -17,7 +17,8 @@ export const getItem = defineQuery(run);
17
17
  ### Hand-written implementation
18
18
 
19
19
  ```typescript
20
- import type { ReadonlyDB } from "../../shared/internal";
20
+ import type { ReadonlyDB } from "../../../shared";
21
+ import { ok } from "../../../shared";
21
22
  import type { DB } from "../generated/kysely-tailordb";
22
23
 
23
24
  export type GetItemInput = { id: string } | { sku: string };
@@ -32,42 +33,96 @@ export async function run(db: ReadonlyDB<DB>, input: GetItemInput) {
32
33
  }
33
34
 
34
35
  const item = await query.executeTakeFirst();
35
- return { item: item ?? null };
36
+ return ok({ item: item ?? null });
36
37
  }
37
38
  ```
38
39
 
39
40
  ## Custom Queries
40
41
 
41
- For queries beyond simple lookups (joins, aggregations, complex filters), write them by hand in `query/*.ts`:
42
+ For queries beyond simple lookups (joins, aggregations, complex filters), write them by hand in `query/*.ts`. List queries must use pagination — see [Paginated List Queries](#paginated-list-queries) for the full pattern.
43
+
44
+ ## Conventions
45
+
46
+ - `defineQuery` wraps all queries via generated shells
47
+ - `ReadonlyDB<DB>` ensures read-only access
48
+ - All queries return Result types using `ok()` / `err()` from `shared` — consistent with commands
49
+ - Get queries return `ok({ entity: T | null })` using `executeTakeFirst()`
50
+ - List queries return `ok(PaginatedResult<T>)` using pagination utilities — see [Paginated List Queries](#paginated-list-queries)
51
+ - Input types: `type` for union inputs (get), `interface` for single-shape inputs (list)
52
+ - `.generated.ts` files are always overwritten — never edit them
53
+
54
+ ## Paginated List Queries
55
+
56
+ All list queries use offset/limit pagination via shared utilities. This is the standard for ERP module-level APIs.
57
+
58
+ ### Types
59
+
60
+ ```typescript
61
+ // PaginationInput accepts a generic TOrderBy for per-query sortable fields.
62
+ // "id" is always available as a sort field.
63
+ interface PaginationInput<TOrderBy extends string = never> {
64
+ limit?: number; // default: 20 (DEFAULT_PAGE_SIZE)
65
+ offset?: number; // default: 0
66
+ orderBy?: "id" | TOrderBy; // default: "id"
67
+ orderDirection?: "asc" | "desc"; // default: "asc"
68
+ }
69
+
70
+ interface PaginatedResult<T> {
71
+ items: T[];
72
+ total?: number; // optional — caller opts in to COUNT(*) overhead
73
+ hasNextPage: boolean;
74
+ }
75
+ ```
76
+
77
+ ### Pattern
78
+
79
+ 1. Extend `PaginationInput<T>` with query-specific sortable fields
80
+ 2. Apply `.orderBy()`, `.limit(limit + 1)`, `.offset()` to the Kysely query
81
+ 3. Use `buildPaginatedResult(rows, limit)` to build the response — the limit+1 strategy determines `hasNextPage` without a separate count query
42
82
 
43
83
  ```typescript
44
- import type { ReadonlyDB } from "../../shared/internal";
84
+ import {
85
+ ok,
86
+ type ReadonlyDB,
87
+ type PaginationInput,
88
+ buildPaginatedResult,
89
+ DEFAULT_PAGE_SIZE,
90
+ } from "../../../shared";
45
91
  import type { DB } from "../generated/kysely-tailordb";
46
92
 
47
- export interface ListActiveItemsByCategoryInput {
93
+ // Define sortable fields for this query
94
+ type UnitOrderByField = "name" | "symbol" | "createdAt";
95
+
96
+ export interface ListUnitsByCategoryInput extends PaginationInput<UnitOrderByField> {
48
97
  categoryId: string;
49
98
  }
50
99
 
51
- export async function run(db: ReadonlyDB<DB>, input: ListActiveItemsByCategoryInput) {
52
- const items = await db
53
- .selectFrom("Item")
100
+ export async function run(db: ReadonlyDB<DB>, input: ListUnitsByCategoryInput) {
101
+ const limit = input.limit ?? DEFAULT_PAGE_SIZE;
102
+ const offset = input.offset ?? 0;
103
+ const orderBy = input.orderBy ?? "id";
104
+ const orderDirection = input.orderDirection ?? "asc";
105
+
106
+ const units = await db
107
+ .selectFrom("Unit")
54
108
  .selectAll()
55
109
  .where("categoryId", "=", input.categoryId)
56
- .where("status", "=", "ACTIVE")
110
+ .orderBy(orderBy, orderDirection)
111
+ .limit(limit + 1)
112
+ .offset(offset)
57
113
  .execute();
58
114
 
59
- return { items };
115
+ return ok(buildPaginatedResult(units, limit));
60
116
  }
61
117
  ```
62
118
 
63
- ## Conventions
119
+ ### Rules
64
120
 
65
- - `defineQuery` wraps all queries via generated shells
66
- - `ReadonlyDB<DB>` ensures read-only access
67
- - Get queries return `{ entity: T | null }` using `executeTakeFirst()`
68
- - List queries return `{ entities: T[] }` using `execute()`
69
- - Input types: `type` for union inputs (get), `interface` for single-shape inputs (list)
70
- - `.generated.ts` files are always overwritten — never edit them
121
+ - Every list query must extend `PaginationInput` no unbounded result sets
122
+ - Define a `TOrderBy` type alias with the query's sortable columns (exclude `id` — it's always included)
123
+ - Default sort is `"id" asc` deterministic ordering is required for stable pagination
124
+ - Use `limit + 1` fetch strategy never issue a separate `COUNT(*)` unless the caller explicitly needs `total`
125
+ - Queries with no custom sort fields use plain `PaginationInput` (only `"id"` is sortable)
71
126
 
72
127
  ## Status-Aware Query Rules
73
128
 
@@ -86,43 +141,47 @@ Models with a status lifecycle (Stateful models with `status` enum, or simple mo
86
141
 
87
142
  ```typescript
88
143
  // Business use case — status baked into the name
89
- export async function run(db: ReadonlyDB<DB>, input: ListActiveItemsByCategoryInput) {
90
- const items = await db
91
- .selectFrom("Item")
92
- .selectAll()
93
- .where("categoryId", "=", input.categoryId)
94
- .where("status", "=", "ACTIVE")
95
- .execute();
96
- return { items };
144
+ // List queries use pagination (see Paginated List Queries section)
145
+ export interface ListActiveItemsByCategoryInput extends PaginationInput {
146
+ categoryId: string;
97
147
  }
98
148
 
99
- // Unfiltered no status filter, returns everything
100
- export async function run(db: ReadonlyDB<DB>, input: ListItemsByCategoryInput) {
149
+ export async function run(db: ReadonlyDB<DB>, input: ListActiveItemsByCategoryInput) {
150
+ const limit = input.limit ?? DEFAULT_PAGE_SIZE;
151
+ const offset = input.offset ?? 0;
152
+
101
153
  const items = await db
102
154
  .selectFrom("Item")
103
155
  .selectAll()
104
156
  .where("categoryId", "=", input.categoryId)
157
+ .where("status", "=", "ACTIVE")
158
+ .orderBy(input.orderBy ?? "id", input.orderDirection ?? "asc")
159
+ .limit(limit + 1)
160
+ .offset(offset)
105
161
  .execute();
106
- return { items };
162
+ return ok(buildPaginatedResult(items, limit));
107
163
  }
108
164
 
109
- // Single lookup — status-unaware, returns any status
165
+ // Single lookup — status-unaware, returns any status (no pagination)
110
166
  export async function run(db: ReadonlyDB<DB>, input: GetItemInput) {
111
167
  const item = await db
112
168
  .selectFrom("Item")
113
169
  .selectAll()
114
170
  .where("id", "=", input.id)
115
171
  .executeTakeFirst();
116
- return { item: item ?? null };
172
+ return ok({ item: item ?? null });
117
173
  }
118
174
 
119
- // Admin/exploratory — parametric status filter
120
- export interface SearchItemsInput {
175
+ // Admin/exploratory — parametric status filter with pagination
176
+ export interface SearchItemsInput extends PaginationInput {
121
177
  status?: string;
122
178
  categoryId?: string;
123
179
  }
124
180
 
125
181
  export async function run(db: ReadonlyDB<DB>, input: SearchItemsInput) {
182
+ const limit = input.limit ?? DEFAULT_PAGE_SIZE;
183
+ const offset = input.offset ?? 0;
184
+
126
185
  let query = db.selectFrom("Item").selectAll();
127
186
  if (input.status) {
128
187
  query = query.where("status", "=", input.status);
@@ -130,8 +189,12 @@ export async function run(db: ReadonlyDB<DB>, input: SearchItemsInput) {
130
189
  if (input.categoryId) {
131
190
  query = query.where("categoryId", "=", input.categoryId);
132
191
  }
133
- const items = await query.execute();
134
- return { items };
192
+ const items = await query
193
+ .orderBy(input.orderBy ?? "id", input.orderDirection ?? "asc")
194
+ .limit(limit + 1)
195
+ .offset(offset)
196
+ .execute();
197
+ return ok(buildPaginatedResult(items, limit));
135
198
  }
136
199
  ```
137
200
 
@@ -142,14 +205,24 @@ The same naming rules apply. For models using `isActive` instead of a `status` e
142
205
  ```typescript
143
206
  // Business use case — active units only
144
207
  // listActiveUnitsByCategory
208
+ export interface ListActiveUnitsByCategoryInput extends PaginationInput {
209
+ categoryId: string;
210
+ }
211
+
145
212
  export async function run(db: ReadonlyDB<DB>, input: ListActiveUnitsByCategoryInput) {
213
+ const limit = input.limit ?? DEFAULT_PAGE_SIZE;
214
+ const offset = input.offset ?? 0;
215
+
146
216
  const units = await db
147
217
  .selectFrom("Unit")
148
218
  .selectAll()
149
219
  .where("categoryId", "=", input.categoryId)
150
220
  .where("isActive", "=", true)
221
+ .orderBy(input.orderBy ?? "id", input.orderDirection ?? "asc")
222
+ .limit(limit + 1)
223
+ .offset(offset)
151
224
  .execute();
152
- return { units };
225
+ return ok(buildPaginatedResult(units, limit));
153
226
  }
154
227
  ```
155
228
 
@@ -29,6 +29,16 @@ For commands with generic `CF`, add one test verifying custom fields reach `.val
29
29
  - Assert with `spies.values`: `expect(spies.values).toHaveBeenNthCalledWith(1, expect.objectContaining({ myField: "value" }))`
30
30
  - Use `toHaveBeenNthCalledWith(n, ...)` when multiple inserts occur (e.g., audit events)
31
31
 
32
+ ## Test Case Documentation Sync
33
+
34
+ Command and query docs include a `## Test Cases` section listing each `it()` description. This list must stay in sync with the actual test file:
35
+
36
+ - Each `it("...")` in the test file must appear as `- ...` in the doc's `## Test Cases`
37
+ - Each item in `## Test Cases` must have a corresponding `it()` in the test file
38
+ - Run `erp-kit module sync-check` to verify alignment
39
+ - When adding a new test, add the `it()` description to the doc first, then write the test
40
+ - Test case descriptions should match the doc's Process Flow branches and Error Scenarios
41
+
32
42
  ## Fixtures (`testing/fixtures.ts`)
33
43
 
34
44
  - Import `Schema` from `lib/types` (not `Namespace` from generated code)
@@ -31,7 +31,7 @@ Dynamically discover available erp-kit skills:
31
31
  1. Glob for `erp-kit-app-*/SKILL.md` or `erp-kit-module-*/SKILL.md` files (based on domain from Phase 1) in the skills directory
32
32
  2. Read each SKILL.md's frontmatter `name` and `description`
33
33
  3. Skip `erp-kit-module-shared` (not directly invocable)
34
- 4. Sort skills by their numeric step (extract number from name, e.g. `erp-kit-app-2-breakdown` → step 2)
34
+ 4. Sort skills by their numeric step (extract number from name, e.g. `erp-kit-app-3-plan` → step 3)
35
35
 
36
36
  This builds the routing table at runtime — new or renamed skills are picked up automatically.
37
37
 
@@ -53,7 +53,7 @@ Only list downstream skills that are plausibly affected by the change.
53
53
 
54
54
  Use the `Skill` tool to invoke the routed skill. Pass the app or module name as the argument.
55
55
 
56
- Example: `Skill: erp-kit-app-2-breakdown, args: "inventory-management"`
56
+ Example: `Skill: erp-kit-app-3-plan, args: "inventory-management"`
57
57
 
58
58
  ## Multiple Changes
59
59
 
package/src/app.ts CHANGED
@@ -1 +1 @@
1
- export { createContext } from "./modules/shared/createContext";
1
+ export { createContext } from "./shared/createContext";
@@ -25,7 +25,7 @@ export function buildCheckTargets(config: {
25
25
  if (config.appRoot) {
26
26
  const a = config.appRoot;
27
27
  targets.push(
28
- { glob: `${a}/[a-zA-Z]*/README.md`, schemaKey: "requirements" },
28
+ { glob: `${a}/[a-zA-Z]*/README.md`, schemaKey: "app" },
29
29
  { glob: `${a}/[a-zA-Z]*/docs/actors/*.md`, schemaKey: "actors" },
30
30
  { glob: `${a}/[a-zA-Z]*/docs/business-flow/*/README.md`, schemaKey: "business-flow" },
31
31
  { glob: `${a}/[a-zA-Z]*/docs/business-flow/*/story/*.md`, schemaKey: "story" },
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { defineCommand, arg } from "politty";
3
3
  import { runInit } from "./init";
4
+ import { runUpdate } from "./update";
4
5
  import { runLicenseCheck, runLicenseList } from "./license";
5
6
  import { moduleCommand } from "./module/index";
6
7
  import { appCommand } from "./app/index";
@@ -14,15 +15,24 @@ const cwd = process.cwd();
14
15
 
15
16
  export const initCommand = defineCommand({
16
17
  name: "init",
17
- description: "Set up consumer repo with framework skills",
18
+ description: "First-time setup for a consumer repo",
19
+ run: () => {
20
+ const exitCode = runInit(cwd);
21
+ process.exit(exitCode);
22
+ },
23
+ });
24
+
25
+ export const updateCommand = defineCommand({
26
+ name: "update",
27
+ description: "Refresh framework-managed resources (skills, workflows)",
18
28
  args: z.object({
19
- force: arg(z.boolean().default(false), {
20
- alias: "f",
21
- description: "Overwrite existing skills",
29
+ resources: arg(z.array(z.string()).default([]), {
30
+ positional: true,
31
+ description: "Resources to update (skills, workflows). Defaults to all.",
22
32
  }),
23
33
  }),
24
34
  run: (args) => {
25
- const exitCode = runInit(cwd, args.force);
35
+ const exitCode = runUpdate(cwd, args.resources);
26
36
  process.exit(exitCode);
27
37
  },
28
38
  });
@@ -68,6 +78,7 @@ export const mainCommand = defineCommand({
68
78
  app: appCommand,
69
79
  mock: mockCommand,
70
80
  init: initCommand,
81
+ update: updateCommand,
71
82
  license: licenseCommand,
72
83
  },
73
84
  });
@@ -15,91 +15,44 @@ describe("runInit", () => {
15
15
  fs.rmSync(tmpDir, { recursive: true, force: true });
16
16
  });
17
17
 
18
- it("copies framework skills to .agents/skills/", () => {
19
- runInit(tmpDir, false);
20
- const skillPath = path.join(tmpDir, ".agents", "skills", "erp-kit-module-1-docs", "SKILL.md");
21
- expect(fs.existsSync(skillPath)).toBe(true);
22
- });
18
+ it("copies skills, workflows, config, and symlink on fresh repo", () => {
19
+ const exitCode = runInit(tmpDir);
20
+ expect(exitCode).toBe(0);
23
21
 
24
- it("copies skill references/ directories", () => {
25
- runInit(tmpDir, false);
26
- const refPath = path.join(
22
+ // Skills
23
+ const skillPath = path.join(
27
24
  tmpDir,
28
25
  ".agents",
29
26
  "skills",
30
- "erp-kit-module-4-tdd",
31
- "references",
32
- "models.md",
27
+ "erp-kit-module-1-requirements",
28
+ "SKILL.md",
33
29
  );
34
- expect(fs.existsSync(refPath)).toBe(true);
35
-
36
- const content = fs.readFileSync(refPath, "utf-8");
37
- expect(content).toContain("# Database Models");
38
- });
39
-
40
- it("does not overwrite project-specific skills", () => {
41
- const customSkillDir = path.join(tmpDir, ".agents", "skills", "my-custom-skill");
42
- fs.mkdirSync(customSkillDir, { recursive: true });
43
- fs.writeFileSync(path.join(customSkillDir, "SKILL.md"), "# Custom");
44
- runInit(tmpDir, false);
45
- const content = fs.readFileSync(path.join(customSkillDir, "SKILL.md"), "utf-8");
46
- expect(content).toBe("# Custom");
47
- });
48
-
49
- it("does not overwrite existing framework skills", () => {
50
- const skillDir = path.join(tmpDir, ".agents", "skills", "erp-kit-module-1-docs");
51
- fs.mkdirSync(skillDir, { recursive: true });
52
- fs.writeFileSync(path.join(skillDir, "SKILL.md"), "# Customized");
53
- runInit(tmpDir, false);
54
- const content = fs.readFileSync(path.join(skillDir, "SKILL.md"), "utf-8");
55
- expect(content).toBe("# Customized");
56
- });
57
-
58
- it("overwrites existing framework skills with --force", () => {
59
- const skillDir = path.join(tmpDir, ".agents", "skills", "erp-kit-module-1-docs");
60
- fs.mkdirSync(skillDir, { recursive: true });
61
- fs.writeFileSync(path.join(skillDir, "SKILL.md"), "# Customized");
62
- runInit(tmpDir, true);
63
- const content = fs.readFileSync(path.join(skillDir, "SKILL.md"), "utf-8");
64
- expect(content).not.toBe("# Customized");
65
- });
30
+ expect(fs.existsSync(skillPath)).toBe(true);
66
31
 
67
- it("creates .claude/skills symlink to .agents/skills", () => {
68
- runInit(tmpDir, false);
32
+ // Symlink
69
33
  const claudeSkills = path.join(tmpDir, ".claude", "skills");
70
34
  expect(fs.lstatSync(claudeSkills).isSymbolicLink()).toBe(true);
71
- expect(fs.readlinkSync(claudeSkills)).toBe(path.join("..", ".agents", "skills"));
72
- });
73
35
 
74
- it("skips symlink when .claude/skills is a real directory", () => {
75
- const claudeSkills = path.join(tmpDir, ".claude", "skills");
76
- fs.mkdirSync(claudeSkills, { recursive: true });
77
- runInit(tmpDir, false);
78
- expect(fs.lstatSync(claudeSkills).isSymbolicLink()).toBe(false);
36
+ // Workflows
37
+ const wfPath = path.join(tmpDir, ".github", "workflows", "erp-kit-check.yml");
38
+ expect(fs.existsSync(wfPath)).toBe(true);
39
+
40
+ // Config
41
+ const configPath = path.join(tmpDir, "license.config.json");
42
+ expect(fs.existsSync(configPath)).toBe(true);
79
43
  });
80
44
 
81
- it("removes stale erp-kit-* skills with --force", () => {
82
- const staleDir = path.join(tmpDir, ".agents", "skills", "erp-kit-old-skill");
83
- fs.mkdirSync(staleDir, { recursive: true });
84
- fs.writeFileSync(path.join(staleDir, "SKILL.md"), "# Stale");
85
- runInit(tmpDir, true);
86
- expect(fs.existsSync(staleDir)).toBe(false);
45
+ it("refuses to run if already initialized", () => {
46
+ runInit(tmpDir);
47
+ const exitCode = runInit(tmpDir);
48
+ expect(exitCode).toBe(1);
87
49
  });
88
50
 
89
- it("preserves non-erp-kit skills with --force", () => {
51
+ it("preserves non-erp-kit skills", () => {
90
52
  const customDir = path.join(tmpDir, ".agents", "skills", "my-custom-skill");
91
53
  fs.mkdirSync(customDir, { recursive: true });
92
54
  fs.writeFileSync(path.join(customDir, "SKILL.md"), "# Custom");
93
- runInit(tmpDir, true);
94
- expect(fs.existsSync(path.join(customDir, "SKILL.md"))).toBe(true);
55
+ runInit(tmpDir);
95
56
  expect(fs.readFileSync(path.join(customDir, "SKILL.md"), "utf-8")).toBe("# Custom");
96
57
  });
97
-
98
- it("relinks symlink with --force when target differs", () => {
99
- const claudeSkills = path.join(tmpDir, ".claude", "skills");
100
- fs.mkdirSync(path.dirname(claudeSkills), { recursive: true });
101
- fs.symlinkSync("../old-target", claudeSkills);
102
- runInit(tmpDir, true);
103
- expect(fs.readlinkSync(claudeSkills)).toBe(path.join("..", ".agents", "skills"));
104
- });
105
58
  });
@@ -1,127 +1,40 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
1
  import chalk from "chalk";
4
- import { PACKAGE_ROOT } from "../util";
5
-
6
- const SKILLS_SRC = path.join(PACKAGE_ROOT, "skills");
7
-
8
- function discoverFrameworkSkills(): string[] {
9
- if (!fs.existsSync(SKILLS_SRC)) return [];
10
- return fs
11
- .readdirSync(SKILLS_SRC, { withFileTypes: true })
12
- .filter((entry) => entry.isDirectory() && entry.name.startsWith("erp-kit-"))
13
- .map((entry) => entry.name);
14
- }
15
-
16
- function copyDirectoryRecursive(
17
- srcDir: string,
18
- destDir: string,
19
- force: boolean,
20
- ): { copied: number; skipped: number } {
21
- let copied = 0;
22
- let skipped = 0;
23
-
24
- for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
25
- const srcPath = path.join(srcDir, entry.name);
26
- const destPath = path.join(destDir, entry.name);
27
-
28
- if (entry.isDirectory()) {
29
- const sub = copyDirectoryRecursive(srcPath, destPath, force);
30
- copied += sub.copied;
31
- skipped += sub.skipped;
32
- } else {
33
- if (!force && fs.existsSync(destPath)) {
34
- skipped++;
35
- continue;
36
- }
37
- fs.mkdirSync(destDir, { recursive: true });
38
- fs.copyFileSync(srcPath, destPath);
39
- copied++;
40
- }
41
- }
42
-
43
- return { copied, skipped };
44
- }
45
-
46
- export function runInit(cwd: string, force: boolean): number {
2
+ import {
3
+ copySkills,
4
+ copyWorkflows,
5
+ copyConfigs,
6
+ setupSymlink,
7
+ isAlreadyInitialized,
8
+ } from "./lib/distribute";
9
+
10
+ export function runInit(cwd: string): number {
47
11
  console.log(chalk.bold("erp-kit init\n"));
48
12
 
49
- // --- Skills ---
50
- const skillsDest = path.join(cwd, ".agents", "skills");
51
-
52
- // Clean up existing erp-kit-* skills before copying to remove stale names
53
- if (force && fs.existsSync(skillsDest)) {
54
- let removedCount = 0;
55
- for (const entry of fs.readdirSync(skillsDest)) {
56
- if (entry.startsWith("erp-kit-")) {
57
- fs.rmSync(path.join(skillsDest, entry), { recursive: true, force: true });
58
- removedCount++;
59
- }
60
- }
61
- if (removedCount > 0) {
62
- console.log(chalk.green(` Removed ${removedCount} existing erp-kit-* skills`));
63
- }
64
- }
65
-
66
- let copiedCount = 0;
67
- let skippedCount = 0;
68
- const frameworkSkills = discoverFrameworkSkills();
69
- for (const skill of frameworkSkills) {
70
- const srcSkillDir = path.join(SKILLS_SRC, skill);
71
- if (!fs.existsSync(srcSkillDir)) continue;
72
-
73
- const destDir = path.join(skillsDest, skill);
74
- const result = copyDirectoryRecursive(srcSkillDir, destDir, force);
75
- copiedCount += result.copied;
76
-
77
- if (result.skipped > 0) {
78
- console.log(chalk.yellow(` Skipped ${skill}/ (${result.skipped} existing files)`));
79
- skippedCount += result.skipped;
80
- }
81
- }
82
- console.log(chalk.green(` Copied ${copiedCount} skill files to .agents/skills/`));
83
- if (skippedCount > 0) {
13
+ if (isAlreadyInitialized(cwd)) {
84
14
  console.log(
85
- chalk.yellow(` Skipped ${skippedCount} existing files (use --force to overwrite)`),
15
+ chalk.yellow("Already initialized. Use `erp-kit update` to refresh framework resources."),
86
16
  );
17
+ return 1;
87
18
  }
88
19
 
89
- // --- Claude Code symlink ---
90
- const claudeSkills = path.join(cwd, ".claude", "skills");
91
- const relTarget = path.relative(path.dirname(claudeSkills), skillsDest);
20
+ const skills = copySkills(cwd);
21
+ console.log(chalk.green(` Copied ${skills.copied} skill files to .agents/skills/`));
92
22
 
93
- // lstatSync doesn't follow symlinks, so dangling symlinks are detected
94
- const claudeSkillsExists = (() => {
95
- try {
96
- fs.lstatSync(claudeSkills);
97
- return true;
98
- } catch {
99
- return false;
100
- }
101
- })();
102
-
103
- if (claudeSkillsExists) {
104
- const stat = fs.lstatSync(claudeSkills);
105
- if (stat.isSymbolicLink()) {
106
- const current = fs.readlinkSync(claudeSkills);
107
- if (current === relTarget) {
108
- console.log(chalk.green(" .claude/skills -> .agents/skills/ (already linked)"));
109
- } else if (force) {
110
- fs.unlinkSync(claudeSkills);
111
- fs.symlinkSync(relTarget, claudeSkills);
112
- console.log(chalk.green(" .claude/skills -> .agents/skills/ (relinked)"));
113
- } else {
114
- console.log(
115
- chalk.yellow(` Skipped .claude/skills (symlink exists -> ${current}, use --force)`),
116
- );
117
- }
118
- } else {
119
- console.log(chalk.yellow(" Skipped .claude/skills (directory exists, not a symlink)"));
120
- }
121
- } else {
122
- fs.mkdirSync(path.dirname(claudeSkills), { recursive: true });
123
- fs.symlinkSync(relTarget, claudeSkills);
23
+ const symlink = setupSymlink(cwd);
24
+ if (symlink === "linked") {
124
25
  console.log(chalk.green(" .claude/skills -> .agents/skills/ (linked)"));
26
+ } else if (symlink === "skipped_directory") {
27
+ console.log(chalk.yellow(" Skipped .claude/skills (directory exists, not a symlink)"));
28
+ }
29
+
30
+ const workflows = copyWorkflows(cwd);
31
+ if (workflows.copied > 0) {
32
+ console.log(chalk.green(` Copied ${workflows.copied} workflow(s) to .github/workflows/`));
33
+ }
34
+
35
+ const configs = copyConfigs(cwd);
36
+ if (configs.copied > 0) {
37
+ console.log(chalk.green(` Copied ${configs.copied} config file(s)`));
125
38
  }
126
39
 
127
40
  console.log(chalk.bold.green("\nDone! Run `erp-kit check` to validate your docs."));