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,261 @@
1
+ -- Ekwo OS — a company has a face, and an invoice has to print it.
2
+ --
3
+ -- The core knew a company's name, its legal name, its address, its two
4
+ -- identifiers and its currency. An invoice needs more than that, and every
5
+ -- one of the missing pieces is a thing a renderer would otherwise have to be
6
+ -- configured with separately — which is the same fact written twice, in a
7
+ -- place the books cannot see.
8
+ --
9
+ -- **What is added, and why each one is a column rather than a setting.**
10
+ -- `trade_name` because a company trades under a name that is not its
11
+ -- statutory one and the invoice carries both. `logo_url` because a renderer
12
+ -- needs to find the image — a URL or a storage path, never the file: the core
13
+ -- keeps books, not binaries. `share_capital` with its own currency because
14
+ -- several European legal forms must state it on every document.
15
+ -- `activity_code` with the scheme it is written in, because NACE, APE and SIC
16
+ -- are different registers and a bare code is unreadable without the one it
17
+ -- came from. `default_bank_account_id` because an invoice without an IBAN
18
+ -- cannot be paid. `document_template` because a company that has chosen a
19
+ -- layout has chosen it once, not per invoice.
20
+ --
21
+ -- **What is deliberately not added.** No `registry_reference`:
22
+ -- `companies.registration_number` is already the number the commercial
23
+ -- register holds — a BCE number in Belgium, an RCS or SIRET in France — and a
24
+ -- second column for it would be two answers to one question, which is the one
25
+ -- thing this schema will not do.
26
+ --
27
+ -- **No literal default anywhere.** `share_capital_currency` falls back to the
28
+ -- company's own currency, in a trigger, and never to a currency written into
29
+ -- this file.
30
+
31
+ alter table companies
32
+ add column if not exists trade_name text,
33
+ add column if not exists logo_url text,
34
+ add column if not exists share_capital numeric(16, 2),
35
+ add column if not exists share_capital_currency char(3) references currencies(code),
36
+ add column if not exists activity_code text,
37
+ add column if not exists activity_scheme text,
38
+ add column if not exists default_bank_account_id uuid,
39
+ add column if not exists document_template text;
40
+
41
+ comment on column companies.trade_name is
42
+ 'The name the company trades under, when it is not the statutory one. A renderer shows this and keeps legal_name for the footer.';
43
+ comment on column companies.logo_url is
44
+ 'Where the logo is, as a URL or a storage path. The core stores no file: an accounting schema that held binaries would be backing up images with the ledger.';
45
+ comment on column companies.share_capital is
46
+ 'Capital to be stated on documents where the law requires it. Null where it does not, which is not zero.';
47
+ comment on column companies.share_capital_currency is
48
+ 'Currency the capital is expressed in. Filled with the company''s own currency when it is left empty, and never with a currency written into the schema.';
49
+ comment on column companies.activity_code is
50
+ 'The company''s activity in the register of its country — NACE, APE, SIC. Text, because the registers are not numbers and not the same length.';
51
+ comment on column companies.activity_scheme is
52
+ 'Which register activity_code belongs to. A code without its scheme cannot be looked up.';
53
+ comment on column companies.default_bank_account_id is
54
+ 'The account a customer is asked to pay into. It fills documents.payee_iban (BT-84) when a sales document names none.';
55
+ comment on column companies.document_template is
56
+ 'A code the renderer interprets. The core never reads it: what a document looks like is not an accounting question.';
57
+
58
+ alter table companies
59
+ add constraint companies_share_capital_positive
60
+ check (share_capital is null or share_capital >= 0),
61
+ add constraint companies_share_capital_has_currency
62
+ check (share_capital is null or share_capital_currency is not null),
63
+ add constraint companies_default_bank_account_fkey
64
+ foreign key (default_bank_account_id) references bank_accounts(id) on delete set null;
65
+
66
+ -- The account also has to belong to this company, and that is a trigger
67
+ -- rather than the composite key `(default_bank_account_id, id) references
68
+ -- bank_accounts(id, company_id)` that says it in one line. The composite key
69
+ -- works and its `on delete set null` does not: PostgreSQL nulls *every*
70
+ -- referencing column, so deleting a bank account would try to null
71
+ -- `companies.id`. A plain key keeps the friendly behaviour — withdrawing an
72
+ -- account clears the default instead of refusing the delete — and the trigger
73
+ -- keeps the guarantee.
74
+
75
+ create or replace function companies_default_bank_account_is_ours()
76
+ returns trigger
77
+ language plpgsql
78
+ as $$
79
+ begin
80
+ if new.default_bank_account_id is not null
81
+ and not exists (select 1 from bank_accounts b
82
+ where b.id = new.default_bank_account_id
83
+ and b.company_id = new.id) then
84
+ raise exception 'foreign_bank_account: that bank account belongs to another company'
85
+ using errcode = '23503';
86
+ end if;
87
+ return new;
88
+ end;
89
+ $$;
90
+
91
+ create trigger companies_default_bank_account_is_ours
92
+ before insert or update of default_bank_account_id on companies
93
+ for each row execute function companies_default_bank_account_is_ours();
94
+
95
+ -- ---------------------------------------------------------------------------
96
+ -- The currency of the capital, when nobody said
97
+ -- ---------------------------------------------------------------------------
98
+
99
+ create or replace function companies_default_capital_currency()
100
+ returns trigger
101
+ language plpgsql
102
+ as $$
103
+ begin
104
+ if new.share_capital is not null and new.share_capital_currency is null then
105
+ new.share_capital_currency := new.currency_code;
106
+ end if;
107
+ return new;
108
+ end;
109
+ $$;
110
+
111
+ create trigger companies_default_capital_currency
112
+ before insert or update of share_capital, share_capital_currency, currency_code on companies
113
+ for each row execute function companies_default_capital_currency();
114
+
115
+ comment on function companies_default_capital_currency() is
116
+ 'A capital stated with no currency is stated in the company''s own. The alternative was a literal in the schema, which is one country''s answer given to every country.';
117
+
118
+ -- ---------------------------------------------------------------------------
119
+ -- The IBAN a sales document carries
120
+ --
121
+ -- A trigger and not a default on the column, for the reason the account of a
122
+ -- document line is resolved in a trigger: every client that inserts a
123
+ -- document has to get the same answer, and a client that did not know about
124
+ -- the company default would produce an invoice nobody can pay.
125
+ --
126
+ -- Only on what the company issues. On a purchase invoice the payee is the
127
+ -- supplier, and filling our own IBAN in there would be writing the wrong
128
+ -- fact — worse than an empty column, because it looks right.
129
+ -- ---------------------------------------------------------------------------
130
+
131
+ create or replace function documents_default_payee_iban()
132
+ returns trigger
133
+ language plpgsql
134
+ as $$
135
+ declare
136
+ v_iban text;
137
+ begin
138
+ if new.payee_iban is null and new.doc_type::text like 'sale%' then
139
+ select b.iban into v_iban
140
+ from companies c
141
+ join bank_accounts b on b.id = c.default_bank_account_id
142
+ where c.id = new.company_id;
143
+ new.payee_iban := v_iban;
144
+ end if;
145
+ return new;
146
+ end;
147
+ $$;
148
+
149
+ create trigger documents_default_payee_iban
150
+ before insert on documents
151
+ for each row execute function documents_default_payee_iban();
152
+
153
+ comment on function documents_default_payee_iban() is
154
+ 'A sales document with no payee IBAN takes the company''s default bank account. A purchase document never does: the payee there is somebody else.';
155
+
156
+ -- ---------------------------------------------------------------------------
157
+ -- document_header — everything a renderer needs, in one read
158
+ --
159
+ -- The lines are `document_line_items`, the sentences are
160
+ -- `document_legal_mentions`, and the third read a renderer had to invent for
161
+ -- itself was the header: who issues, who receives, what is owed, where it is
162
+ -- paid, and what the country of the document requires of it. Three views,
163
+ -- three selects, and no client holding a copy of the company's letterhead.
164
+ --
165
+ -- `security_invoker`, like the other two: what a person may see through it is
166
+ -- what they may see under it.
167
+ -- ---------------------------------------------------------------------------
168
+
169
+ create or replace view document_header
170
+ with (security_invoker = true) as
171
+ select d.id as document_id,
172
+ d.company_id,
173
+ d.doc_type,
174
+ d.state,
175
+ d.payment_state,
176
+ d.number,
177
+ d.supplier_reference,
178
+ d.document_date,
179
+ d.accounting_date,
180
+ d.due_date,
181
+ d.delivery_date,
182
+ d.currency_code,
183
+ d.amount_untaxed,
184
+ d.amount_tax,
185
+ d.amount_total,
186
+ d.amount_paid,
187
+ d.amount_residual,
188
+ d.payment_terms,
189
+ d.payment_means_code,
190
+ d.payment_reference,
191
+ d.buyer_reference,
192
+ d.order_reference,
193
+ d.contract_reference,
194
+ d.project_reference,
195
+ d.note,
196
+ -- BT-84: what the document says, else what the company's default
197
+ -- bank account says. The trigger fills it on the way in, so the
198
+ -- coalesce is what keeps a document written before this migration
199
+ -- true as well.
200
+ coalesce(d.payee_iban, seller_bank.iban) as payee_iban,
201
+ seller_bank.bic as payee_bic,
202
+
203
+ -- The seller: this company.
204
+ coalesce(c.trade_name, c.name) as seller_name,
205
+ c.legal_name as seller_legal_name,
206
+ c.legal_form as seller_legal_form,
207
+ c.vat_number as seller_vat_number,
208
+ c.registration_number as seller_registration_number,
209
+ c.address_line1 as seller_address_line1,
210
+ c.address_line2 as seller_address_line2,
211
+ c.postal_code as seller_postal_code,
212
+ c.city as seller_city,
213
+ c.country as seller_country,
214
+ c.region as seller_region,
215
+ c.email as seller_email,
216
+ c.phone as seller_phone,
217
+ c.website as seller_website,
218
+ c.logo_url as seller_logo_url,
219
+ c.share_capital as seller_share_capital,
220
+ c.share_capital_currency as seller_share_capital_currency,
221
+ c.activity_code as seller_activity_code,
222
+ c.activity_scheme as seller_activity_scheme,
223
+ c.document_template,
224
+
225
+ -- The buyer: the contact the document is written against.
226
+ ct.id as buyer_id,
227
+ ct.name as buyer_name,
228
+ ct.vat_number as buyer_vat_number,
229
+ ct.registration_number as buyer_registration_number,
230
+ ct.address_line1 as buyer_address_line1,
231
+ ct.address_line2 as buyer_address_line2,
232
+ ct.postal_code as buyer_postal_code,
233
+ ct.city as buyer_city,
234
+ ct.country as buyer_country,
235
+ ct.region as buyer_region,
236
+ ct.email as buyer_email,
237
+
238
+ -- What the country of the document requires. Its country is the
239
+ -- company's fiscal_country — the country whose VAT rules apply — and
240
+ -- not its address, which is the same distinction
241
+ -- document_legal_mentions makes.
242
+ c.fiscal_country as country,
243
+ cd.number_format,
244
+ cd.numbering_gapless,
245
+ cd.legal_payment_days,
246
+ cd.late_payment_reference,
247
+ cd.tax_point_rule,
248
+ cd.einvoice_profile,
249
+ cd.einvoice_mandatory_from,
250
+ cd.party_scheme,
251
+ cd.vat_scheme
252
+ from documents d
253
+ join companies c on c.id = d.company_id
254
+ join contacts ct on ct.id = d.contact_id
255
+ left join bank_accounts seller_bank on seller_bank.id = c.default_bank_account_id
256
+ left join country_defaults cd on cd.country = c.fiscal_country;
257
+
258
+ comment on view document_header is
259
+ 'One document with everything printed above its lines: the seller, the buyer, the amounts, where it is paid and what its country requires. The lines are document_line_items and the sentences are document_legal_mentions.';
260
+
261
+ revoke execute on all functions in schema public from public;
@@ -0,0 +1,235 @@
1
+ -- Ekwo OS — the number a country asked for, instead of the one we built.
2
+ --
3
+ -- P0-7 put `number_format` and `numbering_gapless` on the country model and
4
+ -- said, in as many words, that `next_entry_number()` did not read them: "a
5
+ -- numbering engine that consumes a format is its own piece of work, and both
6
+ -- packs declare exactly the pattern the engine already produces, so nothing
7
+ -- moves under anybody's feet the day it lands." This is that piece of work.
8
+ --
9
+ -- **The grammar is the one already published**, in the comment on the column
10
+ -- and in `packs/schema/pack.1.json`, and it is not reinvented here:
11
+ --
12
+ -- {CODE} the journal code
13
+ -- {YYYY} the year, four digits — {YY} for two
14
+ -- {MM} the month, two digits
15
+ -- {NNNN} the counter, padded to as many N as are written
16
+ --
17
+ -- **There is no fallback.** A pack that declares no format gets
18
+ -- `no_number_format`, naming `documents.number_format` — the field it has to
19
+ -- fill — rather than `CODE/YYYY/NNNN`, which is Belgium's and France's answer
20
+ -- handed to a country that has not spoken. It is the same rule `closing_style`
21
+ -- and `fiscal_year_default` already keep, and the reason is the one P0-8 gave:
22
+ -- a default is one country's law given to every country that has not said.
23
+ --
24
+ -- **The counter follows the pattern.** A pattern that carries the year
25
+ -- restarts with it, which is what the four numbering styles of the pack
26
+ -- format compile to; a pattern that carries none counts on for the life of
27
+ -- the journal, and that series is kept under year 0 in `journal_sequences` —
28
+ -- the counter is keyed by journal and period, and 0 is the period that is not
29
+ -- a year. A `{MM}` in the pattern **prints** the month and does not restart
30
+ -- the counter: a monthly series is a fifth style, no pack declares one, and
31
+ -- inventing the behaviour before a pack asks for it is how a guess becomes a
32
+ -- rule.
33
+ --
34
+ -- **`numbering_gapless` gets its reader too**, and it is `post_entry()`: where
35
+ -- the law forbids a hole in the sequence, an entry may not be posted with a
36
+ -- number chosen by hand, because a number that skips the counter is exactly
37
+ -- how a hole appears. The core has no path that imports entries under their
38
+ -- old numbers — an opening balance is a trial balance, not a journal — so
39
+ -- nothing that exists is refused by this. The day such an import is written,
40
+ -- this is the rule it will have to argue with.
41
+
42
+ -- ---------------------------------------------------------------------------
43
+ -- One reader for both columns
44
+ -- ---------------------------------------------------------------------------
45
+
46
+ create or replace function numbering_rules(
47
+ p_company_id uuid,
48
+ out number_format text,
49
+ out numbering_gapless boolean
50
+ )
51
+ language sql
52
+ stable
53
+ as $$
54
+ select d.number_format, coalesce(d.numbering_gapless, false)
55
+ from companies c
56
+ left join country_defaults d on d.country = c.fiscal_country
57
+ where c.id = p_company_id;
58
+ $$;
59
+
60
+ comment on function numbering_rules(uuid) is
61
+ 'What the country of a company says about its document numbers: the pattern, and whether the law forbids a hole. The only function that reads either column.';
62
+
63
+ -- ---------------------------------------------------------------------------
64
+ -- Rendering one number
65
+ --
66
+ -- Separate from `next_entry_number()` so that the pattern can be tested
67
+ -- without burning a counter, and so a document series of its own — which is
68
+ -- not in this release — has the same renderer rather than a second one.
69
+ -- ---------------------------------------------------------------------------
70
+
71
+ create or replace function format_number(p_format text, p_code text, p_date date, p_number integer)
72
+ returns text
73
+ language plpgsql
74
+ immutable
75
+ as $$
76
+ declare
77
+ v_out text := p_format;
78
+ v_token text;
79
+ v_width integer;
80
+ v_digits text := p_number::text;
81
+ v_left text;
82
+ begin
83
+ if p_format is null or p_format = '' then
84
+ raise exception 'no_number_format: this country declares no documents.number_format, and there is no default to fall back on';
85
+ end if;
86
+
87
+ v_out := replace(v_out, '{CODE}', coalesce(p_code, ''));
88
+ v_out := replace(v_out, '{YYYY}', to_char(p_date, 'YYYY'));
89
+ v_out := replace(v_out, '{YY}', to_char(p_date, 'YY'));
90
+ v_out := replace(v_out, '{MM}', to_char(p_date, 'MM'));
91
+
92
+ v_token := (regexp_match(v_out, '\{N+\}'))[1];
93
+ if v_token is null then
94
+ raise exception 'number_format_without_counter: % carries no {N...} counter, so every document would be numbered the same', p_format;
95
+ end if;
96
+
97
+ -- Padded to the width the pattern asks for, and never truncated to it: a
98
+ -- counter that has outgrown its padding is a longer number, not a wrong one.
99
+ v_width := length(v_token) - 2;
100
+ v_out := replace(v_out, v_token,
101
+ case when length(v_digits) >= v_width then v_digits
102
+ else lpad(v_digits, v_width, '0') end);
103
+
104
+ v_left := (regexp_match(v_out, '\{[^}]*\}'))[1];
105
+ if v_left is not null then
106
+ raise exception 'unknown_number_token: % is not a token of the number format grammar ({CODE}, {YYYY}, {YY}, {MM}, {N...})', v_left;
107
+ end if;
108
+
109
+ return v_out;
110
+ end;
111
+ $$;
112
+
113
+ comment on function format_number(text, text, date, integer) is
114
+ 'One document number, rendered from the pattern the country pack declares. Raises rather than guessing at a token it does not know.';
115
+
116
+ -- ---------------------------------------------------------------------------
117
+ -- next_entry_number, on the pattern
118
+ -- ---------------------------------------------------------------------------
119
+
120
+ create or replace function next_entry_number(p_journal_id uuid, p_date date)
121
+ returns text
122
+ language plpgsql
123
+ security definer
124
+ set search_path = public, pg_temp
125
+ as $$
126
+ declare
127
+ v_code text;
128
+ v_company uuid;
129
+ v_format text;
130
+ v_period smallint;
131
+ v_number integer;
132
+ begin
133
+ select j.code, j.company_id into v_code, v_company from journals j where j.id = p_journal_id;
134
+ if v_code is null then
135
+ raise exception 'unknown_journal: journal % does not exist', p_journal_id;
136
+ end if;
137
+
138
+ if auth.uid() is not null and not has_capability(v_company, 'entries.post') then
139
+ raise exception 'not_allowed: drawing a number in this company needs entries.post'
140
+ using errcode = '42501';
141
+ end if;
142
+
143
+ select number_format into v_format from numbering_rules(v_company);
144
+ if v_format is null or v_format = '' then
145
+ raise exception 'no_number_format: the country pack of this company declares no documents.number_format, and there is no default to fall back on';
146
+ end if;
147
+
148
+ -- A pattern that carries the year restarts with it; one that does not is a
149
+ -- single series, kept under the period that is not a year.
150
+ v_period := case when v_format ~ '\{(YYYY|YY)\}'
151
+ then extract(year from p_date)::smallint
152
+ else 0::smallint end;
153
+
154
+ insert into journal_sequences (journal_id, year, last_number)
155
+ values (p_journal_id, v_period, 1)
156
+ on conflict (journal_id, year)
157
+ do update set last_number = journal_sequences.last_number + 1
158
+ returning last_number into v_number;
159
+
160
+ return format_number(v_format, v_code, p_date, v_number);
161
+ end;
162
+ $$;
163
+
164
+ comment on function next_entry_number(uuid, date) is
165
+ 'Next number for a journal, on the pattern the country pack declares. Atomic: the counter row is locked, not the journal. Definer, because the counter is infrastructure and nobody writes it by hand.';
166
+
167
+ comment on column journal_sequences.year is
168
+ 'The period the counter belongs to: the year where the pattern carries one, and 0 where it does not and the series runs on.';
169
+
170
+ -- ---------------------------------------------------------------------------
171
+ -- post_entry, reading numbering_gapless
172
+ --
173
+ -- Unchanged but for the guard: everything else is the function as published.
174
+ -- ---------------------------------------------------------------------------
175
+
176
+ create or replace function post_entry(p_entry_id uuid)
177
+ returns entries
178
+ language plpgsql
179
+ as $$
180
+ declare
181
+ v_entry entries%rowtype;
182
+ v_lines integer;
183
+ v_gapless boolean;
184
+ begin
185
+ select * into v_entry from entries where id = p_entry_id for update;
186
+ if not found then
187
+ raise exception 'unknown_entry: entry % does not exist', p_entry_id;
188
+ end if;
189
+ if v_entry.state = 'posted' then
190
+ return v_entry;
191
+ end if;
192
+ if v_entry.state = 'cancelled' then
193
+ raise exception 'entry_cancelled: entry % cannot be posted', p_entry_id;
194
+ end if;
195
+
196
+ select count(*) into v_lines from entry_lines where entry_id = p_entry_id;
197
+ if v_lines = 0 then
198
+ raise exception 'entry_empty: entry % has no lines', p_entry_id;
199
+ end if;
200
+
201
+ -- Re-read the totals maintained by the line trigger.
202
+ select * into v_entry from entries where id = p_entry_id;
203
+ if v_entry.total_debit <> v_entry.total_credit then
204
+ raise exception 'entry_unbalanced: entry % has debit % and credit %',
205
+ p_entry_id, v_entry.total_debit, v_entry.total_credit;
206
+ end if;
207
+
208
+ -- Where the law forbids a hole, the number comes from the counter and from
209
+ -- nowhere else. A number chosen by hand is how a sequence acquires one.
210
+ if v_entry.number is not null then
211
+ select numbering_gapless into v_gapless from numbering_rules(v_entry.company_id);
212
+ if v_gapless then
213
+ raise exception 'numbering_gapless: this country forbids a hole in the sequence, so entry % may not be posted under a number chosen by hand. Leave entries.number empty and the journal counter draws it',
214
+ p_entry_id;
215
+ end if;
216
+ end if;
217
+
218
+ perform assert_period_open(v_entry.company_id, v_entry.entry_date, true);
219
+
220
+ update entries
221
+ set number = coalesce(number, next_entry_number(journal_id, entry_date)),
222
+ fiscal_year_id = coalesce(fiscal_year_id, fiscal_year_at(company_id, entry_date)),
223
+ state = 'posted',
224
+ posted_at = now()
225
+ where id = p_entry_id
226
+ returning * into v_entry;
227
+
228
+ return v_entry;
229
+ end;
230
+ $$;
231
+
232
+ comment on function post_entry(uuid) is
233
+ 'Validates, numbers and posts an entry. Raises rather than warning: a swallowed error is a missing entry. Where the country forbids a hole in the sequence, it refuses a number chosen by hand.';
234
+
235
+ revoke execute on all functions in schema public from public;