ekwo-os 0.4.1

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 (361) hide show
  1. package/README.md +873 -0
  2. package/dist/args.d.ts +57 -0
  3. package/dist/args.d.ts.map +1 -0
  4. package/dist/args.js +134 -0
  5. package/dist/args.js.map +1 -0
  6. package/dist/assets/expected-objects.json +9432 -0
  7. package/dist/assets/migrations/20260911120000_core_companies.sql +260 -0
  8. package/dist/assets/migrations/20260911120100_accounts_journals.sql +211 -0
  9. package/dist/assets/migrations/20260911120200_contacts.sql +90 -0
  10. package/dist/assets/migrations/20260911120300_taxes.sql +146 -0
  11. package/dist/assets/migrations/20260911120400_entries.sql +338 -0
  12. package/dist/assets/migrations/20260911120500_documents.sql +279 -0
  13. package/dist/assets/migrations/20260911120600_payments_reconciliation.sql +251 -0
  14. package/dist/assets/migrations/20260911120700_bank.sql +178 -0
  15. package/dist/assets/migrations/20260911120800_analytics_attachments.sql +128 -0
  16. package/dist/assets/migrations/20260911120900_post_document.sql +279 -0
  17. package/dist/assets/migrations/20260911121000_reporting.sql +235 -0
  18. package/dist/assets/migrations/20260911121100_country_templates.sql +226 -0
  19. package/dist/assets/migrations/20260911121200_fec.sql +71 -0
  20. package/dist/assets/migrations/20260911130000_instance.sql +77 -0
  21. package/dist/assets/migrations/20260911130100_instance_members.sql +224 -0
  22. package/dist/assets/migrations/20260911140000_instance_admins.sql +112 -0
  23. package/dist/assets/migrations/20260911160000_tax_posting_templates_unique.sql +17 -0
  24. package/dist/assets/migrations/20260911170000_document_amount_paid.sql +82 -0
  25. package/dist/assets/migrations/20260911173000_post_payment.sql +122 -0
  26. package/dist/assets/migrations/20260911173100_sequence_counters_under_rls.sql +84 -0
  27. package/dist/assets/migrations/20260911183000_country_journal_defaults.sql +143 -0
  28. package/dist/assets/migrations/20260911193853_line_account_defaults.sql +274 -0
  29. package/dist/assets/migrations/20260911195054_products.sql +221 -0
  30. package/dist/assets/migrations/20260911210131_anon_surface.sql +85 -0
  31. package/dist/assets/migrations/20260912074712_country_packs.sql +318 -0
  32. package/dist/assets/migrations/20260912080311_report_code_and_region.sql +198 -0
  33. package/dist/assets/migrations/20260912081014_pack_certification_maintained.sql +31 -0
  34. package/dist/assets/migrations/20260912081015_pack_certification_backfill.sql +16 -0
  35. package/dist/assets/migrations/20260912090407_tax_report_boxes.sql +329 -0
  36. package/dist/assets/migrations/20260912091917_tax_on_base_value.sql +25 -0
  37. package/dist/assets/migrations/20260912091918_tax_engine_columns.sql +776 -0
  38. package/dist/assets/migrations/20260912094412_opening_and_closing.sql +759 -0
  39. package/dist/assets/migrations/20260912095825_charts_of_accounts.sql +326 -0
  40. package/dist/assets/migrations/20260912100412_financial_statements.sql +632 -0
  41. package/dist/assets/migrations/20260912104719_one_formula_evaluator.sql +209 -0
  42. package/dist/assets/migrations/20260912105720_entry_kind_appropriation.sql +26 -0
  43. package/dist/assets/migrations/20260912105721_appropriation_entry_kind.sql +444 -0
  44. package/dist/assets/migrations/20260912111751_document_rules.sql +274 -0
  45. package/dist/assets/migrations/20260912112132_cash_basis_vat_and_fx.sql +1189 -0
  46. package/dist/assets/migrations/20260913074512_modules.sql +493 -0
  47. package/dist/assets/migrations/20260913075903_asset_disposal_roles.sql +47 -0
  48. package/dist/assets/migrations/20260913083216_capabilities.sql +637 -0
  49. package/dist/assets/migrations/20260913083901_company_invitations.sql +262 -0
  50. package/dist/assets/migrations/20260913084402_user_preferences.sql +376 -0
  51. package/dist/assets/migrations/20260913084847_company_profile.sql +261 -0
  52. package/dist/assets/migrations/20260913085436_numbering_reads_the_pack.sql +235 -0
  53. package/dist/assets/migrations/20260913085932_api_keys.sql +303 -0
  54. package/dist/assets/migrations/20260913090216_fiscal_year_bounds.sql +159 -0
  55. package/dist/assets/migrations/20260913092527_entries_import.sql +219 -0
  56. package/dist/assets/migrations/20260913101536_null_safe_guards.sql +188 -0
  57. package/dist/assets/migrations/20260913102115_installer_is_named.sql +462 -0
  58. package/dist/assets/migrations/20260913102758_no_currency_default.sql +138 -0
  59. package/dist/assets/migrations/20260913103355_cash_basis_needs_a_box.sql +453 -0
  60. package/dist/assets/migrations/20260913104014_aged_balance_named_group.sql +79 -0
  61. package/dist/assets/migrations/20260913104232_foreign_key_indexes.sql +144 -0
  62. package/dist/assets/migrations/20260913105120_declared_no_reader.sql +41 -0
  63. package/dist/assets/migrations/20260913111407_pack_languages.sql +223 -0
  64. package/dist/assets/migrations/20260913112233_schema_comments_for_a_reader.sql +27 -0
  65. package/dist/assets/migrations/20260913114535_fec_opening_balances.sql +307 -0
  66. package/dist/assets/migrations/20260914103412_audit_log.sql +509 -0
  67. package/dist/assets/migrations/20260914111907_pack_upgrade.sql +428 -0
  68. package/dist/assets/migrations/20260914120500_rounding_reads_the_currency.sql +206 -0
  69. package/dist/assets/migrations/20260914121200_amounts_round_at_the_currency.sql +2403 -0
  70. package/dist/assets/migrations/20260914134325_schema_version_0_2_0.sql +36 -0
  71. package/dist/assets/migrations/20260914143915_accounts_in_use.sql +428 -0
  72. package/dist/assets/migrations/20260914144731_account_code_frozen.sql +99 -0
  73. package/dist/assets/migrations/20260914151207_schema_grants_its_own_rights.sql +284 -0
  74. package/dist/assets/migrations/20260914152840_pack_upgrade_records_its_own_line.sql +237 -0
  75. package/dist/assets/migrations/20260914163943_declaration_periodicity.sql +349 -0
  76. package/dist/assets/migrations/20260915094000_foreign_services_received.sql +37 -0
  77. package/dist/assets/migrations/20260915094500_mentions_read_a_foreign_service.sql +72 -0
  78. package/dist/assets/migrations/20260915153000_document_shares.sql +568 -0
  79. package/dist/assets/migrations/20260915160000_ec_sales_list.sql +181 -0
  80. package/dist/assets/migrations/20260915161842_pack_sources.sql +56 -0
  81. package/dist/assets/migrations/20260915170500_schema_version_0_3_0.sql +45 -0
  82. package/dist/assets/migrations/20260915174500_a_vat_category_is_a_code.sql +177 -0
  83. package/dist/assets/migrations/20260915180000_document_rule_references.sql +85 -0
  84. package/dist/assets/migrations/20260915181000_territories.sql +342 -0
  85. package/dist/assets/migrations/20260915181500_ec_sales_list_reads_the_territories.sql +222 -0
  86. package/dist/assets/migrations/20260915182000_intracom_triangular.sql +53 -0
  87. package/dist/assets/migrations/20260915182500_a_triangular_supply_says_reverse_charge.sql +99 -0
  88. package/dist/assets/migrations/20260915191200_a_document_knows_its_language.sql +633 -0
  89. package/dist/assets/migrations/20260915195000_a_price_that_holds_its_tax.sql +649 -0
  90. package/dist/assets/migrations/20260915200000_a_posting_names_its_boxes.sql +1004 -0
  91. package/dist/assets/migrations/20260916094500_a_company_files_more_than_one_declaration.sql +795 -0
  92. package/dist/assets/migrations/20260916103000_a_ledger_line_names_its_posting.sql +902 -0
  93. package/dist/assets/migrations/20260916123000_a_vocabulary_for_a_tax_that_is_not_a_vat.sql +144 -0
  94. package/dist/assets/migrations/20260916124000_a_box_can_be_a_rate_of_a_box.sql +525 -0
  95. package/dist/assets/migrations/20260916125000_a_tax_follows_the_territory.sql +1318 -0
  96. package/dist/assets/migrations/20260916126000_a_tax_point_and_its_exception.sql +1211 -0
  97. package/dist/assets/migrations/20260917090000_a_counterparty_that_learns.sql +561 -0
  98. package/dist/assets/migrations/20260917120000_what_the_money_pays.sql +545 -0
  99. package/dist/assets/migrations/20260917150000_a_filing_is_a_row.sql +488 -0
  100. package/dist/assets/migrations/20260917170000_when_it_is_due.sql +194 -0
  101. package/dist/assets/migrations/20260917180000_a_box_is_a_number_and_a_kind.sql +213 -0
  102. package/dist/assets/migrations/20260917190000_what_a_declaration_owes.sql +486 -0
  103. package/dist/assets/migrations/20260917200000_what_moved_after_it_went.sql +227 -0
  104. package/dist/assets/migrations/20260918090000_a_form_names_its_file.sql +27 -0
  105. package/dist/assets/migrations/20260918110000_a_deposit_and_what_came_back.sql +286 -0
  106. package/dist/assets/migrations/20260918113741_a_fourth_preset_is_named.sql +9 -0
  107. package/dist/assets/migrations/20260918113807_a_client_reads_and_hands_over.sql +96 -0
  108. package/dist/assets/migrations/20260918114322_two_definer_functions_check_their_caller.sql +75 -0
  109. package/dist/assets/migrations/20260918130000_every_company_somebody_keeps.sql +177 -0
  110. package/dist/assets/migrations/20260918140000_a_session_nobody_prepared.sql +40 -0
  111. package/dist/assets/migrations/20260918141107_a_line_keeps_the_tax_it_was_posted_with.sql +256 -0
  112. package/dist/assets/migrations/20260918141342_a_company_has_an_electronic_address.sql +66 -0
  113. package/dist/assets/migrations/20260918141605_an_invoice_reads_whole_from_the_views.sql +313 -0
  114. package/dist/assets/migrations/20260918141627_a_policy_asks_once.sql +132 -0
  115. package/dist/assets/migrations/20260918143352_a_suggestion_reads_the_words_once.sql +204 -0
  116. package/dist/assets/migrations/20260918143417_a_reference_of_the_caller_and_a_rehearsal.sql +115 -0
  117. package/dist/assets/migrations/20260918150712_a_company_leaves_with_its_books.sql +1119 -0
  118. package/dist/assets/migrations/20260918150931_a_statement_is_imported_once.sql +654 -0
  119. package/dist/assets/migrations/20260918161204_a_posted_document_does_not_move.sql +437 -0
  120. package/dist/assets/migrations/20260918161538_a_posted_entry_does_not_move.sql +252 -0
  121. package/dist/assets/migrations/20260918171946_an_entry_is_posted_by_post_entry.sql +289 -0
  122. package/dist/assets/migrations/20260918174312_schema_version_0_4_0.sql +53 -0
  123. package/dist/assets/modules/assets/module.json +13 -0
  124. package/dist/assets/modules/assets/supabase/migrations/20260913081447_assets.sql +1190 -0
  125. package/dist/assets/modules/assets/supabase/migrations/20260913104234_foreign_key_indexes.sql +47 -0
  126. package/dist/assets/modules/assets/supabase/migrations/20260913104500_assets_capabilities.sql +145 -0
  127. package/dist/assets/modules/assets/supabase/migrations/20260914122100_assets_round_at_the_currency.sql +564 -0
  128. package/dist/assets/modules/assets/supabase/migrations/20260914145012_assets_accounts_in_use.sql +37 -0
  129. package/dist/assets/modules/assets/supabase/migrations/20260914151530_assets_grants_its_own_rights.sql +63 -0
  130. package/dist/assets/modules/assets/supabase/migrations/20260918113912_assets_client_reads.sql +20 -0
  131. package/dist/assets/modules/assets/supabase/migrations/20260918150801_assets_leave_with_the_company.sql +41 -0
  132. package/dist/assets/modules/budgets/module.json +12 -0
  133. package/dist/assets/modules/budgets/supabase/migrations/20260913083012_budgets.sql +210 -0
  134. package/dist/assets/modules/budgets/supabase/migrations/20260913104233_foreign_key_indexes.sql +37 -0
  135. package/dist/assets/modules/budgets/supabase/migrations/20260913104501_budgets_capabilities.sql +72 -0
  136. package/dist/assets/modules/budgets/supabase/migrations/20260914122400_budgets_round_at_the_currency.sql +68 -0
  137. package/dist/assets/modules/budgets/supabase/migrations/20260914145048_budgets_accounts_in_use.sql +30 -0
  138. package/dist/assets/modules/budgets/supabase/migrations/20260914151812_budgets_grants_its_own_rights.sql +31 -0
  139. package/dist/assets/modules/budgets/supabase/migrations/20260918113954_budgets_client_reads.sql +20 -0
  140. package/dist/assets/modules/budgets/supabase/migrations/20260918150823_budgets_leave_with_the_company.sql +37 -0
  141. package/dist/assets/modules/schema/module.1.json +69 -0
  142. package/dist/assets/seed/00_currencies.sql +15 -0
  143. package/dist/assets/seed/00_territories.sql +280 -0
  144. package/dist/assets/seed/05_framework_generic.sql +110 -0
  145. package/dist/assets/seed/10_pack_be.sql +1284 -0
  146. package/dist/assets/seed/11_pack_fr.sql +1112 -0
  147. package/dist/assets/seed/12_pack_lu.sql +2484 -0
  148. package/dist/assets/seed/13_pack_ee.sql +733 -0
  149. package/dist/assets/seed/14_pack_gb.sql +796 -0
  150. package/dist/assets/seed/15_pack_us.sql +751 -0
  151. package/dist/assets/seed/90_demo_company.sql +368 -0
  152. package/dist/assets/seed/modules/assets/10_pack_be.sql +58 -0
  153. package/dist/assets/seed/modules/assets/11_pack_fr.sql +57 -0
  154. package/dist/assets/seed/modules/assets/14_pack_gb.sql +58 -0
  155. package/dist/assets/seed/modules/assets/15_pack_us.sql +60 -0
  156. package/dist/auth.d.ts +59 -0
  157. package/dist/auth.d.ts.map +1 -0
  158. package/dist/auth.js +134 -0
  159. package/dist/auth.js.map +1 -0
  160. package/dist/bin.d.ts +6 -0
  161. package/dist/bin.d.ts.map +1 -0
  162. package/dist/bin.js +8 -0
  163. package/dist/bin.js.map +1 -0
  164. package/dist/books.d.ts +60 -0
  165. package/dist/books.d.ts.map +1 -0
  166. package/dist/books.js +168 -0
  167. package/dist/books.js.map +1 -0
  168. package/dist/bootstrap.d.ts +236 -0
  169. package/dist/bootstrap.d.ts.map +1 -0
  170. package/dist/bootstrap.js +459 -0
  171. package/dist/bootstrap.js.map +1 -0
  172. package/dist/bundle.d.ts +27 -0
  173. package/dist/bundle.d.ts.map +1 -0
  174. package/dist/bundle.js +47 -0
  175. package/dist/bundle.js.map +1 -0
  176. package/dist/checklist.d.ts +35 -0
  177. package/dist/checklist.d.ts.map +1 -0
  178. package/dist/checklist.js +64 -0
  179. package/dist/checklist.js.map +1 -0
  180. package/dist/cli.d.ts +14 -0
  181. package/dist/cli.d.ts.map +1 -0
  182. package/dist/cli.js +318 -0
  183. package/dist/cli.js.map +1 -0
  184. package/dist/commands/company.d.ts +59 -0
  185. package/dist/commands/company.d.ts.map +1 -0
  186. package/dist/commands/company.js +287 -0
  187. package/dist/commands/company.js.map +1 -0
  188. package/dist/commands/contact.d.ts +9 -0
  189. package/dist/commands/contact.d.ts.map +1 -0
  190. package/dist/commands/contact.js +82 -0
  191. package/dist/commands/contact.js.map +1 -0
  192. package/dist/commands/demo.d.ts +19 -0
  193. package/dist/commands/demo.d.ts.map +1 -0
  194. package/dist/commands/demo.js +72 -0
  195. package/dist/commands/demo.js.map +1 -0
  196. package/dist/commands/doctor.d.ts +12 -0
  197. package/dist/commands/doctor.d.ts.map +1 -0
  198. package/dist/commands/doctor.js +68 -0
  199. package/dist/commands/doctor.js.map +1 -0
  200. package/dist/commands/document.d.ts +17 -0
  201. package/dist/commands/document.d.ts.map +1 -0
  202. package/dist/commands/document.js +217 -0
  203. package/dist/commands/document.js.map +1 -0
  204. package/dist/commands/init.d.ts +31 -0
  205. package/dist/commands/init.d.ts.map +1 -0
  206. package/dist/commands/init.js +535 -0
  207. package/dist/commands/init.js.map +1 -0
  208. package/dist/commands/login.d.ts +24 -0
  209. package/dist/commands/login.d.ts.map +1 -0
  210. package/dist/commands/login.js +128 -0
  211. package/dist/commands/login.js.map +1 -0
  212. package/dist/commands/migrate.d.ts +30 -0
  213. package/dist/commands/migrate.d.ts.map +1 -0
  214. package/dist/commands/migrate.js +115 -0
  215. package/dist/commands/migrate.js.map +1 -0
  216. package/dist/commands/module.d.ts +32 -0
  217. package/dist/commands/module.d.ts.map +1 -0
  218. package/dist/commands/module.js +285 -0
  219. package/dist/commands/module.js.map +1 -0
  220. package/dist/commands/pack.d.ts +22 -0
  221. package/dist/commands/pack.d.ts.map +1 -0
  222. package/dist/commands/pack.js +481 -0
  223. package/dist/commands/pack.js.map +1 -0
  224. package/dist/commands/payment.d.ts +15 -0
  225. package/dist/commands/payment.d.ts.map +1 -0
  226. package/dist/commands/payment.js +97 -0
  227. package/dist/commands/payment.js.map +1 -0
  228. package/dist/commands/register.d.ts +20 -0
  229. package/dist/commands/register.d.ts.map +1 -0
  230. package/dist/commands/register.js +134 -0
  231. package/dist/commands/register.js.map +1 -0
  232. package/dist/commands/status.d.ts +8 -0
  233. package/dist/commands/status.d.ts.map +1 -0
  234. package/dist/commands/status.js +134 -0
  235. package/dist/commands/status.js.map +1 -0
  236. package/dist/commands/whoami.d.ts +21 -0
  237. package/dist/commands/whoami.d.ts.map +1 -0
  238. package/dist/commands/whoami.js +133 -0
  239. package/dist/commands/whoami.js.map +1 -0
  240. package/dist/company.d.ts +16 -0
  241. package/dist/company.d.ts.map +1 -0
  242. package/dist/company.js +26 -0
  243. package/dist/company.js.map +1 -0
  244. package/dist/config.d.ts +24 -0
  245. package/dist/config.d.ts.map +1 -0
  246. package/dist/config.js +50 -0
  247. package/dist/config.js.map +1 -0
  248. package/dist/connection.d.ts +79 -0
  249. package/dist/connection.d.ts.map +1 -0
  250. package/dist/connection.js +116 -0
  251. package/dist/connection.js.map +1 -0
  252. package/dist/context.d.ts +47 -0
  253. package/dist/context.d.ts.map +1 -0
  254. package/dist/context.js +93 -0
  255. package/dist/context.js.map +1 -0
  256. package/dist/doctor.d.ts +45 -0
  257. package/dist/doctor.d.ts.map +1 -0
  258. package/dist/doctor.js +448 -0
  259. package/dist/doctor.js.map +1 -0
  260. package/dist/grants.d.ts +88 -0
  261. package/dist/grants.d.ts.map +1 -0
  262. package/dist/grants.js +174 -0
  263. package/dist/grants.js.map +1 -0
  264. package/dist/identity.d.ts +54 -0
  265. package/dist/identity.d.ts.map +1 -0
  266. package/dist/identity.js +132 -0
  267. package/dist/identity.js.map +1 -0
  268. package/dist/index.d.ts +44 -0
  269. package/dist/index.d.ts.map +1 -0
  270. package/dist/index.js +43 -0
  271. package/dist/index.js.map +1 -0
  272. package/dist/inventory.d.ts +155 -0
  273. package/dist/inventory.d.ts.map +1 -0
  274. package/dist/inventory.js +303 -0
  275. package/dist/inventory.js.map +1 -0
  276. package/dist/migrations.d.ts +76 -0
  277. package/dist/migrations.d.ts.map +1 -0
  278. package/dist/migrations.js +226 -0
  279. package/dist/migrations.js.map +1 -0
  280. package/dist/module/read.d.ts +91 -0
  281. package/dist/module/read.d.ts.map +1 -0
  282. package/dist/module/read.js +172 -0
  283. package/dist/module/read.js.map +1 -0
  284. package/dist/output.d.ts +110 -0
  285. package/dist/output.d.ts.map +1 -0
  286. package/dist/output.js +173 -0
  287. package/dist/output.js.map +1 -0
  288. package/dist/pack/certification.d.ts +27 -0
  289. package/dist/pack/certification.d.ts.map +1 -0
  290. package/dist/pack/certification.js +38 -0
  291. package/dist/pack/certification.js.map +1 -0
  292. package/dist/pack/compile.d.ts +75 -0
  293. package/dist/pack/compile.d.ts.map +1 -0
  294. package/dist/pack/compile.js +801 -0
  295. package/dist/pack/compile.js.map +1 -0
  296. package/dist/pack/filing.d.ts +48 -0
  297. package/dist/pack/filing.d.ts.map +1 -0
  298. package/dist/pack/filing.js +56 -0
  299. package/dist/pack/filing.js.map +1 -0
  300. package/dist/pack/read.d.ts +766 -0
  301. package/dist/pack/read.d.ts.map +1 -0
  302. package/dist/pack/read.js +2336 -0
  303. package/dist/pack/read.js.map +1 -0
  304. package/dist/pack/schema.d.ts +26 -0
  305. package/dist/pack/schema.d.ts.map +1 -0
  306. package/dist/pack/schema.js +181 -0
  307. package/dist/pack/schema.js.map +1 -0
  308. package/dist/pack/territories.d.ts +98 -0
  309. package/dist/pack/territories.d.ts.map +1 -0
  310. package/dist/pack/territories.js +0 -0
  311. package/dist/pack/territories.js.map +1 -0
  312. package/dist/pack/upgrade.d.ts +86 -0
  313. package/dist/pack/upgrade.d.ts.map +1 -0
  314. package/dist/pack/upgrade.js +76 -0
  315. package/dist/pack/upgrade.js.map +1 -0
  316. package/dist/pack/vat-codes.d.ts +273 -0
  317. package/dist/pack/vat-codes.d.ts.map +1 -0
  318. package/dist/pack/vat-codes.js +513 -0
  319. package/dist/pack/vat-codes.js.map +1 -0
  320. package/dist/profiles.d.ts +67 -0
  321. package/dist/profiles.d.ts.map +1 -0
  322. package/dist/profiles.js +187 -0
  323. package/dist/profiles.js.map +1 -0
  324. package/dist/prompt.d.ts +40 -0
  325. package/dist/prompt.d.ts.map +1 -0
  326. package/dist/prompt.js +120 -0
  327. package/dist/prompt.js.map +1 -0
  328. package/dist/registry.d.ts +84 -0
  329. package/dist/registry.d.ts.map +1 -0
  330. package/dist/registry.js +104 -0
  331. package/dist/registry.js.map +1 -0
  332. package/dist/rest.d.ts +81 -0
  333. package/dist/rest.d.ts.map +1 -0
  334. package/dist/rest.js +245 -0
  335. package/dist/rest.js.map +1 -0
  336. package/dist/schema.d.ts +15 -0
  337. package/dist/schema.d.ts.map +1 -0
  338. package/dist/schema.js +15 -0
  339. package/dist/schema.js.map +1 -0
  340. package/dist/seeds.d.ts +27 -0
  341. package/dist/seeds.d.ts.map +1 -0
  342. package/dist/seeds.js +47 -0
  343. package/dist/seeds.js.map +1 -0
  344. package/dist/session.d.ts +39 -0
  345. package/dist/session.d.ts.map +1 -0
  346. package/dist/session.js +92 -0
  347. package/dist/session.js.map +1 -0
  348. package/dist/sql.d.ts +48 -0
  349. package/dist/sql.d.ts.map +1 -0
  350. package/dist/sql.js +112 -0
  351. package/dist/sql.js.map +1 -0
  352. package/dist/status.d.ts +94 -0
  353. package/dist/status.d.ts.map +1 -0
  354. package/dist/status.js +120 -0
  355. package/dist/status.js.map +1 -0
  356. package/dist/ui.d.ts +55 -0
  357. package/dist/ui.d.ts.map +1 -0
  358. package/dist/ui.js +114 -0
  359. package/dist/ui.js.map +1 -0
  360. package/package.json +29 -0
  361. package/schema/output.1.json +613 -0
