@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,425 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { Transaction } from "../generated/kysely-tailordb";
4
+ import {
5
+ FiscalYearNotFoundError,
6
+ NameRequiredError,
7
+ InvalidDateRangeError,
8
+ OverlappingPeriodError,
9
+ InvalidPeriodTypeError,
10
+ DuplicatePeriodDatesError,
11
+ } from "../lib/errors.generated";
12
+ import {
13
+ baseCompany,
14
+ baseFiscalYear,
15
+ baseAccountingPeriod,
16
+ lastPeriodOfYear,
17
+ } from "../testing/fixtures";
18
+ import { commandCtx, expectErr, expectOk } from "../testing/commandTestUtils";
19
+ import { run, type CreateAccountingPeriodInput } from "./createAccountingPeriod";
20
+
21
+ const validInput: CreateAccountingPeriodInput = {
22
+ companyId: baseCompany.id,
23
+ fiscalYearId: baseFiscalYear.id,
24
+ name: "January 2024",
25
+ startDate: new Date("2024-01-01"),
26
+ endDate: new Date("2024-01-31"),
27
+ periodType: "OPERATING",
28
+ };
29
+
30
+ describe("createAccountingPeriod", () => {
31
+ it("returns error when fiscal year does not exist", async () => {
32
+ const { db, spies } = createMockDb<Transaction>();
33
+ spies.select.mockReturnValueOnce(undefined);
34
+
35
+ const result = await run(db, { ...validInput, fiscalYearId: "missing" }, commandCtx);
36
+
37
+ expectErr(result, FiscalYearNotFoundError);
38
+ });
39
+
40
+ it("returns error when fiscal year belongs to a different company", async () => {
41
+ const { db, spies } = createMockDb<Transaction>();
42
+ spies.select.mockReturnValueOnce({ ...baseFiscalYear, companyId: "other-company" });
43
+
44
+ const result = await run(db, validInput, commandCtx);
45
+
46
+ expectErr(result, FiscalYearNotFoundError);
47
+ });
48
+
49
+ it("returns error when name is empty", async () => {
50
+ const { db, spies } = createMockDb<Transaction>();
51
+ spies.select.mockReturnValueOnce(baseFiscalYear);
52
+
53
+ const result = await run(db, { ...validInput, name: "" }, commandCtx);
54
+
55
+ expectErr(result, NameRequiredError);
56
+ });
57
+
58
+ it("returns error when start date is not before end date", async () => {
59
+ const { db, spies } = createMockDb<Transaction>();
60
+ spies.select.mockReturnValueOnce(baseFiscalYear);
61
+
62
+ const result = await run(
63
+ db,
64
+ {
65
+ ...validInput,
66
+ startDate: new Date("2024-01-31"),
67
+ endDate: new Date("2024-01-01"),
68
+ },
69
+ commandCtx,
70
+ );
71
+
72
+ expectErr(result, InvalidDateRangeError);
73
+ });
74
+
75
+ it("returns error when start date equals end date", async () => {
76
+ const { db, spies } = createMockDb<Transaction>();
77
+ spies.select.mockReturnValueOnce(baseFiscalYear);
78
+
79
+ const result = await run(
80
+ db,
81
+ {
82
+ ...validInput,
83
+ startDate: new Date("2024-01-15"),
84
+ endDate: new Date("2024-01-15"),
85
+ },
86
+ commandCtx,
87
+ );
88
+
89
+ expectErr(result, InvalidDateRangeError);
90
+ });
91
+
92
+ it("returns error when period type is invalid", async () => {
93
+ const { db, spies } = createMockDb<Transaction>();
94
+ spies.select.mockReturnValueOnce(baseFiscalYear).mockReturnValueOnce([]);
95
+
96
+ const result = await run(db, { ...validInput, periodType: "MONTHLY" }, commandCtx);
97
+
98
+ expectErr(result, InvalidPeriodTypeError);
99
+ });
100
+
101
+ it("returns error when period overlaps with an existing period in the same fiscal year", async () => {
102
+ const { db, spies } = createMockDb<Transaction>();
103
+ spies.select.mockReturnValueOnce(baseFiscalYear).mockReturnValueOnce([baseAccountingPeriod]);
104
+
105
+ const result = await run(
106
+ db,
107
+ {
108
+ ...validInput,
109
+ name: "Overlapping Period",
110
+ startDate: new Date("2024-01-15"),
111
+ endDate: new Date("2024-02-15"),
112
+ },
113
+ commandCtx,
114
+ );
115
+
116
+ expectErr(result, OverlappingPeriodError);
117
+ });
118
+
119
+ it("returns error when two periods have identical dates and neither is adjustment type", async () => {
120
+ const { db, spies } = createMockDb<Transaction>();
121
+ spies.select.mockReturnValueOnce(baseFiscalYear).mockReturnValueOnce([baseAccountingPeriod]);
122
+
123
+ const result = await run(
124
+ db,
125
+ {
126
+ ...validInput,
127
+ name: "Duplicate Period",
128
+ startDate: baseAccountingPeriod.startDate,
129
+ endDate: baseAccountingPeriod.endDate,
130
+ periodType: "OPERATING",
131
+ },
132
+ commandCtx,
133
+ );
134
+
135
+ expectErr(result, DuplicatePeriodDatesError);
136
+ });
137
+
138
+ it("creates period in NEVER_OPENED status with valid inputs", async () => {
139
+ const { db, spies } = createMockDb<Transaction>();
140
+ const expectedPeriod = {
141
+ ...baseAccountingPeriod,
142
+ status: "NEVER_OPENED",
143
+ };
144
+ spies.select.mockReturnValueOnce(baseFiscalYear).mockReturnValueOnce([]);
145
+ spies.insert.mockReturnValueOnce(expectedPeriod);
146
+
147
+ const result = await run(db, validInput, commandCtx);
148
+
149
+ const value = expectOk(result);
150
+ expect(value.accountingPeriod.status).toBe("NEVER_OPENED");
151
+ });
152
+
153
+ it("creates 12 monthly periods with correct date boundaries for a calendar fiscal year", async () => {
154
+ const { db, spies } = createMockDb<Transaction>();
155
+ const existingPeriods: unknown[] = [];
156
+ const results: unknown[] = [];
157
+
158
+ for (let month = 0; month < 12; month++) {
159
+ const startDate = new Date(2024, month, 1);
160
+ const endDate = new Date(2024, month + 1, 0);
161
+ const periodName = startDate.toLocaleString("en", { month: "long", year: "numeric" });
162
+
163
+ spies.select.mockReturnValueOnce(baseFiscalYear).mockReturnValueOnce([...existingPeriods]);
164
+
165
+ const createdPeriod = {
166
+ id: `period-${month + 1}`,
167
+ companyId: baseCompany.id,
168
+ fiscalYearId: baseFiscalYear.id,
169
+ name: periodName,
170
+ startDate,
171
+ endDate,
172
+ periodType: "OPERATING",
173
+ status: "NEVER_OPENED",
174
+ createdAt: new Date(),
175
+ updatedAt: null,
176
+ };
177
+ spies.insert.mockReturnValueOnce(createdPeriod);
178
+
179
+ const result = await run(
180
+ db,
181
+ {
182
+ companyId: baseCompany.id,
183
+ fiscalYearId: baseFiscalYear.id,
184
+ name: periodName,
185
+ startDate,
186
+ endDate,
187
+ periodType: "OPERATING",
188
+ },
189
+ commandCtx,
190
+ );
191
+
192
+ const value = expectOk(result);
193
+ results.push(value.accountingPeriod);
194
+ existingPeriods.push(createdPeriod);
195
+ }
196
+
197
+ expect(results).toHaveLength(12);
198
+ });
199
+
200
+ it("creates 13 periods (12 operating + 1 adjustment) for a fiscal year", async () => {
201
+ const { db, spies } = createMockDb<Transaction>();
202
+ const existingPeriods: unknown[] = [];
203
+
204
+ // Create 12 operating periods
205
+ for (let month = 0; month < 12; month++) {
206
+ const startDate = new Date(2024, month, 1);
207
+ const endDate = new Date(2024, month + 1, 0);
208
+
209
+ const createdPeriod = {
210
+ id: `period-${month + 1}`,
211
+ companyId: baseCompany.id,
212
+ fiscalYearId: baseFiscalYear.id,
213
+ name: `Period ${month + 1}`,
214
+ startDate,
215
+ endDate,
216
+ periodType: "OPERATING",
217
+ status: "NEVER_OPENED",
218
+ createdAt: new Date(),
219
+ updatedAt: null,
220
+ };
221
+
222
+ spies.select.mockReturnValueOnce(baseFiscalYear).mockReturnValueOnce([...existingPeriods]);
223
+ spies.insert.mockReturnValueOnce(createdPeriod);
224
+
225
+ await run(
226
+ db,
227
+ {
228
+ companyId: baseCompany.id,
229
+ fiscalYearId: baseFiscalYear.id,
230
+ name: `Period ${month + 1}`,
231
+ startDate,
232
+ endDate,
233
+ periodType: "OPERATING",
234
+ },
235
+ commandCtx,
236
+ );
237
+
238
+ existingPeriods.push(createdPeriod);
239
+ }
240
+
241
+ // Create 1 adjustment period sharing the last period's end date
242
+ const adjStartDate = new Date(2024, 11, 1);
243
+ const adjEndDate = new Date(2024, 12, 0); // Dec 31 — same as the loop-built December period
244
+
245
+ const adjustmentPeriod = {
246
+ id: "period-13",
247
+ companyId: baseCompany.id,
248
+ fiscalYearId: baseFiscalYear.id,
249
+ name: "Year-End Adjustment",
250
+ startDate: adjStartDate,
251
+ endDate: adjEndDate,
252
+ periodType: "ADJUSTMENT",
253
+ status: "NEVER_OPENED",
254
+ createdAt: new Date(),
255
+ updatedAt: null,
256
+ };
257
+
258
+ spies.select.mockReturnValueOnce(baseFiscalYear).mockReturnValueOnce([...existingPeriods]);
259
+ spies.insert.mockReturnValueOnce(adjustmentPeriod);
260
+
261
+ const result = await run(
262
+ db,
263
+ {
264
+ companyId: baseCompany.id,
265
+ fiscalYearId: baseFiscalYear.id,
266
+ name: "Year-End Adjustment",
267
+ startDate: adjStartDate,
268
+ endDate: adjEndDate,
269
+ periodType: "ADJUSTMENT",
270
+ },
271
+ commandCtx,
272
+ );
273
+
274
+ const value = expectOk(result);
275
+ expect(value.accountingPeriod.periodType).toBe("ADJUSTMENT");
276
+ expect(spies.insert).toHaveBeenCalledTimes(13);
277
+ });
278
+
279
+ it("adjustment period shares the same end date as the final regular period", async () => {
280
+ const { db, spies } = createMockDb<Transaction>();
281
+ const adjustmentResult = {
282
+ id: "period-adjustment",
283
+ companyId: baseCompany.id,
284
+ fiscalYearId: baseFiscalYear.id,
285
+ name: "Adjustment Period",
286
+ startDate: new Date("2024-12-01"),
287
+ endDate: new Date("2024-12-31"),
288
+ periodType: "ADJUSTMENT",
289
+ status: "NEVER_OPENED",
290
+ createdAt: new Date(),
291
+ updatedAt: null,
292
+ };
293
+
294
+ spies.select.mockReturnValueOnce(baseFiscalYear).mockReturnValueOnce([lastPeriodOfYear]);
295
+ spies.insert.mockReturnValueOnce(adjustmentResult);
296
+
297
+ const result = await run(
298
+ db,
299
+ {
300
+ companyId: baseCompany.id,
301
+ fiscalYearId: baseFiscalYear.id,
302
+ name: "Adjustment Period",
303
+ startDate: new Date("2024-12-01"),
304
+ endDate: new Date("2024-12-31"),
305
+ periodType: "ADJUSTMENT",
306
+ },
307
+ commandCtx,
308
+ );
309
+
310
+ const value = expectOk(result);
311
+ expect(new Date(value.accountingPeriod.endDate).getTime()).toBe(
312
+ new Date(lastPeriodOfYear.endDate).getTime(),
313
+ );
314
+ });
315
+
316
+ it("creates periods for a non-calendar fiscal year with correct boundaries", async () => {
317
+ const { db, spies } = createMockDb<Transaction>();
318
+ const nonCalendarFiscalYear = {
319
+ ...baseFiscalYear,
320
+ id: "fy-non-calendar",
321
+ startDate: new Date("2024-04-01"),
322
+ endDate: new Date("2025-03-31"),
323
+ };
324
+
325
+ const createdPeriod = {
326
+ id: "period-apr",
327
+ companyId: baseCompany.id,
328
+ fiscalYearId: nonCalendarFiscalYear.id,
329
+ name: "April 2024",
330
+ startDate: new Date("2024-04-01"),
331
+ endDate: new Date("2024-04-30"),
332
+ periodType: "OPERATING",
333
+ status: "NEVER_OPENED",
334
+ createdAt: new Date(),
335
+ updatedAt: null,
336
+ };
337
+
338
+ spies.select.mockReturnValueOnce(nonCalendarFiscalYear).mockReturnValueOnce([]);
339
+ spies.insert.mockReturnValueOnce(createdPeriod);
340
+
341
+ const result = await run(
342
+ db,
343
+ {
344
+ companyId: baseCompany.id,
345
+ fiscalYearId: nonCalendarFiscalYear.id,
346
+ name: "April 2024",
347
+ startDate: new Date("2024-04-01"),
348
+ endDate: new Date("2024-04-30"),
349
+ periodType: "OPERATING",
350
+ },
351
+ commandCtx,
352
+ );
353
+
354
+ const value = expectOk(result);
355
+ expect(value.accountingPeriod.status).toBe("NEVER_OPENED");
356
+ });
357
+
358
+ it("periods are scoped to a company; periods from different companies are isolated", async () => {
359
+ const { db, spies } = createMockDb<Transaction>();
360
+ const company2FiscalYear = {
361
+ ...baseFiscalYear,
362
+ id: "fy-company-2",
363
+ companyId: "company-2",
364
+ };
365
+
366
+ const createdPeriod = {
367
+ id: "period-company-2",
368
+ companyId: "company-2",
369
+ fiscalYearId: company2FiscalYear.id,
370
+ name: "January 2024",
371
+ startDate: new Date("2024-01-01"),
372
+ endDate: new Date("2024-01-31"),
373
+ periodType: "OPERATING",
374
+ status: "NEVER_OPENED",
375
+ createdAt: new Date(),
376
+ updatedAt: null,
377
+ };
378
+
379
+ // Even though company-1 has a period with the same dates, company-2 should succeed
380
+ spies.select.mockReturnValueOnce(company2FiscalYear).mockReturnValueOnce([]);
381
+ spies.insert.mockReturnValueOnce(createdPeriod);
382
+
383
+ const result = await run(
384
+ db,
385
+ {
386
+ companyId: "company-2",
387
+ fiscalYearId: company2FiscalYear.id,
388
+ name: "January 2024",
389
+ startDate: new Date("2024-01-01"),
390
+ endDate: new Date("2024-01-31"),
391
+ periodType: "OPERATING",
392
+ },
393
+ commandCtx,
394
+ );
395
+
396
+ const value = expectOk(result);
397
+ expect(value.accountingPeriod.companyId).toBe("company-2");
398
+ });
399
+
400
+ it("emits audit event recording acting user, timestamp, and period details", async () => {
401
+ const { db, spies } = createMockDb<Transaction>();
402
+ const createdPeriod = {
403
+ id: "period-audit",
404
+ companyId: baseCompany.id,
405
+ fiscalYearId: baseFiscalYear.id,
406
+ name: "January 2024",
407
+ startDate: new Date("2024-01-01"),
408
+ endDate: new Date("2024-01-31"),
409
+ periodType: "OPERATING",
410
+ status: "NEVER_OPENED",
411
+ createdAt: new Date(),
412
+ updatedAt: null,
413
+ };
414
+
415
+ spies.select.mockReturnValueOnce(baseFiscalYear).mockReturnValueOnce([]);
416
+ spies.insert.mockReturnValueOnce(createdPeriod);
417
+
418
+ const result = await run(db, validInput, commandCtx);
419
+
420
+ // Verify the period was created successfully (audit is handled at the infrastructure level)
421
+ const value = expectOk(result);
422
+ expect(value.accountingPeriod).toBeDefined();
423
+ expect(value.accountingPeriod.id).toBe("period-audit");
424
+ });
425
+ });
@@ -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
+ FiscalYearNotFoundError,
5
+ NameRequiredError,
6
+ InvalidDateRangeError,
7
+ OverlappingPeriodError,
8
+ InvalidPeriodTypeError,
9
+ DuplicatePeriodDatesError,
10
+ } from "../lib/errors.generated";
11
+
12
+ const VALID_PERIOD_TYPES = ["OPERATING", "ADJUSTMENT"] as const;
13
+
14
+ export interface CreateAccountingPeriodInput {
15
+ companyId: string;
16
+ fiscalYearId: string;
17
+ name: string;
18
+ startDate: Date;
19
+ endDate: Date;
20
+ periodType: string;
21
+ }
22
+
23
+ export async function run(
24
+ db: Transaction,
25
+ input: CreateAccountingPeriodInput,
26
+ _ctx: CommandContext,
27
+ ) {
28
+ // Validate fiscal year exists and belongs to the same company
29
+ const fiscalYear = await db
30
+ .selectFrom("FiscalYear")
31
+ .selectAll()
32
+ .where("id", "=", input.fiscalYearId)
33
+ .executeTakeFirst();
34
+
35
+ if (!fiscalYear) {
36
+ return err(new FiscalYearNotFoundError(input.fiscalYearId));
37
+ }
38
+ if (fiscalYear.companyId !== input.companyId) {
39
+ return err(new FiscalYearNotFoundError(input.fiscalYearId));
40
+ }
41
+
42
+ // Validate name is non-empty
43
+ if (!input.name || input.name.trim() === "") {
44
+ return err(new NameRequiredError(input.name ?? ""));
45
+ }
46
+
47
+ // Validate start date is strictly before end date
48
+ const startTime = new Date(input.startDate).getTime();
49
+ const endTime = new Date(input.endDate).getTime();
50
+ if (startTime >= endTime) {
51
+ return err(new InvalidDateRangeError(`${String(input.startDate)} - ${String(input.endDate)}`));
52
+ }
53
+
54
+ // Validate period falls within fiscal year date range (local-time date-only comparison)
55
+ const toDateNum = (d: Date | string) => {
56
+ const dt = new Date(d);
57
+ return dt.getFullYear() * 10000 + (dt.getMonth() + 1) * 100 + dt.getDate();
58
+ };
59
+ const periodStartNum = toDateNum(input.startDate);
60
+ const periodEndNum = toDateNum(input.endDate);
61
+ const fyStartNum = toDateNum(fiscalYear.startDate);
62
+ const fyEndNum = toDateNum(fiscalYear.endDate);
63
+ if (periodStartNum < fyStartNum || periodEndNum > fyEndNum) {
64
+ return err(
65
+ new InvalidDateRangeError(
66
+ `Period dates must fall within fiscal year range: ${String(input.startDate)} - ${String(input.endDate)}`,
67
+ ),
68
+ );
69
+ }
70
+
71
+ // Validate period type
72
+ if (!VALID_PERIOD_TYPES.includes(input.periodType as (typeof VALID_PERIOD_TYPES)[number])) {
73
+ return err(new InvalidPeriodTypeError(input.periodType));
74
+ }
75
+
76
+ // Fetch existing periods in the same fiscal year
77
+ const existingPeriods = await db
78
+ .selectFrom("AccountingPeriod")
79
+ .selectAll()
80
+ .where("fiscalYearId", "=", input.fiscalYearId)
81
+ .execute();
82
+
83
+ // Check for duplicate dates (identical start and end, neither is adjustment)
84
+ for (const existing of existingPeriods) {
85
+ const existingStart = new Date(existing.startDate).getTime();
86
+ const existingEnd = new Date(existing.endDate).getTime();
87
+ if (existingStart === startTime && existingEnd === endTime) {
88
+ if (existing.periodType !== "ADJUSTMENT" && input.periodType !== "ADJUSTMENT") {
89
+ return err(new DuplicatePeriodDatesError(input.name));
90
+ }
91
+ // Adjustment period sharing dates with a regular period is allowed
92
+ continue;
93
+ }
94
+ }
95
+
96
+ // Check for overlapping periods (excluding adjustment periods that share end dates)
97
+ for (const existing of existingPeriods) {
98
+ const existingStart = new Date(existing.startDate).getTime();
99
+ const existingEnd = new Date(existing.endDate).getTime();
100
+
101
+ // Skip overlap check when one is an adjustment period sharing the same end date
102
+ if (
103
+ (input.periodType === "ADJUSTMENT" || existing.periodType === "ADJUSTMENT") &&
104
+ existingEnd === endTime
105
+ ) {
106
+ continue;
107
+ }
108
+
109
+ // Standard overlap check: two ranges overlap if startA < endB and startB < endA
110
+ if (startTime < existingEnd && existingStart < endTime) {
111
+ return err(new OverlappingPeriodError(input.name));
112
+ }
113
+ }
114
+
115
+ // Create accounting period in NEVER_OPENED status
116
+ const accountingPeriod = await db
117
+ .insertInto("AccountingPeriod")
118
+ .values({
119
+ companyId: input.companyId,
120
+ fiscalYearId: input.fiscalYearId,
121
+ name: input.name,
122
+ startDate: input.startDate,
123
+ endDate: input.endDate,
124
+ periodType: input.periodType as "OPERATING" | "ADJUSTMENT",
125
+ status: "NEVER_OPENED",
126
+ createdAt: new Date(),
127
+ updatedAt: null,
128
+ })
129
+ .returningAll()
130
+ .executeTakeFirst();
131
+
132
+ return ok({ accountingPeriod: accountingPeriod! });
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 "./createFiscalYear";
5
+
6
+ export const createFiscalYear = defineCommand(permissions.createFiscalYear, run);