@tailor-platform/erp-kit 0.6.0 → 0.7.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 (290) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +10 -10
  3. package/dist/cli.mjs +407 -69
  4. package/package.json +1 -1
  5. package/skills/erp-kit-app-1-requirements/SKILL.md +33 -17
  6. package/skills/erp-kit-app-2-requirements-review/SKILL.md +12 -0
  7. package/skills/erp-kit-app-3-plan/SKILL.md +18 -4
  8. package/skills/erp-kit-app-3-plan/references/resolver-extraction.md +1 -1
  9. package/skills/erp-kit-app-3-plan/references/screen-extraction.md +1 -1
  10. package/skills/erp-kit-app-4-plan-review/SKILL.md +12 -0
  11. package/skills/erp-kit-app-5-impl-backend/SKILL.md +12 -0
  12. package/skills/erp-kit-app-6-impl-frontend/SKILL.md +12 -0
  13. package/skills/erp-kit-app-7-impl-review/SKILL.md +13 -1
  14. package/skills/erp-kit-app-shared/references/progress-protocol.md +77 -0
  15. package/skills/erp-kit-mock-scenario/SKILL.md +1 -1
  16. package/skills/erp-kit-module-1-requirements/SKILL.md +1 -1
  17. package/skills/erp-kit-module-3-plan/SKILL.md +3 -3
  18. package/skills/erp-kit-module-3-update-plan/SKILL.md +3 -3
  19. package/skills/erp-kit-module-5-impl/SKILL.md +1 -1
  20. package/src/commands/app/index.ts +2 -0
  21. package/src/commands/app/progress/git-context.ts +16 -0
  22. package/src/commands/app/progress/index.ts +45 -0
  23. package/src/commands/app/progress/log.ts +49 -0
  24. package/src/commands/app/progress/progress.test.ts +128 -0
  25. package/src/commands/app/progress/schema-cmd.ts +10 -0
  26. package/src/commands/check.test.ts +4 -4
  27. package/src/commands/lib/discovery.test.ts +5 -7
  28. package/src/commands/lib/discovery.ts +8 -8
  29. package/src/commands/lib/sync-check-source.test.ts +1 -1
  30. package/src/commands/lib/sync-check-source.ts +6 -1
  31. package/src/commands/lib/sync-check-tests.test.ts +43 -0
  32. package/src/commands/lib/sync-check-tests.ts +20 -2
  33. package/src/commands/sync-check.ts +3 -0
  34. package/src/generator/generate-app-code.test.ts +0 -6
  35. package/src/generator/generate-app-code.ts +3 -13
  36. package/src/generator/generate-code.test.ts +10 -40
  37. package/src/generator/generate-code.ts +6 -12
  38. package/src/generator/stub-templates.test.ts +0 -7
  39. package/src/generator/stub-templates.ts +0 -14
  40. package/src/modules/finance-ledger/README.md +50 -0
  41. package/src/modules/finance-ledger/command/.gitkeep +0 -0
  42. package/src/modules/finance-ledger/command/addJournalLine.generated.ts +6 -0
  43. package/src/modules/finance-ledger/command/addJournalLine.test.ts +438 -0
  44. package/src/modules/finance-ledger/command/addJournalLine.ts +122 -0
  45. package/src/modules/finance-ledger/command/approveAndLockPeriod.generated.ts +6 -0
  46. package/src/modules/finance-ledger/command/approveAndLockPeriod.test.ts +107 -0
  47. package/src/modules/finance-ledger/command/approveAndLockPeriod.ts +72 -0
  48. package/src/modules/finance-ledger/command/beginClose.generated.ts +6 -0
  49. package/src/modules/finance-ledger/command/beginClose.test.ts +106 -0
  50. package/src/modules/finance-ledger/command/beginClose.ts +58 -0
  51. package/src/modules/finance-ledger/command/closePeriod.generated.ts +6 -0
  52. package/src/modules/finance-ledger/command/closePeriod.test.ts +87 -0
  53. package/src/modules/finance-ledger/command/closePeriod.ts +44 -0
  54. package/src/modules/finance-ledger/command/createAccountingPeriod.generated.ts +6 -0
  55. package/src/modules/finance-ledger/command/createAccountingPeriod.test.ts +425 -0
  56. package/src/modules/finance-ledger/command/createAccountingPeriod.ts +133 -0
  57. package/src/modules/finance-ledger/command/createFiscalYear.generated.ts +6 -0
  58. package/src/modules/finance-ledger/command/createFiscalYear.test.ts +197 -0
  59. package/src/modules/finance-ledger/command/createFiscalYear.ts +70 -0
  60. package/src/modules/finance-ledger/command/createJournalEntry.generated.ts +6 -0
  61. package/src/modules/finance-ledger/command/createJournalEntry.test.ts +261 -0
  62. package/src/modules/finance-ledger/command/createJournalEntry.ts +121 -0
  63. package/src/modules/finance-ledger/command/deleteAccountingPeriod.generated.ts +6 -0
  64. package/src/modules/finance-ledger/command/deleteAccountingPeriod.test.ts +71 -0
  65. package/src/modules/finance-ledger/command/deleteAccountingPeriod.ts +55 -0
  66. package/src/modules/finance-ledger/command/deleteFiscalYear.generated.ts +6 -0
  67. package/src/modules/finance-ledger/command/deleteFiscalYear.test.ts +38 -0
  68. package/src/modules/finance-ledger/command/deleteFiscalYear.ts +34 -0
  69. package/src/modules/finance-ledger/command/deleteJournalEntry.generated.ts +6 -0
  70. package/src/modules/finance-ledger/command/deleteJournalEntry.test.ts +58 -0
  71. package/src/modules/finance-ledger/command/deleteJournalEntry.ts +43 -0
  72. package/src/modules/finance-ledger/command/executeYearEndClose.generated.ts +6 -0
  73. package/src/modules/finance-ledger/command/executeYearEndClose.test.ts +239 -0
  74. package/src/modules/finance-ledger/command/executeYearEndClose.ts +415 -0
  75. package/src/modules/finance-ledger/command/finalCloseAndLockPeriod.generated.ts +6 -0
  76. package/src/modules/finance-ledger/command/finalCloseAndLockPeriod.test.ts +102 -0
  77. package/src/modules/finance-ledger/command/finalCloseAndLockPeriod.ts +76 -0
  78. package/src/modules/finance-ledger/command/finalizeFinancialStatement.generated.ts +6 -0
  79. package/src/modules/finance-ledger/command/finalizeFinancialStatement.test.ts +73 -0
  80. package/src/modules/finance-ledger/command/finalizeFinancialStatement.ts +73 -0
  81. package/src/modules/finance-ledger/command/generateFinancialStatement.generated.ts +6 -0
  82. package/src/modules/finance-ledger/command/generateFinancialStatement.test.ts +311 -0
  83. package/src/modules/finance-ledger/command/generateFinancialStatement.ts +275 -0
  84. package/src/modules/finance-ledger/command/generatePreliminaryStatements.generated.ts +6 -0
  85. package/src/modules/finance-ledger/command/generatePreliminaryStatements.test.ts +152 -0
  86. package/src/modules/finance-ledger/command/generatePreliminaryStatements.ts +140 -0
  87. package/src/modules/finance-ledger/command/generateTrialBalance.generated.ts +6 -0
  88. package/src/modules/finance-ledger/command/generateTrialBalance.test.ts +439 -0
  89. package/src/modules/finance-ledger/command/generateTrialBalance.ts +268 -0
  90. package/src/modules/finance-ledger/command/initiatePeriodClose.generated.ts +6 -0
  91. package/src/modules/finance-ledger/command/initiatePeriodClose.test.ts +153 -0
  92. package/src/modules/finance-ledger/command/initiatePeriodClose.ts +84 -0
  93. package/src/modules/finance-ledger/command/openForAdvanceEntry.generated.ts +6 -0
  94. package/src/modules/finance-ledger/command/openForAdvanceEntry.test.ts +87 -0
  95. package/src/modules/finance-ledger/command/openForAdvanceEntry.ts +44 -0
  96. package/src/modules/finance-ledger/command/openPeriod.generated.ts +6 -0
  97. package/src/modules/finance-ledger/command/openPeriod.test.ts +90 -0
  98. package/src/modules/finance-ledger/command/openPeriod.ts +44 -0
  99. package/src/modules/finance-ledger/command/permanentlyClosePeriod.generated.ts +6 -0
  100. package/src/modules/finance-ledger/command/permanentlyClosePeriod.test.ts +87 -0
  101. package/src/modules/finance-ledger/command/permanentlyClosePeriod.ts +48 -0
  102. package/src/modules/finance-ledger/command/postAdjustingEntries.generated.ts +6 -0
  103. package/src/modules/finance-ledger/command/postAdjustingEntries.test.ts +392 -0
  104. package/src/modules/finance-ledger/command/postAdjustingEntries.ts +156 -0
  105. package/src/modules/finance-ledger/command/postJournalEntry.generated.ts +6 -0
  106. package/src/modules/finance-ledger/command/postJournalEntry.test.ts +346 -0
  107. package/src/modules/finance-ledger/command/postJournalEntry.ts +160 -0
  108. package/src/modules/finance-ledger/command/processInventoryHandoff.generated.ts +6 -0
  109. package/src/modules/finance-ledger/command/processInventoryHandoff.test.ts +211 -0
  110. package/src/modules/finance-ledger/command/processInventoryHandoff.ts +133 -0
  111. package/src/modules/finance-ledger/command/processManufacturingHandoff.generated.ts +6 -0
  112. package/src/modules/finance-ledger/command/processManufacturingHandoff.test.ts +221 -0
  113. package/src/modules/finance-ledger/command/processManufacturingHandoff.ts +133 -0
  114. package/src/modules/finance-ledger/command/processPurchaseHandoff.generated.ts +6 -0
  115. package/src/modules/finance-ledger/command/processPurchaseHandoff.test.ts +222 -0
  116. package/src/modules/finance-ledger/command/processPurchaseHandoff.ts +133 -0
  117. package/src/modules/finance-ledger/command/processSalesHandoff.generated.ts +6 -0
  118. package/src/modules/finance-ledger/command/processSalesHandoff.test.ts +257 -0
  119. package/src/modules/finance-ledger/command/processSalesHandoff.ts +135 -0
  120. package/src/modules/finance-ledger/command/regenerateFinancialStatement.generated.ts +6 -0
  121. package/src/modules/finance-ledger/command/regenerateFinancialStatement.test.ts +129 -0
  122. package/src/modules/finance-ledger/command/regenerateFinancialStatement.ts +186 -0
  123. package/src/modules/finance-ledger/command/removeJournalLine.generated.ts +6 -0
  124. package/src/modules/finance-ledger/command/removeJournalLine.test.ts +65 -0
  125. package/src/modules/finance-ledger/command/removeJournalLine.ts +39 -0
  126. package/src/modules/finance-ledger/command/reopenPeriod.generated.ts +6 -0
  127. package/src/modules/finance-ledger/command/reopenPeriod.test.ts +87 -0
  128. package/src/modules/finance-ledger/command/reopenPeriod.ts +44 -0
  129. package/src/modules/finance-ledger/command/reverseJournalEntry.generated.ts +6 -0
  130. package/src/modules/finance-ledger/command/reverseJournalEntry.test.ts +337 -0
  131. package/src/modules/finance-ledger/command/reverseJournalEntry.ts +140 -0
  132. package/src/modules/finance-ledger/command/revertSoftLock.generated.ts +6 -0
  133. package/src/modules/finance-ledger/command/revertSoftLock.test.ts +96 -0
  134. package/src/modules/finance-ledger/command/revertSoftLock.ts +67 -0
  135. package/src/modules/finance-ledger/command/updateFiscalYear.generated.ts +6 -0
  136. package/src/modules/finance-ledger/command/updateFiscalYear.test.ts +138 -0
  137. package/src/modules/finance-ledger/command/updateFiscalYear.ts +85 -0
  138. package/src/modules/finance-ledger/command/updateJournalEntry.generated.ts +6 -0
  139. package/src/modules/finance-ledger/command/updateJournalEntry.test.ts +195 -0
  140. package/src/modules/finance-ledger/command/updateJournalEntry.ts +86 -0
  141. package/src/modules/finance-ledger/command/updateJournalLine.generated.ts +6 -0
  142. package/src/modules/finance-ledger/command/updateJournalLine.test.ts +385 -0
  143. package/src/modules/finance-ledger/command/updateJournalLine.ts +155 -0
  144. package/src/modules/finance-ledger/command/verifySubledgerTransfers.generated.ts +6 -0
  145. package/src/modules/finance-ledger/command/verifySubledgerTransfers.test.ts +201 -0
  146. package/src/modules/finance-ledger/command/verifySubledgerTransfers.ts +113 -0
  147. package/src/modules/finance-ledger/command/verifyTrialBalance.generated.ts +6 -0
  148. package/src/modules/finance-ledger/command/verifyTrialBalance.test.ts +136 -0
  149. package/src/modules/finance-ledger/command/verifyTrialBalance.ts +97 -0
  150. package/src/modules/finance-ledger/db/.gitkeep +0 -0
  151. package/src/modules/finance-ledger/db/accountingPeriod.ts +58 -0
  152. package/src/modules/finance-ledger/db/financialStatement.ts +92 -0
  153. package/src/modules/finance-ledger/db/financialStatementLineItem.ts +76 -0
  154. package/src/modules/finance-ledger/db/fiscalYear.ts +41 -0
  155. package/src/modules/finance-ledger/db/journalEntry.ts +101 -0
  156. package/src/modules/finance-ledger/db/journalLine.ts +64 -0
  157. package/src/modules/finance-ledger/db/periodClose.ts +97 -0
  158. package/src/modules/finance-ledger/db/trialBalance.ts +63 -0
  159. package/src/modules/finance-ledger/db/trialBalanceLine.ts +63 -0
  160. package/src/modules/finance-ledger/docs/commands/AddJournalLine.md +74 -0
  161. package/src/modules/finance-ledger/docs/commands/ApproveAndLockPeriod.md +53 -0
  162. package/src/modules/finance-ledger/docs/commands/BeginClose.md +47 -0
  163. package/src/modules/finance-ledger/docs/commands/ClosePeriod.md +45 -0
  164. package/src/modules/finance-ledger/docs/commands/CreateAccountingPeriod.md +69 -0
  165. package/src/modules/finance-ledger/docs/commands/CreateFiscalYear.md +56 -0
  166. package/src/modules/finance-ledger/docs/commands/CreateJournalEntry.md +63 -0
  167. package/src/modules/finance-ledger/docs/commands/DeleteAccountingPeriod.md +46 -0
  168. package/src/modules/finance-ledger/docs/commands/DeleteFiscalYear.md +40 -0
  169. package/src/modules/finance-ledger/docs/commands/DeleteJournalEntry.md +44 -0
  170. package/src/modules/finance-ledger/docs/commands/ExecuteYearEndClose.md +81 -0
  171. package/src/modules/finance-ledger/docs/commands/FinalCloseAndLockPeriod.md +49 -0
  172. package/src/modules/finance-ledger/docs/commands/FinalizeFinancialStatement.md +43 -0
  173. package/src/modules/finance-ledger/docs/commands/GenerateFinancialStatement.md +86 -0
  174. package/src/modules/finance-ledger/docs/commands/GeneratePreliminaryStatements.md +53 -0
  175. package/src/modules/finance-ledger/docs/commands/GenerateTrialBalance.md +75 -0
  176. package/src/modules/finance-ledger/docs/commands/InitiatePeriodClose.md +58 -0
  177. package/src/modules/finance-ledger/docs/commands/OpenForAdvanceEntry.md +44 -0
  178. package/src/modules/finance-ledger/docs/commands/OpenPeriod.md +45 -0
  179. package/src/modules/finance-ledger/docs/commands/PermanentlyClosePeriod.md +45 -0
  180. package/src/modules/finance-ledger/docs/commands/PostAdjustingEntries.md +61 -0
  181. package/src/modules/finance-ledger/docs/commands/PostJournalEntry.md +81 -0
  182. package/src/modules/finance-ledger/docs/commands/ProcessInventoryHandoff.md +72 -0
  183. package/src/modules/finance-ledger/docs/commands/ProcessManufacturingHandoff.md +68 -0
  184. package/src/modules/finance-ledger/docs/commands/ProcessPurchaseHandoff.md +68 -0
  185. package/src/modules/finance-ledger/docs/commands/ProcessSalesHandoff.md +71 -0
  186. package/src/modules/finance-ledger/docs/commands/RegenerateFinancialStatement.md +60 -0
  187. package/src/modules/finance-ledger/docs/commands/RemoveJournalLine.md +42 -0
  188. package/src/modules/finance-ledger/docs/commands/ReopenPeriod.md +45 -0
  189. package/src/modules/finance-ledger/docs/commands/ReverseJournalEntry.md +62 -0
  190. package/src/modules/finance-ledger/docs/commands/RevertSoftLock.md +49 -0
  191. package/src/modules/finance-ledger/docs/commands/UpdateFiscalYear.md +60 -0
  192. package/src/modules/finance-ledger/docs/commands/UpdateJournalEntry.md +50 -0
  193. package/src/modules/finance-ledger/docs/commands/UpdateJournalLine.md +61 -0
  194. package/src/modules/finance-ledger/docs/commands/VerifySubledgerTransfers.md +59 -0
  195. package/src/modules/finance-ledger/docs/commands/VerifyTrialBalance.md +53 -0
  196. package/src/modules/finance-ledger/docs/features/accounting-period-management.md +110 -0
  197. package/src/modules/finance-ledger/docs/features/financial-statement-generation.md +115 -0
  198. package/src/modules/finance-ledger/docs/features/journal-entry-management.md +138 -0
  199. package/src/modules/finance-ledger/docs/features/period-end-close.md +102 -0
  200. package/src/modules/finance-ledger/docs/features/subledger-integration.md +141 -0
  201. package/src/modules/finance-ledger/docs/features/trial-balance.md +99 -0
  202. package/src/modules/finance-ledger/docs/features/year-end-close.md +84 -0
  203. package/src/modules/finance-ledger/docs/models/AccountingPeriod.md +71 -0
  204. package/src/modules/finance-ledger/docs/models/FinancialStatement.md +76 -0
  205. package/src/modules/finance-ledger/docs/models/FinancialStatementLineItem.md +41 -0
  206. package/src/modules/finance-ledger/docs/models/FiscalYear.md +41 -0
  207. package/src/modules/finance-ledger/docs/models/JournalEntry.md +80 -0
  208. package/src/modules/finance-ledger/docs/models/JournalLine.md +47 -0
  209. package/src/modules/finance-ledger/docs/models/PeriodClose.md +83 -0
  210. package/src/modules/finance-ledger/docs/models/TrialBalance.md +56 -0
  211. package/src/modules/finance-ledger/docs/models/TrialBalanceLine.md +37 -0
  212. package/src/modules/finance-ledger/docs/queries/GetAccountingPeriod.md +35 -0
  213. package/src/modules/finance-ledger/docs/queries/GetFinancialStatement.md +38 -0
  214. package/src/modules/finance-ledger/docs/queries/GetFiscalYear.md +35 -0
  215. package/src/modules/finance-ledger/docs/queries/GetJournalEntry.md +37 -0
  216. package/src/modules/finance-ledger/docs/queries/GetPeriodByDate.md +38 -0
  217. package/src/modules/finance-ledger/docs/queries/GetPeriodClose.md +36 -0
  218. package/src/modules/finance-ledger/docs/queries/GetSubledgerTransferStatus.md +45 -0
  219. package/src/modules/finance-ledger/docs/queries/GetTrialBalance.md +38 -0
  220. package/src/modules/finance-ledger/docs/queries/ListAccountingPeriods.md +46 -0
  221. package/src/modules/finance-ledger/docs/queries/ListFinancialStatements.md +46 -0
  222. package/src/modules/finance-ledger/docs/queries/ListFiscalYears.md +42 -0
  223. package/src/modules/finance-ledger/docs/queries/ListJournalEntries.md +48 -0
  224. package/src/modules/finance-ledger/docs/queries/ListPeriodCloses.md +46 -0
  225. package/src/modules/finance-ledger/docs/queries/ListTrialBalances.md +51 -0
  226. package/src/modules/finance-ledger/executor/.gitkeep +0 -0
  227. package/src/modules/finance-ledger/generated/enums.ts +109 -0
  228. package/src/modules/finance-ledger/generated/kysely-tailordb.ts +202 -0
  229. package/src/modules/finance-ledger/index.ts +2 -0
  230. package/src/modules/finance-ledger/lib/_db_deps.ts +56 -0
  231. package/src/modules/finance-ledger/lib/errors.generated.ts +332 -0
  232. package/src/modules/finance-ledger/lib/permissions.generated.ts +41 -0
  233. package/src/modules/finance-ledger/lib/types.ts +66 -0
  234. package/src/modules/finance-ledger/module.ts +262 -0
  235. package/src/modules/finance-ledger/package.json +26 -0
  236. package/src/modules/finance-ledger/permissions.ts +3 -0
  237. package/src/modules/finance-ledger/query/.gitkeep +0 -0
  238. package/src/modules/finance-ledger/query/getAccountingPeriod.generated.ts +5 -0
  239. package/src/modules/finance-ledger/query/getAccountingPeriod.test.ts +31 -0
  240. package/src/modules/finance-ledger/query/getAccountingPeriod.ts +21 -0
  241. package/src/modules/finance-ledger/query/getFinancialStatement.generated.ts +5 -0
  242. package/src/modules/finance-ledger/query/getFinancialStatement.test.ts +35 -0
  243. package/src/modules/finance-ledger/query/getFinancialStatement.ts +29 -0
  244. package/src/modules/finance-ledger/query/getFiscalYear.generated.ts +5 -0
  245. package/src/modules/finance-ledger/query/getFiscalYear.test.ts +31 -0
  246. package/src/modules/finance-ledger/query/getFiscalYear.ts +21 -0
  247. package/src/modules/finance-ledger/query/getJournalEntry.generated.ts +5 -0
  248. package/src/modules/finance-ledger/query/getJournalEntry.test.ts +35 -0
  249. package/src/modules/finance-ledger/query/getJournalEntry.ts +29 -0
  250. package/src/modules/finance-ledger/query/getPeriodByDate.generated.ts +5 -0
  251. package/src/modules/finance-ledger/query/getPeriodByDate.test.ts +53 -0
  252. package/src/modules/finance-ledger/query/getPeriodByDate.ts +27 -0
  253. package/src/modules/finance-ledger/query/getPeriodClose.generated.ts +5 -0
  254. package/src/modules/finance-ledger/query/getPeriodClose.test.ts +31 -0
  255. package/src/modules/finance-ledger/query/getPeriodClose.ts +21 -0
  256. package/src/modules/finance-ledger/query/getSubledgerTransferStatus.generated.ts +5 -0
  257. package/src/modules/finance-ledger/query/getSubledgerTransferStatus.test.ts +101 -0
  258. package/src/modules/finance-ledger/query/getSubledgerTransferStatus.ts +68 -0
  259. package/src/modules/finance-ledger/query/getTrialBalance.generated.ts +5 -0
  260. package/src/modules/finance-ledger/query/getTrialBalance.test.ts +33 -0
  261. package/src/modules/finance-ledger/query/getTrialBalance.ts +30 -0
  262. package/src/modules/finance-ledger/query/listAccountingPeriods.generated.ts +5 -0
  263. package/src/modules/finance-ledger/query/listAccountingPeriods.test.ts +81 -0
  264. package/src/modules/finance-ledger/query/listAccountingPeriods.ts +61 -0
  265. package/src/modules/finance-ledger/query/listFinancialStatements.generated.ts +5 -0
  266. package/src/modules/finance-ledger/query/listFinancialStatements.test.ts +76 -0
  267. package/src/modules/finance-ledger/query/listFinancialStatements.ts +62 -0
  268. package/src/modules/finance-ledger/query/listFiscalYears.generated.ts +5 -0
  269. package/src/modules/finance-ledger/query/listFiscalYears.test.ts +63 -0
  270. package/src/modules/finance-ledger/query/listFiscalYears.ts +45 -0
  271. package/src/modules/finance-ledger/query/listJournalEntries.generated.ts +5 -0
  272. package/src/modules/finance-ledger/query/listJournalEntries.test.ts +91 -0
  273. package/src/modules/finance-ledger/query/listJournalEntries.ts +64 -0
  274. package/src/modules/finance-ledger/query/listPeriodCloses.generated.ts +5 -0
  275. package/src/modules/finance-ledger/query/listPeriodCloses.test.ts +63 -0
  276. package/src/modules/finance-ledger/query/listPeriodCloses.ts +64 -0
  277. package/src/modules/finance-ledger/query/listTrialBalances.generated.ts +5 -0
  278. package/src/modules/finance-ledger/query/listTrialBalances.test.ts +78 -0
  279. package/src/modules/finance-ledger/query/listTrialBalances.ts +56 -0
  280. package/src/modules/finance-ledger/seed/index.ts +19 -0
  281. package/src/modules/finance-ledger/tailor.config.ts +13 -0
  282. package/src/modules/finance-ledger/tailor.d.ts +13 -0
  283. package/src/modules/finance-ledger/testing/commandTestUtils.ts +35 -0
  284. package/src/modules/finance-ledger/testing/fixtures.ts +382 -0
  285. package/src/modules/finance-ledger/tsconfig.json +16 -0
  286. package/src/progress/schema.test.ts +161 -0
  287. package/src/progress/schema.ts +316 -0
  288. package/templates/scaffold/app/backend/package.json +1 -3
  289. package/templates/scaffold/app/backend/vitest.config.ts +4 -21
  290. package/src/generator/generate-stubs.ts +0 -35