@@ -0,0 +1,545 @@
1
+ -- Ekwo OS — what the money pays.
2
+ --
3
+ -- The other half of recognising a statement line. `confirm_contact()` says who
4
+ -- the money came from; this says what it settles, which is a different
5
+ -- question and a stricter one: getting the counterparty wrong misfiles a line,
6
+ -- getting the settlement wrong marks an invoice paid that nobody paid.
7
+ --
8
+ -- Three rules hold the whole file together.
9
+ --
10
+ -- **A statement line does not become an entry.** It becomes a *payment* —
11
+ -- the object the ledger already knows, with its journal, its direction, its
12
+ -- counterpart account — and `post_payment()` books it. There is no second way
13
+ -- of writing a ledger here, and nothing in this file inserts an `entries` or
14
+ -- an `entry_lines` row.
15
+ --
16
+ -- **Only identification is applied; resemblance is proposed.** A reference
17
+ -- that matches, or an exact amount with exactly one candidate, is an
18
+ -- identification. A sum of invoices that happens to reach the right total is a
19
+ -- resemblance: it is offered and never applied on its own. The production this
20
+ -- comes from does apply combinations, at two cents of tolerance, and it is
21
+ -- right often enough to be tempting — but a combination that lands on the
22
+ -- right total from the wrong invoices leaves no trace that anything went
23
+ -- wrong, and that is the one mistake a ledger cannot show you afterwards.
24
+ --
25
+ -- **Partial is never automatic.** A payment smaller than the invoice may be a
26
+ -- deposit, a discount, a short payment or an error — four different treatments
27
+ -- and the ledger cannot tell them apart. `settle_from_statement()` will settle
28
+ -- partially when a person names the lines; `auto_settle()` never will.
29
+
30
+ -- ---------------------------------------------------------------------------
31
+ -- open_items
32
+ --
33
+ -- What is still owed, line by line, in the shape matching needs: the side, the
34
+ -- amount still open, the document behind it and the references it carries.
35
+ -- `aged_balance()` answers a neighbouring question for a human to read; this
36
+ -- one is keyed for a machine to search.
37
+ -- ---------------------------------------------------------------------------
38
+
39
+ create or replace function open_items(
40
+ p_company_id uuid,
41
+ p_contact_id uuid default null,
42
+ p_as_of date default null
43
+ )
44
+ returns table (
45
+ line_id uuid,
46
+ contact_id uuid,
47
+ account_id uuid,
48
+ side text,
49
+ amount_open numeric,
50
+ entry_date date,
51
+ date_maturity date,
52
+ document_id uuid,
53
+ document_number text,
54
+ reference text
55
+ )
56
+ language sql
57
+ stable
58
+ security invoker
59
+ as $$
60
+ select l.id,
61
+ l.contact_id,
62
+ l.account_id,
63
+ case when l.debit > 0 then 'debit' else 'credit' end,
64
+ abs(l.balance) - l.matched_amount,
65
+ e.entry_date,
66
+ l.date_maturity,
67
+ d.id,
68
+ d.number,
69
+ coalesce(d.payment_reference, d.number)
70
+ from entry_lines l
71
+ join entries e on e.id = l.entry_id
72
+ join accounts a on a.id = l.account_id
73
+ left join documents d on d.entry_id = e.id
74
+ where l.company_id = p_company_id
75
+ and e.state = 'posted'
76
+ and a.reconcilable
77
+ and abs(l.balance) - l.matched_amount > 0
78
+ and (p_contact_id is null or l.contact_id = p_contact_id)
79
+ and (p_as_of is null or e.entry_date <= p_as_of);
80
+ $$;
81
+
82
+ comment on function open_items(uuid, uuid, date) is
83
+ 'Third-party lines with something still open, with the document behind each and the references it carries. Read by the matching, and by anybody asking what is still owed.';
84
+
85
+ revoke execute on function open_items(uuid, uuid, date) from public, anon;
86
+ grant execute on function open_items(uuid, uuid, date) to authenticated, service_role;
87
+
88
+ -- ---------------------------------------------------------------------------
89
+ -- suggest_matches
90
+ --
91
+ -- Read-only, and — like `suggest_contacts()` — it decides nothing. Every
92
+ -- candidate says what kind of evidence it rests on and how many other
93
+ -- candidates the same evidence produced.
94
+ -- ---------------------------------------------------------------------------
95
+
96
+ create or replace function suggest_matches(p_transaction_id uuid)
97
+ returns table (
98
+ kind text,
99
+ line_ids uuid[],
100
+ amount numeric,
101
+ method text,
102
+ score numeric,
103
+ because text,
104
+ alternatives integer
105
+ )
106
+ language plpgsql
107
+ stable
108
+ security invoker
109
+ as $$
110
+ declare
111
+ v_tx bank_transactions;
112
+ v_policy matching_policy;
113
+ v_round money_rounding;
114
+ v_tolerance numeric;
115
+ v_side text;
116
+ v_target numeric;
117
+ v_home char(3);
118
+ v_internal boolean;
119
+ begin
120
+ select * into v_tx from bank_transactions t where t.id = p_transaction_id;
121
+ if not found then
122
+ raise exception 'not_found: bank transaction %', p_transaction_id
123
+ using errcode = 'no_data_found';
124
+ end if;
125
+
126
+ v_policy := matching_policy_of(v_tx.company_id);
127
+ select c.currency_code into v_home from companies c where c.id = v_tx.company_id;
128
+
129
+ -- One smallest unit of the currency, whatever that currency calls a unit.
130
+ -- A yen has none, a dinar has three, and `round_amount` has known that since
131
+ -- the rounding read the currency.
132
+ v_round := rounding_of(v_tx.company_id, v_tx.currency_code);
133
+ v_tolerance := v_policy.amount_tolerance_units * power(10::numeric, -v_round.decimals);
134
+
135
+ -- Money in settles what a customer owes, which is a debit still open. Money
136
+ -- out settles what we owe, which is a credit.
137
+ v_side := case when v_tx.amount > 0 then 'debit' else 'credit' end;
138
+ v_target := abs(v_tx.amount);
139
+
140
+ -- A transfer between two accounts of this company is not a settlement of
141
+ -- anything, and saying so is the point: the production this comes from
142
+ -- learnt that an internal wire left alone gets matched to whatever invoice
143
+ -- happens to carry the same amount.
144
+ select exists (
145
+ select 1 from bank_accounts b
146
+ where b.company_id = v_tx.company_id
147
+ and b.iban is not null
148
+ and v_tx.counterpart_iban is not null
149
+ and upper(replace(b.iban, ' ', '')) = upper(replace(v_tx.counterpart_iban, ' ', ''))
150
+ ) into v_internal;
151
+
152
+ if v_internal then
153
+ return query
154
+ select 'internal_transfer'::text, '{}'::uuid[], v_target, 'own_account'::text, 1::numeric,
155
+ 'the counterparty account is an account of this company'::text, 1;
156
+ return;
157
+ end if;
158
+
159
+ -- Matching across currencies is not done here. The ledger amount and the
160
+ -- statement amount are then two numbers in two currencies, and the rate that
161
+ -- reconciles them is a question `reconcile()` answers at the moment of
162
+ -- matching, not one a search may assume. Recorded in docs/international.md.
163
+ if v_tx.currency_code <> v_home then
164
+ return;
165
+ end if;
166
+
167
+ return query
168
+ with items as (
169
+ select * from open_items(v_tx.company_id, v_tx.contact_id)
170
+ where side = v_side
171
+ ),
172
+ -- 1. A reference. The strongest evidence there is, because it was put there
173
+ -- for this purpose — and the weakest link in the chain too, which is why
174
+ -- its check digits are a gap written down rather than a guess made here.
175
+ by_reference as (
176
+ select 'document'::text as kind, array[i.line_id] as line_ids,
177
+ least(i.amount_open, v_target) as amount,
178
+ 'reference'::text as method, 1::numeric as score,
179
+ format('the statement carries the reference of %s', coalesce(i.document_number, i.reference)) as because
180
+ from items i
181
+ where i.reference is not null
182
+ and (
183
+ (v_tx.structured_reference is not null
184
+ and upper(regexp_replace(v_tx.structured_reference, '[^0-9A-Za-z]', '', 'g'))
185
+ = upper(regexp_replace(i.reference, '[^0-9A-Za-z]', '', 'g')))
186
+ or (v_tx.reference is not null
187
+ and upper(regexp_replace(v_tx.reference, '[^0-9A-Za-z]', '', 'g'))
188
+ = upper(regexp_replace(i.reference, '[^0-9A-Za-z]', '', 'g')))
189
+ or (v_tx.description is not null
190
+ and position(upper(i.reference) in upper(v_tx.description)) > 0)
191
+ )
192
+ ),
193
+ -- 2. The amount, to the tolerance the company set, inside the window it set.
194
+ by_amount as (
195
+ select 'document'::text, array[i.line_id], i.amount_open,
196
+ 'exact_amount'::text, 0.900::numeric,
197
+ format('%s is open on %s and the statement is for the same amount',
198
+ i.amount_open, coalesce(i.document_number, 'an entry')) as because
199
+ from items i
200
+ where abs(i.amount_open - v_target) <= v_tolerance
201
+ and abs(i.entry_date - v_tx.transaction_date) <= v_policy.date_window_days
202
+ ),
203
+ candidates as (
204
+ select * from by_reference
205
+ union all select * from by_amount
206
+ )
207
+ select c.kind, c.line_ids, c.amount, c.method, c.score, c.because,
208
+ count(*) over (partition by c.method)::integer
209
+ from candidates c
210
+ order by c.score desc, c.amount desc;
211
+ end;
212
+ $$;
213
+
214
+ comment on function suggest_matches(uuid) is
215
+ 'What a statement line could settle: the open items it matches, the evidence, and how many candidates that same evidence produced. Writes nothing. A combination of several documents is offered by suggest_combination(), separately, because it is a resemblance and not an identification.';
216
+
217
+ revoke execute on function suggest_matches(uuid) from public, anon;
218
+ grant execute on function suggest_matches(uuid) to authenticated, service_role;
219
+
220
+ -- ---------------------------------------------------------------------------
221
+ -- suggest_combination
222
+ --
223
+ -- One transaction paying several invoices at once — the ordinary shape of a
224
+ -- customer who settles a month of them in one wire. Deliberately its own
225
+ -- function: the answer is a *proposal*, never applied by `auto_settle()`, and
226
+ -- keeping it apart makes that visible rather than buried in a score.
227
+ --
228
+ -- The walk is oldest first and greedy, which is what the production this comes
229
+ -- from does, and it is deterministic — the same statement and the same ledger
230
+ -- give the same answer every time. It does not prove the subset is the only
231
+ -- one that works, and that is exactly why it is not applied.
232
+ -- ---------------------------------------------------------------------------
233
+
234
+ create or replace function suggest_combination(p_transaction_id uuid)
235
+ returns table (
236
+ line_ids uuid[],
237
+ amount numeric,
238
+ because text
239
+ )
240
+ language plpgsql
241
+ stable
242
+ security invoker
243
+ as $$
244
+ declare
245
+ v_tx bank_transactions;
246
+ v_policy matching_policy;
247
+ v_round money_rounding;
248
+ v_tolerance numeric;
249
+ v_side text;
250
+ v_remaining numeric;
251
+ v_picked uuid[] := '{}';
252
+ v_total numeric := 0;
253
+ v_home char(3);
254
+ r record;
255
+ begin
256
+ select * into v_tx from bank_transactions t where t.id = p_transaction_id;
257
+ if not found then
258
+ raise exception 'not_found: bank transaction %', p_transaction_id
259
+ using errcode = 'no_data_found';
260
+ end if;
261
+
262
+ -- Without a counterparty the search space is every open item of the company,
263
+ -- and a sum that reaches the right total across unrelated customers is
264
+ -- arithmetic, not evidence.
265
+ if v_tx.contact_id is null then return; end if;
266
+
267
+ select c.currency_code into v_home from companies c where c.id = v_tx.company_id;
268
+ if v_tx.currency_code <> v_home then return; end if;
269
+
270
+ v_policy := matching_policy_of(v_tx.company_id);
271
+ v_round := rounding_of(v_tx.company_id, v_tx.currency_code);
272
+ -- Each document was rounded on its own, so a sum of them may miss by more
273
+ -- than one unit. Two, by default, and the company may say otherwise.
274
+ v_tolerance := v_policy.sum_tolerance_units * power(10::numeric, -v_round.decimals);
275
+ v_side := case when v_tx.amount > 0 then 'debit' else 'credit' end;
276
+ v_remaining := abs(v_tx.amount);
277
+
278
+ for r in
279
+ select * from open_items(v_tx.company_id, v_tx.contact_id)
280
+ where side = v_side
281
+ and abs(entry_date - v_tx.transaction_date) <= v_policy.date_window_days
282
+ order by entry_date, line_id
283
+ loop
284
+ if r.amount_open <= v_remaining + v_tolerance then
285
+ v_picked := v_picked || r.line_id;
286
+ v_total := v_total + r.amount_open;
287
+ v_remaining := v_remaining - r.amount_open;
288
+ end if;
289
+ exit when abs(v_remaining) <= v_tolerance;
290
+ end loop;
291
+
292
+ if cardinality(v_picked) > 1 and abs(v_remaining) <= v_tolerance then
293
+ return query select v_picked, v_total,
294
+ format('%s open items of this counterparty add up to %s', cardinality(v_picked), v_total);
295
+ end if;
296
+ end;
297
+ $$;
298
+
299
+ comment on function suggest_combination(uuid) is
300
+ 'A subset of one counterparty''s open items that adds up to the statement line, oldest first. A proposal only: it is never applied automatically, because a sum that reaches the right total from the wrong documents leaves nothing behind to notice.';
301
+
302
+ revoke execute on function suggest_combination(uuid) from public, anon;
303
+ grant execute on function suggest_combination(uuid) to authenticated, service_role;
304
+
305
+ -- ---------------------------------------------------------------------------
306
+ -- settle_from_statement
307
+ --
308
+ -- The act. A person — or an agent acting as one — names the lines this money
309
+ -- settles, and this books the payment and matches it.
310
+ -- ---------------------------------------------------------------------------
311
+
312
+ create or replace function settle_from_statement(p_transaction_id uuid, p_line_ids uuid[])
313
+ returns bank_transactions
314
+ language plpgsql
315
+ volatile
316
+ security invoker
317
+ as $$
318
+ declare
319
+ v_tx bank_transactions;
320
+ v_policy matching_policy;
321
+ v_round money_rounding;
322
+ v_tolerance numeric;
323
+ v_side text;
324
+ v_contact uuid;
325
+ v_contacts integer;
326
+ v_open numeric;
327
+ v_journal uuid;
328
+ v_payment uuid;
329
+ v_entry entries;
330
+ v_pay_line uuid;
331
+ v_remaining numeric;
332
+ v_amount numeric;
333
+ r record;
334
+ begin
335
+ select * into v_tx from bank_transactions t where t.id = p_transaction_id;
336
+ if not found then
337
+ raise exception 'not_found: bank transaction %', p_transaction_id
338
+ using errcode = 'no_data_found';
339
+ end if;
340
+ if v_tx.entry_id is not null then
341
+ raise exception 'statement_line_already_settled: % already points at entry %',
342
+ p_transaction_id, v_tx.entry_id;
343
+ end if;
344
+ if p_line_ids is null or cardinality(p_line_ids) = 0 then
345
+ raise exception 'no_lines_named: settling needs the open items this money pays';
346
+ end if;
347
+
348
+ v_side := case when v_tx.amount > 0 then 'debit' else 'credit' end;
349
+
350
+ -- Every line has to be open, of this company, and on the side this money can
351
+ -- settle. Anything else is a caller that has not looked.
352
+ select count(distinct i.contact_id), count(*), sum(i.amount_open)
353
+ into v_contacts, v_amount, v_open
354
+ from open_items(v_tx.company_id) i
355
+ where i.line_id = any(p_line_ids) and i.side = v_side;
356
+
357
+ if v_amount is distinct from cardinality(p_line_ids) then
358
+ raise exception 'line_not_open: one of the lines named is not an open item of this company on the % side', v_side;
359
+ end if;
360
+ if v_contacts > 1 then
361
+ raise exception 'mixed_contacts: one payment settles the items of one counterparty';
362
+ end if;
363
+
364
+ select i.contact_id into v_contact
365
+ from open_items(v_tx.company_id) i where i.line_id = p_line_ids[1];
366
+ if v_contact is null then
367
+ raise exception 'no_contact_on_open_item: a payment is made to or by somebody, and this item names nobody';
368
+ end if;
369
+
370
+ v_policy := matching_policy_of(v_tx.company_id);
371
+ v_round := rounding_of(v_tx.company_id, v_tx.currency_code);
372
+ v_tolerance := v_policy.amount_tolerance_units * power(10::numeric, -v_round.decimals);
373
+ if abs(v_tx.amount) > v_open + v_tolerance then
374
+ raise exception 'more_money_than_open: the statement line is % and the items named leave % open',
375
+ abs(v_tx.amount), v_open;
376
+ end if;
377
+
378
+ select coalesce(b.journal_id, (select j.id from journals j
379
+ where j.company_id = v_tx.company_id and j.bank_account_id = b.id
380
+ limit 1))
381
+ into v_journal
382
+ from bank_accounts b where b.id = v_tx.bank_account_id;
383
+ if v_journal is null then
384
+ raise exception 'no_journal_for_bank_account: account % books through no journal', v_tx.bank_account_id;
385
+ end if;
386
+
387
+ insert into payments (company_id, direction, payment_date, amount, currency_code,
388
+ contact_id, journal_id, bank_account_id, reference, memo)
389
+ values (v_tx.company_id,
390
+ (case when v_tx.amount > 0 then 'inbound' else 'outbound' end)::payment_direction,
391
+ v_tx.transaction_date, abs(v_tx.amount), v_tx.currency_code,
392
+ v_contact, v_journal, v_tx.bank_account_id,
393
+ coalesce(v_tx.structured_reference, v_tx.reference),
394
+ v_tx.description)
395
+ returning id into v_payment;
396
+
397
+ v_entry := post_payment(v_payment);
398
+
399
+ -- The third-party side of the payment: the line the open items are matched
400
+ -- against. The other side is the bank account, which settles nothing.
401
+ select l.id into v_pay_line
402
+ from entry_lines l
403
+ join accounts a on a.id = l.account_id
404
+ where l.entry_id = v_entry.id and a.reconcilable
405
+ limit 1;
406
+ if v_pay_line is null then
407
+ raise exception 'payment_has_no_third_party_line: entry % books against no reconcilable account',
408
+ v_entry.id;
409
+ end if;
410
+
411
+ -- Oldest first, each item settled up to what is left of the money. A partial
412
+ -- settlement is possible here because a person asked for it by naming the
413
+ -- lines; `auto_settle()` never gets here with less money than is open.
414
+ v_remaining := abs(v_tx.amount);
415
+ for r in
416
+ select * from open_items(v_tx.company_id) i
417
+ where i.line_id = any(p_line_ids)
418
+ order by i.entry_date, i.line_id
419
+ loop
420
+ exit when v_remaining <= 0;
421
+ perform reconcile(v_pay_line, r.line_id, least(r.amount_open, v_remaining));
422
+ v_remaining := v_remaining - least(r.amount_open, v_remaining);
423
+ end loop;
424
+
425
+ update bank_transactions t
426
+ set entry_id = v_entry.id,
427
+ contact_id = coalesce(t.contact_id, v_contact),
428
+ state = 'reconciled'
429
+ where t.id = p_transaction_id
430
+ returning * into v_tx;
431
+
432
+ return v_tx;
433
+ end;
434
+ $$;
435
+
436
+ comment on function settle_from_statement(uuid, uuid[]) is
437
+ 'Books the payment a statement line is, and matches it against the open items named. One counterparty, one payment, `post_payment()` and `reconcile()` doing the accounting — nothing here writes a ledger of its own.';
438
+
439
+ revoke execute on function settle_from_statement(uuid, uuid[]) from public, anon;
440
+ grant execute on function settle_from_statement(uuid, uuid[]) to authenticated, service_role;
441
+
442
+ -- ---------------------------------------------------------------------------
443
+ -- auto_settle
444
+ --
445
+ -- The pass over a period. It applies what is an identification and leaves
446
+ -- everything else with a reason, which is the report a bookkeeper actually
447
+ -- reads: what went through, what is waiting for them, and what nobody can
448
+ -- decide from the ledger alone.
449
+ -- ---------------------------------------------------------------------------
450
+
451
+ create or replace function auto_settle(
452
+ p_company_id uuid,
453
+ p_from date,
454
+ p_to date,
455
+ p_apply boolean default false
456
+ )
457
+ returns table (
458
+ transaction_id uuid,
459
+ action text,
460
+ method text,
461
+ line_ids uuid[],
462
+ because text
463
+ )
464
+ language plpgsql
465
+ volatile
466
+ security invoker
467
+ as $$
468
+ declare
469
+ v_policy matching_policy;
470
+ v_round money_rounding;
471
+ v_tolerance numeric;
472
+ t record;
473
+ best record;
474
+ v_count integer;
475
+ v_open numeric;
476
+ begin
477
+ v_policy := matching_policy_of(p_company_id);
478
+
479
+ for t in
480
+ select * from bank_transactions b
481
+ where b.company_id = p_company_id
482
+ and b.state = 'pending'
483
+ and b.entry_id is null
484
+ and b.transaction_date between p_from and p_to
485
+ order by b.transaction_date, b.sequence
486
+ loop
487
+ v_round := rounding_of(p_company_id, t.currency_code);
488
+ v_tolerance := v_policy.amount_tolerance_units * power(10::numeric, -v_round.decimals);
489
+
490
+ select count(*) into v_count
491
+ from suggest_matches(t.id) s
492
+ where s.kind = 'internal_transfer';
493
+ if v_count > 0 then
494
+ transaction_id := t.id; action := 'left'; method := 'internal_transfer';
495
+ line_ids := '{}'::uuid[];
496
+ because := 'a transfer between two accounts of this company settles nothing, and its other side is its own statement line';
497
+ return next; continue;
498
+ end if;
499
+
500
+ -- The one candidate whose evidence identified exactly one thing.
501
+ select * into best
502
+ from suggest_matches(t.id) s
503
+ where s.alternatives = 1 and s.method in ('reference', 'exact_amount')
504
+ order by s.score desc
505
+ limit 1;
506
+
507
+ if not found then
508
+ select count(*) into v_count from suggest_matches(t.id);
509
+ transaction_id := t.id; action := 'proposed'; method := 'none';
510
+ line_ids := '{}'::uuid[];
511
+ because := case when v_count = 0
512
+ then 'nothing open matches this line'
513
+ else format('%s candidates, none of them an identification', v_count) end;
514
+ return next; continue;
515
+ end if;
516
+
517
+ -- Partial settlement is four different accounting treatments wearing the
518
+ -- same face. The machine proposes; a person decides which one it is.
519
+ select sum(i.amount_open) into v_open
520
+ from open_items(p_company_id) i where i.line_id = any(best.line_ids);
521
+ if abs(t.amount) + v_tolerance < v_open then
522
+ transaction_id := t.id; action := 'proposed'; method := best.method;
523
+ line_ids := best.line_ids;
524
+ because := format('%s of %s — a deposit, a discount, a short payment or an error, and the ledger cannot tell which',
525
+ abs(t.amount), v_open);
526
+ return next; continue;
527
+ end if;
528
+
529
+ if p_apply then
530
+ perform settle_from_statement(t.id, best.line_ids);
531
+ transaction_id := t.id; action := 'settled';
532
+ else
533
+ transaction_id := t.id; action := 'would_settle';
534
+ end if;
535
+ method := best.method; line_ids := best.line_ids; because := best.because;
536
+ return next;
537
+ end loop;
538
+ end;
539
+ $$;
540
+
541
+ comment on function auto_settle(uuid, date, date, boolean) is
542
+ 'Walks the pending statement lines of a period and settles the ones a single piece of evidence identifies — a reference, or an exact amount with one candidate. Everything else comes back with the reason it was left: a combination, a partial payment, an internal transfer, or nothing open that fits. With p_apply false it changes nothing and says what it would do.';
543
+
544
+ revoke execute on function auto_settle(uuid, date, date, boolean) from public, anon;
545
+ grant execute on function auto_settle(uuid, date, date, boolean) to authenticated, service_role;