@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,31 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { DB } from "../generated/kysely-tailordb";
4
+ import { basePeriodClose } from "../testing/fixtures";
5
+ import { run } from "./getPeriodClose";
6
+
7
+ describe("getPeriodClose", () => {
8
+ it("returns period close when found by accounting period id", async () => {
9
+ const { db, spies } = createMockDb<DB>();
10
+ spies.select.mockReturnValue(basePeriodClose);
11
+
12
+ const result = await run(db, { accountingPeriodId: basePeriodClose.accountingPeriodId });
13
+
14
+ expect(result.ok).toBe(true);
15
+ if (result.ok) {
16
+ expect(result.value.periodClose).toEqual(basePeriodClose);
17
+ }
18
+ });
19
+
20
+ it("returns null when not found", async () => {
21
+ const { db, spies } = createMockDb<DB>();
22
+ spies.select.mockReturnValue(undefined);
23
+
24
+ const result = await run(db, { accountingPeriodId: "nonexistent" });
25
+
26
+ expect(result.ok).toBe(true);
27
+ if (result.ok) {
28
+ expect(result.value.periodClose).toBeNull();
29
+ }
30
+ });
31
+ });
@@ -0,0 +1,21 @@
1
+ import { ok, type ReadonlyDB } from "@tailor-platform/erp-kit/module";
2
+ import type { DB } from "../generated/kysely-tailordb";
3
+
4
+ export interface GetPeriodCloseInput {
5
+ accountingPeriodId: string;
6
+ }
7
+
8
+ /**
9
+ * Function: getPeriodClose
10
+ *
11
+ * Retrieves a single period close by accounting period id.
12
+ */
13
+ export async function run(db: ReadonlyDB<DB>, input: GetPeriodCloseInput) {
14
+ const result = await db
15
+ .selectFrom("PeriodClose")
16
+ .selectAll()
17
+ .where("accountingPeriodId", "=", input.accountingPeriodId)
18
+ .executeTakeFirst();
19
+
20
+ return ok({ periodClose: result ?? null });
21
+ }
@@ -0,0 +1,5 @@
1
+ // @generated — do not edit
2
+ import { defineQuery } from "@tailor-platform/erp-kit/module";
3
+ import { run } from "./getSubledgerTransferStatus";
4
+
5
+ export const getSubledgerTransferStatus = defineQuery(run);
@@ -0,0 +1,101 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { DB } from "../generated/kysely-tailordb";
4
+ import { AccountingPeriodNotFoundError } from "../lib/errors.generated";
5
+ import { baseAccountingPeriod, baseJournalEntry, postedJournalEntry } from "../testing/fixtures";
6
+ import { run } from "./getSubledgerTransferStatus";
7
+
8
+ describe("getSubledgerTransferStatus", () => {
9
+ it("returns error when accounting period does not exist", async () => {
10
+ const { db, spies } = createMockDb<DB>();
11
+ spies.select.mockReturnValueOnce(undefined); // AccountingPeriod lookup
12
+
13
+ const result = await run(db, { accountingPeriodId: "nonexistent" });
14
+
15
+ expect(result.ok).toBe(false);
16
+ if (!result.ok) {
17
+ expect(result.error).toBeInstanceOf(AccountingPeriodNotFoundError);
18
+ }
19
+ });
20
+
21
+ it("returns status for all 4 modules", async () => {
22
+ const { db, spies } = createMockDb<DB>();
23
+ spies.select.mockReturnValueOnce(baseAccountingPeriod); // AccountingPeriod lookup
24
+ spies.select.mockReturnValue([]);
25
+
26
+ const result = await run(db, { accountingPeriodId: "period-1" });
27
+
28
+ expect(result.ok).toBe(true);
29
+ if (result.ok) {
30
+ expect(result.value.statuses).toHaveLength(4);
31
+ const modules = result.value.statuses.map((s) => s.module);
32
+ expect(modules).toEqual(["purchase", "sales", "inventory", "manufacturing"]);
33
+ }
34
+ });
35
+
36
+ it("returns zero counts when no entries exist", async () => {
37
+ const { db, spies } = createMockDb<DB>();
38
+ spies.select.mockReturnValueOnce(baseAccountingPeriod); // AccountingPeriod lookup
39
+ spies.select.mockReturnValue([]);
40
+
41
+ const result = await run(db, { accountingPeriodId: "period-1" });
42
+
43
+ expect(result.ok).toBe(true);
44
+ if (result.ok) {
45
+ for (const status of result.value.statuses) {
46
+ expect(status.totalExpected).toBe(0);
47
+ expect(status.acknowledged).toBe(0);
48
+ expect(status.outstanding).toBe(0);
49
+ }
50
+ }
51
+ });
52
+
53
+ it("correctly counts posted vs draft entries", async () => {
54
+ const { db, spies } = createMockDb<DB>();
55
+ spies.select.mockReturnValueOnce(baseAccountingPeriod); // AccountingPeriod lookup
56
+ // First module (purchase) has 2 entries: 1 draft + 1 posted
57
+ spies.select
58
+ .mockReturnValueOnce([baseJournalEntry, postedJournalEntry])
59
+ // Remaining modules have no entries
60
+ .mockReturnValueOnce([])
61
+ .mockReturnValueOnce([])
62
+ .mockReturnValueOnce([]);
63
+
64
+ const result = await run(db, { accountingPeriodId: "period-1" });
65
+
66
+ expect(result.ok).toBe(true);
67
+ if (result.ok) {
68
+ const purchaseStatus = result.value.statuses[0];
69
+ expect(purchaseStatus.totalExpected).toBe(2);
70
+ expect(purchaseStatus.acknowledged).toBe(1);
71
+ expect(purchaseStatus.outstanding).toBe(1);
72
+ }
73
+ });
74
+
75
+ it("returns correct outstanding counts", async () => {
76
+ const { db, spies } = createMockDb<DB>();
77
+ spies.select.mockReturnValueOnce(baseAccountingPeriod); // AccountingPeriod lookup
78
+ // All entries posted for purchase module
79
+ spies.select
80
+ .mockReturnValueOnce([postedJournalEntry])
81
+ // Sales has one draft
82
+ .mockReturnValueOnce([baseJournalEntry])
83
+ .mockReturnValueOnce([])
84
+ .mockReturnValueOnce([]);
85
+
86
+ const result = await run(db, { accountingPeriodId: "period-1" });
87
+
88
+ expect(result.ok).toBe(true);
89
+ if (result.ok) {
90
+ const purchaseStatus = result.value.statuses[0];
91
+ expect(purchaseStatus.totalExpected).toBe(1);
92
+ expect(purchaseStatus.acknowledged).toBe(1);
93
+ expect(purchaseStatus.outstanding).toBe(0);
94
+
95
+ const salesStatus = result.value.statuses[1];
96
+ expect(salesStatus.totalExpected).toBe(1);
97
+ expect(salesStatus.acknowledged).toBe(0);
98
+ expect(salesStatus.outstanding).toBe(1);
99
+ }
100
+ });
101
+ });
@@ -0,0 +1,68 @@
1
+ import { ok, err, type ReadonlyDB } from "@tailor-platform/erp-kit/module";
2
+ import type { DB } from "../generated/kysely-tailordb";
3
+ import { AccountingPeriodNotFoundError } from "../lib/errors.generated";
4
+
5
+ export interface GetSubledgerTransferStatusInput {
6
+ accountingPeriodId: string;
7
+ }
8
+
9
+ interface ModuleStatus {
10
+ module: string;
11
+ journalType: string;
12
+ totalExpected: number;
13
+ acknowledged: number;
14
+ outstanding: number;
15
+ }
16
+
17
+ const SUBLEDGER_MODULES = [
18
+ { module: "purchase", journalType: "PURCHASE" as const },
19
+ { module: "sales", journalType: "SALES" as const },
20
+ { module: "inventory", journalType: "INVENTORY" as const },
21
+ { module: "manufacturing", journalType: "MANUFACTURING" as const },
22
+ ];
23
+
24
+ /**
25
+ * Function: getSubledgerTransferStatus
26
+ *
27
+ * Returns transfer completeness status for all subledger modules for a given
28
+ * accounting period. Per-module status includes: totalExpected, acknowledged,
29
+ * outstanding. Registered modules: purchase, sales, inventory, manufacturing.
30
+ * Returns status for all modules even if zero expected events.
31
+ */
32
+ export async function run(db: ReadonlyDB<DB>, input: GetSubledgerTransferStatusInput) {
33
+ // Validate that the accounting period exists
34
+ const period = await db
35
+ .selectFrom("AccountingPeriod")
36
+ .selectAll()
37
+ .where("id", "=", input.accountingPeriodId)
38
+ .executeTakeFirst();
39
+
40
+ if (!period) {
41
+ return err(new AccountingPeriodNotFoundError(input.accountingPeriodId));
42
+ }
43
+
44
+ const statuses: ModuleStatus[] = [];
45
+
46
+ for (const subledger of SUBLEDGER_MODULES) {
47
+ // Count all entries of this type for the period
48
+ const allEntries = await db
49
+ .selectFrom("JournalEntry")
50
+ .selectAll()
51
+ .where("accountingPeriodId", "=", input.accountingPeriodId)
52
+ .where("journalType", "=", subledger.journalType)
53
+ .execute();
54
+
55
+ const totalExpected = allEntries.length;
56
+ const acknowledged = allEntries.filter((e) => e.status === "POSTED").length;
57
+
58
+ statuses.push({
59
+ module: subledger.module,
60
+ journalType: subledger.journalType,
61
+ totalExpected,
62
+ acknowledged,
63
+ outstanding: totalExpected - acknowledged,
64
+ });
65
+ }
66
+
67
+ return ok({ statuses });
68
+ }
@@ -0,0 +1,5 @@
1
+ // @generated — do not edit
2
+ import { defineQuery } from "@tailor-platform/erp-kit/module";
3
+ import { run } from "./getTrialBalance";
4
+
5
+ export const getTrialBalance = defineQuery(run);
@@ -0,0 +1,33 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { DB } from "../generated/kysely-tailordb";
4
+ import { baseTrialBalance, baseTrialBalanceLine } from "../testing/fixtures";
5
+ import { run } from "./getTrialBalance";
6
+
7
+ describe("getTrialBalance", () => {
8
+ it("returns trial balance with lines when found by id", async () => {
9
+ const { db, spies } = createMockDb<DB>();
10
+ spies.select.mockReturnValueOnce(baseTrialBalance).mockReturnValueOnce([baseTrialBalanceLine]);
11
+
12
+ const result = await run(db, { id: baseTrialBalance.id });
13
+
14
+ expect(result.ok).toBe(true);
15
+ if (result.ok) {
16
+ expect(result.value.trialBalance).toEqual(baseTrialBalance);
17
+ expect(result.value.lines).toEqual([baseTrialBalanceLine]);
18
+ }
19
+ });
20
+
21
+ it("returns null with empty lines when not found", async () => {
22
+ const { db, spies } = createMockDb<DB>();
23
+ spies.select.mockReturnValue(undefined);
24
+
25
+ const result = await run(db, { id: "nonexistent" });
26
+
27
+ expect(result.ok).toBe(true);
28
+ if (result.ok) {
29
+ expect(result.value.trialBalance).toBeNull();
30
+ expect(result.value.lines).toEqual([]);
31
+ }
32
+ });
33
+ });
@@ -0,0 +1,30 @@
1
+ import { ok, type ReadonlyDB } from "@tailor-platform/erp-kit/module";
2
+ import type { DB } from "../generated/kysely-tailordb";
3
+
4
+ export interface GetTrialBalanceInput {
5
+ id: string;
6
+ }
7
+
8
+ /**
9
+ * Function: getTrialBalance
10
+ *
11
+ * Retrieves a single trial balance by id, along with its associated trial balance lines.
12
+ */
13
+ export async function run(db: ReadonlyDB<DB>, input: GetTrialBalanceInput) {
14
+ const result = await db
15
+ .selectFrom("TrialBalance")
16
+ .selectAll()
17
+ .where("id", "=", input.id)
18
+ .executeTakeFirst();
19
+
20
+ const lines = result
21
+ ? await db
22
+ .selectFrom("TrialBalanceLine")
23
+ .selectAll()
24
+ .where("trialBalanceId", "=", input.id)
25
+ .orderBy("accountCode", "asc")
26
+ .execute()
27
+ : [];
28
+
29
+ return ok({ trialBalance: result ?? null, lines });
30
+ }
@@ -0,0 +1,5 @@
1
+ // @generated — do not edit
2
+ import { defineQuery } from "@tailor-platform/erp-kit/module";
3
+ import { run } from "./listAccountingPeriods";
4
+
5
+ export const listAccountingPeriods = defineQuery(run);
@@ -0,0 +1,81 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { DB } from "../generated/kysely-tailordb";
4
+ import { EmptyResultError } from "../lib/errors.generated";
5
+ import { baseAccountingPeriod, closedPeriod } from "../testing/fixtures";
6
+ import { run } from "./listAccountingPeriods";
7
+
8
+ describe("listAccountingPeriods", () => {
9
+ it("returns error when neither companyId nor fiscalYearId is provided", async () => {
10
+ const { db } = createMockDb<DB>();
11
+
12
+ const result = await run(db, {});
13
+
14
+ expect(result.ok).toBe(false);
15
+ if (!result.ok) {
16
+ expect(result.error).toBeInstanceOf(EmptyResultError);
17
+ }
18
+ });
19
+
20
+ it("returns all accounting periods for a company", async () => {
21
+ const { db, spies } = createMockDb<DB>();
22
+ spies.select.mockReturnValue([baseAccountingPeriod, closedPeriod]);
23
+
24
+ const result = await run(db, { companyId: "company-1" });
25
+
26
+ expect(result.ok).toBe(true);
27
+ if (result.ok) {
28
+ expect(result.value.items).toEqual([baseAccountingPeriod, closedPeriod]);
29
+ expect(result.value.hasNextPage).toBe(false);
30
+ }
31
+ });
32
+
33
+ it("returns accounting periods filtered by fiscal year", async () => {
34
+ const { db, spies } = createMockDb<DB>();
35
+ spies.select.mockReturnValue([baseAccountingPeriod]);
36
+
37
+ const result = await run(db, { fiscalYearId: "fiscal-year-1" });
38
+
39
+ expect(result.ok).toBe(true);
40
+ if (result.ok) {
41
+ expect(result.value.items).toEqual([baseAccountingPeriod]);
42
+ }
43
+ });
44
+
45
+ it("returns accounting periods filtered by status", async () => {
46
+ const { db, spies } = createMockDb<DB>();
47
+ spies.select.mockReturnValue([closedPeriod]);
48
+
49
+ const result = await run(db, { companyId: "company-1", status: "CLOSED" });
50
+
51
+ expect(result.ok).toBe(true);
52
+ if (result.ok) {
53
+ expect(result.value.items).toEqual([closedPeriod]);
54
+ }
55
+ });
56
+
57
+ it("returns accounting periods filtered by period type", async () => {
58
+ const { db, spies } = createMockDb<DB>();
59
+ spies.select.mockReturnValue([baseAccountingPeriod]);
60
+
61
+ const result = await run(db, { companyId: "company-1", periodType: "OPERATING" });
62
+
63
+ expect(result.ok).toBe(true);
64
+ if (result.ok) {
65
+ expect(result.value.items).toEqual([baseAccountingPeriod]);
66
+ }
67
+ });
68
+
69
+ it("returns empty list when no accounting periods match", async () => {
70
+ const { db, spies } = createMockDb<DB>();
71
+ spies.select.mockReturnValue([]);
72
+
73
+ const result = await run(db, { companyId: "nonexistent" });
74
+
75
+ expect(result.ok).toBe(true);
76
+ if (result.ok) {
77
+ expect(result.value.items).toEqual([]);
78
+ expect(result.value.hasNextPage).toBe(false);
79
+ }
80
+ });
81
+ });
@@ -0,0 +1,61 @@
1
+ import {
2
+ ok,
3
+ err,
4
+ type ReadonlyDB,
5
+ type PaginationInput,
6
+ buildPaginatedResult,
7
+ DEFAULT_PAGE_SIZE,
8
+ } from "@tailor-platform/erp-kit/module";
9
+ import type { AccountingPeriodPeriodType, AccountingPeriodStatus } from "../generated/enums";
10
+ import type { DB } from "../generated/kysely-tailordb";
11
+ import { EmptyResultError } from "../lib/errors.generated";
12
+
13
+ type AccountingPeriodOrderByField = "startDate" | "endDate" | "name" | "status" | "createdAt";
14
+
15
+ export interface ListAccountingPeriodsInput extends PaginationInput<AccountingPeriodOrderByField> {
16
+ companyId?: string;
17
+ fiscalYearId?: string;
18
+ status?: string;
19
+ periodType?: string;
20
+ }
21
+
22
+ /**
23
+ * Function: listAccountingPeriods
24
+ *
25
+ * Lists accounting periods with optional filters for company, fiscal year,
26
+ * status, and period type. At least one scoping parameter (companyId or
27
+ * fiscalYearId) is required. All filters use AND logic.
28
+ */
29
+ export async function run(db: ReadonlyDB<DB>, input: ListAccountingPeriodsInput) {
30
+ if (!input.companyId && !input.fiscalYearId) {
31
+ return err(new EmptyResultError("companyId or fiscalYearId is required"));
32
+ }
33
+
34
+ const limit = input.limit ?? DEFAULT_PAGE_SIZE;
35
+ const offset = input.offset ?? 0;
36
+ const orderBy = input.orderBy ?? "startDate";
37
+ const orderDirection = input.orderDirection ?? "asc";
38
+
39
+ let query = db.selectFrom("AccountingPeriod").selectAll();
40
+
41
+ if (input.companyId) {
42
+ query = query.where("companyId", "=", input.companyId);
43
+ }
44
+ if (input.fiscalYearId) {
45
+ query = query.where("fiscalYearId", "=", input.fiscalYearId);
46
+ }
47
+ if (input.status) {
48
+ query = query.where("status", "=", input.status as AccountingPeriodStatus);
49
+ }
50
+ if (input.periodType) {
51
+ query = query.where("periodType", "=", input.periodType as AccountingPeriodPeriodType);
52
+ }
53
+
54
+ const results = await query
55
+ .orderBy(orderBy, orderDirection)
56
+ .limit(limit + 1)
57
+ .offset(offset)
58
+ .execute();
59
+
60
+ return ok(buildPaginatedResult(results, limit));
61
+ }
@@ -0,0 +1,5 @@
1
+ // @generated — do not edit
2
+ import { defineQuery } from "@tailor-platform/erp-kit/module";
3
+ import { run } from "./listFinancialStatements";
4
+
5
+ export const listFinancialStatements = defineQuery(run);
@@ -0,0 +1,76 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { DB } from "../generated/kysely-tailordb";
4
+ import { baseFinancialStatement, finalizedFinancialStatement } from "../testing/fixtures";
5
+ import { run } from "./listFinancialStatements";
6
+
7
+ describe("listFinancialStatements", () => {
8
+ it("returns all financial statements for a company", async () => {
9
+ const { db, spies } = createMockDb<DB>();
10
+ spies.select.mockReturnValue([baseFinancialStatement, finalizedFinancialStatement]);
11
+
12
+ const result = await run(db, { companyId: "company-1" });
13
+
14
+ expect(result.ok).toBe(true);
15
+ if (result.ok) {
16
+ expect(result.value.items).toEqual([baseFinancialStatement, finalizedFinancialStatement]);
17
+ expect(result.value.hasNextPage).toBe(false);
18
+ }
19
+ });
20
+
21
+ it("returns financial statements filtered by statement type", async () => {
22
+ const { db, spies } = createMockDb<DB>();
23
+ spies.select.mockReturnValue([baseFinancialStatement]);
24
+
25
+ const result = await run(db, {
26
+ companyId: "company-1",
27
+ statementType: "BALANCE_SHEET",
28
+ });
29
+
30
+ expect(result.ok).toBe(true);
31
+ if (result.ok) {
32
+ expect(result.value.items).toEqual([baseFinancialStatement]);
33
+ }
34
+ });
35
+
36
+ it("returns financial statements filtered by status", async () => {
37
+ const { db, spies } = createMockDb<DB>();
38
+ spies.select.mockReturnValue([finalizedFinancialStatement]);
39
+
40
+ const result = await run(db, { companyId: "company-1", status: "FINALIZED" });
41
+
42
+ expect(result.ok).toBe(true);
43
+ if (result.ok) {
44
+ expect(result.value.items).toEqual([finalizedFinancialStatement]);
45
+ }
46
+ });
47
+
48
+ it("returns financial statements filtered by dateRange", async () => {
49
+ const { db, spies } = createMockDb<DB>();
50
+ spies.select.mockReturnValue([baseFinancialStatement]);
51
+
52
+ const result = await run(db, {
53
+ companyId: "company-1",
54
+ startDate: new Date("2024-01-01"),
55
+ endDate: new Date("2024-01-31"),
56
+ });
57
+
58
+ expect(result.ok).toBe(true);
59
+ if (result.ok) {
60
+ expect(result.value.items).toEqual([baseFinancialStatement]);
61
+ }
62
+ });
63
+
64
+ it("returns empty list when no financial statements match", async () => {
65
+ const { db, spies } = createMockDb<DB>();
66
+ spies.select.mockReturnValue([]);
67
+
68
+ const result = await run(db, { companyId: "nonexistent" });
69
+
70
+ expect(result.ok).toBe(true);
71
+ if (result.ok) {
72
+ expect(result.value.items).toEqual([]);
73
+ expect(result.value.hasNextPage).toBe(false);
74
+ }
75
+ });
76
+ });
@@ -0,0 +1,62 @@
1
+ import {
2
+ ok,
3
+ type ReadonlyDB,
4
+ type PaginationInput,
5
+ buildPaginatedResult,
6
+ DEFAULT_PAGE_SIZE,
7
+ } from "@tailor-platform/erp-kit/module";
8
+ import type { FinancialStatementStatementType, FinancialStatementStatus } from "../generated/enums";
9
+ import type { DB } from "../generated/kysely-tailordb";
10
+
11
+ type FinancialStatementOrderByField = "createdAt" | "statementType" | "status" | "generatedAt";
12
+
13
+ export interface ListFinancialStatementsInput extends PaginationInput<FinancialStatementOrderByField> {
14
+ companyId: string;
15
+ statementType?: string;
16
+ status?: string;
17
+ startDate?: Date;
18
+ endDate?: Date;
19
+ }
20
+
21
+ /**
22
+ * Function: listFinancialStatements
23
+ *
24
+ * Lists financial statement headers for a company with optional filters
25
+ * for statement type, status, and date range (by reportingDate).
26
+ */
27
+ export async function run(db: ReadonlyDB<DB>, input: ListFinancialStatementsInput) {
28
+ const limit = input.limit ?? DEFAULT_PAGE_SIZE;
29
+ const offset = input.offset ?? 0;
30
+ const orderBy = input.orderBy ?? "createdAt";
31
+ const orderDirection = input.orderDirection ?? "desc";
32
+
33
+ let query = db
34
+ .selectFrom("FinancialStatement")
35
+ .selectAll()
36
+ .where("companyId", "=", input.companyId);
37
+
38
+ if (input.statementType) {
39
+ query = query.where(
40
+ "statementType",
41
+ "=",
42
+ input.statementType as FinancialStatementStatementType,
43
+ );
44
+ }
45
+ if (input.status) {
46
+ query = query.where("status", "=", input.status as FinancialStatementStatus);
47
+ }
48
+ if (input.startDate) {
49
+ query = query.where("reportingDate", ">=", input.startDate);
50
+ }
51
+ if (input.endDate) {
52
+ query = query.where("reportingDate", "<=", input.endDate);
53
+ }
54
+
55
+ const results = await query
56
+ .orderBy(orderBy, orderDirection)
57
+ .limit(limit + 1)
58
+ .offset(offset)
59
+ .execute();
60
+
61
+ return ok(buildPaginatedResult(results, limit));
62
+ }
@@ -0,0 +1,5 @@
1
+ // @generated — do not edit
2
+ import { defineQuery } from "@tailor-platform/erp-kit/module";
3
+ import { run } from "./listFiscalYears";
4
+
5
+ export const listFiscalYears = defineQuery(run);
@@ -0,0 +1,63 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createMockDb } from "../../../testing/index";
3
+ import type { DB } from "../generated/kysely-tailordb";
4
+ import { baseFiscalYear, baseFiscalYear2 } from "../testing/fixtures";
5
+ import { run } from "./listFiscalYears";
6
+
7
+ describe("listFiscalYears", () => {
8
+ it("returns all fiscal years for a company", async () => {
9
+ const { db, spies } = createMockDb<DB>();
10
+ spies.select.mockReturnValue([baseFiscalYear, baseFiscalYear2]);
11
+
12
+ const result = await run(db, { companyId: "company-1" });
13
+
14
+ expect(result.ok).toBe(true);
15
+ if (result.ok) {
16
+ expect(result.value.items).toEqual([baseFiscalYear, baseFiscalYear2]);
17
+ expect(result.value.hasNextPage).toBe(false);
18
+ }
19
+ });
20
+
21
+ it("returns fiscal years filtered by startDate", async () => {
22
+ const { db, spies } = createMockDb<DB>();
23
+ spies.select.mockReturnValue([baseFiscalYear2]);
24
+
25
+ const result = await run(db, {
26
+ companyId: "company-1",
27
+ startDate: new Date("2025-01-01"),
28
+ });
29
+
30
+ expect(result.ok).toBe(true);
31
+ if (result.ok) {
32
+ expect(result.value.items).toEqual([baseFiscalYear2]);
33
+ }
34
+ });
35
+
36
+ it("returns fiscal years filtered by endDate", async () => {
37
+ const { db, spies } = createMockDb<DB>();
38
+ spies.select.mockReturnValue([baseFiscalYear]);
39
+
40
+ const result = await run(db, {
41
+ companyId: "company-1",
42
+ endDate: new Date("2024-12-31"),
43
+ });
44
+
45
+ expect(result.ok).toBe(true);
46
+ if (result.ok) {
47
+ expect(result.value.items).toEqual([baseFiscalYear]);
48
+ }
49
+ });
50
+
51
+ it("returns empty list when no fiscal years match", async () => {
52
+ const { db, spies } = createMockDb<DB>();
53
+ spies.select.mockReturnValue([]);
54
+
55
+ const result = await run(db, { companyId: "nonexistent" });
56
+
57
+ expect(result.ok).toBe(true);
58
+ if (result.ok) {
59
+ expect(result.value.items).toEqual([]);
60
+ expect(result.value.hasNextPage).toBe(false);
61
+ }
62
+ });
63
+ });