@@ -0,0 +1,128 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { execFileSync } from "node:child_process";
5
+ import { describe, it, expect, vi, afterEach } from "vitest";
6
+ import { runProgressLog } from "./log";
7
+ import { runProgressSchema } from "./schema-cmd";
8
+
9
+ function makeTmpApp(): string {
10
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "progress-test-"));
11
+ execFileSync("git", ["init"], { cwd: dir });
12
+ execFileSync("git", ["config", "user.email", "test@test.com"], { cwd: dir });
13
+ execFileSync("git", ["config", "user.name", "test"], { cwd: dir });
14
+ execFileSync("git", ["commit", "--allow-empty", "-m", "init"], { cwd: dir });
15
+ return dir;
16
+ }
17
+
18
+ describe("runProgressLog", () => {
19
+ let tmpDir: string;
20
+
21
+ afterEach(() => {
22
+ if (tmpDir) {
23
+ fs.rmSync(tmpDir, { recursive: true, force: true });
24
+ }
25
+ });
26
+
27
+ it("creates .erp-kit/progress.jsonl and appends a valid entry", () => {
28
+ tmpDir = makeTmpApp();
29
+ const input = JSON.stringify({
30
+ v: 1,
31
+ sessionId: "s1",
32
+ prompt: "test prompt",
33
+ event: "note",
34
+ data: { message: "test", tags: [] },
35
+ });
36
+
37
+ const result = runProgressLog(input, false, tmpDir);
38
+ expect(result.exitCode).toBe(0);
39
+
40
+ const logFile = path.join(tmpDir, ".erp-kit", "progress.jsonl");
41
+ expect(fs.existsSync(logFile)).toBe(true);
42
+
43
+ const lines = fs.readFileSync(logFile, "utf-8").trim().split("\n");
44
+ expect(lines).toHaveLength(1);
45
+
46
+ const entry = JSON.parse(lines[0]) as Record<string, unknown>;
47
+ expect(entry.sessionId).toBe("s1");
48
+ expect(entry.timestamp).toBeDefined();
49
+ expect(entry.git).toBeDefined();
50
+ expect(entry.conversation).toEqual([]);
51
+ });
52
+
53
+ it("appends multiple entries", () => {
54
+ tmpDir = makeTmpApp();
55
+ const input1 = JSON.stringify({
56
+ v: 1,
57
+ sessionId: "s1",
58
+ prompt: "test prompt",
59
+ event: "note",
60
+ data: { message: "first", tags: [] },
61
+ });
62
+ const input2 = JSON.stringify({
63
+ v: 1,
64
+ sessionId: "s1",
65
+ prompt: "test prompt",
66
+ event: "note",
67
+ data: { message: "second", tags: [] },
68
+ });
69
+
70
+ runProgressLog(input1, false, tmpDir);
71
+ runProgressLog(input2, false, tmpDir);
72
+
73
+ const logFile = path.join(tmpDir, ".erp-kit", "progress.jsonl");
74
+ const lines = fs.readFileSync(logFile, "utf-8").trim().split("\n");
75
+ expect(lines).toHaveLength(2);
76
+ });
77
+
78
+ it("rejects invalid JSON", () => {
79
+ tmpDir = makeTmpApp();
80
+ const result = runProgressLog("not json", false, tmpDir);
81
+ expect(result.exitCode).toBe(1);
82
+ });
83
+
84
+ it("rejects invalid schema (missing prompt)", () => {
85
+ tmpDir = makeTmpApp();
86
+ const input = JSON.stringify({
87
+ v: 1,
88
+ sessionId: "s1",
89
+ event: "note",
90
+ data: { message: "x", tags: [] },
91
+ });
92
+ const result = runProgressLog(input, false, tmpDir);
93
+ expect(result.exitCode).toBe(1);
94
+ });
95
+
96
+ it("dry-run does not write to file", () => {
97
+ tmpDir = makeTmpApp();
98
+ const input = JSON.stringify({
99
+ v: 1,
100
+ sessionId: "s1",
101
+ prompt: "test prompt",
102
+ event: "note",
103
+ data: { message: "test", tags: [] },
104
+ });
105
+
106
+ const result = runProgressLog(input, true, tmpDir);
107
+ expect(result.exitCode).toBe(0);
108
+
109
+ const logFile = path.join(tmpDir, ".erp-kit", "progress.jsonl");
110
+ expect(fs.existsSync(logFile)).toBe(false);
111
+ });
112
+ });
113
+
114
+ describe("runProgressSchema", () => {
115
+ it("outputs valid JSON Schema", () => {
116
+ const spy = vi.spyOn(console, "log").mockImplementation(() => undefined);
117
+
118
+ const result = runProgressSchema();
119
+
120
+ expect(result.exitCode).toBe(0);
121
+ expect(spy).toHaveBeenCalledOnce();
122
+
123
+ const schema = JSON.parse(String(spy.mock.calls[0]?.[0])) as Record<string, unknown>;
124
+ expect(schema).toHaveProperty("anyOf");
125
+
126
+ spy.mockRestore();
127
+ });
128
+ });
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ import { ProgressInput } from "../../../progress/schema";
3
+ import type { CommandResult } from "../../lib/command-result";
4
+ import { success } from "../../lib/command-result";
5
+
6
+ export function runProgressSchema(): CommandResult {
7
+ const jsonSchema = z.toJSONSchema(ProgressInput);
8
+ console.log(JSON.stringify(jsonSchema, null, 2));
9
+ return success();
10
+ }
@@ -13,14 +13,14 @@ describe("buildCheckTargets", () => {
13
13
  ]);
