@tailor-platform/erp-kit 0.2.1 → 0.3.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 (633) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +154 -80
  3. package/dist/cli.mjs +1742 -0
  4. package/package.json +16 -14
  5. package/schemas/app-compose/story.yml +12 -0
  6. package/schemas/module/command.yml +9 -0
  7. package/schemas/module/module.yml +4 -0
  8. package/schemas/module/query.yml +9 -0
  9. package/skills/erp-kit-app-1-requirements/SKILL.md +22 -11
  10. package/skills/erp-kit-app-2-requirements-review/SKILL.md +103 -0
  11. package/skills/erp-kit-app-2-requirements-review/references/best-practices-check.md +71 -0
  12. package/skills/erp-kit-app-2-requirements-review/references/boundary-consistency-check.md +74 -0
  13. package/skills/erp-kit-app-2-requirements-review/references/requirements-report-format.md +25 -0
  14. package/skills/erp-kit-app-3-plan/SKILL.md +154 -0
  15. package/skills/erp-kit-app-3-plan/references/resolver-extraction.md +89 -0
  16. package/skills/erp-kit-app-3-plan/references/screen-extraction.md +74 -0
  17. package/skills/erp-kit-app-3-plan/references/story-extraction.md +86 -0
  18. package/skills/erp-kit-app-4-plan-review/SKILL.md +168 -0
  19. package/skills/erp-kit-app-4-plan-review/references/actor-flow-parity.md +73 -0
  20. package/skills/erp-kit-app-4-plan-review/references/business-flow-story-parity.md +86 -0
  21. package/skills/erp-kit-app-4-plan-review/references/orphan-detection.md +69 -0
  22. package/skills/erp-kit-app-4-plan-review/references/parity-report-format.md +52 -0
  23. package/skills/erp-kit-app-4-plan-review/references/story-resolver-parity.md +83 -0
  24. package/skills/erp-kit-app-4-plan-review/references/story-screen-parity.md +73 -0
  25. package/skills/erp-kit-app-5-impl-backend/SKILL.md +98 -0
  26. package/skills/erp-kit-app-5-impl-backend/references/app-config.md +38 -0
  27. package/skills/erp-kit-app-5-impl-backend/references/module-wiring.md +48 -0
  28. package/skills/erp-kit-app-5-impl-backend/references/resolver-patterns.md +68 -0
  29. package/skills/erp-kit-app-6-impl-frontend/SKILL.md +74 -0
  30. package/skills/{erp-kit-app-5-implementation/references/frontend.md → erp-kit-app-6-impl-frontend/references/pages.md} +8 -90
  31. package/skills/erp-kit-app-7-impl-review/SKILL.md +176 -0
  32. package/skills/erp-kit-app-7-impl-review/references/impl-parity-report-format.md +52 -0
  33. package/skills/erp-kit-app-7-impl-review/references/module-wiring-parity.md +84 -0
  34. package/skills/erp-kit-app-7-impl-review/references/resolver-doc-code-parity.md +86 -0
  35. package/skills/erp-kit-app-7-impl-review/references/screen-doc-code-parity.md +86 -0
  36. package/skills/erp-kit-app-shared/SKILL.md +15 -0
  37. package/skills/erp-kit-app-shared/references/link-format-reference.md +13 -0
  38. package/skills/erp-kit-app-shared/references/naming-conventions.md +21 -0
  39. package/skills/erp-kit-app-shared/references/resolver-classification.md +23 -0
  40. package/skills/erp-kit-app-shared/references/schema-constraints.md +25 -0
  41. package/skills/erp-kit-module-1-requirements/SKILL.md +126 -0
  42. package/skills/erp-kit-module-1-requirements/references/boundary-analysis.md +51 -0
  43. package/skills/erp-kit-module-1-requirements/references/erp-research.md +57 -0
  44. package/skills/erp-kit-module-1-requirements/references/feature-doc.md +61 -0
  45. package/skills/erp-kit-module-2-requirements-review/SKILL.md +112 -0
  46. package/skills/erp-kit-module-2-requirements-review/references/best-practices-check.md +79 -0
  47. package/skills/erp-kit-module-2-requirements-review/references/boundary-consistency-check.md +70 -0
  48. package/skills/erp-kit-module-2-requirements-review/references/requirements-report-format.md +25 -0
  49. package/skills/erp-kit-module-3-plan/SKILL.md +107 -0
  50. package/skills/erp-kit-module-3-plan/references/command-extraction.md +87 -0
  51. package/skills/erp-kit-module-3-plan/references/model-extraction.md +72 -0
  52. package/skills/{erp-kit-module-2-feature-breakdown → erp-kit-module-3-plan}/references/naming.md +15 -1
  53. package/skills/erp-kit-module-3-plan/references/query-extraction.md +59 -0
  54. package/skills/erp-kit-module-4-plan-review/SKILL.md +158 -0
  55. package/skills/erp-kit-module-4-plan-review/references/command-model-consistency.md +46 -0
  56. package/skills/erp-kit-module-4-plan-review/references/feature-command-parity.md +97 -0
  57. package/skills/erp-kit-module-4-plan-review/references/feature-model-parity.md +47 -0
  58. package/skills/erp-kit-module-4-plan-review/references/feature-query-parity.md +70 -0
  59. package/skills/erp-kit-module-4-plan-review/references/parity-report-format.md +52 -0
  60. package/skills/erp-kit-module-5-impl/SKILL.md +120 -0
  61. package/skills/erp-kit-module-5-impl/references/command-impl.md +68 -0
  62. package/skills/erp-kit-module-5-impl/references/exports.md +10 -0
  63. package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/generated-code.md +2 -2
  64. package/skills/erp-kit-module-5-impl/references/model-impl.md +45 -0
  65. package/skills/erp-kit-module-5-impl/references/query-impl.md +53 -0
  66. package/skills/erp-kit-module-6-impl-review/SKILL.md +187 -0
  67. package/skills/erp-kit-module-6-impl-review/references/command-doc-code-parity.md +92 -0
  68. package/skills/erp-kit-module-6-impl-review/references/command-doc-test-parity.md +93 -0
  69. package/skills/erp-kit-module-6-impl-review/references/error-implementation-parity.md +95 -0
  70. package/skills/{erp-kit-module-5-impl-review → erp-kit-module-6-impl-review}/references/errors.md +2 -2
  71. package/skills/erp-kit-module-6-impl-review/references/impl-parity-report-format.md +52 -0
  72. package/skills/erp-kit-module-6-impl-review/references/model-doc-code-parity.md +80 -0
  73. package/skills/erp-kit-module-shared/SKILL.md +1 -1
  74. package/skills/erp-kit-module-shared/references/commands.md +1 -1
  75. package/skills/erp-kit-module-shared/references/errors.md +13 -10
  76. package/skills/erp-kit-module-shared/references/queries.md +110 -37
  77. package/skills/erp-kit-module-shared/references/structure.md +1 -1
  78. package/skills/erp-kit-module-shared/references/testing.md +10 -0
  79. package/skills/erp-kit-update/SKILL.md +4 -4
  80. package/src/app.ts +1 -1
  81. package/src/commands/app/index.ts +57 -24
  82. package/src/commands/check.ts +1 -1
  83. package/src/commands/generate-doc.test.ts +63 -0
  84. package/src/commands/generate-doc.ts +98 -0
  85. package/src/commands/index.ts +16 -5
  86. package/src/commands/init-module.test.ts +43 -0
  87. package/src/commands/init-module.ts +74 -0
  88. package/src/commands/init.test.ts +22 -69
  89. package/src/commands/init.ts +28 -115
  90. package/src/commands/lib/distribute.test.ts +126 -0
  91. package/src/commands/lib/distribute.ts +129 -0
  92. package/src/commands/module/generate.ts +33 -13
  93. package/src/commands/module/index.ts +18 -28
  94. package/src/commands/parse-doc-test-cases.ts +55 -0
  95. package/src/commands/sync-check.test.ts +173 -0
  96. package/src/commands/sync-check.ts +103 -2
  97. package/src/commands/update.test.ts +87 -0
  98. package/src/commands/update.ts +41 -0
  99. package/src/generator/generate-code-boilerplate.test.ts +142 -0
  100. package/src/generator/generate-code.test.ts +47 -12
  101. package/src/generator/generate-code.ts +123 -20
  102. package/src/integration.test.ts +3 -3
  103. package/src/module.ts +14 -97
  104. package/src/modules/item-management/README.md +8 -0
  105. package/src/modules/item-management/command/activateItem.generated.ts +1 -1
  106. package/src/modules/item-management/command/activateItem.test.ts +12 -18
  107. package/src/modules/item-management/command/activateItem.ts +9 -5
  108. package/src/modules/item-management/command/assignItemToTaxonomy.generated.ts +1 -1
  109. package/src/modules/item-management/command/assignItemToTaxonomy.test.ts +10 -24
  110. package/src/modules/item-management/command/assignItemToTaxonomy.ts +19 -16
  111. package/src/modules/item-management/command/createItem.generated.ts +1 -1
  112. package/src/modules/item-management/command/createItem.test.ts +11 -11
  113. package/src/modules/item-management/command/createItem.ts +16 -7
  114. package/src/modules/item-management/command/createTaxonomyNode.generated.ts +1 -1
  115. package/src/modules/item-management/command/createTaxonomyNode.test.ts +9 -9
  116. package/src/modules/item-management/command/createTaxonomyNode.ts +33 -14
  117. package/src/modules/item-management/command/deactivateItem.generated.ts +1 -1
  118. package/src/modules/item-management/command/deactivateItem.test.ts +12 -18
  119. package/src/modules/item-management/command/deactivateItem.ts +9 -5
  120. package/src/modules/item-management/command/deleteItem.generated.ts +1 -1
  121. package/src/modules/item-management/command/deleteItem.test.ts +10 -16
  122. package/src/modules/item-management/command/deleteItem.ts +9 -5
  123. package/src/modules/item-management/command/deleteTaxonomyNode.generated.ts +1 -1
  124. package/src/modules/item-management/command/deleteTaxonomyNode.test.ts +10 -16
  125. package/src/modules/item-management/command/deleteTaxonomyNode.ts +22 -12
  126. package/src/modules/item-management/command/moveTaxonomyNode.generated.ts +1 -1
  127. package/src/modules/item-management/command/moveTaxonomyNode.test.ts +10 -10
  128. package/src/modules/item-management/command/moveTaxonomyNode.ts +63 -19
  129. package/src/modules/item-management/command/reactivateItem.generated.ts +1 -1
  130. package/src/modules/item-management/command/reactivateItem.test.ts +12 -18
  131. package/src/modules/item-management/command/reactivateItem.ts +9 -5
  132. package/src/modules/item-management/command/removeItemFromTaxonomy.generated.ts +1 -1
  133. package/src/modules/item-management/command/removeItemFromTaxonomy.test.ts +9 -16
  134. package/src/modules/item-management/command/removeItemFromTaxonomy.ts +11 -6
  135. package/src/modules/item-management/command/updateItem.generated.ts +1 -1
  136. package/src/modules/item-management/command/updateItem.test.ts +16 -16
  137. package/src/modules/item-management/command/updateItem.ts +11 -6
  138. package/src/modules/item-management/command/updateTaxonomyNode.generated.ts +1 -1
  139. package/src/modules/item-management/command/updateTaxonomyNode.test.ts +14 -20
  140. package/src/modules/item-management/command/updateTaxonomyNode.ts +9 -6
  141. package/src/modules/item-management/docs/commands/ActivateItem.md +8 -0
  142. package/src/modules/item-management/docs/commands/AssignItemToTaxonomy.md +7 -0
  143. package/src/modules/item-management/docs/commands/CreateItem.md +10 -0
  144. package/src/modules/item-management/docs/commands/CreateTaxonomyNode.md +9 -0
  145. package/src/modules/item-management/docs/commands/DeactivateItem.md +8 -0
  146. package/src/modules/item-management/docs/commands/DeleteItem.md +7 -0
  147. package/src/modules/item-management/docs/commands/DeleteTaxonomyNode.md +7 -0
  148. package/src/modules/item-management/docs/commands/MoveTaxonomyNode.md +10 -0
  149. package/src/modules/item-management/docs/commands/ReactivateItem.md +8 -0
  150. package/src/modules/item-management/docs/commands/RemoveItemFromTaxonomy.md +5 -0
  151. package/src/modules/item-management/docs/commands/UpdateItem.md +15 -0
  152. package/src/modules/item-management/docs/commands/UpdateTaxonomyNode.md +9 -0
  153. package/src/modules/item-management/docs/queries/CalculateNodeDepth.md +8 -0
  154. package/src/modules/item-management/docs/queries/CalculateSubtreeDepth.md +7 -0
  155. package/src/modules/item-management/docs/queries/DetectCircularReference.md +9 -0
  156. package/src/modules/item-management/docs/queries/GetItem.md +9 -0
  157. package/src/modules/item-management/docs/queries/GetItemTaxonomyAssignment.md +5 -0
  158. package/src/modules/item-management/docs/queries/GetTaxonomyNode.md +7 -0
  159. package/src/modules/item-management/docs/queries/GetTaxonomyNodeAssignments.md +5 -0
  160. package/src/modules/item-management/docs/queries/GetTaxonomyNodeChildren.md +6 -0
  161. package/src/modules/item-management/index.ts +0 -51
  162. package/src/modules/item-management/lib/errors.generated.ts +24 -24
  163. package/src/modules/item-management/lib/permissions.generated.ts +1 -1
  164. package/src/modules/item-management/lib/types.ts +1 -1
  165. package/src/modules/item-management/module.ts +1 -1
  166. package/src/modules/item-management/query/calculateNodeDepth.generated.ts +1 -1
  167. package/src/modules/item-management/query/calculateNodeDepth.test.ts +21 -6
  168. package/src/modules/item-management/query/calculateNodeDepth.ts +2 -2
  169. package/src/modules/item-management/query/calculateSubtreeDepth.generated.ts +1 -1
  170. package/src/modules/item-management/query/calculateSubtreeDepth.test.ts +17 -5
  171. package/src/modules/item-management/query/calculateSubtreeDepth.ts +2 -2
  172. package/src/modules/item-management/query/detectCircularReference.generated.ts +1 -1
  173. package/src/modules/item-management/query/detectCircularReference.test.ts +25 -7
  174. package/src/modules/item-management/query/detectCircularReference.ts +4 -4
  175. package/src/modules/item-management/query/getItem.generated.ts +1 -1
  176. package/src/modules/item-management/query/getItem.test.ts +25 -7
  177. package/src/modules/item-management/query/getItem.ts +2 -2
  178. package/src/modules/item-management/query/getItemTaxonomyAssignment.generated.ts +1 -1
  179. package/src/modules/item-management/query/getItemTaxonomyAssignment.test.ts +9 -3
  180. package/src/modules/item-management/query/getItemTaxonomyAssignment.ts +2 -2
  181. package/src/modules/item-management/query/getTaxonomyNode.generated.ts +1 -1
  182. package/src/modules/item-management/query/getTaxonomyNode.test.ts +17 -5
  183. package/src/modules/item-management/query/getTaxonomyNode.ts +2 -2
  184. package/src/modules/item-management/query/getTaxonomyNodeAssignments.generated.ts +1 -1
  185. package/src/modules/item-management/query/getTaxonomyNodeAssignments.test.ts +9 -3
  186. package/src/modules/item-management/query/getTaxonomyNodeAssignments.ts +2 -2
  187. package/src/modules/item-management/query/getTaxonomyNodeChildren.generated.ts +1 -1
  188. package/src/modules/item-management/query/getTaxonomyNodeChildren.test.ts +13 -4
  189. package/src/modules/item-management/query/getTaxonomyNodeChildren.ts +2 -2
  190. package/src/modules/item-management/tailor.config.ts +6 -4
  191. package/src/modules/item-management/tailor.d.ts +13 -0
  192. package/src/modules/primitives/README.md +8 -0
  193. package/src/modules/primitives/command/activateCategory.generated.ts +1 -1
  194. package/src/modules/primitives/command/activateCategory.test.ts +8 -18
  195. package/src/modules/primitives/command/activateCategory.ts +9 -5
  196. package/src/modules/primitives/command/activateCurrency.generated.ts +1 -1
  197. package/src/modules/primitives/command/activateCurrency.test.ts +8 -18
  198. package/src/modules/primitives/command/activateCurrency.ts +9 -5
  199. package/src/modules/primitives/command/activateUnit.generated.ts +1 -1
  200. package/src/modules/primitives/command/activateUnit.test.ts +8 -15
  201. package/src/modules/primitives/command/activateUnit.ts +9 -5
  202. package/src/modules/primitives/command/createCategory.generated.ts +1 -1
  203. package/src/modules/primitives/command/createCategory.test.ts +29 -44
  204. package/src/modules/primitives/command/createCategory.ts +9 -5
  205. package/src/modules/primitives/command/createCurrency.generated.ts +1 -1
  206. package/src/modules/primitives/command/createCurrency.test.ts +53 -78
  207. package/src/modules/primitives/command/createCurrency.ts +9 -6
  208. package/src/modules/primitives/command/createExchangeRate.generated.ts +1 -1
  209. package/src/modules/primitives/command/createExchangeRate.test.ts +59 -97
  210. package/src/modules/primitives/command/createExchangeRate.ts +13 -7
  211. package/src/modules/primitives/command/createUnit.generated.ts +1 -1
  212. package/src/modules/primitives/command/createUnit.test.ts +59 -90
  213. package/src/modules/primitives/command/createUnit.ts +9 -6
  214. package/src/modules/primitives/command/deactivateCategory.generated.ts +1 -1
  215. package/src/modules/primitives/command/deactivateCategory.test.ts +15 -33
  216. package/src/modules/primitives/command/deactivateCategory.ts +9 -5
  217. package/src/modules/primitives/command/deactivateCurrency.generated.ts +1 -1
  218. package/src/modules/primitives/command/deactivateCurrency.test.ts +12 -26
  219. package/src/modules/primitives/command/deactivateCurrency.ts +9 -5
  220. package/src/modules/primitives/command/deactivateUnit.generated.ts +1 -1
  221. package/src/modules/primitives/command/deactivateUnit.test.ts +15 -30
  222. package/src/modules/primitives/command/deactivateUnit.ts +14 -7
  223. package/src/modules/primitives/command/setBaseCurrency.generated.ts +1 -1
  224. package/src/modules/primitives/command/setBaseCurrency.test.ts +18 -40
  225. package/src/modules/primitives/command/setBaseCurrency.ts +15 -7
  226. package/src/modules/primitives/command/setReferenceUnit.generated.ts +1 -1
  227. package/src/modules/primitives/command/setReferenceUnit.test.ts +22 -44
  228. package/src/modules/primitives/command/setReferenceUnit.ts +21 -9
  229. package/src/modules/primitives/docs/commands/ActivateCategory.md +6 -0
  230. package/src/modules/primitives/docs/commands/ActivateCurrency.md +6 -0
  231. package/src/modules/primitives/docs/commands/ActivateUnit.md +6 -0
  232. package/src/modules/primitives/docs/commands/CreateCategory.md +6 -0
  233. package/src/modules/primitives/docs/commands/CreateCurrency.md +10 -0
  234. package/src/modules/primitives/docs/commands/CreateExchangeRate.md +11 -0
  235. package/src/modules/primitives/docs/commands/CreateUnit.md +10 -0
  236. package/src/modules/primitives/docs/commands/DeactivateCategory.md +7 -0
  237. package/src/modules/primitives/docs/commands/DeactivateCurrency.md +7 -0
  238. package/src/modules/primitives/docs/commands/DeactivateUnit.md +7 -0
  239. package/src/modules/primitives/docs/commands/SetBaseCurrency.md +7 -0
  240. package/src/modules/primitives/docs/commands/SetReferenceUnit.md +7 -0
  241. package/src/modules/primitives/docs/queries/ConvertAmount.md +14 -0
  242. package/src/modules/primitives/docs/queries/ConvertQuantity.md +13 -0
  243. package/src/modules/primitives/docs/queries/GetBaseCurrency.md +5 -0
  244. package/src/modules/primitives/docs/queries/GetCurrency.md +7 -0
  245. package/src/modules/primitives/docs/queries/GetUnit.md +7 -0
  246. package/src/modules/primitives/docs/queries/GetUoMCategory.md +7 -0
  247. package/src/modules/primitives/docs/queries/ListUnitsByCategory.md +15 -5
  248. package/src/modules/primitives/index.ts +0 -49
  249. package/src/modules/primitives/lib/errors.generated.ts +23 -23
  250. package/src/modules/primitives/lib/permissions.generated.ts +1 -1
  251. package/src/modules/primitives/lib/types.ts +1 -1
  252. package/src/modules/primitives/module.ts +1 -1
  253. package/src/modules/primitives/query/convertAmount.generated.ts +1 -1
  254. package/src/modules/primitives/query/convertAmount.test.ts +110 -77
  255. package/src/modules/primitives/query/convertAmount.ts +61 -47
  256. package/src/modules/primitives/query/convertQuantity.generated.ts +1 -1
  257. package/src/modules/primitives/query/convertQuantity.test.ts +99 -69
  258. package/src/modules/primitives/query/convertQuantity.ts +12 -10
  259. package/src/modules/primitives/query/getBaseCurrency.generated.ts +1 -1
  260. package/src/modules/primitives/query/getBaseCurrency.test.ts +10 -4
  261. package/src/modules/primitives/query/getBaseCurrency.ts +2 -2
  262. package/src/modules/primitives/query/getCurrency.generated.ts +1 -1
  263. package/src/modules/primitives/query/getCurrency.test.ts +17 -5
  264. package/src/modules/primitives/query/getCurrency.ts +2 -2
  265. package/src/modules/primitives/query/getUnit.generated.ts +1 -1
  266. package/src/modules/primitives/query/getUnit.test.ts +17 -5
  267. package/src/modules/primitives/query/getUnit.ts +2 -2
  268. package/src/modules/primitives/query/getUoMCategory.generated.ts +1 -1
  269. package/src/modules/primitives/query/getUoMCategory.test.ts +17 -5
  270. package/src/modules/primitives/query/getUoMCategory.ts +2 -2
  271. package/src/modules/primitives/query/listUnitsByCategory.generated.ts +1 -1
  272. package/src/modules/primitives/query/listUnitsByCategory.test.ts +80 -0
  273. package/src/modules/primitives/query/listUnitsByCategory.ts +19 -3
  274. package/src/modules/primitives/tailor.config.ts +6 -4
  275. package/src/modules/primitives/tailor.d.ts +13 -0
  276. package/src/modules/product-management/README.md +52 -0
  277. package/src/modules/product-management/command/activateProduct.generated.ts +6 -0
  278. package/src/modules/product-management/command/activateProduct.test.ts +40 -0
  279. package/src/modules/product-management/command/activateProduct.ts +42 -0
  280. package/src/modules/product-management/command/assignProductToCategory.generated.ts +6 -0
  281. package/src/modules/product-management/command/assignProductToCategory.test.ts +90 -0
  282. package/src/modules/product-management/command/assignProductToCategory.ts +62 -0
  283. package/src/modules/product-management/command/createProduct.generated.ts +6 -0
  284. package/src/modules/product-management/command/createProduct.test.ts +149 -0
  285. package/src/modules/product-management/command/createProduct.ts +73 -0
  286. package/src/modules/product-management/command/createProductAttribute.generated.ts +6 -0
  287. package/src/modules/product-management/command/createProductAttribute.test.ts +70 -0
  288. package/src/modules/product-management/command/createProductAttribute.ts +53 -0
  289. package/src/modules/product-management/command/createProductAttributeValue.generated.ts +6 -0
  290. package/src/modules/product-management/command/createProductAttributeValue.test.ts +68 -0
  291. package/src/modules/product-management/command/createProductAttributeValue.ts +63 -0
  292. package/src/modules/product-management/command/createProductCategory.generated.ts +6 -0
  293. package/src/modules/product-management/command/createProductCategory.test.ts +135 -0
  294. package/src/modules/product-management/command/createProductCategory.ts +82 -0
  295. package/src/modules/product-management/command/deactivateProduct.generated.ts +6 -0
  296. package/src/modules/product-management/command/deactivateProduct.test.ts +40 -0
  297. package/src/modules/product-management/command/deactivateProduct.ts +42 -0
  298. package/src/modules/product-management/command/deleteProduct.generated.ts +6 -0
  299. package/src/modules/product-management/command/deleteProduct.test.ts +42 -0
  300. package/src/modules/product-management/command/deleteProduct.ts +42 -0
  301. package/src/modules/product-management/command/deleteProductAttribute.generated.ts +6 -0
  302. package/src/modules/product-management/command/deleteProductAttribute.test.ts +49 -0
  303. package/src/modules/product-management/command/deleteProductAttribute.ts +45 -0
  304. package/src/modules/product-management/command/deleteProductAttributeValue.generated.ts +6 -0
  305. package/src/modules/product-management/command/deleteProductAttributeValue.test.ts +71 -0
  306. package/src/modules/product-management/command/deleteProductAttributeValue.ts +68 -0
  307. package/src/modules/product-management/command/deleteProductCategory.generated.ts +6 -0
  308. package/src/modules/product-management/command/deleteProductCategory.test.ts +74 -0
  309. package/src/modules/product-management/command/deleteProductCategory.ts +53 -0
  310. package/src/modules/product-management/command/generateVariants.generated.ts +6 -0
  311. package/src/modules/product-management/command/generateVariants.test.ts +365 -0
  312. package/src/modules/product-management/command/generateVariants.ts +168 -0
  313. package/src/modules/product-management/command/moveProductCategory.generated.ts +6 -0
  314. package/src/modules/product-management/command/moveProductCategory.test.ts +170 -0
  315. package/src/modules/product-management/command/moveProductCategory.ts +124 -0
  316. package/src/modules/product-management/command/reactivateProduct.generated.ts +6 -0
  317. package/src/modules/product-management/command/reactivateProduct.test.ts +40 -0
  318. package/src/modules/product-management/command/reactivateProduct.ts +42 -0
  319. package/src/modules/product-management/command/removeProductFromCategory.generated.ts +6 -0
  320. package/src/modules/product-management/command/removeProductFromCategory.test.ts +42 -0
  321. package/src/modules/product-management/command/removeProductFromCategory.ts +32 -0
  322. package/src/modules/product-management/command/setProductAttributeAssignment.generated.ts +6 -0
  323. package/src/modules/product-management/command/setProductAttributeAssignment.test.ts +206 -0
  324. package/src/modules/product-management/command/setProductAttributeAssignment.ts +102 -0
  325. package/src/modules/product-management/command/updateProduct.generated.ts +6 -0
  326. package/src/modules/product-management/command/updateProduct.test.ts +168 -0
  327. package/src/modules/product-management/command/updateProduct.ts +95 -0
  328. package/src/modules/product-management/command/updateProductAttribute.generated.ts +6 -0
  329. package/src/modules/product-management/command/updateProductAttribute.test.ts +101 -0
  330. package/src/modules/product-management/command/updateProductAttribute.ts +68 -0
  331. package/src/modules/product-management/command/updateProductAttributeValue.generated.ts +6 -0
  332. package/src/modules/product-management/command/updateProductAttributeValue.test.ts +80 -0
  333. package/src/modules/product-management/command/updateProductAttributeValue.ts +58 -0
  334. package/src/modules/product-management/command/updateProductCategory.generated.ts +6 -0
  335. package/src/modules/product-management/command/updateProductCategory.test.ts +80 -0
  336. package/src/modules/product-management/command/updateProductCategory.ts +66 -0
  337. package/src/modules/product-management/db/product.ts +47 -0
  338. package/src/modules/product-management/db/productAttribute.ts +26 -0
  339. package/src/modules/product-management/db/productAttributeAssignment.ts +58 -0
  340. package/src/modules/product-management/db/productAttributeValue.ts +39 -0
  341. package/src/modules/product-management/db/productCategory.ts +34 -0
  342. package/src/modules/product-management/db/productCategoryAssignment.ts +49 -0
  343. package/src/modules/product-management/db/productVariant.ts +52 -0
  344. package/src/modules/product-management/docs/commands/ActivateProduct.md +39 -0
  345. package/src/modules/product-management/docs/commands/AssignProductToCategory.md +43 -0
  346. package/src/modules/product-management/docs/commands/CreateProduct.md +48 -0
  347. package/src/modules/product-management/docs/commands/CreateProductAttribute.md +39 -0
  348. package/src/modules/product-management/docs/commands/CreateProductAttributeValue.md +42 -0
  349. package/src/modules/product-management/docs/commands/CreateProductCategory.md +54 -0
  350. package/src/modules/product-management/docs/commands/DeactivateProduct.md +39 -0
  351. package/src/modules/product-management/docs/commands/DeleteProduct.md +42 -0
  352. package/src/modules/product-management/docs/commands/DeleteProductAttribute.md +39 -0
  353. package/src/modules/product-management/docs/commands/DeleteProductAttributeValue.md +42 -0
  354. package/src/modules/product-management/docs/commands/DeleteProductCategory.md +43 -0
  355. package/src/modules/product-management/docs/commands/GenerateVariants.md +68 -0
  356. package/src/modules/product-management/docs/commands/MoveProductCategory.md +54 -0
  357. package/src/modules/product-management/docs/commands/ReactivateProduct.md +38 -0
  358. package/src/modules/product-management/docs/commands/RemoveProductFromCategory.md +34 -0
  359. package/src/modules/product-management/docs/commands/SetProductAttributeAssignment.md +62 -0
  360. package/src/modules/product-management/docs/commands/UpdateProduct.md +61 -0
  361. package/src/modules/product-management/docs/commands/UpdateProductAttribute.md +46 -0
  362. package/src/modules/product-management/docs/commands/UpdateProductAttributeValue.md +47 -0
  363. package/src/modules/product-management/docs/commands/UpdateProductCategory.md +46 -0
  364. package/src/modules/product-management/docs/features/attribute-management.md +48 -0
  365. package/src/modules/product-management/docs/features/product-category.md +71 -0
  366. package/src/modules/product-management/docs/features/product-lifecycle.md +66 -0
  367. package/src/modules/product-management/docs/features/variant-generation.md +77 -0
  368. package/src/modules/product-management/docs/models/Product.md +58 -0
  369. package/src/modules/product-management/docs/models/ProductAttribute.md +37 -0
  370. package/src/modules/product-management/docs/models/ProductAttributeAssignment.md +41 -0
  371. package/src/modules/product-management/docs/models/ProductAttributeValue.md +40 -0
  372. package/src/modules/product-management/docs/models/ProductCategory.md +46 -0
  373. package/src/modules/product-management/docs/models/ProductCategoryAssignment.md +37 -0
  374. package/src/modules/product-management/docs/models/ProductVariant.md +41 -0
  375. package/src/modules/product-management/docs/queries/CalculateCategoryDepth.md +47 -0
  376. package/src/modules/product-management/docs/queries/DetectCategoryCircularReference.md +51 -0
  377. package/src/modules/product-management/docs/queries/GetProduct.md +42 -0
  378. package/src/modules/product-management/docs/queries/GetProductAttribute.md +42 -0
  379. package/src/modules/product-management/docs/queries/GetProductAttributeAssignment.md +34 -0
  380. package/src/modules/product-management/docs/queries/GetProductAttributeValue.md +40 -0
  381. package/src/modules/product-management/docs/queries/GetProductCategory.md +42 -0
  382. package/src/modules/product-management/docs/queries/GetProductCategoryAssignment.md +34 -0
  383. package/src/modules/product-management/docs/queries/GetProductVariant.md +41 -0
  384. package/src/modules/product-management/docs/queries/ListAttributeAssignmentsByAttribute.md +34 -0
  385. package/src/modules/product-management/docs/queries/ListCategoryAssignmentsByProduct.md +35 -0
  386. package/src/modules/product-management/docs/queries/ListProductAttributeAssignments.md +34 -0
  387. package/src/modules/product-management/docs/queries/ListProductAttributeValues.md +36 -0
  388. package/src/modules/product-management/docs/queries/ListProductCategoryAssignments.md +34 -0
  389. package/src/modules/product-management/docs/queries/ListProductCategoryChildren.md +34 -0
  390. package/src/modules/product-management/docs/queries/ListProductVariants.md +34 -0
  391. package/src/modules/product-management/generated/enums.ts +9 -0
  392. package/src/modules/product-management/generated/kysely-tailordb.ts +100 -0
  393. package/src/modules/product-management/index.ts +2 -0
  394. package/src/modules/product-management/lib/_db_deps.ts +17 -0
  395. package/src/modules/product-management/lib/errors.generated.ts +152 -0
  396. package/src/modules/product-management/lib/permissions.generated.ts +25 -0
  397. package/src/modules/product-management/lib/types.ts +51 -0
  398. package/src/modules/product-management/module.ts +201 -0
  399. package/src/modules/product-management/query/calculateCategoryDepth.generated.ts +5 -0
  400. package/src/modules/product-management/query/calculateCategoryDepth.test.ts +72 -0
  401. package/src/modules/product-management/query/calculateCategoryDepth.ts +37 -0
  402. package/src/modules/product-management/query/detectCategoryCircularReference.generated.ts +5 -0
  403. package/src/modules/product-management/query/detectCategoryCircularReference.test.ts +72 -0
  404. package/src/modules/product-management/query/detectCategoryCircularReference.ts +44 -0
  405. package/src/modules/product-management/query/getProduct.generated.ts +5 -0
  406. package/src/modules/product-management/query/getProduct.test.ts +59 -0
  407. package/src/modules/product-management/query/getProduct.ts +18 -0
  408. package/src/modules/product-management/query/getProductAttribute.generated.ts +5 -0
  409. package/src/modules/product-management/query/getProductAttribute.test.ts +59 -0
  410. package/src/modules/product-management/query/getProductAttribute.ts +18 -0
  411. package/src/modules/product-management/query/getProductAttributeAssignment.generated.ts +5 -0
  412. package/src/modules/product-management/query/getProductAttributeAssignment.test.ts +37 -0
  413. package/src/modules/product-management/query/getProductAttributeAssignment.ts +18 -0
  414. package/src/modules/product-management/query/getProductAttributeValue.generated.ts +5 -0
  415. package/src/modules/product-management/query/getProductAttributeValue.test.ts +31 -0
  416. package/src/modules/product-management/query/getProductAttributeValue.ts +16 -0
  417. package/src/modules/product-management/query/getProductCategory.generated.ts +5 -0
  418. package/src/modules/product-management/query/getProductCategory.test.ts +59 -0
  419. package/src/modules/product-management/query/getProductCategory.ts +18 -0
  420. package/src/modules/product-management/query/getProductCategoryAssignment.generated.ts +5 -0
  421. package/src/modules/product-management/query/getProductCategoryAssignment.test.ts +37 -0
  422. package/src/modules/product-management/query/getProductCategoryAssignment.ts +18 -0
  423. package/src/modules/product-management/query/getProductVariant.generated.ts +5 -0
  424. package/src/modules/product-management/query/getProductVariant.test.ts +43 -0
  425. package/src/modules/product-management/query/getProductVariant.ts +20 -0
  426. package/src/modules/product-management/query/listAttributeAssignmentsByAttribute.generated.ts +5 -0
  427. package/src/modules/product-management/query/listAttributeAssignmentsByAttribute.test.ts +31 -0
  428. package/src/modules/product-management/query/listAttributeAssignmentsByAttribute.ts +16 -0
  429. package/src/modules/product-management/query/listCategoryAssignmentsByProduct.generated.ts +5 -0
  430. package/src/modules/product-management/query/listCategoryAssignmentsByProduct.test.ts +31 -0
  431. package/src/modules/product-management/query/listCategoryAssignmentsByProduct.ts +16 -0
  432. package/src/modules/product-management/query/listProductAttributeAssignments.generated.ts +5 -0
  433. package/src/modules/product-management/query/listProductAttributeAssignments.test.ts +31 -0
  434. package/src/modules/product-management/query/listProductAttributeAssignments.ts +16 -0
  435. package/src/modules/product-management/query/listProductAttributeValues.generated.ts +5 -0
  436. package/src/modules/product-management/query/listProductAttributeValues.test.ts +31 -0
  437. package/src/modules/product-management/query/listProductAttributeValues.ts +17 -0
  438. package/src/modules/product-management/query/listProductCategoryAssignments.generated.ts +5 -0
  439. package/src/modules/product-management/query/listProductCategoryAssignments.test.ts +31 -0
  440. package/src/modules/product-management/query/listProductCategoryAssignments.ts +16 -0
  441. package/src/modules/product-management/query/listProductCategoryChildren.generated.ts +5 -0
  442. package/src/modules/product-management/query/listProductCategoryChildren.test.ts +31 -0
  443. package/src/modules/product-management/query/listProductCategoryChildren.ts +16 -0
  444. package/src/modules/product-management/query/listProductVariants.generated.ts +5 -0
  445. package/src/modules/product-management/query/listProductVariants.test.ts +31 -0
  446. package/src/modules/product-management/query/listProductVariants.ts +16 -0
  447. package/src/modules/product-management/tailor.config.ts +13 -0
  448. package/src/modules/product-management/tailor.d.ts +13 -0
  449. package/src/modules/product-management/testing/fixtures.ts +151 -0
  450. package/src/modules/user-management/README.md +9 -3
  451. package/src/modules/user-management/command/activateUser.generated.ts +1 -1
  452. package/src/modules/user-management/command/activateUser.test.ts +12 -65
  453. package/src/modules/user-management/command/activateUser.ts +5 -20
  454. package/src/modules/user-management/command/assignPermissionToRole.generated.ts +1 -1
  455. package/src/modules/user-management/command/assignPermissionToRole.test.ts +25 -60
  456. package/src/modules/user-management/command/assignPermissionToRole.ts +5 -24
  457. package/src/modules/user-management/command/assignRoleToUser.generated.ts +1 -1
  458. package/src/modules/user-management/command/assignRoleToUser.test.ts +35 -87
  459. package/src/modules/user-management/command/assignRoleToUser.ts +5 -24
  460. package/src/modules/user-management/command/createPermission.generated.ts +1 -1
  461. package/src/modules/user-management/command/createPermission.test.ts +23 -33
  462. package/src/modules/user-management/command/createPermission.ts +4 -5
  463. package/src/modules/user-management/command/createRole.generated.ts +1 -1
  464. package/src/modules/user-management/command/createRole.test.ts +17 -27
  465. package/src/modules/user-management/command/createRole.ts +4 -5
  466. package/src/modules/user-management/command/createUser.generated.ts +1 -1
  467. package/src/modules/user-management/command/createUser.test.ts +31 -118
  468. package/src/modules/user-management/command/createUser.ts +7 -25
  469. package/src/modules/user-management/command/deactivateUser.generated.ts +1 -1
  470. package/src/modules/user-management/command/deactivateUser.test.ts +12 -65
  471. package/src/modules/user-management/command/deactivateUser.ts +6 -21
  472. package/src/modules/user-management/command/reactivateUser.generated.ts +1 -1
  473. package/src/modules/user-management/command/reactivateUser.test.ts +13 -66
  474. package/src/modules/user-management/command/reactivateUser.ts +5 -20
  475. package/src/modules/user-management/command/revokePermissionFromRole.generated.ts +1 -1
  476. package/src/modules/user-management/command/revokePermissionFromRole.test.ts +24 -62
  477. package/src/modules/user-management/command/revokePermissionFromRole.ts +5 -24
  478. package/src/modules/user-management/command/revokeRoleFromUser.generated.ts +1 -1
  479. package/src/modules/user-management/command/revokeRoleFromUser.test.ts +24 -60
  480. package/src/modules/user-management/command/revokeRoleFromUser.ts +5 -24
  481. package/src/modules/user-management/docs/commands/ActivateUser.md +7 -0
  482. package/src/modules/user-management/docs/commands/AssignPermissionToRole.md +7 -0
  483. package/src/modules/user-management/docs/commands/AssignRoleToUser.md +9 -0
  484. package/src/modules/user-management/docs/commands/CreatePermission.md +12 -0
  485. package/src/modules/user-management/docs/commands/CreateRole.md +9 -0
  486. package/src/modules/user-management/docs/commands/CreateUser.md +11 -0
  487. package/src/modules/user-management/docs/commands/DeactivateUser.md +7 -0
  488. package/src/modules/user-management/docs/commands/ReactivateUser.md +7 -0
  489. package/src/modules/user-management/docs/commands/RevokePermissionFromRole.md +7 -0
  490. package/src/modules/user-management/docs/commands/RevokeRoleFromUser.md +7 -0
  491. package/src/modules/user-management/index.ts +0 -30
  492. package/src/modules/user-management/lib/errors.generated.ts +14 -14
  493. package/src/modules/user-management/lib/permissions.generated.ts +1 -2
  494. package/src/modules/user-management/lib/recomputeUserPermissions.ts +4 -3
  495. package/src/modules/user-management/lib/types.ts +1 -1
  496. package/src/modules/user-management/module.ts +2 -7
  497. package/src/modules/user-management/tailor.config.ts +6 -4
  498. package/src/modules/user-management/tailor.d.ts +13 -0
  499. package/src/modules/user-management/testing/fixtures.ts +1 -20
  500. package/src/schemas.ts +1 -1
  501. package/src/{modules/shared → shared}/defineCommand.test.ts +23 -7
  502. package/src/{modules/shared → shared}/defineCommand.ts +19 -10
  503. package/src/{modules/shared/internal.ts → shared/index.ts} +9 -1
  504. package/src/shared/pagination.test.ts +43 -0
  505. package/src/shared/pagination.ts +22 -0
  506. package/src/{modules/shared → shared}/types.ts +13 -0
  507. package/src/{modules/testing → testing}/index.ts +14 -7
  508. package/src/testing.ts +1 -1
  509. package/src/util.ts +8 -0
  510. package/templates/config/license.config.json +4 -0
  511. package/templates/scaffold/app/backend/.env.example +1 -0
  512. package/templates/scaffold/app/backend/__dot__gitignore +4 -0
  513. package/templates/scaffold/app/backend/eslint.config.js +32 -0
  514. package/templates/scaffold/app/backend/package.json +31 -0
  515. package/templates/scaffold/app/backend/seed/data/AuditEvent.jsonl +0 -0
  516. package/templates/scaffold/app/backend/seed/data/Permission.jsonl +0 -0
  517. package/templates/scaffold/app/backend/seed/data/Permission.schema.ts +20 -0
  518. package/templates/scaffold/app/backend/seed/data/Role.jsonl +0 -0
  519. package/templates/scaffold/app/backend/seed/data/Role.schema.ts +20 -0
  520. package/templates/scaffold/app/backend/seed/data/RolePermission.jsonl +0 -0
  521. package/templates/scaffold/app/backend/seed/data/RolePermission.schema.ts +24 -0
  522. package/templates/scaffold/app/backend/seed/data/User.jsonl +1 -0
  523. package/templates/scaffold/app/backend/seed/data/User.schema.ts +20 -0
  524. package/templates/scaffold/app/backend/seed/data/UserRole.jsonl +0 -0
  525. package/templates/scaffold/app/backend/seed/data/UserRole.schema.ts +24 -0
  526. package/templates/scaffold/app/backend/seed/data/_User.jsonl +1 -0
  527. package/templates/scaffold/app/backend/seed/data/_User.schema.ts +30 -0
  528. package/templates/scaffold/app/backend/seed/exec.mjs +659 -0
  529. package/templates/scaffold/app/backend/src/executors/permissionCreated.ts +3 -0
  530. package/templates/scaffold/app/backend/src/executors/permissionDeleted.ts +3 -0
  531. package/templates/scaffold/app/backend/src/generated/kysely-tailordb.ts +83 -0
  532. package/templates/scaffold/app/backend/src/modules.ts +9 -0
  533. package/templates/scaffold/app/backend/src/resolvers/createUser.ts +46 -0
  534. package/templates/scaffold/app/backend/tailor.config.ts +68 -0
  535. package/templates/scaffold/app/backend/tailor.d.ts +15 -0
  536. package/templates/scaffold/app/backend/tsconfig.json +19 -0
  537. package/templates/scaffold/app/docs/actors/.gitkeep +0 -0
  538. package/templates/scaffold/app/docs/business-flow/.gitkeep +0 -0
  539. package/templates/scaffold/app/docs/resolver/.gitkeep +0 -0
  540. package/templates/scaffold/app/docs/screen/.gitkeep +0 -0
  541. package/templates/scaffold/app/frontend/.env.example +2 -0
  542. package/templates/scaffold/app/frontend/__dot__gitignore +3 -0
  543. package/templates/scaffold/app/frontend/components.json +23 -0
  544. package/templates/scaffold/app/frontend/eslint.config.js +48 -0
  545. package/templates/scaffold/app/frontend/index.html +13 -0
  546. package/templates/scaffold/app/frontend/package.json +53 -0
  547. package/templates/scaffold/app/frontend/scripts/generate-graphql.mjs +6 -0
  548. package/templates/scaffold/app/frontend/src/App.tsx +58 -0
  549. package/templates/scaffold/app/frontend/src/components/composed/empty-state.tsx +26 -0
  550. package/templates/scaffold/app/frontend/src/components/composed/error-fallback.tsx +28 -0
  551. package/templates/scaffold/app/frontend/src/components/composed/loading.tsx +13 -0
  552. package/templates/scaffold/app/frontend/src/components/ui/badge.tsx +39 -0
  553. package/templates/scaffold/app/frontend/src/components/ui/button.tsx +60 -0
  554. package/templates/scaffold/app/frontend/src/components/ui/card.tsx +75 -0
  555. package/templates/scaffold/app/frontend/src/components/ui/form.tsx +152 -0
  556. package/templates/scaffold/app/frontend/src/components/ui/input.tsx +21 -0
  557. package/templates/scaffold/app/frontend/src/components/ui/label.tsx +21 -0
  558. package/templates/scaffold/app/frontend/src/components/ui/spinner.tsx +16 -0
  559. package/templates/scaffold/app/frontend/src/components/ui/table.tsx +90 -0
  560. package/templates/scaffold/app/frontend/src/graphql/generated/graphql-env.d.ts +103 -0
  561. package/templates/scaffold/app/frontend/src/graphql/generated/schema.graphql +1235 -0
  562. package/templates/scaffold/app/frontend/src/graphql/index.ts +15 -0
  563. package/templates/scaffold/app/frontend/src/index.css +5 -0
  564. package/templates/scaffold/app/frontend/src/lib/auth-client.ts +17 -0
  565. package/templates/scaffold/app/frontend/src/lib/utils.ts +6 -0
  566. package/templates/scaffold/app/frontend/src/main.tsx +10 -0
  567. package/templates/scaffold/app/frontend/src/pages/page.tsx +20 -0
  568. package/templates/scaffold/app/frontend/src/pages/user-management/page.tsx +19 -0
  569. package/templates/scaffold/app/frontend/src/pages/user-management/profile/page.tsx +97 -0
  570. package/templates/scaffold/app/frontend/src/pages/user-management/user/[id]/components/user-detail.tsx +58 -0
  571. package/templates/scaffold/app/frontend/src/pages/user-management/user/[id]/page.tsx +51 -0
  572. package/templates/scaffold/app/frontend/src/pages/user-management/user/components/users-table.tsx +101 -0
  573. package/templates/scaffold/app/frontend/src/pages/user-management/user/create/components/create-user-form.tsx +99 -0
  574. package/templates/scaffold/app/frontend/src/pages/user-management/user/create/page.tsx +19 -0
  575. package/templates/scaffold/app/frontend/src/pages/user-management/user/page.tsx +61 -0
  576. package/templates/scaffold/app/frontend/src/providers/graphql-provider.tsx +21 -0
  577. package/templates/scaffold/app/frontend/tsconfig.app.json +35 -0
  578. package/templates/scaffold/app/frontend/tsconfig.json +16 -0
  579. package/templates/scaffold/app/frontend/tsconfig.node.json +23 -0
  580. package/templates/scaffold/app/frontend/vite.config.ts +23 -0
  581. package/templates/scaffold/module/command/.gitkeep +0 -0
  582. package/templates/scaffold/module/db/.gitkeep +0 -0
  583. package/templates/scaffold/module/executor/.gitkeep +0 -0
  584. package/templates/scaffold/module/generated/.gitkeep +0 -0
  585. package/templates/scaffold/module/index.ts +2 -0
  586. package/templates/scaffold/module/lib/errors.ts +1 -0
  587. package/templates/scaffold/module/lib/types.ts +4 -0
  588. package/templates/scaffold/module/module.ts +7 -0
  589. package/templates/scaffold/module/permissions.ts +3 -0
  590. package/templates/scaffold/module/query/.gitkeep +0 -0
  591. package/templates/scaffold/module/tailor.config.ts +13 -0
  592. package/templates/scaffold/module/testing/fixtures.ts +1 -0
  593. package/templates/workflows/erp-kit-check.yml +37 -0
  594. package/dist/cli.js +0 -1654
  595. package/skills/erp-kit-app-2-breakdown/SKILL.md +0 -88
  596. package/skills/erp-kit-app-3-doc-review/SKILL.md +0 -112
  597. package/skills/erp-kit-app-4-impl-spec/SKILL.md +0 -116
  598. package/skills/erp-kit-app-5-implementation/SKILL.md +0 -149
  599. package/skills/erp-kit-app-5-implementation/references/backend.md +0 -232
  600. package/skills/erp-kit-module-1-docs/SKILL.md +0 -111
  601. package/skills/erp-kit-module-2-feature-breakdown/SKILL.md +0 -76
  602. package/skills/erp-kit-module-3-doc-review/SKILL.md +0 -294
  603. package/skills/erp-kit-module-4-tdd/SKILL.md +0 -94
  604. package/skills/erp-kit-module-4-tdd/references/exports.md +0 -8
  605. package/skills/erp-kit-module-5-impl-review/SKILL.md +0 -410
  606. package/src/commands/scaffold-templates.ts +0 -65
  607. package/src/commands/scaffold.test.ts +0 -171
  608. package/src/commands/scaffold.ts +0 -140
  609. package/src/modules/shared/index.ts +0 -1
  610. package/src/modules/user-management/command/logAuditEvent.generated.ts +0 -6
  611. package/src/modules/user-management/command/logAuditEvent.test.ts +0 -187
  612. package/src/modules/user-management/command/logAuditEvent.ts +0 -56
  613. package/src/modules/user-management/db/auditEvent.ts +0 -47
  614. package/src/modules/user-management/docs/commands/LogAuditEvent.md +0 -37
  615. package/src/modules/user-management/docs/features/audit-trail.md +0 -80
  616. package/src/modules/user-management/docs/models/AuditEvent.md +0 -36
  617. /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/cross-module-dependency.md +0 -0
  618. /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/db-relations.md +0 -0
  619. /package/skills/{erp-kit-module-4-tdd → erp-kit-module-5-impl}/references/models.md +0 -0
  620. /package/skills/{erp-kit-module-5-impl-review → erp-kit-module-6-impl-review}/references/commands.md +0 -0
  621. /package/skills/{erp-kit-module-5-impl-review → erp-kit-module-6-impl-review}/references/testing.md +0 -0
  622. /package/src/modules/{product-management → audit}/.gitkeep +0 -0
  623. /package/src/{modules/shared → shared}/createContext.test.ts +0 -0
  624. /package/src/{modules/shared → shared}/createContext.ts +0 -0
  625. /package/src/{modules/shared → shared}/definePermissions.test.ts +0 -0
  626. /package/src/{modules/shared → shared}/definePermissions.ts +0 -0
  627. /package/src/{modules/shared → shared}/defineQuery.test.ts +0 -0
  628. /package/src/{modules/shared → shared}/defineQuery.ts +0 -0
  629. /package/src/{modules/shared → shared}/entityTypes.ts +0 -0
  630. /package/src/{modules/shared → shared}/errors.ts +0 -0
  631. /package/src/{modules/shared → shared}/requirePermission.test.ts +0 -0
  632. /package/src/{modules/shared → shared}/requirePermission.ts +0 -0
  633. /package/src/{modules/shared → shared}/result.ts +0 -0
