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,279 @@
1
+ -- Ekwo OS — documents (sales and purchase invoices, credit notes, quotes)
2
+ -- and their lines.
3
+ --
4
+ -- One table, one `doc_type`: matching, attachments, bank reconciliation and
5
+ -- Peppol are then written once instead of once per document family.
6
+ -- A document is NOT the entry. post_document() joins them by foreign key.
7
+
8
+ create type doc_type as enum (
9
+ 'sale_invoice',
10
+ 'sale_credit_note',
11
+ 'sale_quote',
12
+ 'purchase_invoice',
13
+ 'purchase_credit_note',
14
+ 'purchase_order'
15
+ );
16
+
17
+ -- Lifecycle of the document itself. Whether it was e-mailed is `sent_at`,
18
+ -- whether it was paid is `payment_state`: three different questions.
19
+ create type doc_state as enum ('draft', 'posted', 'cancelled');
20
+
21
+ create type payment_state as enum ('not_paid', 'partially_paid', 'paid', 'overpaid', 'reversed');
22
+
23
+ create type document_line_type as enum ('product', 'section', 'note');
24
+
25
+ create table documents (
26
+ id uuid primary key default gen_random_uuid(),
27
+ company_id uuid not null references companies(id) on delete cascade,
28
+ doc_type doc_type not null,
29
+ state doc_state not null default 'draft',
30
+ payment_state payment_state not null default 'not_paid',
31
+ -- Our own number. On a purchase this is the internal reference; the
32
+ -- supplier's number lives in `supplier_reference`.
33
+ number text,
34
+ supplier_reference text,
35
+ contact_id uuid not null references contacts(id) on delete restrict,
36
+ journal_id uuid references journals(id) on delete restrict,
37
+ -- Date of the document, and the date it is booked on. They differ when a
38
+ -- December invoice is recorded in January.
39
+ document_date date not null,
40
+ accounting_date date,
41
+ due_date date,
42
+ currency_code char(3) not null default 'EUR' references currencies(code),
43
+ exchange_rate numeric(18, 8) not null default 1,
44
+
45
+ -- EN 16931 fields, as columns rather than a JSON blob.
46
+ buyer_reference text, -- BT-10
47
+ project_reference text, -- BT-11
48
+ contract_reference text, -- BT-12
49
+ order_reference text, -- BT-13
50
+ delivery_date date, -- BT-72
51
+ delivery_address_line1 text, -- BG-15
52
+ delivery_postal_code text,
53
+ delivery_city text,
54
+ delivery_country char(2),
55
+ payment_terms text, -- BT-20
56
+ payment_means_code text, -- BT-81
57
+ payment_reference text, -- BT-83
58
+ payee_iban text, -- BT-84
59
+ note text, -- BT-22
60
+ currency_code_tax char(3), -- BT-6 VAT accounting currency
61
+
62
+ -- Totals, derived from the lines. Never keyed in.
63
+ amount_untaxed numeric(16, 2) not null default 0,
64
+ amount_tax numeric(16, 2) not null default 0,
65
+ amount_total numeric(16, 2) not null default 0,
66
+ amount_paid numeric(16, 2) not null default 0,
67
+ amount_residual numeric(16, 2) generated always as (amount_total - amount_paid) stored,
68
+
69
+ reversed_document_id uuid references documents(id) on delete set null,
70
+ entry_id uuid references entries(id) on delete set null,
71
+ sent_at timestamptz,
72
+ peppol_status text,
73
+ peppol_message_id text,
74
+ created_at timestamptz not null default now(),
75
+ updated_at timestamptz not null default now(),
76
+ constraint documents_posted_has_number check (state <> 'posted' or number is not null),
77
+ constraint documents_rate_positive check (exchange_rate > 0),
78
+ foreign key (contact_id, company_id) references contacts(id, company_id),
79
+ foreign key (journal_id, company_id) references journals(id, company_id),
80
+ foreign key (entry_id, company_id) references entries(id, company_id)
81
+ );
82
+
83
+ comment on table documents is
84
+ 'Sales and purchase invoices, credit notes, quotes and orders. `state` is the document, `payment_state` the settlement.';
85
+ comment on column documents.accounting_date is 'Date the entry is booked on; defaults to document_date.';
86
+ comment on column documents.supplier_reference is 'The supplier''s own invoice number on a purchase.';
87
+
88
+ create unique index documents_company_number_idx
89
+ on documents (company_id, doc_type, number) where number is not null;
90
+ create unique index documents_id_company_idx on documents (id, company_id);
91
+ create unique index documents_entry_idx on documents (entry_id) where entry_id is not null;
92
+ create index documents_company_type_state_idx on documents (company_id, doc_type, state);
93
+ create index documents_contact_idx on documents (contact_id);
94
+ create index documents_date_idx on documents (company_id, document_date);
95
+
96
+ create trigger documents_set_updated_at
97
+ before update on documents
98
+ for each row execute function set_updated_at();
99
+
100
+ -- Close the loop: an entry knows which document produced it.
101
+ alter table entries
102
+ add constraint entries_document_fkey
103
+ foreign key (document_id) references documents(id) on delete set null;
104
+
105
+ -- ---------------------------------------------------------------------------
106
+ -- document_lines
107
+ -- ---------------------------------------------------------------------------
108
+
109
+ create table document_lines (
110
+ id uuid primary key default gen_random_uuid(),
111
+ document_id uuid not null references documents(id) on delete cascade,
112
+ company_id uuid not null references companies(id) on delete cascade,
113
+ sequence integer not null default 10,
114
+ line_type document_line_type not null default 'product',
115
+ name text not null,
116
+ quantity numeric(16, 4) not null default 1,
117
+ -- UN/ECE Recommendation 20 code, BT-130.
118
+ unit_code text not null default 'C62',
119
+ unit_price numeric(16, 6) not null default 0,
120
+ -- One discount semantics in the whole system: a percentage off the line.
121
+ discount_percent numeric(7, 4) not null default 0,
122
+ tax_id uuid references taxes(id) on delete restrict,
123
+ account_id uuid references accounts(id) on delete restrict,
124
+ -- EN 16931 BT-151 / BT-152, snapshotted so a later rate change cannot
125
+ -- rewrite history.
126
+ vat_category char(2),
127
+ vat_rate numeric(7, 4),
128
+ amount_untaxed numeric(16, 2) generated always as (
129
+ case when line_type = 'product'
130
+ then round(quantity * unit_price * (1 - discount_percent / 100), 2)
131
+ else 0
132
+ end
133
+ ) stored,
134
+ created_at timestamptz not null default now(),
135
+ updated_at timestamptz not null default now(),
136
+ constraint document_lines_discount_range check (discount_percent >= 0 and discount_percent < 100),
137
+ constraint document_lines_product_has_account check (
138
+ line_type <> 'product' or account_id is not null
139
+ ),
140
+ foreign key (document_id, company_id) references documents(id, company_id) on delete cascade,
141
+ foreign key (tax_id, company_id) references taxes(id, company_id),
142
+ foreign key (account_id, company_id) references accounts(id, company_id)
143
+ );
144
+
145
+ comment on table document_lines is 'Document lines in a table, not JSON: EN 16931 needs a VAT category per line and the FEC needs the detail.';
146
+ comment on column document_lines.amount_untaxed is 'quantity x unit_price less the discount, rounded to two decimals once.';
147
+
148
+ create index document_lines_document_idx on document_lines (document_id, sequence);
149
+ create index document_lines_tax_idx on document_lines (tax_id);
150
+ create unique index document_lines_id_company_idx on document_lines (id, company_id);
151
+
152
+ create trigger document_lines_set_updated_at
153
+ before update on document_lines
154
+ for each row execute function set_updated_at();
155
+
156
+ -- ---------------------------------------------------------------------------
157
+ -- Totals
158
+ --
159
+ -- VAT is computed per tax group on the rounded basis, which is the EN 16931
160
+ -- rule (BR-CO-14) and what every validator checks. Not per line, not on the
161
+ -- document total.
162
+ -- ---------------------------------------------------------------------------
163
+
164
+ create or replace view document_tax_summary
165
+ with (security_invoker = true) as
166
+ select l.document_id,
167
+ l.company_id,
168
+ d.doc_type,
169
+ l.tax_id,
170
+ t.code as tax_code,
171
+ t.name as tax_name,
172
+ t.vat_category,
173
+ t.amount as tax_rate,
174
+ sum(l.amount_untaxed) as base_amount,
175
+ -- Gross tax: what the VAT return reports.
176
+ round(sum(l.amount_untaxed) * coalesce(t.amount, 0) / 100, 2) as tax_amount,
177
+ -- Charged tax: what the other party actually pays. Zero when the tax
178
+ -- postings net out, which is exactly what self-assessment means.
179
+ round(
180
+ sum(l.amount_untaxed) * coalesce(t.amount, 0) / 100
181
+ * coalesce((
182
+ select sum(tp.factor_percent)
183
+ from tax_postings tp
184
+ where tp.tax_id = t.id
185
+ and tp.posting_type = 'tax'
186
+ and tp.document_kind = case
187
+ when d.doc_type in ('sale_credit_note', 'purchase_credit_note')
188
+ then 'credit_note'::tax_document_kind
189
+ else 'invoice'::tax_document_kind
190
+ end
191
+ ), 100) / 100,
192
+ 2) as tax_charged
193
+ from document_lines l
194
+ join documents d on d.id = l.document_id
195
+ left join taxes t on t.id = l.tax_id
196
+ where l.line_type = 'product'
197
+ group by l.document_id, l.company_id, d.doc_type, l.tax_id,
198
+ t.id, t.code, t.name, t.vat_category, t.amount;
199
+
200
+ comment on view document_tax_summary is
201
+ 'VAT breakdown of a document, one row per tax, rounded on the group basis (EN 16931 BR-CO-14).';
202
+
203
+ create or replace function documents_refresh_totals(p_document_id uuid)
204
+ returns void
205
+ language plpgsql
206
+ as $$
207
+ declare
208
+ v_untaxed numeric(16, 2);
209
+ v_tax numeric(16, 2);
210
+ begin
211
+ select coalesce(sum(base_amount), 0), coalesce(sum(tax_charged), 0)
212
+ into v_untaxed, v_tax
213
+ from document_tax_summary
214
+ where document_id = p_document_id;
215
+
216
+ update documents
217
+ set amount_untaxed = v_untaxed,
218
+ amount_tax = v_tax,
219
+ amount_total = v_untaxed + v_tax
220
+ where id = p_document_id;
221
+ end;
222
+ $$;
223
+
224
+ create or replace function document_lines_refresh_totals()
225
+ returns trigger
226
+ language plpgsql
227
+ as $$
228
+ begin
229
+ perform documents_refresh_totals(coalesce(new.document_id, old.document_id));
230
+ return null;
231
+ end;
232
+ $$;
233
+
234
+ create trigger document_lines_refresh_totals
235
+ after insert or update or delete on document_lines
236
+ for each row execute function document_lines_refresh_totals();
237
+
238
+ -- Payment state follows the residual, never the other way round.
239
+ create or replace function documents_refresh_payment_state()
240
+ returns trigger
241
+ language plpgsql
242
+ as $$
243
+ begin
244
+ if new.amount_total = 0 then
245
+ new.payment_state := case when new.amount_paid <> 0 then 'overpaid' else 'not_paid' end;
246
+ elsif new.amount_paid = 0 then
247
+ new.payment_state := 'not_paid';
248
+ elsif abs(new.amount_paid) >= abs(new.amount_total) then
249
+ new.payment_state := case
250
+ when abs(new.amount_paid) > abs(new.amount_total) then 'overpaid'
251
+ else 'paid'
252
+ end;
253
+ else
254
+ new.payment_state := 'partially_paid';
255
+ end if;
256
+ return new;
257
+ end;
258
+ $$;
259
+
260
+ create trigger documents_refresh_payment_state
261
+ before insert or update of amount_total, amount_paid on documents
262
+ for each row execute function documents_refresh_payment_state();
263
+
264
+ -- ---------------------------------------------------------------------------
265
+ -- Row level security
266
+ -- ---------------------------------------------------------------------------
267
+
268
+ alter table documents enable row level security;
269
+ alter table document_lines enable row level security;
270
+
271
+ create policy documents_select on documents
272
+ for select using (is_company_member(company_id));
273
+ create policy documents_write on documents
274
+ for all using (can_write_company(company_id)) with check (can_write_company(company_id));
275
+
276
+ create policy document_lines_select on document_lines
277
+ for select using (is_company_member(company_id));
278
+ create policy document_lines_write on document_lines
279
+ for all using (can_write_company(company_id)) with check (can_write_company(company_id));
@@ -0,0 +1,251 @@
1
+ -- Ekwo OS — payments and bilateral matching.
2
+
3
+ create type payment_direction as enum ('inbound', 'outbound');
4
+ create type payment_state_t as enum ('draft', 'posted', 'cancelled');
5
+
6
+ create table payments (
7
+ id uuid primary key default gen_random_uuid(),
8
+ company_id uuid not null references companies(id) on delete cascade,
9
+ direction payment_direction not null,
10
+ payment_date date not null,
11
+ amount numeric(16, 2) not null,
12
+ currency_code char(3) not null default 'EUR' references currencies(code),
13
+ contact_id uuid references contacts(id) on delete set null,
14
+ journal_id uuid not null references journals(id) on delete restrict,
15
+ bank_account_id uuid,
16
+ entry_id uuid references entries(id) on delete set null,
17
+ reference text,
18
+ memo text,
19
+ state payment_state_t not null default 'draft',
20
+ created_at timestamptz not null default now(),
21
+ updated_at timestamptz not null default now(),
22
+ constraint payments_amount_positive check (amount > 0),
23
+ foreign key (contact_id, company_id) references contacts(id, company_id),
24
+ foreign key (journal_id, company_id) references journals(id, company_id),
25
+ foreign key (entry_id, company_id) references entries(id, company_id)
26
+ );
27
+
28
+ comment on table payments is 'Money in and out. Amounts are positive; `direction` carries the sign.';
29
+
30
+ create unique index payments_id_company_idx on payments (id, company_id);
31
+ create index payments_company_date_idx on payments (company_id, payment_date);
32
+ create index payments_contact_idx on payments (contact_id);
33
+
34
+ create trigger payments_set_updated_at
35
+ before update on payments
36
+ for each row execute function set_updated_at();
37
+
38
+ -- ---------------------------------------------------------------------------
39
+ -- reconciliations
40
+ --
41
+ -- Matching is bilateral and by amount: each pairing of a debit with a credit
42
+ -- is a row. The FEC needs the letter, the aged balance needs the residual.
43
+ -- ---------------------------------------------------------------------------
44
+
45
+ create table reconciliations (
46
+ id uuid primary key default gen_random_uuid(),
47
+ company_id uuid not null references companies(id) on delete cascade,
48
+ debit_line_id uuid not null references entry_lines(id) on delete cascade,
49
+ credit_line_id uuid not null references entry_lines(id) on delete cascade,
50
+ amount numeric(16, 2) not null,
51
+ matching_number text not null,
52
+ matched_at date not null default current_date,
53
+ created_at timestamptz not null default now(),
54
+ constraint reconciliations_amount_positive check (amount > 0),
55
+ constraint reconciliations_distinct_lines check (debit_line_id <> credit_line_id),
56
+ unique (debit_line_id, credit_line_id),
57
+ foreign key (debit_line_id, company_id) references entry_lines(id, company_id) on delete cascade,
58
+ foreign key (credit_line_id, company_id) references entry_lines(id, company_id) on delete cascade
59
+ );
60
+
61
+ comment on table reconciliations is 'One row per pairing of a debit with a credit. Full matching is the sum of partials.';
62
+
63
+ create index reconciliations_debit_idx on reconciliations (debit_line_id);
64
+ create index reconciliations_credit_idx on reconciliations (credit_line_id);
65
+ create index reconciliations_number_idx on reconciliations (company_id, matching_number);
66
+
67
+ -- Company-wide letter counter: A0001, A0002, ...
68
+ create table matching_sequences (
69
+ company_id uuid primary key references companies(id) on delete cascade,
70
+ last_number integer not null default 0
71
+ );
72
+
73
+ create or replace function next_matching_number(p_company_id uuid)
74
+ returns text
75
+ language plpgsql
76
+ as $$
77
+ declare
78
+ v_number integer;
79
+ begin
80
+ insert into matching_sequences (company_id, last_number)
81
+ values (p_company_id, 1)
82
+ on conflict (company_id)
83
+ do update set last_number = matching_sequences.last_number + 1
84
+ returning last_number into v_number;
85
+ return 'A' || lpad(v_number::text, 4, '0');
86
+ end;
87
+ $$;
88
+
89
+ comment on function next_matching_number(uuid) is 'Next reconciliation letter for a company, as A0001.';
90
+
91
+ -- Keep entry_lines.matched_amount and matching_number in step.
92
+ create or replace function reconciliations_refresh_lines()
93
+ returns trigger
94
+ language plpgsql
95
+ as $$
96
+ declare
97
+ v_ids uuid[];
98
+ v_id uuid;
99
+ begin
100
+ v_ids := array_remove(array[
101
+ coalesce(new.debit_line_id, old.debit_line_id),
102
+ coalesce(new.credit_line_id, old.credit_line_id)
103
+ ], null);
104
+
105
+ foreach v_id in array v_ids loop
106
+ update entry_lines l
107
+ set matched_amount = coalesce((
108
+ select sum(r.amount) from reconciliations r
109
+ where r.debit_line_id = l.id or r.credit_line_id = l.id
110
+ ), 0),
111
+ matching_number = (
112
+ select r.matching_number from reconciliations r
113
+ where r.debit_line_id = l.id or r.credit_line_id = l.id
114
+ order by r.created_at
115
+ limit 1
116
+ )
117
+ where l.id = v_id;
118
+ end loop;
119
+
120
+ return null;
121
+ end;
122
+ $$;
123
+
124
+ create trigger reconciliations_refresh_lines
125
+ after insert or update or delete on reconciliations
126
+ for each row execute function reconciliations_refresh_lines();
127
+
128
+ -- ---------------------------------------------------------------------------
129
+ -- reconcile / unreconcile
130
+ -- ---------------------------------------------------------------------------
131
+
132
+ create or replace function reconcile(
133
+ p_line_a uuid,
134
+ p_line_b uuid,
135
+ p_amount numeric default null
136
+ )
137
+ returns reconciliations
138
+ language plpgsql
139
+ as $$
140
+ declare
141
+ v_a entry_lines%rowtype;
142
+ v_b entry_lines%rowtype;
143
+ v_debit entry_lines%rowtype;
144
+ v_credit entry_lines%rowtype;
145
+ v_amount numeric(16, 2);
146
+ v_letter text;
147
+ v_result reconciliations%rowtype;
148
+ v_reconcilable boolean;
149
+ begin
150
+ select * into v_a from entry_lines where id = p_line_a for update;
151
+ if not found then raise exception 'unknown_entry_line: %', p_line_a; end if;
152
+ select * into v_b from entry_lines where id = p_line_b for update;
153
+ if not found then raise exception 'unknown_entry_line: %', p_line_b; end if;
154
+
155
+ if v_a.account_id <> v_b.account_id then
156
+ raise exception 'reconcile_account_mismatch: lines are on different accounts';
157
+ end if;
158
+ if v_a.company_id <> v_b.company_id then
159
+ raise exception 'reconcile_company_mismatch: lines belong to different companies';
160
+ end if;
161
+
162
+ select a.reconcilable into v_reconcilable from accounts a where a.id = v_a.account_id;
163
+ if not v_reconcilable then
164
+ raise exception 'account_not_reconcilable: account of line % is not reconcilable', p_line_a;
165
+ end if;
166
+
167
+ if (v_a.debit > 0) = (v_b.debit > 0) then
168
+ raise exception 'reconcile_same_side: a debit must be matched against a credit';
169
+ end if;
170
+
171
+ if v_a.debit > 0 then
172
+ v_debit := v_a; v_credit := v_b;
173
+ else
174
+ v_debit := v_b; v_credit := v_a;
175
+ end if;
176
+
177
+ v_amount := coalesce(
178
+ p_amount,
179
+ least(
180
+ abs(v_debit.debit - v_debit.credit) - v_debit.matched_amount,
181
+ abs(v_credit.debit - v_credit.credit) - v_credit.matched_amount
182
+ )
183
+ );
184
+
185
+ if v_amount is null or v_amount <= 0 then
186
+ raise exception 'reconcile_nothing_left: no open amount to match';
187
+ end if;
188
+ if v_amount > abs(v_debit.debit - v_debit.credit) - v_debit.matched_amount + 0.001 then
189
+ raise exception 'reconcile_over_debit: % exceeds the open amount of the debit line', v_amount;
190
+ end if;
191
+ if v_amount > abs(v_credit.debit - v_credit.credit) - v_credit.matched_amount + 0.001 then
192
+ raise exception 'reconcile_over_credit: % exceeds the open amount of the credit line', v_amount;
193
+ end if;
194
+
195
+ -- Reuse a letter already carried by either side, otherwise draw a new one.
196
+ v_letter := coalesce(v_debit.matching_number, v_credit.matching_number,
197
+ next_matching_number(v_debit.company_id));
198
+
199
+ -- Two chains meeting: merge them under a single letter.
200
+ if v_debit.matching_number is not null
201
+ and v_credit.matching_number is not null
202
+ and v_debit.matching_number <> v_credit.matching_number then
203
+ update reconciliations
204
+ set matching_number = v_letter
205
+ where company_id = v_debit.company_id
206
+ and matching_number = v_credit.matching_number;
207
+ end if;
208
+
209
+ insert into reconciliations (company_id, debit_line_id, credit_line_id, amount, matching_number)
210
+ values (v_debit.company_id, v_debit.id, v_credit.id, v_amount, v_letter)
211
+ returning * into v_result;
212
+
213
+ return v_result;
214
+ end;
215
+ $$;
216
+
217
+ comment on function reconcile(uuid, uuid, numeric) is
218
+ 'Matches a debit line against a credit line for an amount, defaulting to the smaller open amount.';
219
+
220
+ create or replace function unreconcile(p_reconciliation_id uuid)
221
+ returns void
222
+ language plpgsql
223
+ as $$
224
+ begin
225
+ delete from reconciliations where id = p_reconciliation_id;
226
+ if not found then
227
+ raise exception 'unknown_reconciliation: %', p_reconciliation_id;
228
+ end if;
229
+ end;
230
+ $$;
231
+
232
+ -- ---------------------------------------------------------------------------
233
+ -- Row level security
234
+ -- ---------------------------------------------------------------------------
235
+
236
+ alter table payments enable row level security;
237
+ alter table reconciliations enable row level security;
238
+ alter table matching_sequences enable row level security;
239
+
240
+ create policy payments_select on payments
241
+ for select using (is_company_member(company_id));
242
+ create policy payments_write on payments
243
+ for all using (can_write_company(company_id)) with check (can_write_company(company_id));
244
+
245
+ create policy reconciliations_select on reconciliations
246
+ for select using (is_company_member(company_id));
247
+ create policy reconciliations_write on reconciliations
248
+ for all using (can_write_company(company_id)) with check (can_write_company(company_id));
249
+
250
+ create policy matching_sequences_select on matching_sequences
251
+ for select using (is_company_member(company_id));