14
14
  });
15
15
 
16
- it("generates app targets when appRoot is set", () => {
17
- const targets = buildCheckTargets({ modulesRoot: undefined, appRoot: "apps" });
18
- expect(targets[0].glob).toBe("apps/[a-zA-Z]*/README.md");
16
+ it("generates app-compose targets when appRoot is set", () => {
17
+ const targets = buildCheckTargets({ modulesRoot: undefined, appRoot: "apps/myapp" });
18
+ expect(targets[0].glob).toBe("apps/myapp/README.md");
19
19
  expect(targets).toHaveLength(6);
20
20
  });
21
21
 
22
22
  it("generates both when both roots are set", () => {
23
- const targets = buildCheckTargets({ modulesRoot: "modules", appRoot: "examples" });
23
+ const targets = buildCheckTargets({ modulesRoot: "modules", appRoot: "examples/app1" });
24
24
  expect(targets).toHaveLength(11);
25
25
  });
26
26
 
@@ -29,10 +29,10 @@ describe("moduleCategories", () => {
29
29
 
30
30
  describe("appComposeCategories", () => {
31
31
  it("produces resolver category", () => {
32
- const cats = appComposeCategories("apps");
32
+ const cats = appComposeCategories("apps/myapp");
33
33
  expect(cats).toHaveLength(1);
34
34
  expect(cats[0].name).toBe("resolver");
35
- expect(cats[0].docPattern).toBe("apps/*/docs/resolver/*.md");
35
+ expect(cats[0].docPattern).toBe("apps/myapp/docs/resolver/*.md");
36
36
  });
37
37
  });
38
38
 
@@ -69,16 +69,14 @@ describe("buildCheckTargets", () => {
69
69
  });
70
70
 
71
71
  it("builds app check targets", () => {
72
- const targets = buildCheckTargets({ appRoot: "apps" });
72
+ const targets = buildCheckTargets({ appRoot: "apps/myapp" });
73
73
  expect(targets).toHaveLength(6);
74
74
  expect(targets.map((t) => t.schemaKey)).toContain("screen");
75
- expect(targets.find((t) => t.schemaKey === "screen")!.glob).toBe(
76
- "apps/[a-zA-Z]*/docs/screen/*.md",
77
- );
75
+ expect(targets.find((t) => t.schemaKey === "screen")!.glob).toBe("apps/myapp/docs/screen/*.md");
78
76
  });
79
77
 
80
78
  it("builds both when both roots provided", () => {
81
- const targets = buildCheckTargets({ modulesRoot: "modules", appRoot: "apps" });
79
+ const targets = buildCheckTargets({ modulesRoot: "modules", appRoot: "apps/myapp" });
82
80
  expect(targets).toHaveLength(11);
83
81
  });
84
82
  });
@@ -45,8 +45,8 @@ export function appComposeCategories(root: string): CategoryConfig[] {
45
45
  return [
46
46
  {
47
47
  name: "resolver",
48
- sourcePattern: `${root}/*/backend/src/resolvers/*.ts`,
49
- docPattern: `${root}/*/${APP_PATHS.docs.resolver}/*.md`,
48
+ sourcePattern: `${root}/backend/src/resolvers/*.ts`,
49
+ docPattern: `${root}/${APP_PATHS.docs.resolver}/*.md`,
50
50
  exclusions: [/\.test\.ts$/, /^index\.ts$/],
51
51
  },
52
52
  ];
@@ -95,18 +95,18 @@ export function buildCheckTargets(config: {
95
95
  if (config.appRoot) {
96
96
  const a = config.appRoot;
97
97
  targets.push(
98
- { glob: `${a}/[a-zA-Z]*/README.md`, schemaKey: "app" },
99
- { glob: `${a}/[a-zA-Z]*/${APP_PATHS.docs.actors}/*.md`, schemaKey: "actors" },
98
+ { glob: `${a}/README.md`, schemaKey: "app" },
99
+ { glob: `${a}/${APP_PATHS.docs.actors}/*.md`, schemaKey: "actors" },
100
100
  {
101
- glob: `${a}/[a-zA-Z]*/${APP_PATHS.docs.businessFlow}/*/README.md`,
101
+ glob: `${a}/${APP_PATHS.docs.businessFlow}/*/README.md`,
102
102
  schemaKey: "business-flow",
103
103
  },
104
104
  {
105
- glob: `${a}/[a-zA-Z]*/${APP_PATHS.docs.businessFlow}/*/${APP_PATHS.docs.story}/*.md`,
105
+ glob: `${a}/${APP_PATHS.docs.businessFlow}/*/${APP_PATHS.docs.story}/*.md`,
106
106
  schemaKey: "story",
107
107
  },
108
- { glob: `${a}/[a-zA-Z]*/${APP_PATHS.docs.screen}/*.md`, schemaKey: "screen" },
109
- { glob: `${a}/[a-zA-Z]*/${APP_PATHS.docs.resolver}/*.md`, schemaKey: "resolver" },
108
+ { glob: `${a}/${APP_PATHS.docs.screen}/*.md`, schemaKey: "screen" },
109
+ { glob: `${a}/${APP_PATHS.docs.resolver}/*.md`, schemaKey: "resolver" },
110
110
  );
111
111
  }
112
112
 
@@ -104,7 +104,7 @@ describe("runSourceSyncCheck", () => {
104
104
  fs.writeFileSync(path.join(srcDir, "myResolver.ts"), "export {}");
105
105
  fs.writeFileSync(path.join(docDir, "myResolver.md"), "# MyResolver");
106
106
 
107
- const result = await runSourceSyncCheck({ appRoot: "apps" }, tmpDir);
107
+ const result = await runSourceSyncCheck({ appRoot: "apps/app1" }, tmpDir);
108
108
  expect(result.exitCode).toBe(0);
109
109
  expect(result.summary.totalSources).toBe(1);
110
110
  });
@@ -3,7 +3,12 @@ import fg from "fast-glob";
3
3
  import { moduleCategories, appComposeCategories, type CategoryConfig } from "./discovery";
4
4
 
5
5
  export interface CheckError {
6
- type: "missing-doc" | "orphaned-doc" | "missing-test-case" | "extra-test-case";
6
+ type:
7
+ | "missing-doc"
8
+ | "orphaned-doc"
9
+ | "missing-test-case"
10
+ | "extra-test-case"
11
+ | "missing-test-file";
7
12
  category: string;
8
13
  sourcePath?: string;
9
14
  docPath?: string;
@@ -153,6 +153,29 @@ describe("runModuleTestCaseSyncCheck", () => {
153
153
  expect(tcErrors).toHaveLength(0);
154
154
  });
155
155
 
156
+ it("reports missing-test-file when test file does not exist", async () => {
157
+ const docDir = path.join(tmpDir, "modules", "foo", "docs", "commands");
158
+ const testDir = path.join(tmpDir, "modules", "foo", "command");
159
+ fs.mkdirSync(docDir, { recursive: true });
160
+ fs.mkdirSync(testDir, { recursive: true });
161
+
162
+ fs.writeFileSync(
163
+ path.join(docDir, "CreateOrder.md"),
164
+ "# CreateOrder\n\n## Test Cases\n\n- creates order\n- validates input\n",
165
+ );
166
+ fs.writeFileSync(path.join(testDir, "createOrder.ts"), "export {}");
167
+ // No createOrder.test.ts file
168
+
169
+ const errors = await runModuleTestCaseSyncCheck("modules", tmpDir);
170
+ expect(errors).toContainEqual(
171
+ expect.objectContaining({
172
+ type: "missing-test-file",
173
+ category: "command-test-case",
174
+ expectedBasename: "createOrder.test.ts",
175
+ }),
176
+ );
177
+ });
178
+
156
179
  it("skips test-case check when doc has no Test Cases section", async () => {
157
180
  const docDir = path.join(tmpDir, "modules", "foo", "docs", "commands");
158
181
  const testDir = path.join(tmpDir, "modules", "foo", "command");
@@ -243,6 +266,26 @@ describe("runAppTestCaseSyncCheck", () => {
243
266
  expect(errors).toHaveLength(0);
244
267
  });
245
268
 
269
+ it("reports missing-test-file when story test file does not exist", async () => {
270
+ const flow = "item-lifecycle";
271
+ const storyDir = path.join(tmpDir, "apps", "my-app", "docs", "business-flow", flow, "story");
272
+ fs.mkdirSync(storyDir, { recursive: true });
273
+ // No test file created
274
+ fs.writeFileSync(
275
+ path.join(storyDir, "admin--create-item.md"),
276
+ "# Create Item\n\n## Test Cases\n\n- creates item\n- validates input\n",
277
+ );
278
+
279
+ const errors = await runAppTestCaseSyncCheck("apps", tmpDir);
280
+ expect(errors).toContainEqual(
281
+ expect.objectContaining({
282
+ type: "missing-test-file",
283
+ category: "story-test-case",
284
+ expectedBasename: "admin--create-item.test.ts",
285
+ }),
286
+ );
287
+ });
288
+
246
289
  it("skips when story doc has no Test Cases section", async () => {
247
290
  setupStoryFixture(
248
291
  "admin--view-items",
@@ -31,7 +31,16 @@ export async function runModuleTestCaseSyncCheck(root: string, cwd: string): Pro
31
31
  const testPath = path.join(modulePath, category.testDir, testFileName);
32
32
  const testFullPath = path.join(cwd, testPath);
33
33
 
34
- if (!fs.existsSync(testFullPath)) continue;
34
+ if (!fs.existsSync(testFullPath)) {
35
+ errors.push({
36
+ type: "missing-test-file",
37
+ category: category.name,
38
+ docPath,
39
+ sourcePath: testPath,
40
+ expectedBasename: testFileName,
41
+ });
42
+ continue;
43
+ }
35
44
 
36
45
  const testContent = fs.readFileSync(testFullPath, "utf-8");
37
46
  const itDescriptions = parseItDescriptionsFromTest(testContent);
@@ -92,7 +101,16 @@ export async function runAppTestCaseSyncCheck(appRoot: string, cwd: string): Pro
92
101
  if (!testPath) continue;
93
102
 
94
103
  const testFullPath = path.join(cwd, testPath);
95
- if (!fs.existsSync(testFullPath)) continue;
104
+ if (!fs.existsSync(testFullPath)) {
105
+ errors.push({
106
+ type: "missing-test-file",
107
+ category: config.name,
108
+ docPath,
109
+ sourcePath: testPath,
110
+ expectedBasename: path.basename(testPath),
111
+ });
112
+ continue;
113
+ }
96
114
 
97
115
  const testContent = fs.readFileSync(testFullPath, "utf-8");
98
116
  const itDescriptions = parseItDescriptionsFromTest(testContent);
@@ -54,6 +54,9 @@ export function formatSyncCheckReport(result: SyncCheckResult): string {
54
54
  lines.push(
55
55
  ` ${chalk.yellow("Extra test case:")} "${error.expectedBasename}" is in test but not in doc`,
56
56
  );
57
+ } else if (error.type === "missing-test-file") {
58
+ lines.push(` ${chalk.red(error.docPath)}`);
59
+ lines.push(` ${chalk.yellow("Missing test file:")} ${error.expectedBasename}`);
57
60
  }
58
61
  lines.push("");
59
62
  }
@@ -62,9 +62,7 @@ Gets profile.
62
62
 
63
63
  const files = fs.readdirSync(resolverDir).sort();
64
64
  // Template scaffolding may copy additional files (e.g. createUser.ts)
65
- expect(files).toContain("createItem.test.ts");
66
65
  expect(files).toContain("createItem.ts");
67
- expect(files).toContain("getMyProfile.test.ts");
68
66
  expect(files).toContain("getMyProfile.ts");
69
67
  expect(files).not.toContain("createItem.generated.ts");
70
68
 
@@ -73,10 +71,6 @@ Gets profile.
73
71
  expect(stub).toContain("createResolver");
74
72
  expect(stub).toContain('name: "createItem"');
75
73
  expect(stub).toContain('getDB("main-db")');
76
-
77
- // Test stub exists
78
- const test = fs.readFileSync(path.join(resolverDir, "createItem.test.ts"), "utf-8");
79
- expect(test).toContain('describe("createItem"');
80
74
  });
81
75
 
82
76
  it("does not overwrite existing stubs on re-run", () => {
@@ -3,11 +3,7 @@ import path from "node:path";
3
3
  import { parseTestCasesFromDoc } from "../commands/parse-doc-test-cases";
4
4
  import { APP_PATHS } from "../commands/lib/paths";
5
5
  import { parseResolverDoc } from "./parse-resolver-doc";
6
- import {
7
- generateResolverStub,
8
- generateResolverTestStub,
9
- generateStoryTestStub,
10
- } from "./generate-stubs";
6
+ import { renderStub } from "./stub-templates";
11
7
  import { scaffoldAppBoilerplate } from "./scaffold";
12
8
 
13
9
  export function runGenerateAppCode(appPath: string): number {
@@ -38,16 +34,10 @@ function generateResolverStubs(appPath: string, appName: string): void {
38
34
 
39
35
  const implFile = path.join(resolverDir, `${doc.resolverName}.ts`);
40
36
  if (!fs.existsSync(implFile)) {
41
- fs.writeFileSync(implFile, generateResolverStub(doc.resolverName));
37
+ fs.writeFileSync(implFile, renderStub("resolver", doc.resolverName));
42
38
  console.log(` scaffolded ${path.relative(appPath, implFile)}`);
43
39
  generated++;
44
40
  }
45
-
46
- const testFile = path.join(resolverDir, `${doc.resolverName}.test.ts`);
47
- if (!fs.existsSync(testFile)) {
48
- fs.writeFileSync(testFile, generateResolverTestStub(doc.resolverName));
49
- console.log(` scaffolded ${path.relative(appPath, testFile)}`);
50
- }
51
41
  }
52
42
 
53
43
  if (generated > 0) {
@@ -75,7 +65,7 @@ function generateStoryTestStubs(appPath: string, appName: string): void {
75
65
  if (fs.existsSync(testFile)) continue;
76
66
 
77
67
  fs.mkdirSync(testDir, { recursive: true });
78
- fs.writeFileSync(testFile, generateStoryTestStub(storyName, testCases));
68
+ fs.writeFileSync(testFile, renderStub("storyTest", storyName, testCases));
79
69
  console.log(` scaffolded ${path.relative(appPath, testFile)}`);
80
70
  generated++;
81
71
  }
@@ -2,13 +2,7 @@ import { describe, expect, it } from "vitest";
2
2
  import { moduleNameToPrefix, generateErrors } from "./generate-errors";
3
3
  import { generatePermissions } from "./generate-permissions";
4
4
  import { generateCommandShell, generateQueryShell } from "./generate-shells";
5
- import {
6
- generateQueryStub,
7
- generateQueryTestStub,
8
- generateDbStub,
9
- generateResolverStub,
10
- generateResolverTestStub,
11
- } from "./generate-stubs";
5
+ import { renderStub } from "./stub-templates";
12
6
  import type { ParsedCommandDoc } from "./parse-command-doc";
13
7
 
14
8
  describe("moduleNameToPrefix", () => {
@@ -174,15 +168,9 @@ describe("generateQueryShell", () => {
174
168
  });
175
169
  });
176
170
 
177
- describe("generateQueryStub", () => {
171
+ describe("renderStub query", () => {
178
172
  it("generates a stub implementation with ReadonlyDB and input interface", () => {
179
- const doc: ParsedCommandDoc = {
180
- commandName: "getTaxonomyNode",
181
- errors: [],
182
- externalDependencies: [],
183
- };
184
-
185
- const result = generateQueryStub(doc);
173
+ const result = renderStub("query", "getTaxonomyNode");
186
174
 
187
175
  expect(result).toContain('import type { ReadonlyDB } from "@tailor-platform/erp-kit/module";');
188
176
  expect(result).toContain('import type { DB } from "../generated/kysely-tailordb";');
@@ -194,9 +182,9 @@ describe("generateQueryStub", () => {
194
182
  });
195
183
  });
196
184
 
197
- describe("generateDbStub", () => {
185
+ describe("renderStub db", () => {
198
186
  it("generates an empty db type definition with TODO", () => {
199
- const result = generateDbStub("item");
187
+ const result = renderStub("db", "item");
200
188
 
201
189
  expect(result).toContain(
202
190
  "import { db, unsafeAllowAllGqlPermission, unsafeAllowAllTypePermission }",
@@ -210,22 +198,16 @@ describe("generateDbStub", () => {
210
198
  });
211
199
 
212
200
  it("handles camelCase model names", () => {
213
- const result = generateDbStub("taxonomyNode");
201
+ const result = renderStub("db", "taxonomyNode");
214
202
 
215
203
  expect(result).toContain("export const taxonomyNode = db");
216
204
  expect(result).toContain('.type("TaxonomyNode"');
217
205
  });
218
206
  });
219
207
 
220
- describe("generateQueryTestStub", () => {
208
+ describe("renderStub queryTest", () => {
221
209
  it("generates a test stub with createMockDb and run import", () => {
222
- const doc: ParsedCommandDoc = {
223
- commandName: "getTaxonomyNode",
224
- errors: [],
225
- externalDependencies: [],
226
- };
227
-
228
- const result = generateQueryTestStub(doc);
210
+ const result = renderStub("queryTest", "getTaxonomyNode");
229
211
 
230
212
  expect(result).toContain('import { describe, expect, it } from "vitest";');
231
213
  expect(result).toContain('import { createMockDb } from "../../../testing/index";');
@@ -238,9 +220,9 @@ describe("generateQueryTestStub", () => {
238
220
  });
239
221
  });
240
222
 
241
- describe("generateResolverStub", () => {
223
+ describe("renderStub resolver", () => {
242
224
  it("generates a createResolver stub with SDK imports and transaction boilerplate", () => {
243
- const result = generateResolverStub("createItem");
225
+ const result = renderStub("resolver", "createItem");
244
226
 
245
227
  expect(result).toContain('import { createResolver, t } from "@tailor-platform/sdk";');
246
228
  expect(result).toContain('import { createContext } from "@tailor-platform/erp-kit/app";');
@@ -252,15 +234,3 @@ describe("generateResolverStub", () => {
252
234
  expect(result).toContain('.description("CreateItem response")');
253
235
  });
254
236
  });
255
-
256
- describe("generateResolverTestStub", () => {
257
- it("generates a test that imports and verifies the resolver", () => {
258
- const result = generateResolverTestStub("createItem");
259
-
260
- expect(result).toContain('import { describe, expect, it } from "vitest";');
261
- expect(result).toContain('describe("createItem"');
262
- expect(result).toContain('import("./createItem")');
263
- expect(result).toContain("expect(resolver.default).toBeDefined()");
264
- expect(result).toContain('expect(resolver.default.name).toBe("createItem")');
265
- });
266
- });
@@ -4,13 +4,7 @@ import { parseCommandDoc, type ParsedCommandDoc } from "./parse-command-doc";
4
4
  import { generateErrors } from "./generate-errors";
5
5
  import { generatePermissions } from "./generate-permissions";
6
6
  import { generateCommandShell, generateQueryShell } from "./generate-shells";
7
- import {
8
- generateCommandStub,
9
- generateTestStub,
10
- generateQueryStub,
11
- generateQueryTestStub,
12
- generateDbStub,
13
- } from "./generate-stubs";
7
+ import { renderStub } from "./stub-templates";
14
8
  import { scaffoldModuleBoilerplate } from "./scaffold";
15
9
 
16
10
  export function runGenerateCode(modulePath: string, moduleName: string): number {
@@ -81,13 +75,13 @@ export function runGenerateCode(modulePath: string, moduleName: string): number
81
75
  generated++;
82
76
 
83
77
  if (!fs.existsSync(implFile)) {
84
- fs.writeFileSync(implFile, generateCommandStub(doc));
78
+ fs.writeFileSync(implFile, renderStub("command", doc.commandName));
85
79
  console.log(` scaffolded ${path.relative(modulePath, implFile)}`);
86
80
  }
87
81
 
88
82
  const testFile = path.join(commandDir, `${doc.commandName}.test.ts`);
89
83
  if (!fs.existsSync(testFile)) {
90
- fs.writeFileSync(testFile, generateTestStub(doc));
84
+ fs.writeFileSync(testFile, renderStub("commandTest", doc.commandName));
91
85
  console.log(` scaffolded ${path.relative(modulePath, testFile)}`);
92
86
  }
93
87
  }
@@ -111,13 +105,13 @@ export function runGenerateCode(modulePath: string, moduleName: string): number
111
105
 
112
106
  const implFile = path.join(queryDir, `${doc.commandName}.ts`);
113
107
  if (!fs.existsSync(implFile)) {
114
- fs.writeFileSync(implFile, generateQueryStub(doc));
108
+ fs.writeFileSync(implFile, renderStub("query", doc.commandName));
115
109
  console.log(` scaffolded ${path.relative(modulePath, implFile)}`);
116
110
  }
117
111
 
118
112
  const testFile = path.join(queryDir, `${doc.commandName}.test.ts`);
119
113
  if (!fs.existsSync(testFile)) {
120
- fs.writeFileSync(testFile, generateQueryTestStub(doc));
114
+ fs.writeFileSync(testFile, renderStub("queryTest", doc.commandName));
121
115
  console.log(` scaffolded ${path.relative(modulePath, testFile)}`);
122
116
  }
123
117
  }
@@ -137,7 +131,7 @@ export function runGenerateCode(modulePath: string, moduleName: string): number
137
131
  const camelName = modelName.charAt(0).toLowerCase() + modelName.slice(1);
138
132
  const dbFile = path.join(dbDir, `${camelName}.ts`);
139
133
  if (!fs.existsSync(dbFile)) {
140
- fs.writeFileSync(dbFile, generateDbStub(camelName));
134
+ fs.writeFileSync(dbFile, renderStub("db", camelName));
141
135
  console.log(` scaffolded ${path.relative(modulePath, dbFile)}`);
142
136
  }
143
137
  }
@@ -46,13 +46,6 @@ describe("renderStub", () => {
46
46
  expect(result).toContain('getDB("main-db")');
47
47
  });
48
48
 
49
- it("resolverTest: generates test that imports resolver", () => {
50
- const result = renderStub("resolverTest", "createItem");
51
- expect(result).toContain('describe("createItem"');
52
- expect(result).toContain('import("./createItem")');
53
- expect(result).toContain("resolver.default");
54
- });
55
-
56
49
  it("storyTest: generates integration test with graphql client and test cases", () => {
57
50
  const result = renderStub("storyTest", "admin--create-item", [
58
51
  "creates item successfully",
@@ -119,20 +119,6 @@ export default createResolver({
119
119
  })
120
120
  .description("${toPascal(name)} response"),
121
121
  });
122
- `;
123
- },
124
- },
125
- resolverTest: {
126
- render: (name: string) => {
127
- return `import { describe, expect, it } from "vitest";
128
-
129
- describe("${name}", () => {
130
- it("should be implemented", async () => {
131
- const resolver = await import("./${name}");
132
- expect(resolver.default).toBeDefined();
133
- expect(resolver.default.name).toBe("${name}");
134
- });
135
- });
136
122
  `;
137
123
  },
138
124
  },
@@ -0,0 +1,50 @@
1
+ # README
2
+
3
+ <!-- This section should contain the following subsections in order: -->
4
+ <!-- 1. ## Overview (required) -->
5
+ <!-- 2. ## Key Features (required) -->
6
+ <!-- 3. ## Module Scope (required) -->
7
+ <!-- 4. ## Module Dependencies (required) -->
8
+
9
+ ## Overview
10
+
11
+ ## Key Features
12
+
13
+ <!-- List requirements: -->
14
+ <!-- Minimum 1 unordered lists required -->
15
+ <!-- Minimum 1 items per list -->
16
+
17
+ - TODO: Add list item
18
+
19
+ ## Module Scope
20
+
21
+ <!-- This section should contain the following subsections in order: -->
22
+ <!-- 1. ### In Scope (required) -->
23
+ <!-- 2. ### Out of Scope (required) -->
24
+ <!-- 3. ### Scope Decision Rationale (required) -->
25
+
26
+ ### In Scope
27
+
28
+ <!-- List requirements: -->
29
+ <!-- Minimum 1 unordered lists required -->
30
+ <!-- Minimum 1 items per list -->
31
+
32
+ - TODO: Add list item
33
+
34
+ ### Out of Scope
35
+
36
+ <!-- List requirements: -->
37
+ <!-- Minimum 1 unordered lists required -->
38
+ <!-- Minimum 1 items per list -->
39
+
40
+ - TODO: Add list item
41
+
42
+ ### Scope Decision Rationale
43
+
44
+ <!-- Explain why capabilities are in-scope or out-of-scope — domain alignment, separation of concerns, etc. -->
45
+
46
+ ## Module Dependencies
47
+
48
+ <!-- List requirements: -->
49
+ <!-- Minimum 1 items per list -->
50
+
File without changes