@@ -2,13 +2,13 @@
2
2
 
3
3
  ## Generated Query Shells
4
4
 
5
- Run `erp-kit module generate code` to generate query shells from `docs/queries/*.md`. Each generated shell wraps your `run` function with `defineQuery`.
5
+ Run `erp-kit module generate code -p <path>` to generate query shells from `docs/queries/*.md`. Each generated shell wraps your `run` function with `defineQuery`.
6
6
 
7
7
  ### Generated shell example
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
 
@@ -1,6 +1,6 @@
1
1
  # Module Directory Structure
2
2
 
3
- This structure is automatically scaffolded by `erp-kit module scaffold module <name>`.
3
+ This structure is automatically scaffolded by `erp-kit module init <name> <dir>`.
4
4
 
5
5
  ```
6
6
  {module}/
@@ -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)
@@ -19,8 +19,8 @@ Ask the user:
19
19
 
20
20
  1. **What changed?** (free-text description of the change)
21
21
  2. **Where?** Determine domain from the target:
22
- - `examples/<app>/` → **App workflow** (skills matching `erp-kit-app-*`)
23
- - `modules/<module>/` → **Module workflow** (skills matching `erp-kit-module-*`)
22
+ - App directory (e.g., `{APP_ROOT}/{APP_NAME}/`) → **App workflow** (skills matching `erp-kit-app-*`)
23
+ - Module directory (e.g., `{MODULE_ROOT}/{MODULE_NAME}/`) → **Module workflow** (skills matching `erp-kit-module-*`)
24
24
 
25
25
  If the user names a specific app or module, confirm the path. If ambiguous, check both directories.
26
26
 
@@ -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";
@@ -1,14 +1,17 @@
1
+ import path from "node:path";
1
2
  import { z } from "zod";
2
3
  import { defineCommand, arg } from "politty";
3
4
  import { runCheck } from "../check";
4
5
  import { runSyncCheck, formatSyncCheckReport } from "../sync-check";
5
- import { runScaffold, APP_TYPES, type ScaffoldType } from "../scaffold";
6
+ import { runGenerateDoc, APP_DOC_TYPES, type DocType } from "../generate-doc";
7
+ import { runGenerateAppCode } from "../../generator/generate-code";
8
+ import { runInitAppWithReadme } from "../init-module";
6
9
 
7
10
  const cwd = process.cwd();
8
11
 
9
- const rootArgs = z.object({
10
- root: arg(z.string(), {
11
- alias: "r",
12
+ const pathArgs = z.object({
13
+ path: arg(z.string(), {
14
+ alias: "p",
12
15
  description: "Path to app-compose directory",
13
16
  }),
14
17
  });
@@ -16,9 +19,9 @@ const rootArgs = z.object({
16
19
  const checkCommand = defineCommand({
17
20
  name: "check",
18
21
  description: "Validate app docs against schemas",
19
- args: rootArgs,
22
+ args: pathArgs,
20
23
  run: async (args) => {
21
- const exitCode = await runCheck({ appRoot: args.root }, cwd);
24
+ const exitCode = await runCheck({ appRoot: args.path }, cwd);
22
25
  process.exit(exitCode);
23
26
  },
24
27
  });
@@ -26,25 +29,40 @@ const checkCommand = defineCommand({
26
29
  const syncCheckCommand = defineCommand({
27
30
  name: "sync-check",
28
31
  description: "Validate source <-> doc correspondence",
29
- args: rootArgs,
32
+ args: pathArgs,
30
33
  run: async (args) => {
31
- const result = await runSyncCheck({ appRoot: args.root }, cwd);
34
+ const result = await runSyncCheck({ appRoot: args.path }, cwd);
32
35
  console.log(formatSyncCheckReport(result));
33
36
  process.exit(result.exitCode);
34
37
  },
35
38
  });
36
39
 
37
- const scaffoldCommand = defineCommand({
38
- name: "scaffold",
39
- description: "Generate app doc from schema template",
40
- args: rootArgs.extend({
41
- type: arg(z.enum(APP_TYPES as unknown as [string, ...string[]]), {
40
+ const initCommand = defineCommand({
41
+ name: "init",
42
+ description: "Bootstrap a new app with directory structure and README",
43
+ args: z.object({
44
+ name: arg(z.string(), {
42
45
  positional: true,
43
- description: `Scaffold type (${APP_TYPES.join(", ")})`,
46
+ description: "App name",
44
47
  }),
45
- parent: arg(z.string(), {
48
+ dir: arg(z.string(), {
46
49
  positional: true,
47
- description: "App name",
50
+ description: "Parent directory where the app will be created",
51
+ }),
52
+ }),
53
+ run: async (args) => {
54
+ const exitCode = await runInitAppWithReadme(args.name, args.dir, cwd);
55
+ process.exit(exitCode);
56
+ },
57
+ });
58
+
59
+ const docCommand = defineCommand({
60
+ name: "doc",
61
+ description: "Create a documentation file from a schema template",
62
+ args: pathArgs.extend({
63
+ type: arg(z.enum(APP_DOC_TYPES as unknown as [string, ...string[]]), {
64
+ positional: true,
65
+ description: `Doc type (${APP_DOC_TYPES.join(", ")})`,
48
66
  }),
49
67
  name: arg(z.string().optional(), {
50
68
  positional: true,
@@ -52,23 +70,38 @@ const scaffoldCommand = defineCommand({
52
70
  }),
53
71
  }),
54
72
  run: async (args) => {
55
- const exitCode = await runScaffold(
56
- args.type as ScaffoldType,
57
- args.parent,
58
- args.name,
59
- args.root,
60
- cwd,
61
- );
73
+ const exitCode = await runGenerateDoc(args.type as DocType, args.name, args.path, cwd);
74
+ process.exit(exitCode);
75
+ },
76
+ });
77
+
78
+ const codeCommand = defineCommand({
79
+ name: "code",
80
+ description: "Generate boilerplate source files from docs",
81
+ args: pathArgs,
82
+ run: (args) => {
83
+ const appPath = path.resolve(cwd, args.path);
84
+ const exitCode = runGenerateAppCode(appPath);
62
85
  process.exit(exitCode);
63
86
  },
64
87
  });
65
88
 
89
+ const generateCommand = defineCommand({
90
+ name: "generate",
91
+ description: "Generate docs and code for an app",
92
+ subCommands: {
93
+ doc: docCommand,
94
+ code: codeCommand,
95
+ },
96
+ });
97
+
66
98
  export const appCommand = defineCommand({
67
99
  name: "app",
68
100
  description: "App-compose management",
69
101
  subCommands: {
70
102
  check: checkCommand,
71
103
  "sync-check": syncCheckCommand,
72
- scaffold: scaffoldCommand,
104
+ init: initCommand,
105
+ generate: generateCommand,
73
106
  },
74
107
  });
@@ -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" },
@@ -0,0 +1,63 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { resolveDocPath } from "./generate-doc";
3
+
4
+ describe("resolveDocPath", () => {
5
+ it("resolves command doc path", () => {
6
+ const result = resolveDocPath("command", "CreateOrder", "modules/inventory");
7
+ expect(result).toBe("modules/inventory/docs/commands/CreateOrder.md");
8
+ });
9
+
10
+ it("resolves feature doc path", () => {
11
+ const result = resolveDocPath("feature", "stock-tracking", "modules/inventory");
12
+ expect(result).toBe("modules/inventory/docs/features/stock-tracking.md");
13
+ });
14
+
15
+ it("resolves model doc path", () => {
16
+ const result = resolveDocPath("model", "StockItem", "modules/inventory");
17
+ expect(result).toBe("modules/inventory/docs/models/StockItem.md");
18
+ });
19
+
20
+ it("resolves query doc path", () => {
21
+ const result = resolveDocPath("query", "ConvertQuantity", "modules/inventory");
22
+ expect(result).toBe("modules/inventory/docs/queries/ConvertQuantity.md");
23
+ });
24
+
25
+ it("resolves actors doc path", () => {
26
+ const result = resolveDocPath("actors", "admin", "examples/my-app");
27
+ expect(result).toBe("examples/my-app/docs/actors/admin.md");
28
+ });
29
+
30
+ it("resolves business-flow doc path", () => {
31
+ const result = resolveDocPath("business-flow", "onboarding", "examples/my-app");
32
+ expect(result).toBe("examples/my-app/docs/business-flow/onboarding/README.md");
33
+ });
34
+
35
+ it("resolves story doc path with flow/name format", () => {
36
+ const result = resolveDocPath("story", "onboarding/admin--create-user", "examples/my-app");
37
+ expect(result).toBe(
38
+ "examples/my-app/docs/business-flow/onboarding/story/admin--create-user.md",
39
+ );
40
+ });
41
+
42
+ it("resolves screen doc path", () => {
43
+ const result = resolveDocPath("screen", "supplier-list", "examples/my-app");
44
+ expect(result).toBe("examples/my-app/docs/screen/supplier-list.md");
45
+ });
46
+
47
+ it("resolves resolver doc path", () => {
48
+ const result = resolveDocPath("resolver", "create-supplier", "examples/my-app");
49
+ expect(result).toBe("examples/my-app/docs/resolver/create-supplier.md");
50
+ });
51
+
52
+ it("throws when name is missing", () => {
53
+ expect(() => resolveDocPath("command", undefined, "modules/inventory")).toThrow(
54
+ "Name is required",
55
+ );
56
+ });
57
+
58
+ it("throws when story name is not flow/name format", () => {
59
+ expect(() => resolveDocPath("story", "bad-name", "examples/my-app")).toThrow(
60
+ "Story name must be",
61
+ );
62
+ });
63
+ });
@@ -0,0 +1,98 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs";
3
+ import { runMdschema } from "../mdschema";
4
+ import { ALL_SCHEMAS } from "../schemas";
5
+
6
+ export const MODULE_DOC_TYPES = ["feature", "command", "model", "query"] as const;
7
+ export const APP_DOC_TYPES = ["actors", "business-flow", "story", "screen", "resolver"] as const;
8
+ export const ALL_DOC_TYPES = [...MODULE_DOC_TYPES, ...APP_DOC_TYPES] as const;
9
+
10
+ export type DocType = (typeof ALL_DOC_TYPES)[number];
11
+
12
+ const MODULE_DIR_MAP: Record<string, string> = {
13
+ feature: "docs/features",
14
+ command: "docs/commands",
15
+ model: "docs/models",
16
+ query: "docs/queries",
17
+ };
18
+
19
+ const APP_DIR_MAP: Record<string, string> = {
20
+ actors: "docs/actors",
21
+ "business-flow": "docs/business-flow",
22
+ screen: "docs/screen",
23
+ resolver: "docs/resolver",
24
+ };
25
+
26
+ export function resolveDocPath(
27
+ type: DocType,
28
+ name: string | undefined,
29
+ modulePath: string,
30
+ ): string {
31
+ if (!name) {
32
+ throw new Error(`Name is required for doc type "${type}"`);
33
+ }
34
+
35
+ if (type === "business-flow") {
36
+ return path.join(modulePath, "docs/business-flow", name, "README.md");
37
+ }
38
+
39
+ if (type === "story") {
40
+ const parts = name.split("/");
41
+ if (parts.length !== 2) {
42
+ throw new Error(
43
+ `Story name must be "<flow>/<story>" (e.g., "onboarding/admin--create-user")`,
44
+ );
45
+ }
46
+ return path.join(modulePath, "docs/business-flow", parts[0], "story", `${parts[1]}.md`);
47
+ }
48
+
49
+ if (MODULE_DIR_MAP[type]) {
50
+ return path.join(modulePath, MODULE_DIR_MAP[type], `${name}.md`);
51
+ }
52
+
53
+ if (APP_DIR_MAP[type]) {
54
+ return path.join(modulePath, APP_DIR_MAP[type], `${name}.md`);
55
+ }
56
+
57
+ throw new Error(`Unknown doc type: ${type}`);
58
+ }
59
+
60
+ export async function runGenerateDoc(
61
+ type: DocType,
62
+ name: string | undefined,
63
+ modulePath: string,
64
+ cwd: string,
65
+ ): Promise<number> {
66
+ const outputPath = resolveDocPath(type, name, modulePath);
67
+ const absoluteOutput = path.resolve(cwd, outputPath);
68
+
69
+ if (fs.existsSync(absoluteOutput)) {
70
+ console.error(`File already exists: ${outputPath}`);
71
+ return 1;
72
+ }
73
+
74
+ const schemaPath = ALL_SCHEMAS[type];
75
+ if (!schemaPath) {
76
+ console.error(`No schema found for type: ${type}`);
77
+ return 2;
78
+ }
79
+
80
+ try {
81
+ fs.mkdirSync(path.dirname(absoluteOutput), { recursive: true });
82
+ } catch (err) {
83
+ console.error(
84
+ `Failed to create directory: ${err instanceof Error ? err.message : String(err)}`,
85
+ );
86
+ return 1;
87
+ }
88
+
89
+ const { exitCode, stdout, stderr } = await runMdschema(
90
+ ["generate", "--schema", schemaPath, "--output", absoluteOutput],
91
+ cwd,
92
+ );
93
+
94
+ if (stdout.trim()) console.log(stdout);
95
+ if (stderr.trim()) console.error(stderr);
96
+
97
+ return exitCode;
98
+ }
@@ -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
  });