@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,133 @@
1
+ import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/module";
2
+ import type { Transaction } from "../generated/kysely-tailordb";
3
+ import {
4
+ InvalidPeriodStatusError,
5
+ AccountNotFoundError,
6
+ AccountNotActiveError,
7
+ InvalidAmountError,
8
+ CompanyMismatchError,
9
+ } from "../lib/errors.generated";
10
+
11
+ export interface ProcessManufacturingHandoffInput {
12
+ companyId: string;
13
+ accountingPeriodId: string;
14
+ sourceDocumentReference: string;
15
+ entryDate: Date;
16
+ debitAccountId: string;
17
+ creditAccountId: string;
18
+ amount: number;
19
+ currencyCode?: string;
20
+ exchangeRate?: number;
21
+ description?: string;
22
+ }
23
+
24
+ const VALID_PERIOD_STATUSES = ["OPEN", "FUTURE_ENTERABLE"];
25
+
26
+ export async function run(
27
+ db: Transaction,
28
+ input: ProcessManufacturingHandoffInput,
29
+ _ctx: CommandContext,
30
+ ) {
31
+ // 1. Idempotency check: look for existing entry with same sourceDocumentReference + companyId
32
+ const existing = await db
33
+ .selectFrom("JournalEntry")
34
+ .selectAll()
35
+ .where("sourceDocumentReference", "=", input.sourceDocumentReference)
36
+ .where("companyId", "=", input.companyId)
37
+ .executeTakeFirst();
38
+ if (existing) return ok({ journalEntry: existing, acknowledged: true, idempotent: true });
39
+
40
+ // 2. Validate amount > 0
41
+ if (input.amount <= 0) return err(new InvalidAmountError(input.sourceDocumentReference));
42
+
43
+ // 3. Find and validate period
44
+ const period = await db
45
+ .selectFrom("AccountingPeriod")
46
+ .selectAll()
47
+ .where("id", "=", input.accountingPeriodId)
48
+ .executeTakeFirst();
49
+ if (!period || !VALID_PERIOD_STATUSES.includes(period.status))
50
+ return err(new InvalidPeriodStatusError(input.accountingPeriodId));
51
+
52
+ // 4. Validate company matches period's company
53
+ if (period.companyId !== input.companyId) return err(new CompanyMismatchError(input.companyId));
54
+
55
+ // 5. Validate debit account is ACTIVE
56
+ const debitAccount = await db
57
+ .selectFrom("Account")
58
+ .selectAll()
59
+ .where("id", "=", input.debitAccountId)
60
+ .executeTakeFirst();
61
+ if (!debitAccount) return err(new AccountNotFoundError(input.debitAccountId));
62
+ if (debitAccount.status !== "ACTIVE") return err(new AccountNotActiveError(input.debitAccountId));
63
+
64
+ // 6. Validate credit account is ACTIVE
65
+ const creditAccount = await db
66
+ .selectFrom("Account")
67
+ .selectAll()
68
+ .where("id", "=", input.creditAccountId)
69
+ .executeTakeFirst();
70
+ if (!creditAccount) return err(new AccountNotFoundError(input.creditAccountId));
71
+ if (creditAccount.status !== "ACTIVE")
72
+ return err(new AccountNotActiveError(input.creditAccountId));
73
+
74
+ // 7. Calculate functional amounts
75
+ const rate = input.exchangeRate ?? 1;
76
+ const functionalAmount = input.amount * rate;
77
+
78
+ // 8. Create journal entry (auto-posted)
79
+ const now = new Date();
80
+ const journalEntry = await db
81
+ .insertInto("JournalEntry")
82
+ .values({
83
+ companyId: input.companyId,
84
+ accountingPeriodId: input.accountingPeriodId,
85
+ entryDate: input.entryDate,
86
+ journalType: "MANUFACTURING",
87
+ referenceNumber: input.sourceDocumentReference,
88
+ status: "POSTED",
89
+ description: input.description ?? null,
90
+ sourceDocumentReference: input.sourceDocumentReference,
91
+ postedAt: now,
92
+ createdAt: now,
93
+ })
94
+ .returningAll()
95
+ .executeTakeFirst();
96
+
97
+ // 9. Create journal lines (debit + credit)
98
+ await db
99
+ .insertInto("JournalLine")
100
+ .values([
101
+ {
102
+ journalEntryId: journalEntry!.id,
103
+ accountId: input.debitAccountId,
104
+ debitAmount: input.amount,
105
+ creditAmount: null,
106
+ functionalDebitAmount: functionalAmount,
107
+ functionalCreditAmount: null,
108
+ currencyCode: input.currencyCode ?? null,
109
+ exchangeRate: input.exchangeRate ?? null,
110
+ createdAt: now,
111
+ },
112
+ {
113
+ journalEntryId: journalEntry!.id,
114
+ accountId: input.creditAccountId,
115
+ debitAmount: null,
116
+ creditAmount: input.amount,
117
+ functionalDebitAmount: null,
118
+ functionalCreditAmount: functionalAmount,
119
+ currencyCode: input.currencyCode ?? null,
120
+ exchangeRate: input.exchangeRate ?? null,
121
+ createdAt: now,
122
+ },
123
+ ])
124
+ .returningAll()
125
+ .execute();
126
+
127
+ return ok({
128
+ journalEntry: journalEntry!,
129
+ acknowledged: true,
130
+ acknowledgedAt: now,
131
+ idempotent: false,
132
+ });
133
+ }
@@ -0,0 +1,6 @@
1
+ // @generated — do not edit
2
+ import { defineCommand } from "@tailor-platform/erp-kit/module";
3
+ import { permissions } from "../lib/permissions.generated";
4
+ import { run } from "./processPurchaseHandoff";
5
+
6
+ export const processPurchaseHandoff = defineCommand(permissions.processPurchaseHandoff, run);
@@ -0,0 +1,222 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { Transaction } from "../generated/kysely-tailordb";
4
+ import {
5
+ InvalidPeriodStatusError,
6
+ AccountNotFoundError,
7
+ AccountNotActiveError,
8
+ InvalidAmountError,
9
+ CompanyMismatchError,
10
+ } from "../lib/errors.generated";
11
+ import {
12
+ baseAccountingPeriod,
13
+ neverOpenedPeriod,
14
+ closedPeriod,
15
+ baseAccount,
16
+ baseAccount2,
17
+ inactiveAccount,
18
+ baseCompany,
19
+ baseJournalEntry,
20
+ } from "../testing/fixtures";
21
+ import { commandCtx, expectErr, expectOk } from "../testing/commandTestUtils";
22
+ import { run } from "./processPurchaseHandoff";
23
+
24
+ describe("processPurchaseHandoff", () => {
25
+ const baseInput = {
26
+ companyId: baseCompany.id,
27
+ accountingPeriodId: baseAccountingPeriod.id,
28
+ sourceDocumentReference: "PO-001",
29
+ entryDate: new Date("2024-01-15"),
30
+ debitAccountId: baseAccount.id,
31
+ creditAccountId: baseAccount2.id,
32
+ amount: 1000,
33
+ };
34
+
35
+ it("returns existing entry for idempotent duplicate", async () => {
36
+ const { db, spies } = createMockDb<Transaction>();
37
+ const existingEntry = { ...baseJournalEntry, sourceDocumentReference: "PO-001" };
38
+ spies.select.mockReturnValueOnce(existingEntry);
39
+
40
+ const result = await run(db, baseInput, commandCtx);
41
+
42
+ const value = expectOk(result);
43
+ expect(value.journalEntry).toEqual(existingEntry);
44
+ expect(value.idempotent).toBe(true);
45
+ expect(spies.insert).not.toHaveBeenCalled();
46
+ });
47
+
48
+ it("returns error when amount is zero or negative", async () => {
49
+ const { db, spies } = createMockDb<Transaction>();
50
+ spies.select.mockReturnValueOnce(undefined); // no existing entry
51
+
52
+ const result = await run(db, { ...baseInput, amount: 0 }, commandCtx);
53
+
54
+ expectErr(result, InvalidAmountError);
55
+ });
56
+
57
+ it("returns error when amount is negative", async () => {
58
+ const { db, spies } = createMockDb<Transaction>();
59
+ spies.select.mockReturnValueOnce(undefined); // no existing entry
60
+
61
+ const result = await run(db, { ...baseInput, amount: -100 }, commandCtx);
62
+
63
+ expectErr(result, InvalidAmountError);
64
+ });
65
+
66
+ it("returns error when period is not OPEN or FUTURE_ENTERABLE", async () => {
67
+ const { db, spies } = createMockDb<Transaction>();
68
+ spies.select
69
+ .mockReturnValueOnce(undefined) // no existing entry
70
+ .mockReturnValueOnce(neverOpenedPeriod); // period lookup
71
+
72
+ const result = await run(
73
+ db,
74
+ { ...baseInput, accountingPeriodId: neverOpenedPeriod.id },
75
+ commandCtx,
76
+ );
77
+
78
+ expectErr(result, InvalidPeriodStatusError);
79
+ });
80
+
81
+ it("returns error when period is CLOSED", async () => {
82
+ const { db, spies } = createMockDb<Transaction>();
83
+ spies.select
84
+ .mockReturnValueOnce(undefined) // no existing entry
85
+ .mockReturnValueOnce(closedPeriod); // period lookup
86
+
87
+ const result = await run(db, { ...baseInput, accountingPeriodId: closedPeriod.id }, commandCtx);
88
+
89
+ expectErr(result, InvalidPeriodStatusError);
90
+ });
91
+
92
+ it("returns error when company does not match period company", async () => {
93
+ const { db, spies } = createMockDb<Transaction>();
94
+ spies.select
95
+ .mockReturnValueOnce(undefined) // no existing entry
96
+ .mockReturnValueOnce(baseAccountingPeriod); // period lookup
97
+
98
+ const result = await run(db, { ...baseInput, companyId: "other-company" }, commandCtx);
99
+
100
+ expectErr(result, CompanyMismatchError);
101
+ });
102
+
103
+ it("returns error when debit account does not exist", async () => {
104
+ const { db, spies } = createMockDb<Transaction>();
105
+ spies.select
106
+ .mockReturnValueOnce(undefined) // no existing entry
107
+ .mockReturnValueOnce(baseAccountingPeriod) // period lookup
108
+ .mockReturnValueOnce(undefined); // debit account lookup — not found
109
+
110
+ const result = await run(
111
+ db,
112
+ { ...baseInput, debitAccountId: "nonexistent-account" },
113
+ commandCtx,
114
+ );
115
+
116
+ expectErr(result, AccountNotFoundError);
117
+ });
118
+
119
+ it("returns error when credit account does not exist", async () => {
120
+ const { db, spies } = createMockDb<Transaction>();
121
+ spies.select
122
+ .mockReturnValueOnce(undefined) // no existing entry
123
+ .mockReturnValueOnce(baseAccountingPeriod) // period lookup
124
+ .mockReturnValueOnce(baseAccount) // debit account lookup (active)
125
+ .mockReturnValueOnce(undefined); // credit account lookup — not found
126
+
127
+ const result = await run(
128
+ db,
129
+ { ...baseInput, creditAccountId: "nonexistent-account" },
130
+ commandCtx,
131
+ );
132
+
133
+ expectErr(result, AccountNotFoundError);
134
+ });
135
+
136
+ it("returns error when debit account is not active", async () => {
137
+ const { db, spies } = createMockDb<Transaction>();
138
+ spies.select
139
+ .mockReturnValueOnce(undefined) // no existing entry
140
+ .mockReturnValueOnce(baseAccountingPeriod) // period lookup
141
+ .mockReturnValueOnce(inactiveAccount); // debit account lookup
142
+
143
+ const result = await run(db, { ...baseInput, debitAccountId: inactiveAccount.id }, commandCtx);
144
+
145
+ expectErr(result, AccountNotActiveError);
146
+ });
147
+
148
+ it("returns error when credit account is not active", async () => {
149
+ const { db, spies } = createMockDb<Transaction>();
150
+ spies.select
151
+ .mockReturnValueOnce(undefined) // no existing entry
152
+ .mockReturnValueOnce(baseAccountingPeriod) // period lookup
153
+ .mockReturnValueOnce(baseAccount) // debit account lookup (active)
154
+ .mockReturnValueOnce(inactiveAccount); // credit account lookup
155
+
156
+ const result = await run(db, { ...baseInput, creditAccountId: inactiveAccount.id }, commandCtx);
157
+
158
+ expectErr(result, AccountNotActiveError);
159
+ });
160
+
161
+ it("creates journal entry with correct type and amounts", async () => {
162
+ const { db, spies } = createMockDb<Transaction>();
163
+ const createdEntry = {
164
+ ...baseJournalEntry,
165
+ journalType: "PURCHASE",
166
+ status: "POSTED",
167
+ sourceDocumentReference: "PO-001",
168
+ };
169
+ spies.select
170
+ .mockReturnValueOnce(undefined) // no existing entry
171
+ .mockReturnValueOnce(baseAccountingPeriod) // period lookup
172
+ .mockReturnValueOnce(baseAccount) // debit account lookup
173
+ .mockReturnValueOnce(baseAccount2); // credit account lookup
174
+ spies.insert
175
+ .mockReturnValueOnce(createdEntry) // journal entry insert
176
+ .mockReturnValueOnce([]); // journal lines insert
177
+
178
+ const result = await run(db, baseInput, commandCtx);
179
+
180
+ const value = expectOk(result);
181
+ expect(value.journalEntry.journalType).toBe("PURCHASE");
182
+ expect(value.journalEntry.status).toBe("POSTED");
183
+ expect(value.idempotent).toBe(false);
184
+ expect(value.acknowledged).toBe(true);
185
+ });
186
+
187
+ it("handles multi-currency with exchange rate", async () => {
188
+ const { db, spies } = createMockDb<Transaction>();
189
+ const createdEntry = {
190
+ ...baseJournalEntry,
191
+ journalType: "PURCHASE",
192
+ status: "POSTED",
193
+ sourceDocumentReference: "PO-002",
194
+ };
195
+ spies.select
196
+ .mockReturnValueOnce(undefined) // no existing entry
197
+ .mockReturnValueOnce(baseAccountingPeriod) // period lookup
198
+ .mockReturnValueOnce(baseAccount) // debit account lookup
199
+ .mockReturnValueOnce(baseAccount2); // credit account lookup
200
+ spies.insert
201
+ .mockReturnValueOnce(createdEntry) // journal entry insert
202
+ .mockReturnValueOnce([]); // journal lines insert
203
+
204
+ const result = await run(
205
+ db,
206
+ {
207
+ ...baseInput,
208
+ sourceDocumentReference: "PO-002",
209
+ currencyCode: "currency-1",
210
+ exchangeRate: 1.5,
211
+ amount: 1000,
212
+ },
213
+ commandCtx,
214
+ );
215
+
216
+ const value = expectOk(result);
217
+ expect(value.journalEntry).toBeDefined();
218
+ expect(value.idempotent).toBe(false);
219
+ // Verify the values spy was called with amounts reflecting the exchange rate
220
+ expect(spies.values).toHaveBeenCalled();
221
+ });
222
+ });
@@ -0,0 +1,133 @@
1
+ import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/module";
2
+ import type { Transaction } from "../generated/kysely-tailordb";
3
+ import {
4
+ InvalidPeriodStatusError,
5
+ AccountNotFoundError,
6
+ AccountNotActiveError,
7
+ InvalidAmountError,
8
+ CompanyMismatchError,
9
+ } from "../lib/errors.generated";
10
+
11
+ export interface ProcessPurchaseHandoffInput {
12
+ companyId: string;
13
+ accountingPeriodId: string;
14
+ sourceDocumentReference: string;
15
+ entryDate: Date;
16
+ debitAccountId: string;
17
+ creditAccountId: string;
18
+ amount: number;
19
+ currencyCode?: string;
20
+ exchangeRate?: number;
21
+ description?: string;
22
+ }
23
+
24
+ const VALID_PERIOD_STATUSES = ["OPEN", "FUTURE_ENTERABLE"];
25
+
26
+ export async function run(
27
+ db: Transaction,
28
+ input: ProcessPurchaseHandoffInput,
29
+ _ctx: CommandContext,
30
+ ) {
31
+ // 1. Idempotency check: look for existing entry with same sourceDocumentReference + companyId
32
+ const existing = await db
33
+ .selectFrom("JournalEntry")
34
+ .selectAll()
35
+ .where("sourceDocumentReference", "=", input.sourceDocumentReference)
36
+ .where("companyId", "=", input.companyId)
37
+ .executeTakeFirst();
38
+ if (existing) return ok({ journalEntry: existing, acknowledged: true, idempotent: true });
39
+
40
+ // 2. Validate amount > 0
41
+ if (input.amount <= 0) return err(new InvalidAmountError(input.sourceDocumentReference));
42
+
43
+ // 3. Find and validate period
44
+ const period = await db
45
+ .selectFrom("AccountingPeriod")
46
+ .selectAll()
47
+ .where("id", "=", input.accountingPeriodId)
48
+ .executeTakeFirst();
49
+ if (!period || !VALID_PERIOD_STATUSES.includes(period.status))
50
+ return err(new InvalidPeriodStatusError(input.accountingPeriodId));
51
+
52
+ // 4. Validate company matches period's company
53
+ if (period.companyId !== input.companyId) return err(new CompanyMismatchError(input.companyId));
54
+
55
+ // 5. Validate debit account exists and is ACTIVE
56
+ const debitAccount = await db
57
+ .selectFrom("Account")
58
+ .selectAll()
59
+ .where("id", "=", input.debitAccountId)
60
+ .executeTakeFirst();
61
+ if (!debitAccount) return err(new AccountNotFoundError(input.debitAccountId));
62
+ if (debitAccount.status !== "ACTIVE") return err(new AccountNotActiveError(input.debitAccountId));
63
+
64
+ // 6. Validate credit account exists and is ACTIVE
65
+ const creditAccount = await db
66
+ .selectFrom("Account")
67
+ .selectAll()
68
+ .where("id", "=", input.creditAccountId)
69
+ .executeTakeFirst();
70
+ if (!creditAccount) return err(new AccountNotFoundError(input.creditAccountId));
71
+ if (creditAccount.status !== "ACTIVE")
72
+ return err(new AccountNotActiveError(input.creditAccountId));
73
+
74
+ // 7. Calculate functional amounts
75
+ const rate = input.exchangeRate ?? 1;
76
+ const functionalAmount = input.amount * rate;
77
+
78
+ // 8. Create journal entry (auto-posted)
79
+ const now = new Date();
80
+ const journalEntry = await db
81
+ .insertInto("JournalEntry")
82
+ .values({
83
+ companyId: input.companyId,
84
+ accountingPeriodId: input.accountingPeriodId,
85
+ entryDate: input.entryDate,
86
+ journalType: "PURCHASE",
87
+ referenceNumber: input.sourceDocumentReference,
88
+ status: "POSTED",
89
+ description: input.description ?? null,
90
+ sourceDocumentReference: input.sourceDocumentReference,
91
+ postedAt: now,
92
+ createdAt: now,
93
+ })
94
+ .returningAll()
95
+ .executeTakeFirst();
96
+
97
+ // 9. Create journal lines (debit + credit)
98
+ await db
99
+ .insertInto("JournalLine")
100
+ .values([
101
+ {
102
+ journalEntryId: journalEntry!.id,
103
+ accountId: input.debitAccountId,
104
+ debitAmount: input.amount,
105
+ creditAmount: null,
106
+ functionalDebitAmount: functionalAmount,
107
+ functionalCreditAmount: null,
108
+ currencyCode: input.currencyCode ?? null,
109
+ exchangeRate: input.exchangeRate ?? null,
110
+ createdAt: now,
111
+ },
112
+ {
113
+ journalEntryId: journalEntry!.id,
114
+ accountId: input.creditAccountId,
115
+ debitAmount: null,
116
+ creditAmount: input.amount,
117
+ functionalDebitAmount: null,
118
+ functionalCreditAmount: functionalAmount,
119
+ currencyCode: input.currencyCode ?? null,
120
+ exchangeRate: input.exchangeRate ?? null,
121
+ createdAt: now,
122
+ },
123
+ ])
124
+ .returningAll()
125
+ .execute();
126
+
127
+ return ok({
128
+ journalEntry: journalEntry!,
129
+ acknowledged: true,
130
+ acknowledgedAt: now,
131
+ idempotent: false,
132
+ });
133
+ }
@@ -0,0 +1,6 @@
1
+ // @generated — do not edit
2
+ import { defineCommand } from "@tailor-platform/erp-kit/module";
3
+ import { permissions } from "../lib/permissions.generated";
4
+ import { run } from "./processSalesHandoff";
5
+
6
+ export const processSalesHandoff = defineCommand(permissions.processSalesHandoff, run);