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,41 @@
1
+ -- Ekwo module `assets` — its tables leave with the company.
2
+ --
3
+ -- The socle writes an archive of one company from a registry of tables, and
4
+ -- refuses to write one while a table that belongs to a company is
5
+ -- unclassified. A module answers for its own through `<schema>.archive_tables()`,
6
+ -- looked up by the socle the way `can_disable()` is — a function in this schema
7
+ -- and not rows in a table of the socle, because this migration may be applied
8
+ -- on a socle that does not have that table yet.
9
+ --
10
+ -- All three tables travel. The register and the schedule are the company's,
11
+ -- and a depreciation line points at the entry it posted: left behind, the
12
+ -- ledger would arrive with entries tagged `assets` that nothing explains.
13
+ -- `category_templates` and `country_rules` are reference data of the
14
+ -- installation and belong to no company.
15
+ --
16
+ -- `load_order` is relative to this module; the socle places every module after
17
+ -- its own tables.
18
+
19
+ create or replace function assets.archive_tables()
20
+ returns table (
21
+ table_name text,
22
+ disposition text,
23
+ reason text,
24
+ via_column text,
25
+ via_table text,
26
+ load_order integer
27
+ )
28
+ language sql
29
+ immutable
30
+ as $$
31
+ values
32
+ ('assets'::text, 'exported'::text, null::text, null::text, null::text, 1),
33
+ ('depreciation_lines', 'exported', null, null, null, 2),
34
+ ('disposals', 'exported', null, null, null, 3);
35
+ $$;
36
+
37
+ comment on function assets.archive_tables() is
38
+ 'What an archive of one company does with each table of this module. Read by `public.company_archive_tables()`.';
39
+
40
+ revoke execute on function assets.archive_tables() from public, anon;
41
+ grant execute on function assets.archive_tables() to authenticated, service_role;
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://ekwo.ai/schemas/module/1.json",
3
+ "code": "budgets",
4
+ "name": "Budgets",
5
+ "description": "A budget per financial year, its lines per account and period, and the variance against what the ledger actually holds. Reads the socle and writes nothing to it.",
6
+ "schema": "budgets",
7
+ "version": "1.0.0",
8
+ "status": "available",
9
+ "requires_socle_min": "20260913074512",
10
+ "posts": false,
11
+ "mcp": { "prefix": "budgets" }
12
+ }
@@ -0,0 +1,210 @@
1
+ -- Ekwo — the `budgets` module: what a company planned, against what it booked.
2
+ --
3
+ -- The second module, and the one that proves the mechanism holds for a module
4
+ -- that is not like the first. It has **no country data at all** — a budget is a
5
+ -- decision a business takes, not a rule a country writes — and it **never
6
+ -- writes to the ledger**: it reads `public.entry_lines` and compares. So there
7
+ -- is no pack section, no seed, no call to `post_module_entry()`, and
8
+ -- `module.json` says `"posts": false`, which a test holds it to.
9
+ --
10
+ -- It also deliberately writes **no `budgets.can_disable()`**. The convention
11
+ -- `disable_module()` follows is to look for that function and allow the
12
+ -- disable when there is none, and this is the module that exercises the
13
+ -- absence: turning budgets off takes nothing away, because the rows stay where
14
+ -- they are and come back the moment it is turned on again. Row level security
15
+ -- is what hides them in between, which is the whole meaning of
16
+ -- `module_enabled()` sitting in every policy.
17
+ --
18
+ -- **The sign.** A budget is stated the way a business says it out loud: an
19
+ -- income of 100 000 and a cost of 60 000 are both positive numbers. The ledger
20
+ -- does not work that way — an income account carries a credit balance — so the
21
+ -- comparison multiplies the ledger balance by −1 on an income account and by
22
+ -- +1 everywhere else. That is one rule, it comes from `accounts.internal_group`
23
+ -- rather than from a column somebody fills in, and it is what the eighteen
24
+ -- account types are for.
25
+ --
26
+ -- **What counts as actual.** Posted entries, and only the ones that are
27
+ -- `kind = 'normal'`. A closing entry is the mirror image of the year and an
28
+ -- appropriation entry moves its result; neither is something a budget planned,
29
+ -- and leaving them in would make a closed year read as a variance of exactly
30
+ -- minus the budget. That is the same exclusion `financial_statement()` makes on
31
+ -- an income statement, for the same reason.
32
+
33
+ create schema budgets;
34
+
35
+ comment on schema budgets is
36
+ 'Ekwo module `budgets`: what a company planned, per account and period, against what its ledger holds. Reads the socle, writes nothing to it.';
37
+
38
+ create type budgets.budget_state as enum ('draft', 'approved', 'closed');
39
+
40
+ comment on type budgets.budget_state is
41
+ 'draft while it is being written, approved once it is the plan, closed when the period it covers is behind. It gates nothing in this module: a variance is a reading, and reading a draft is useful.';
42
+
43
+ create table budgets.budgets (
44
+ id uuid primary key default gen_random_uuid(),
45
+ company_id uuid not null references public.companies(id) on delete cascade,
46
+ fiscal_year_id uuid references public.fiscal_years(id) on delete restrict,
47
+ code text not null,
48
+ name text not null,
49
+ state budgets.budget_state not null default 'draft',
50
+ notes text,
51
+ created_at timestamptz not null default now(),
52
+ updated_at timestamptz not null default now(),
53
+ unique (company_id, code),
54
+ foreign key (fiscal_year_id) references public.fiscal_years(id)
55
+ );
56
+
57
+ comment on table budgets.budgets is
58
+ 'One budget of one company, usually for one financial year. A company may hold several — a plan and a revision are two budgets and not two columns.';
59
+ comment on column budgets.budgets.fiscal_year_id is
60
+ 'The year this budget is for, where it is for one. Null on a rolling budget, whose lines carry their own periods anyway.';
61
+
62
+ create unique index budgets_id_company_idx on budgets.budgets (id, company_id);
63
+
64
+ create trigger budgets_set_updated_at
65
+ before update on budgets.budgets
66
+ for each row execute function public.set_updated_at();
67
+
68
+ create table budgets.lines (
69
+ id uuid primary key default gen_random_uuid(),
70
+ budget_id uuid not null references budgets.budgets(id) on delete cascade,
71
+ company_id uuid not null references public.companies(id) on delete cascade,
72
+ account_id uuid not null references public.accounts(id) on delete restrict,
73
+ period_start date not null,
74
+ period_end date not null,
75
+ amount numeric(16, 2) not null,
76
+ note text,
77
+ created_at timestamptz not null default now(),
78
+ updated_at timestamptz not null default now(),
79
+ -- One line per account and period. A second figure for the same month on the
80
+ -- same account is a revision, and a revision is a budget of its own.
81
+ unique (budget_id, account_id, period_start, period_end),
82
+ constraint budgets_lines_period check (period_end >= period_start),
83
+ foreign key (budget_id, company_id) references budgets.budgets(id, company_id) on delete cascade,
84
+ foreign key (account_id, company_id) references public.accounts(id, company_id)
85
+ );
86
+
87
+ comment on table budgets.lines is
88
+ 'What one account is expected to carry over one period, in the sign a business says it: an income and a cost are both positive.';
89
+
90
+ create index budgets_lines_account_idx on budgets.lines (company_id, account_id, period_start);
91
+
92
+ create trigger budgets_lines_set_updated_at
93
+ before update on budgets.lines
94
+ for each row execute function public.set_updated_at();
95
+
96
+ -- ---------------------------------------------------------------------------
97
+ -- The reading
98
+ -- ---------------------------------------------------------------------------
99
+
100
+ create or replace function budgets.variance(
101
+ p_company_id uuid,
102
+ p_budget_id uuid,
103
+ p_from date,
104
+ p_to date
105
+ )
106
+ returns table (
107
+ account_code text,
108
+ account_name text,
109
+ budget numeric,
110
+ actual numeric,
111
+ variance numeric
112
+ )
113
+ language sql
114
+ stable
115
+ as $$
116
+ with planned as (
117
+ select l.account_id, sum(l.amount) as amount
118
+ from budgets.lines l
119
+ where l.budget_id = p_budget_id
120
+ and l.company_id = p_company_id
121
+ and l.period_start >= p_from
122
+ and l.period_end <= p_to
123
+ group by l.account_id
124
+ ),
125
+ booked as (
126
+ select l.account_id,
127
+ sum((l.debit - l.credit) * case when a.internal_group = 'income' then -1 else 1 end) as amount
128
+ from public.entry_lines l
129
+ join public.entries e on e.id = l.entry_id
130
+ join public.accounts a on a.id = l.account_id
131
+ where l.company_id = p_company_id
132
+ and e.state = 'posted'
133
+ and e.kind = 'normal'
134
+ and e.entry_date between p_from and p_to
135
+ and l.account_id in (select account_id from planned)
136
+ group by l.account_id
137
+ )
138
+ select a.code,
139
+ a.name,
140
+ coalesce(p.amount, 0)::numeric(16, 2),
141
+ coalesce(b.amount, 0)::numeric(16, 2),
142
+ (coalesce(b.amount, 0) - coalesce(p.amount, 0))::numeric(16, 2)
143
+ from planned p
144
+ join public.accounts a on a.id = p.account_id
145
+ left join booked b on b.account_id = p.account_id
146
+ order by a.code;
147
+ $$;
148
+
149
+ comment on function budgets.variance(uuid, uuid, date, date) is
150
+ 'Budget against ledger, per account, over a period. Both figures are in the sign a business states them in — an income account''s credit balance is flipped — and the variance is the actual less the plan. Reads posted entries of kind `normal` only: a closing or appropriation entry is not what a period earned.';
151
+
152
+ -- ---------------------------------------------------------------------------
153
+ -- Row level security
154
+ -- ---------------------------------------------------------------------------
155
+
156
+ alter table budgets.budgets enable row level security;
157
+ alter table budgets.lines enable row level security;
158
+
159
+ create policy budgets_select on budgets.budgets
160
+ for select using (public.module_enabled(company_id, 'budgets'));
161
+ create policy budgets_write on budgets.budgets
162
+ for all using (public.module_enabled(company_id, 'budgets') and public.can_write_company(company_id))
163
+ with check (public.module_enabled(company_id, 'budgets') and public.can_write_company(company_id));
164
+
165
+ create policy budgets_lines_select on budgets.lines
166
+ for select using (public.module_enabled(company_id, 'budgets'));
167
+ create policy budgets_lines_write on budgets.lines
168
+ for all using (public.module_enabled(company_id, 'budgets') and public.can_write_company(company_id))
169
+ with check (public.module_enabled(company_id, 'budgets') and public.can_write_company(company_id));
170
+
171
+ -- ---------------------------------------------------------------------------
172
+ -- Privileges — a module schema does its own, because `public` gets them from
173
+ -- Supabase's default privileges and a schema a migration created gets nothing.
174
+ -- ---------------------------------------------------------------------------
175
+
176
+ grant usage on schema budgets to anon, authenticated, service_role;
177
+
178
+ grant select on all tables in schema budgets to anon;
179
+ grant select, insert, update, delete on all tables in schema budgets to authenticated, service_role;
180
+ grant execute on all functions in schema budgets to authenticated, service_role;
181
+
182
+ alter default privileges in schema budgets grant select on tables to anon;
183
+ alter default privileges in schema budgets
184
+ grant select, insert, update, delete on tables to authenticated, service_role;
185
+ alter default privileges in schema budgets revoke execute on functions from public, anon;
186
+ alter default privileges in schema budgets grant execute on functions to authenticated, service_role;
187
+
188
+ revoke execute on all functions in schema budgets from public;
189
+
190
+ -- ---------------------------------------------------------------------------
191
+ -- The registry row
192
+ -- ---------------------------------------------------------------------------
193
+
194
+ insert into public.modules (code, name, description, schema_name, version, status, requires_socle_min)
195
+ values (
196
+ 'budgets',
197
+ 'Budgets',
198
+ 'A budget per financial year, its lines per account and period, and the variance against what the ledger actually holds. No country data, and nothing written to the ledger.',
199
+ 'budgets',
200
+ '1.0.0',
201
+ 'available',
202
+ '20260913074512'
203
+ )
204
+ on conflict (code) do update set
205
+ name = excluded.name,
206
+ description = excluded.description,
207
+ schema_name = excluded.schema_name,
208
+ version = excluded.version,
209
+ status = excluded.status,
210
+ requires_socle_min = excluded.requires_socle_min;
@@ -0,0 +1,37 @@
1
+ -- Ekwo OS — a foreign key without an index is a sequential scan waiting for
2
+ -- a big enough table.
3
+ --
4
+ -- Postgres indexes the *referenced* side of a foreign key, because that side
5
+ -- is a primary key. It indexes nothing on the referencing side. Two things
6
+ -- then read the whole table:
7
+ --
8
+ -- * every delete or key update of the parent, which has to prove no child
9
+ -- points at the row — deleting one contact scans `entry_lines`;
10
+ -- * every join written the natural way, which for an accounting core is
11
+ -- most of them: a document to its lines, an entry to its lines, a line to
12
+ -- its account, its tax, its contact.
13
+ --
14
+ -- On the demo company nothing is slow, which is exactly why this survived 49
15
+ -- migrations. On a company with four years of books it is the difference
16
+ -- between a report and a timeout.
17
+ --
18
+ -- 3 indexes: every foreign key of the `budgets` module that had none, and the
19
+ -- `company_id` of the tables that had none either — which the sweep covers,
20
+ -- because `company_id` is itself a foreign key everywhere it appears.
21
+ --
22
+ -- Where a table has both a single-column key and a composite one leading with
23
+ -- the same column — `(account_id)` and `(account_id, company_id)`, the shape
24
+ -- this schema uses to keep a child in its parent's company — one index on the
25
+ -- composite serves both, and that is the one created.
26
+ --
27
+ -- The list is not maintained by hand. `tests/schema.test.ts` asks the
28
+ -- catalogue the same question and fails when the answer is not empty, so a
29
+ -- foreign key added later arrives with its index or the build says so.
30
+
31
+
32
+ -- budgets.budgets
33
+ create index if not exists budgets_fiscal_year_idx on budgets.budgets (fiscal_year_id);
34
+
35
+ -- budgets.lines
36
+ create index if not exists lines_account_company_idx on budgets.lines (account_id, company_id);
37
+ create index if not exists lines_budget_company_idx on budgets.lines (budget_id, company_id);
@@ -0,0 +1,72 @@
1
+ -- Ekwo module `budgets` — the module names what it lets somebody do.
2
+ --
3
+ -- Its policies asked `public.can_write_company()`, which is `entries.write`:
4
+ -- whoever may draft a journal entry could also write next year's budget. A
5
+ -- budget is not a book — it is written by whoever plans, read by whoever
6
+ -- reports, and it is the one thing in an installation that is deliberately
7
+ -- not the truth. Sharing a lock with the ledger is the wrong shape.
8
+ --
9
+ -- budgets.read — see the budgets and their variance.
10
+ -- budgets.write — create and change a budget and its lines.
11
+ --
12
+ -- There is no `budgets.post`: this module writes nothing to the ledger, which
13
+ -- its manifest says (`"posts": false`) and a test of the socle enforces.
14
+ --
15
+ -- The presets follow the socle's. The owner preset was filled with `select
16
+ -- 'owner', code from capabilities` at the socle's own migration time, so a
17
+ -- code added later has to name the owner itself.
18
+
19
+ insert into public.capabilities (code, area, description) values
20
+ ('budgets.read', 'budgets', 'Read the budgets of a company and their variance against the ledger.'),
21
+ ('budgets.write', 'budgets', 'Create and change a budget and its lines.')
22
+ on conflict (code) do update set area = excluded.area, description = excluded.description;
23
+
24
+ insert into public.role_capabilities (role, capability) values
25
+ ('viewer'::public.member_role, 'budgets.read'),
26
+ ('accountant'::public.member_role, 'budgets.read'),
27
+ ('accountant'::public.member_role, 'budgets.write'),
28
+ ('owner'::public.member_role, 'budgets.read'),
29
+ ('owner'::public.member_role, 'budgets.write')
30
+ on conflict do nothing;
31
+
32
+ -- `module_enabled()` stays in front of every policy: a capability says what a
33
+ -- person may do, and the module being enabled says whether the company has
34
+ -- this at all.
35
+
36
+ drop policy budgets_select on budgets.budgets;
37
+ create policy budgets_select on budgets.budgets
38
+ for select using (
39
+ public.module_enabled(company_id, 'budgets')
40
+ and public.has_capability(company_id, 'budgets.read')
41
+ );
42
+
43
+ drop policy budgets_write on budgets.budgets;
44
+ create policy budgets_write on budgets.budgets
45
+ for all using (
46
+ public.module_enabled(company_id, 'budgets')
47
+ and public.has_capability(company_id, 'budgets.write')
48
+ )
49
+ with check (
50
+ public.module_enabled(company_id, 'budgets')
51
+ and public.has_capability(company_id, 'budgets.write')
52
+ );
53
+
54
+ drop policy budgets_lines_select on budgets.lines;
55
+ create policy budgets_lines_select on budgets.lines
56
+ for select using (
57
+ public.module_enabled(company_id, 'budgets')
58
+ and public.has_capability(company_id, 'budgets.read')
59
+ );
60
+
61
+ drop policy budgets_lines_write on budgets.lines;
62
+ create policy budgets_lines_write on budgets.lines
63
+ for all using (
64
+ public.module_enabled(company_id, 'budgets')
65
+ and public.has_capability(company_id, 'budgets.write')
66
+ )
67
+ with check (
68
+ public.module_enabled(company_id, 'budgets')
69
+ and public.has_capability(company_id, 'budgets.write')
70
+ );
71
+
72
+ revoke execute on all functions in schema budgets from public;
@@ -0,0 +1,68 @@
1
+ -- Ekwo OS (budgets) — a plan and what was booked against it are written at
2
+ -- the decimals of the company's currency.
3
+ --
4
+ -- `budgets.variance()` cast its three figures to `numeric(16, 2)`, which is a
5
+ -- rounding to two decimals wearing the clothes of a type. A plan stated in a
6
+ -- currency with no decimals came back with two of them, and the variance
7
+ -- between a plan and a ledger that both hold whole units read as a fraction.
8
+ --
9
+ -- The three casts become `public.round_amount`, which asks the company what
10
+ -- its currency is. Nothing else about the reading changes: the sign a business
11
+ -- states a figure in, and the closing entries left out of it, are as they were.
12
+
13
+ create or replace function budgets.variance(
14
+ p_company_id uuid,
15
+ p_budget_id uuid,
16
+ p_from date,
17
+ p_to date
18
+ )
19
+ returns table (
20
+ account_code text,
21
+ account_name text,
22
+ budget numeric,
23
+ actual numeric,
24
+ variance numeric
25
+ )
26
+ language sql
27
+ stable
28
+ as $$
29
+ with planned as (
30
+ select l.account_id, sum(l.amount) as amount
31
+ from budgets.lines l
32
+ where l.budget_id = p_budget_id
33
+ and l.company_id = p_company_id
34
+ and l.period_start >= p_from
35
+ and l.period_end <= p_to
36
+ group by l.account_id
37
+ ),
38
+ booked as (
39
+ select l.account_id,
40
+ sum((l.debit - l.credit) * case when a.internal_group = 'income' then -1 else 1 end) as amount
41
+ from public.entry_lines l
42
+ join public.entries e on e.id = l.entry_id
43
+ join public.accounts a on a.id = l.account_id
44
+ where l.company_id = p_company_id
45
+ and e.state = 'posted'
46
+ and e.kind = 'normal'
47
+ and e.entry_date between p_from and p_to
48
+ and l.account_id in (select account_id from planned)
49
+ group by l.account_id
50
+ )
51
+ select a.code,
52
+ a.name,
53
+ public.round_amount(coalesce(p.amount, 0), r.rounding),
54
+ public.round_amount(coalesce(b.amount, 0), r.rounding),
55
+ public.round_amount(coalesce(b.amount, 0) - coalesce(p.amount, 0), r.rounding)
56
+ from planned p
57
+ join public.accounts a on a.id = p.account_id
58
+ left join booked b on b.account_id = p.account_id
59
+ cross join (select public.rounding_of(p_company_id) as rounding) r
60
+ order by a.code;
61
+ $$;
62
+
63
+
64
+ comment on function budgets.variance(uuid, uuid, date, date) is
65
+ 'Budget against ledger, per account, over a period, at the decimals of the company''s currency. Both figures are in the sign a business states them in — an income account''s credit balance is flipped — and the variance is the actual less the plan. Reads posted entries of kind `normal` only: a closing or appropriation entry is not what a period earned.';
66
+
67
+
68
+ revoke execute on all functions in schema budgets from public;
@@ -0,0 +1,30 @@
1
+ -- The `budgets` module answers which accounts of a company it holds.
2
+ --
3
+ -- Same convention as `assets`: `public.accounts_in_use()` asks each module the
4
+ -- company has enabled for `<schema>.accounts_in_use(uuid)` rather than naming
5
+ -- the schema itself, so the socle keeps ignoring what is built beside it.
6
+ --
7
+ -- A budget line is a planned amount on an account, and an account somebody has
8
+ -- budgeted for is an account they mean to use — which is the whole case for
9
+ -- counting it before anything is booked on it.
10
+ --
11
+ -- Security invoker: the policies of `budgets.lines` decide, and a caller who
12
+ -- is not a member of the company sees nothing.
13
+
14
+ create or replace function budgets.accounts_in_use(p_company_id uuid)
15
+ returns setof uuid
16
+ language sql
17
+ stable
18
+ as $$
19
+ select distinct l.account_id
20
+ from budgets.lines l
21
+ where l.company_id = p_company_id;
22
+ $$;
23
+
24
+ comment on function budgets.accounts_in_use(uuid) is
25
+ 'The accounts this module points at for one company: every account a budget line plans an amount on. Read by public.accounts_in_use() through the module convention.';
26
+
27
+ revoke execute on function budgets.accounts_in_use(uuid) from public, anon;
28
+ grant execute on function budgets.accounts_in_use(uuid) to authenticated, service_role;
29
+
30
+ revoke execute on all functions in schema budgets from public;
@@ -0,0 +1,31 @@
1
+ -- The `budgets` module grants its own rights, by name.
2
+ --
3
+ -- Same change as `20260914151207` for the socle and
4
+ -- `20260914151530` for `assets`: the privileges a module schema hands out are
5
+ -- written down, table by table, instead of being taken from a wildcard or
6
+ -- from the project's default privileges.
7
+ --
8
+ -- `20260913083012` granted `select on all tables in schema budgets to anon`.
9
+ -- Row level security answered every such read with an empty set, so nothing
10
+ -- leaked, and the doctrine of `20260911210131` still says the anonymous role
11
+ -- reaches the policy helpers and nothing else. Published migrations are never
12
+ -- edited, so it is corrected here.
13
+
14
+ revoke all on all tables in schema budgets from anon, authenticated, service_role;
15
+ revoke all on all sequences in schema budgets from anon, authenticated, service_role;
16
+
17
+ alter default privileges in schema budgets revoke all on tables from anon, authenticated, service_role;
18
+ alter default privileges in schema budgets revoke all on sequences from anon, authenticated, service_role;
19
+ alter default privileges in schema budgets revoke execute on functions from public, anon, authenticated, service_role;
20
+
21
+ -- Both tables carry a policy `for all`: a budget and its lines are written by
22
+ -- the people who plan the year, and read by everyone who may read the books.
23
+ grant select, insert, update, delete on table
24
+ budgets.budgets,
25
+ budgets.lines
26
+ to authenticated, service_role;
27
+
28
+ -- `budgets.variance` keeps the grant its own migration gave it. The schema
29
+ -- has no trigger function and no sequence.
30
+
31
+ revoke execute on all functions in schema budgets from public;
@@ -0,0 +1,20 @@
1
+ -- Ekwo module `budgets` — the client preset reads this module too.
2
+ --
3
+ -- The socle's `client` preset holds what `viewer` holds, and it was filled
4
+ -- from `role_capabilities` when the socle's migration ran: on an installation
5
+ -- that already carried this module, `budgets.read` was copied then. On a fresh
6
+ -- one the socle is applied before any module, so the row has to come from
7
+ -- here.
8
+ --
9
+ -- The label is read from the catalogue rather than written as a literal. A
10
+ -- module may be applied on a socle older than the preset, where
11
+ -- `'client'::member_role` does not parse; there this inserts nothing, and the
12
+ -- socle's migration copies the row the day it arrives.
13
+
14
+ insert into public.role_capabilities (role, capability)
15
+ select e.enumlabel::text::public.member_role, 'budgets.read'
16
+ from pg_catalog.pg_enum e
17
+ join pg_catalog.pg_type t on t.oid = e.enumtypid
18
+ join pg_catalog.pg_namespace n on n.oid = t.typnamespace
19
+ where n.nspname = 'public' and t.typname = 'member_role' and e.enumlabel = 'client'
20
+ on conflict do nothing;
@@ -0,0 +1,37 @@
1
+ -- Ekwo module `budgets` — its tables leave with the company.
2
+ --
3
+ -- The socle writes an archive of one company from a registry of tables, and
4
+ -- refuses to write one while a table that belongs to a company is
5
+ -- unclassified. A module answers for its own through `<schema>.archive_tables()`,
6
+ -- looked up by the socle the way `can_disable()` is — a function in this schema
7
+ -- and not rows in a table of the socle, because this migration may be applied
8
+ -- on a socle that does not have that table yet.
9
+ --
10
+ -- A budget is a plan the company wrote against its own chart and its own
11
+ -- financial years. It posts nothing, and it is still the company's.
12
+ --
13
+ -- `load_order` is relative to this module; the socle places every module after
14
+ -- its own tables.
15
+
16
+ create or replace function budgets.archive_tables()
17
+ returns table (
18
+ table_name text,
19
+ disposition text,
20
+ reason text,
21
+ via_column text,
22
+ via_table text,
23
+ load_order integer
24
+ )
25
+ language sql
26
+ immutable
27
+ as $$
28
+ values
29
+ ('budgets'::text, 'exported'::text, null::text, null::text, null::text, 1),
30
+ ('lines', 'exported', null, null, null, 2);
31
+ $$;
32
+
33
+ comment on function budgets.archive_tables() is
34
+ 'What an archive of one company does with each table of this module. Read by `public.company_archive_tables()`.';
35
+
36
+ revoke execute on function budgets.archive_tables() from public, anon;
37
+ grant execute on function budgets.archive_tables() to authenticated, service_role;
@@ -0,0 +1,69 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ekwo.ai/schemas/module/1.json",
4
+ "title": "Ekwo module manifest, version 1",
5
+ "description": "What a module of Ekwo OS says about itself. One file, `modules/<code>/module.json`, read by `ekwo module list|enable|migrate`, by the MCP loader and by the guard tests. Everything a module *does* is in its migrations; this says where it lives and what it is allowed to reach.",
6
+ "type": "object",
7
+ "required": ["code", "name", "schema", "version", "status"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "$schema": { "type": "string" },
11
+ "code": {
12
+ "$ref": "#/$defs/identifier",
13
+ "description": "The module's identifier, and the key of `public.modules`. Immutable once published: it is written on every entry the module posts."
14
+ },
15
+ "name": { "type": "string", "minLength": 1, "maxLength": 120 },
16
+ "description": { "type": "string", "minLength": 1, "maxLength": 400 },
17
+ "schema": {
18
+ "$ref": "#/$defs/identifier",
19
+ "description": "The Postgres schema the module lives in. One schema per module, never `public`, and PostgREST only serves it once it is listed in the project's exposed schemas."
20
+ },
21
+ "version": {
22
+ "type": "string",
23
+ "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$",
24
+ "description": "Semver, on the same scale a pack uses: a label is a patch, a table or a column is a minor, a change that asks a company to do something is a major."
25
+ },
26
+ "status": {
27
+ "enum": ["draft", "available", "deprecated"],
28
+ "description": "draft: installed and refused by enable_module(). available: enableable. deprecated: the companies that hold it keep working and no new one may enable it."
29
+ },
30
+ "requires_socle_min": {
31
+ "type": "string",
32
+ "pattern": "^[0-9]{14}$",
33
+ "description": "The oldest socle migration this module needs, by its timestamp version. `ekwo module enable` compares it against the migration history and refuses rather than letting a foreign key fail halfway."
34
+ },
35
+ "posts": {
36
+ "type": "boolean",
37
+ "description": "Whether this module writes to the ledger, always through post_module_entry(). A module that says false is held to it: a test refuses post_module_entry in its migrations."
38
+ },
39
+ "mcp": {
40
+ "type": "object",
41
+ "required": ["prefix"],
42
+ "additionalProperties": false,
43
+ "properties": {
44
+ "prefix": {
45
+ "$ref": "#/$defs/identifier",
46
+ "description": "Every MCP tool of this module is named `<prefix>_<verb>`, so a model reading a tool list can tell which module answers for what."
47
+ }
48
+ }
49
+ },
50
+ "pack": {
51
+ "type": "object",
52
+ "description": "The country data this module reads, if any. A module with no `pack` section has no country rule at all — which is most of them.",
53
+ "required": ["section"],
54
+ "additionalProperties": false,
55
+ "properties": {
56
+ "section": {
57
+ "$ref": "#/$defs/identifier",
58
+ "description": "The file a country pack carries for this module: `packs/<cc>/<section>.json`, compiled by `ekwo pack build` into `supabase/seed/modules/<code>/`."
59
+ }
60
+ }
61
+ }
62
+ },
63
+ "$defs": {
64
+ "identifier": {
65
+ "type": "string",
66
+ "pattern": "^[a-z][a-z0-9_]{1,30}$"
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,15 @@
1
+ -- Ekwo OS — currencies. ISO 4217, the handful a European ledger meets.
2
+
3
+ insert into currencies (code, name, symbol, decimal_places) values
4
+ ('EUR', 'Euro', E'€', 2),
5
+ ('USD', 'US dollar', '$', 2),
6
+ ('GBP', 'Pound sterling', E'£', 2),
7
+ ('CHF', 'Swiss franc', 'CHF', 2),
8
+ ('SEK', 'Swedish krona', 'kr', 2),
9
+ ('DKK', 'Danish krone', 'kr', 2),
10
+ ('NOK', 'Norwegian krone', 'kr', 2),
11
+ ('PLN', 'Polish zloty', E'z\u0142', 2),
12
+ ('CZK', 'Czech koruna', E'Kč', 2),
13
+ ('CAD', 'Canadian dollar', '$', 2),
14
+ ('JPY', 'Japanese yen', E'¥', 0)
15
+ on conflict (code) do nothing;