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.
- package/README.md +873 -0
- package/dist/args.d.ts +57 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +134 -0
- package/dist/args.js.map +1 -0
- package/dist/assets/expected-objects.json +9432 -0
- package/dist/assets/migrations/20260911120000_core_companies.sql +260 -0
- package/dist/assets/migrations/20260911120100_accounts_journals.sql +211 -0
- package/dist/assets/migrations/20260911120200_contacts.sql +90 -0
- package/dist/assets/migrations/20260911120300_taxes.sql +146 -0
- package/dist/assets/migrations/20260911120400_entries.sql +338 -0
- package/dist/assets/migrations/20260911120500_documents.sql +279 -0
- package/dist/assets/migrations/20260911120600_payments_reconciliation.sql +251 -0
- package/dist/assets/migrations/20260911120700_bank.sql +178 -0
- package/dist/assets/migrations/20260911120800_analytics_attachments.sql +128 -0
- package/dist/assets/migrations/20260911120900_post_document.sql +279 -0
- package/dist/assets/migrations/20260911121000_reporting.sql +235 -0
- package/dist/assets/migrations/20260911121100_country_templates.sql +226 -0
- package/dist/assets/migrations/20260911121200_fec.sql +71 -0
- package/dist/assets/migrations/20260911130000_instance.sql +77 -0
- package/dist/assets/migrations/20260911130100_instance_members.sql +224 -0
- package/dist/assets/migrations/20260911140000_instance_admins.sql +112 -0
- package/dist/assets/migrations/20260911160000_tax_posting_templates_unique.sql +17 -0
- package/dist/assets/migrations/20260911170000_document_amount_paid.sql +82 -0
- package/dist/assets/migrations/20260911173000_post_payment.sql +122 -0
- package/dist/assets/migrations/20260911173100_sequence_counters_under_rls.sql +84 -0
- package/dist/assets/migrations/20260911183000_country_journal_defaults.sql +143 -0
- package/dist/assets/migrations/20260911193853_line_account_defaults.sql +274 -0
- package/dist/assets/migrations/20260911195054_products.sql +221 -0
- package/dist/assets/migrations/20260911210131_anon_surface.sql +85 -0
- package/dist/assets/migrations/20260912074712_country_packs.sql +318 -0
- package/dist/assets/migrations/20260912080311_report_code_and_region.sql +198 -0
- package/dist/assets/migrations/20260912081014_pack_certification_maintained.sql +31 -0
- package/dist/assets/migrations/20260912081015_pack_certification_backfill.sql +16 -0
- package/dist/assets/migrations/20260912090407_tax_report_boxes.sql +329 -0
- package/dist/assets/migrations/20260912091917_tax_on_base_value.sql +25 -0
- package/dist/assets/migrations/20260912091918_tax_engine_columns.sql +776 -0
- package/dist/assets/migrations/20260912094412_opening_and_closing.sql +759 -0
- package/dist/assets/migrations/20260912095825_charts_of_accounts.sql +326 -0
- package/dist/assets/migrations/20260912100412_financial_statements.sql +632 -0
- package/dist/assets/migrations/20260912104719_one_formula_evaluator.sql +209 -0
- package/dist/assets/migrations/20260912105720_entry_kind_appropriation.sql +26 -0
- package/dist/assets/migrations/20260912105721_appropriation_entry_kind.sql +444 -0
- package/dist/assets/migrations/20260912111751_document_rules.sql +274 -0
- package/dist/assets/migrations/20260912112132_cash_basis_vat_and_fx.sql +1189 -0
- package/dist/assets/migrations/20260913074512_modules.sql +493 -0
- package/dist/assets/migrations/20260913075903_asset_disposal_roles.sql +47 -0
- package/dist/assets/migrations/20260913083216_capabilities.sql +637 -0
- package/dist/assets/migrations/20260913083901_company_invitations.sql +262 -0
- package/dist/assets/migrations/20260913084402_user_preferences.sql +376 -0
- package/dist/assets/migrations/20260913084847_company_profile.sql +261 -0
- package/dist/assets/migrations/20260913085436_numbering_reads_the_pack.sql +235 -0
- package/dist/assets/migrations/20260913085932_api_keys.sql +303 -0
- package/dist/assets/migrations/20260913090216_fiscal_year_bounds.sql +159 -0
- package/dist/assets/migrations/20260913092527_entries_import.sql +219 -0
- package/dist/assets/migrations/20260913101536_null_safe_guards.sql +188 -0
- package/dist/assets/migrations/20260913102115_installer_is_named.sql +462 -0
- package/dist/assets/migrations/20260913102758_no_currency_default.sql +138 -0
- package/dist/assets/migrations/20260913103355_cash_basis_needs_a_box.sql +453 -0
- package/dist/assets/migrations/20260913104014_aged_balance_named_group.sql +79 -0
- package/dist/assets/migrations/20260913104232_foreign_key_indexes.sql +144 -0
- package/dist/assets/migrations/20260913105120_declared_no_reader.sql +41 -0
- package/dist/assets/migrations/20260913111407_pack_languages.sql +223 -0
- package/dist/assets/migrations/20260913112233_schema_comments_for_a_reader.sql +27 -0
- package/dist/assets/migrations/20260913114535_fec_opening_balances.sql +307 -0
- package/dist/assets/migrations/20260914103412_audit_log.sql +509 -0
- package/dist/assets/migrations/20260914111907_pack_upgrade.sql +428 -0
- package/dist/assets/migrations/20260914120500_rounding_reads_the_currency.sql +206 -0
- package/dist/assets/migrations/20260914121200_amounts_round_at_the_currency.sql +2403 -0
- package/dist/assets/migrations/20260914134325_schema_version_0_2_0.sql +36 -0
- package/dist/assets/migrations/20260914143915_accounts_in_use.sql +428 -0
- package/dist/assets/migrations/20260914144731_account_code_frozen.sql +99 -0
- package/dist/assets/migrations/20260914151207_schema_grants_its_own_rights.sql +284 -0
- package/dist/assets/migrations/20260914152840_pack_upgrade_records_its_own_line.sql +237 -0
- package/dist/assets/migrations/20260914163943_declaration_periodicity.sql +349 -0
- package/dist/assets/migrations/20260915094000_foreign_services_received.sql +37 -0
- package/dist/assets/migrations/20260915094500_mentions_read_a_foreign_service.sql +72 -0
- package/dist/assets/migrations/20260915153000_document_shares.sql +568 -0
- package/dist/assets/migrations/20260915160000_ec_sales_list.sql +181 -0
- package/dist/assets/migrations/20260915161842_pack_sources.sql +56 -0
- package/dist/assets/migrations/20260915170500_schema_version_0_3_0.sql +45 -0
- package/dist/assets/migrations/20260915174500_a_vat_category_is_a_code.sql +177 -0
- package/dist/assets/migrations/20260915180000_document_rule_references.sql +85 -0
- package/dist/assets/migrations/20260915181000_territories.sql +342 -0
- package/dist/assets/migrations/20260915181500_ec_sales_list_reads_the_territories.sql +222 -0
- package/dist/assets/migrations/20260915182000_intracom_triangular.sql +53 -0
- package/dist/assets/migrations/20260915182500_a_triangular_supply_says_reverse_charge.sql +99 -0
- package/dist/assets/migrations/20260915191200_a_document_knows_its_language.sql +633 -0
- package/dist/assets/migrations/20260915195000_a_price_that_holds_its_tax.sql +649 -0
- package/dist/assets/migrations/20260915200000_a_posting_names_its_boxes.sql +1004 -0
- package/dist/assets/migrations/20260916094500_a_company_files_more_than_one_declaration.sql +795 -0
- package/dist/assets/migrations/20260916103000_a_ledger_line_names_its_posting.sql +902 -0
- package/dist/assets/migrations/20260916123000_a_vocabulary_for_a_tax_that_is_not_a_vat.sql +144 -0
- package/dist/assets/migrations/20260916124000_a_box_can_be_a_rate_of_a_box.sql +525 -0
- package/dist/assets/migrations/20260916125000_a_tax_follows_the_territory.sql +1318 -0
- package/dist/assets/migrations/20260916126000_a_tax_point_and_its_exception.sql +1211 -0
- package/dist/assets/migrations/20260917090000_a_counterparty_that_learns.sql +561 -0
- package/dist/assets/migrations/20260917120000_what_the_money_pays.sql +545 -0
- package/dist/assets/migrations/20260917150000_a_filing_is_a_row.sql +488 -0
- package/dist/assets/migrations/20260917170000_when_it_is_due.sql +194 -0
- package/dist/assets/migrations/20260917180000_a_box_is_a_number_and_a_kind.sql +213 -0
- package/dist/assets/migrations/20260917190000_what_a_declaration_owes.sql +486 -0
- package/dist/assets/migrations/20260917200000_what_moved_after_it_went.sql +227 -0
- package/dist/assets/migrations/20260918090000_a_form_names_its_file.sql +27 -0
- package/dist/assets/migrations/20260918110000_a_deposit_and_what_came_back.sql +286 -0
- package/dist/assets/migrations/20260918113741_a_fourth_preset_is_named.sql +9 -0
- package/dist/assets/migrations/20260918113807_a_client_reads_and_hands_over.sql +96 -0
- package/dist/assets/migrations/20260918114322_two_definer_functions_check_their_caller.sql +75 -0
- package/dist/assets/migrations/20260918130000_every_company_somebody_keeps.sql +177 -0
- package/dist/assets/migrations/20260918140000_a_session_nobody_prepared.sql +40 -0
- package/dist/assets/migrations/20260918141107_a_line_keeps_the_tax_it_was_posted_with.sql +256 -0
- package/dist/assets/migrations/20260918141342_a_company_has_an_electronic_address.sql +66 -0
- package/dist/assets/migrations/20260918141605_an_invoice_reads_whole_from_the_views.sql +313 -0
- package/dist/assets/migrations/20260918141627_a_policy_asks_once.sql +132 -0
- package/dist/assets/migrations/20260918143352_a_suggestion_reads_the_words_once.sql +204 -0
- package/dist/assets/migrations/20260918143417_a_reference_of_the_caller_and_a_rehearsal.sql +115 -0
- package/dist/assets/migrations/20260918150712_a_company_leaves_with_its_books.sql +1119 -0
- package/dist/assets/migrations/20260918150931_a_statement_is_imported_once.sql +654 -0
- package/dist/assets/migrations/20260918161204_a_posted_document_does_not_move.sql +437 -0
- package/dist/assets/migrations/20260918161538_a_posted_entry_does_not_move.sql +252 -0
- package/dist/assets/migrations/20260918171946_an_entry_is_posted_by_post_entry.sql +289 -0
- package/dist/assets/migrations/20260918174312_schema_version_0_4_0.sql +53 -0
- package/dist/assets/modules/assets/module.json +13 -0
- package/dist/assets/modules/assets/supabase/migrations/20260913081447_assets.sql +1190 -0
- package/dist/assets/modules/assets/supabase/migrations/20260913104234_foreign_key_indexes.sql +47 -0
- package/dist/assets/modules/assets/supabase/migrations/20260913104500_assets_capabilities.sql +145 -0
- package/dist/assets/modules/assets/supabase/migrations/20260914122100_assets_round_at_the_currency.sql +564 -0
- package/dist/assets/modules/assets/supabase/migrations/20260914145012_assets_accounts_in_use.sql +37 -0
- package/dist/assets/modules/assets/supabase/migrations/20260914151530_assets_grants_its_own_rights.sql +63 -0
- package/dist/assets/modules/assets/supabase/migrations/20260918113912_assets_client_reads.sql +20 -0
- package/dist/assets/modules/assets/supabase/migrations/20260918150801_assets_leave_with_the_company.sql +41 -0
- package/dist/assets/modules/budgets/module.json +12 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260913083012_budgets.sql +210 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260913104233_foreign_key_indexes.sql +37 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260913104501_budgets_capabilities.sql +72 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260914122400_budgets_round_at_the_currency.sql +68 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260914145048_budgets_accounts_in_use.sql +30 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260914151812_budgets_grants_its_own_rights.sql +31 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260918113954_budgets_client_reads.sql +20 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260918150823_budgets_leave_with_the_company.sql +37 -0
- package/dist/assets/modules/schema/module.1.json +69 -0
- package/dist/assets/seed/00_currencies.sql +15 -0
- package/dist/assets/seed/00_territories.sql +280 -0
- package/dist/assets/seed/05_framework_generic.sql +110 -0
- package/dist/assets/seed/10_pack_be.sql +1284 -0
- package/dist/assets/seed/11_pack_fr.sql +1112 -0
- package/dist/assets/seed/12_pack_lu.sql +2484 -0
- package/dist/assets/seed/13_pack_ee.sql +733 -0
- package/dist/assets/seed/14_pack_gb.sql +796 -0
- package/dist/assets/seed/15_pack_us.sql +751 -0
- package/dist/assets/seed/90_demo_company.sql +368 -0
- package/dist/assets/seed/modules/assets/10_pack_be.sql +58 -0
- package/dist/assets/seed/modules/assets/11_pack_fr.sql +57 -0
- package/dist/assets/seed/modules/assets/14_pack_gb.sql +58 -0
- package/dist/assets/seed/modules/assets/15_pack_us.sql +60 -0
- package/dist/auth.d.ts +59 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +134 -0
- package/dist/auth.js.map +1 -0
- package/dist/bin.d.ts +6 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +8 -0
- package/dist/bin.js.map +1 -0
- package/dist/books.d.ts +60 -0
- package/dist/books.d.ts.map +1 -0
- package/dist/books.js +168 -0
- package/dist/books.js.map +1 -0
- package/dist/bootstrap.d.ts +236 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +459 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/bundle.d.ts +27 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +47 -0
- package/dist/bundle.js.map +1 -0
- package/dist/checklist.d.ts +35 -0
- package/dist/checklist.d.ts.map +1 -0
- package/dist/checklist.js +64 -0
- package/dist/checklist.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +318 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/company.d.ts +59 -0
- package/dist/commands/company.d.ts.map +1 -0
- package/dist/commands/company.js +287 -0
- package/dist/commands/company.js.map +1 -0
- package/dist/commands/contact.d.ts +9 -0
- package/dist/commands/contact.d.ts.map +1 -0
- package/dist/commands/contact.js +82 -0
- package/dist/commands/contact.js.map +1 -0
- package/dist/commands/demo.d.ts +19 -0
- package/dist/commands/demo.d.ts.map +1 -0
- package/dist/commands/demo.js +72 -0
- package/dist/commands/demo.js.map +1 -0
- package/dist/commands/doctor.d.ts +12 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +68 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/document.d.ts +17 -0
- package/dist/commands/document.d.ts.map +1 -0
- package/dist/commands/document.js +217 -0
- package/dist/commands/document.js.map +1 -0
- package/dist/commands/init.d.ts +31 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +535 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +24 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +128 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/migrate.d.ts +30 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +115 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/module.d.ts +32 -0
- package/dist/commands/module.d.ts.map +1 -0
- package/dist/commands/module.js +285 -0
- package/dist/commands/module.js.map +1 -0
- package/dist/commands/pack.d.ts +22 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +481 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/payment.d.ts +15 -0
- package/dist/commands/payment.d.ts.map +1 -0
- package/dist/commands/payment.js +97 -0
- package/dist/commands/payment.js.map +1 -0
- package/dist/commands/register.d.ts +20 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +134 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +134 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/whoami.d.ts +21 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +133 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/company.d.ts +16 -0
- package/dist/company.d.ts.map +1 -0
- package/dist/company.js +26 -0
- package/dist/company.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +50 -0
- package/dist/config.js.map +1 -0
- package/dist/connection.d.ts +79 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +116 -0
- package/dist/connection.js.map +1 -0
- package/dist/context.d.ts +47 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +93 -0
- package/dist/context.js.map +1 -0
- package/dist/doctor.d.ts +45 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +448 -0
- package/dist/doctor.js.map +1 -0
- package/dist/grants.d.ts +88 -0
- package/dist/grants.d.ts.map +1 -0
- package/dist/grants.js +174 -0
- package/dist/grants.js.map +1 -0
- package/dist/identity.d.ts +54 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +132 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +155 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +303 -0
- package/dist/inventory.js.map +1 -0
- package/dist/migrations.d.ts +76 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +226 -0
- package/dist/migrations.js.map +1 -0
- package/dist/module/read.d.ts +91 -0
- package/dist/module/read.d.ts.map +1 -0
- package/dist/module/read.js +172 -0
- package/dist/module/read.js.map +1 -0
- package/dist/output.d.ts +110 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +173 -0
- package/dist/output.js.map +1 -0
- package/dist/pack/certification.d.ts +27 -0
- package/dist/pack/certification.d.ts.map +1 -0
- package/dist/pack/certification.js +38 -0
- package/dist/pack/certification.js.map +1 -0
- package/dist/pack/compile.d.ts +75 -0
- package/dist/pack/compile.d.ts.map +1 -0
- package/dist/pack/compile.js +801 -0
- package/dist/pack/compile.js.map +1 -0
- package/dist/pack/filing.d.ts +48 -0
- package/dist/pack/filing.d.ts.map +1 -0
- package/dist/pack/filing.js +56 -0
- package/dist/pack/filing.js.map +1 -0
- package/dist/pack/read.d.ts +766 -0
- package/dist/pack/read.d.ts.map +1 -0
- package/dist/pack/read.js +2336 -0
- package/dist/pack/read.js.map +1 -0
- package/dist/pack/schema.d.ts +26 -0
- package/dist/pack/schema.d.ts.map +1 -0
- package/dist/pack/schema.js +181 -0
- package/dist/pack/schema.js.map +1 -0
- package/dist/pack/territories.d.ts +98 -0
- package/dist/pack/territories.d.ts.map +1 -0
- package/dist/pack/territories.js +0 -0
- package/dist/pack/territories.js.map +1 -0
- package/dist/pack/upgrade.d.ts +86 -0
- package/dist/pack/upgrade.d.ts.map +1 -0
- package/dist/pack/upgrade.js +76 -0
- package/dist/pack/upgrade.js.map +1 -0
- package/dist/pack/vat-codes.d.ts +273 -0
- package/dist/pack/vat-codes.d.ts.map +1 -0
- package/dist/pack/vat-codes.js +513 -0
- package/dist/pack/vat-codes.js.map +1 -0
- package/dist/profiles.d.ts +67 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +187 -0
- package/dist/profiles.js.map +1 -0
- package/dist/prompt.d.ts +40 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +120 -0
- package/dist/prompt.js.map +1 -0
- package/dist/registry.d.ts +84 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +104 -0
- package/dist/registry.js.map +1 -0
- package/dist/rest.d.ts +81 -0
- package/dist/rest.d.ts.map +1 -0
- package/dist/rest.js +245 -0
- package/dist/rest.js.map +1 -0
- package/dist/schema.d.ts +15 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +15 -0
- package/dist/schema.js.map +1 -0
- package/dist/seeds.d.ts +27 -0
- package/dist/seeds.d.ts.map +1 -0
- package/dist/seeds.js +47 -0
- package/dist/seeds.js.map +1 -0
- package/dist/session.d.ts +39 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +92 -0
- package/dist/session.js.map +1 -0
- package/dist/sql.d.ts +48 -0
- package/dist/sql.d.ts.map +1 -0
- package/dist/sql.js +112 -0
- package/dist/sql.js.map +1 -0
- package/dist/status.d.ts +94 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +120 -0
- package/dist/status.js.map +1 -0
- package/dist/ui.d.ts +55 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +114 -0
- package/dist/ui.js.map +1 -0
- package/package.json +29 -0
- package/schema/output.1.json +613 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
-- Ekwo OS — the schema grants its own rights.
|
|
2
|
+
--
|
|
3
|
+
-- Until this file, nothing in `supabase/migrations` gave `anon` or
|
|
4
|
+
-- `authenticated` a single privilege on a single table. The schema worked
|
|
5
|
+
-- anyway, because a Supabase project carries default privileges on `public`
|
|
6
|
+
-- that hand `all` on every new table, sequence and function to `anon`,
|
|
7
|
+
-- `authenticated` and `service_role`. Row level security then decided who saw
|
|
8
|
+
-- what, and the arrangement looked sound.
|
|
9
|
+
--
|
|
10
|
+
-- Two things were wrong with it.
|
|
11
|
+
--
|
|
12
|
+
-- The first is a hole. Those defaults give `anon` — the role behind the
|
|
13
|
+
-- publishable key that any visitor holds — INSERT, UPDATE and DELETE on every
|
|
14
|
+
-- table of the ledger. Only row level security stands between an anonymous
|
|
15
|
+
-- request and the books. That is one layer where the doctrine of this project
|
|
16
|
+
-- says there are two: `anon` reaches the eight policy helpers and nothing
|
|
17
|
+
-- else (`20260911210131`), and "nothing else" has to include the tables.
|
|
18
|
+
--
|
|
19
|
+
-- The second is a dependency nobody declared. The first real end-to-end run,
|
|
20
|
+
-- on 14 September 2026, dropped and recreated `public` on a throwaway
|
|
21
|
+
-- project. The migrations replayed, `ekwo doctor` reported a healthy
|
|
22
|
+
-- installation, and the first read through PostgREST answered "permission
|
|
23
|
+
-- denied for table companies" — because the default privileges live in
|
|
24
|
+
-- `pg_default_acl`, keyed by the schema, and had gone with it. An
|
|
25
|
+
-- installation whose access rights come from something the installer never
|
|
26
|
+
-- wrote is an installation that cannot be reproduced.
|
|
27
|
+
--
|
|
28
|
+
-- So the privileges are declared here, by name, table by table and view by
|
|
29
|
+
-- view. `grant all on all tables` is not used anywhere: a wildcard is how a
|
|
30
|
+
-- table added next year silently becomes writable by a role nobody thought
|
|
31
|
+
-- about. From this migration on, a migration that creates a table, a view or
|
|
32
|
+
-- a function grants it in the same file, beside the `revoke execute ... from
|
|
33
|
+
-- public` that is already compulsory. `tests/grants.test.ts` compares the
|
|
34
|
+
-- catalogue to the inventory generated from the migrations and fails when the
|
|
35
|
+
-- two disagree, and `ekwo doctor` asks the same question of a live database.
|
|
36
|
+
--
|
|
37
|
+
-- What is deliberately *not* decided here: which companies a role may see.
|
|
38
|
+
-- That is row level security, and every policy of this schema is unchanged.
|
|
39
|
+
-- A grant says which verbs a role may attempt; a policy says on which rows
|
|
40
|
+
-- they succeed. This file is only the first half, and it is the half that was
|
|
41
|
+
-- being borrowed.
|
|
42
|
+
|
|
43
|
+
-- ---------------------------------------------------------------------------
|
|
44
|
+
-- 1. The schema itself
|
|
45
|
+
--
|
|
46
|
+
-- A Supabase project already grants this. Saying it again costs nothing and
|
|
47
|
+
-- is what makes a bare Postgres — the reset above, a self-hosted instance, the
|
|
48
|
+
-- test harness — reach the same state from the migrations alone.
|
|
49
|
+
-- ---------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
grant usage on schema public to anon, authenticated, service_role;
|
|
52
|
+
|
|
53
|
+
-- ---------------------------------------------------------------------------
|
|
54
|
+
-- 2. Everything the project's defaults handed out goes back
|
|
55
|
+
--
|
|
56
|
+
-- `revoke all on all tables` is the safe direction of a wildcard: it can only
|
|
57
|
+
-- close. It takes back the blanket privileges an existing installation
|
|
58
|
+
-- received at creation, including the write access `anon` was never meant to
|
|
59
|
+
-- have, and the grants below then re-open exactly what is needed.
|
|
60
|
+
--
|
|
61
|
+
-- The `alter default privileges` lines stop the same thing happening to the
|
|
62
|
+
-- next table. They are scoped to the role running the migration, which on a
|
|
63
|
+
-- Supabase project is `postgres` — the role that owns the entries. A default
|
|
64
|
+
-- privilege set by another role is not reachable from here and would show up
|
|
65
|
+
-- as an extra grant on the first table created after it, which is what the
|
|
66
|
+
-- invariant test and the doctor are for.
|
|
67
|
+
--
|
|
68
|
+
-- The function line closes Ekwo's own backstop, not Supabase's:
|
|
69
|
+
-- `20260911210131` granted EXECUTE on future functions to `authenticated` and
|
|
70
|
+
-- `service_role` by default privilege, and that is the same hidden mechanism
|
|
71
|
+
-- one level down. Functions created before today keep the grants they were
|
|
72
|
+
-- given — a privilege already in `proacl` is not touched by a change of
|
|
73
|
+
-- default — so nothing that works stops working. A function created after
|
|
74
|
+
-- today is granted in its own migration or it is reachable by nobody.
|
|
75
|
+
--
|
|
76
|
+
-- The `revoke execute on functions from public, anon` default of that same
|
|
77
|
+
-- migration stays exactly as it is. It closes rather than opens, and it is
|
|
78
|
+
-- the reason a new function is not published as an anonymous RPC endpoint.
|
|
79
|
+
-- ---------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
revoke all on all tables in schema public from anon, authenticated, service_role;
|
|
82
|
+
revoke all on all sequences in schema public from anon, authenticated, service_role;
|
|
83
|
+
|
|
84
|
+
alter default privileges in schema public revoke all on tables from anon, authenticated, service_role;
|
|
85
|
+
alter default privileges in schema public revoke all on sequences from anon, authenticated, service_role;
|
|
86
|
+
alter default privileges in schema public revoke execute on functions from authenticated, service_role;
|
|
87
|
+
|
|
88
|
+
-- ---------------------------------------------------------------------------
|
|
89
|
+
-- 3. The tables a signed-in user writes
|
|
90
|
+
--
|
|
91
|
+
-- These twenty-six are the ones whose policies allow more than reading: each
|
|
92
|
+
-- carries a policy `for all` — or, for `companies`, `company_members` and
|
|
93
|
+
-- `instance_admins`, one policy per command — so the four verbs are the ones
|
|
94
|
+
-- row level security is already prepared to judge. The grant and the policy
|
|
95
|
+
-- say the same thing about the same table, which is the property the
|
|
96
|
+
-- invariant test checks.
|
|
97
|
+
--
|
|
98
|
+
-- DELETE is granted on `entries`, `entry_lines`, `documents`,
|
|
99
|
+
-- `document_lines`, `payments` and `reconciliations` on purpose. Deleting a
|
|
100
|
+
-- *draft* is an ordinary act of bookkeeping; deleting a posted entry is
|
|
101
|
+
-- refused by `entries_guard_period` and by the period lock, not by a missing
|
|
102
|
+
-- privilege. Taking DELETE away here would break the draft and leave the
|
|
103
|
+
-- posted entry exactly as protected as it already is.
|
|
104
|
+
--
|
|
105
|
+
-- `service_role` gets the same set. It is the backend key: it bypasses row
|
|
106
|
+
-- level security, so its table rights are the only limit it has, and there is
|
|
107
|
+
-- no reason for that limit to be wider than a person's.
|
|
108
|
+
-- ---------------------------------------------------------------------------
|
|
109
|
+
|
|
110
|
+
grant select, insert, update, delete on table
|
|
111
|
+
accounts,
|
|
112
|
+
analytic_axes,
|
|
113
|
+
analytic_values,
|
|
114
|
+
attachments,
|
|
115
|
+
bank_accounts,
|
|
116
|
+
bank_statements,
|
|
117
|
+
bank_transactions,
|
|
118
|
+
companies,
|
|
119
|
+
company_members,
|
|
120
|
+
company_packs,
|
|
121
|
+
contacts,
|
|
122
|
+
document_lines,
|
|
123
|
+
documents,
|
|
124
|
+
entries,
|
|
125
|
+
entry_line_analytics,
|
|
126
|
+
entry_lines,
|
|
127
|
+
fiscal_years,
|
|
128
|
+
instance,
|
|
129
|
+
instance_admins,
|
|
130
|
+
journals,
|
|
131
|
+
payments,
|
|
132
|
+
products,
|
|
133
|
+
reconciliations,
|
|
134
|
+
tax_postings,
|
|
135
|
+
taxes,
|
|
136
|
+
user_preferences
|
|
137
|
+
to authenticated, service_role;
|
|
138
|
+
|
|
139
|
+
-- ---------------------------------------------------------------------------
|
|
140
|
+
-- 4. The reference tables, which a client reads and an installation writes
|
|
141
|
+
--
|
|
142
|
+
-- Eighteen tables a country pack and a release fill: the chart templates, the
|
|
143
|
+
-- taxes and their postings, the declaration boxes, the statement schemes, the
|
|
144
|
+
-- currencies and their rates, the capabilities and the modules this release
|
|
145
|
+
-- carries. Their policies allow SELECT and nothing else, and the writer is
|
|
146
|
+
-- `ekwo migrate` on the owner's connection or `install_country_template()`
|
|
147
|
+
-- running as definer. No INSERT, no UPDATE, no DELETE: a client that could
|
|
148
|
+
-- edit the chart of accounts of a country could edit it for every company of
|
|
149
|
+
-- the installation at once.
|
|
150
|
+
-- ---------------------------------------------------------------------------
|
|
151
|
+
|
|
152
|
+
grant select on table
|
|
153
|
+
account_templates,
|
|
154
|
+
capabilities,
|
|
155
|
+
chart_templates,
|
|
156
|
+
country_defaults,
|
|
157
|
+
country_packs,
|
|
158
|
+
currencies,
|
|
159
|
+
currency_rates,
|
|
160
|
+
journal_templates,
|
|
161
|
+
legal_mention_templates,
|
|
162
|
+
modules,
|
|
163
|
+
role_capabilities,
|
|
164
|
+
statement_line_rules,
|
|
165
|
+
statement_line_templates,
|
|
166
|
+
statement_templates,
|
|
167
|
+
tax_posting_templates,
|
|
168
|
+
tax_report_box_templates,
|
|
169
|
+
tax_report_templates,
|
|
170
|
+
tax_templates
|
|
171
|
+
to authenticated, service_role;
|
|
172
|
+
|
|
173
|
+
-- ---------------------------------------------------------------------------
|
|
174
|
+
-- 5. The tables only a function writes
|
|
175
|
+
--
|
|
176
|
+
-- Five tables whose rows exist because a `security definer` function made
|
|
177
|
+
-- them, and which no client may write directly. `api_keys` holds a sha256 and
|
|
178
|
+
-- is issued by `create_api_key()`; `company_invitations` by `invite_member()`
|
|
179
|
+
-- and consumed by `accept_invitation()`; `company_modules` by
|
|
180
|
+
-- `enable_module()`; and the two counters are advanced by
|
|
181
|
+
-- `next_entry_number()` and `next_matching_number()`, which is the whole
|
|
182
|
+
-- reason those two became definer in `20260911173100`. A client with UPDATE
|
|
183
|
+
-- on `journal_sequences` could rewind the numbering of a journal, which in
|
|
184
|
+
-- several countries is the offence the numbering rule exists to prevent.
|
|
185
|
+
-- ---------------------------------------------------------------------------
|
|
186
|
+
|
|
187
|
+
grant select on table
|
|
188
|
+
api_keys,
|
|
189
|
+
company_invitations,
|
|
190
|
+
company_modules,
|
|
191
|
+
journal_sequences,
|
|
192
|
+
matching_sequences
|
|
193
|
+
to authenticated, service_role;
|
|
194
|
+
|
|
195
|
+
-- ---------------------------------------------------------------------------
|
|
196
|
+
-- 6. The audit trail: SELECT, and nothing else, for anyone
|
|
197
|
+
--
|
|
198
|
+
-- `audit_log` is append-only by trigger for every role including its owner,
|
|
199
|
+
-- and its only policy is a SELECT. UPDATE and DELETE are therefore refused
|
|
200
|
+
-- twice over, which is the point: the trigger is the guarantee and the
|
|
201
|
+
-- missing privilege is the statement of intent. INSERT is not granted either
|
|
202
|
+
-- — the rows are written by `audit_record()`, a definer function the triggers
|
|
203
|
+
-- call, and a client that could insert its own could write a history that
|
|
204
|
+
-- never happened.
|
|
205
|
+
-- ---------------------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
grant select on table audit_log to authenticated, service_role;
|
|
208
|
+
|
|
209
|
+
-- ---------------------------------------------------------------------------
|
|
210
|
+
-- 7. The views
|
|
211
|
+
--
|
|
212
|
+
-- All four are `security_invoker`, so a reader needs SELECT on the view *and*
|
|
213
|
+
-- on the tables under it, and row level security is judged on the reader
|
|
214
|
+
-- rather than on the owner. The grants above give the second half; this gives
|
|
215
|
+
-- the first.
|
|
216
|
+
-- ---------------------------------------------------------------------------
|
|
217
|
+
|
|
218
|
+
grant select on table
|
|
219
|
+
document_header,
|
|
220
|
+
document_legal_mentions,
|
|
221
|
+
document_line_items,
|
|
222
|
+
document_tax_summary
|
|
223
|
+
to authenticated, service_role;
|
|
224
|
+
|
|
225
|
+
-- ---------------------------------------------------------------------------
|
|
226
|
+
-- 8. Sequences: none, and on purpose
|
|
227
|
+
--
|
|
228
|
+
-- The schema has one, `audit_log_id_seq`, and it belongs to an identity
|
|
229
|
+
-- column of a table nobody but a definer function inserts into. An identity
|
|
230
|
+
-- column takes its next value without asking for USAGE on the sequence, so
|
|
231
|
+
-- there is nothing to grant and nothing that breaks by not granting it. A
|
|
232
|
+
-- migration that adds a `serial` or an identity column to a table a client
|
|
233
|
+
-- inserts into will need `grant usage on sequence …` in its own file.
|
|
234
|
+
-- ---------------------------------------------------------------------------
|
|
235
|
+
|
|
236
|
+
-- ---------------------------------------------------------------------------
|
|
237
|
+
-- 9. Functions: the trigger bodies stop being callable
|
|
238
|
+
--
|
|
239
|
+
-- The eighty-two functions a client may call already hold nominative grants,
|
|
240
|
+
-- given by the migration that created each of them. What was left over is the
|
|
241
|
+
-- twenty-nine whose return type is `trigger`. A trigger function is invoked
|
|
242
|
+
-- by the table it is attached to, not by a caller: PostgreSQL checks EXECUTE
|
|
243
|
+
-- when the trigger is *created*, never when it fires, so revoking it changes
|
|
244
|
+
-- nothing about the schema's behaviour and removes twenty-nine RPC endpoints
|
|
245
|
+
-- that answer "trigger functions can only be called as triggers" to anyone who
|
|
246
|
+
-- finds them. Four of them were already closed to `anon` and `authenticated`
|
|
247
|
+
-- by `20260914103412`; this completes the set and adds `service_role`.
|
|
248
|
+
-- ---------------------------------------------------------------------------
|
|
249
|
+
|
|
250
|
+
revoke execute on function
|
|
251
|
+
assert_may_close_year(),
|
|
252
|
+
assert_may_post_document(),
|
|
253
|
+
assert_may_post_entry(),
|
|
254
|
+
audit_changes(),
|
|
255
|
+
audit_entry_posting(),
|
|
256
|
+
audit_log_is_append_only(),
|
|
257
|
+
audit_state_change(),
|
|
258
|
+
bank_statements_recompute(),
|
|
259
|
+
bank_statements_refresh_balance(),
|
|
260
|
+
companies_default_bank_account_is_ours(),
|
|
261
|
+
companies_default_capital_currency(),
|
|
262
|
+
company_members_capabilities_known(),
|
|
263
|
+
currency_of_bank_account(),
|
|
264
|
+
currency_of_company(),
|
|
265
|
+
document_lines_amount_untaxed(),
|
|
266
|
+
document_lines_refresh_totals(),
|
|
267
|
+
document_lines_resolve_account(),
|
|
268
|
+
documents_default_payee_iban(),
|
|
269
|
+
documents_refresh_payment_state(),
|
|
270
|
+
entries_guard_kind(),
|
|
271
|
+
entries_guard_module(),
|
|
272
|
+
entries_guard_period(),
|
|
273
|
+
entries_refresh_totals(),
|
|
274
|
+
entry_lines_guard_period(),
|
|
275
|
+
fiscal_years_guard_closed(),
|
|
276
|
+
fiscal_years_no_overlap(),
|
|
277
|
+
locale_of_country_pack(),
|
|
278
|
+
reconciliations_refresh_lines(),
|
|
279
|
+
set_updated_at()
|
|
280
|
+
from public, anon, authenticated, service_role;
|
|
281
|
+
|
|
282
|
+
-- The rule of `supabase/migrations/README.md`, which this file obeys like any
|
|
283
|
+
-- other even though it creates no function.
|
|
284
|
+
revoke execute on all functions in schema public from public;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
-- `pack_upgrade()` becomes `security definer`, so that it can write the line
|
|
2
|
+
-- it promises to write.
|
|
3
|
+
--
|
|
4
|
+
-- Found by the test that took the default privileges away from the harness.
|
|
5
|
+
-- `20260914103412` closed `audit_record()` to `anon` and `authenticated`: the
|
|
6
|
+
-- audit trail is written by the triggers, which are `security definer` and
|
|
7
|
+
-- therefore call it as the owner, and a client that could call it directly
|
|
8
|
+
-- could append a history that never happened. `pack_upgrade()` is the one
|
|
9
|
+
-- function in the schema that records its own line rather than leaving it to a
|
|
10
|
+
-- trigger — an upgrade is an act, not a row change — and it was `security
|
|
11
|
+
-- invoker`, so the call was made as the caller.
|
|
12
|
+
--
|
|
13
|
+
-- Nothing noticed, because `tests/helpers/db.ts` ended with `grant execute on
|
|
14
|
+
-- all functions in schema public to authenticated`, which handed back the
|
|
15
|
+
-- EXECUTE that migration had just taken away. On a real project the grant does
|
|
16
|
+
-- not exist and the first owner who runs `ekwo pack upgrade` through PostgREST
|
|
17
|
+
-- gets `permission denied for function audit_record` after the upgrade has
|
|
18
|
+
-- already been applied — the writes are committed, the trail is not.
|
|
19
|
+
--
|
|
20
|
+
-- The fix is the one its peers use. `enable_module()`, `invite_member()`,
|
|
21
|
+
-- `create_api_key()` and `accept_invitation()` are all `security definer` with
|
|
22
|
+
-- an explicit membership test, and this function already carries the same
|
|
23
|
+
-- test: it refuses a caller without `company.write` on the company it was
|
|
24
|
+
-- given, by name, before it touches anything. Definer moves who the writes are
|
|
25
|
+
-- made as; it does not move who is allowed to ask, and the answer to that
|
|
26
|
+
-- question is unchanged.
|
|
27
|
+
--
|
|
28
|
+
-- The body is the published one, word for word, with `security definer` and a
|
|
29
|
+
-- fixed `search_path` added — a definer function that resolves its own names
|
|
30
|
+
-- through the caller's `search_path` is the classic way to hand one away.
|
|
31
|
+
|
|
32
|
+
create or replace function pack_upgrade(
|
|
33
|
+
p_company_id uuid,
|
|
34
|
+
p_country char(2) default null,
|
|
35
|
+
p_apply boolean default false
|
|
36
|
+
)
|
|
37
|
+
returns jsonb
|
|
38
|
+
language plpgsql
|
|
39
|
+
security definer
|
|
40
|
+
set search_path = public, pg_temp
|
|
41
|
+
as $$
|
|
42
|
+
declare
|
|
43
|
+
v_country char(2);
|
|
44
|
+
v_chart text;
|
|
45
|
+
v_from text;
|
|
46
|
+
v_to text;
|
|
47
|
+
v_applied jsonb := '[]'::jsonb;
|
|
48
|
+
v_listed jsonb := '[]'::jsonb;
|
|
49
|
+
v_refused jsonb := '[]'::jsonb;
|
|
50
|
+
d record;
|
|
51
|
+
v_tax_id uuid;
|
|
52
|
+
v_template tax_templates%rowtype;
|
|
53
|
+
begin
|
|
54
|
+
select coalesce(p_country, c.country) into v_country
|
|
55
|
+
from companies c where c.id = p_company_id;
|
|
56
|
+
if v_country is null then
|
|
57
|
+
raise exception 'unknown_company: %', p_company_id;
|
|
58
|
+
end if;
|
|
59
|
+
|
|
60
|
+
if auth.uid() is not null and not has_capability(p_company_id, 'company.write') then
|
|
61
|
+
raise exception 'not_allowed: upgrading a country pack needs company.write';
|
|
62
|
+
end if;
|
|
63
|
+
|
|
64
|
+
select cp.version, cp.chart_code into v_from, v_chart
|
|
65
|
+
from company_packs cp
|
|
66
|
+
where cp.company_id = p_company_id and cp.country = v_country;
|
|
67
|
+
if v_chart is null then
|
|
68
|
+
raise exception 'no_pack_installed: company % holds no % pack, so there is nothing to upgrade from', p_company_id, v_country;
|
|
69
|
+
end if;
|
|
70
|
+
|
|
71
|
+
select version into v_to from country_packs where country = v_country;
|
|
72
|
+
if v_to is null then
|
|
73
|
+
raise exception 'no_pack_loaded: this installation holds no % pack. Apply the seeds of this release first.', v_country;
|
|
74
|
+
end if;
|
|
75
|
+
|
|
76
|
+
for d in select * from pack_upgrade_diff(p_company_id, v_country) loop
|
|
77
|
+
-- Never, whatever the caller asked. An upgrade adds and closes; it does
|
|
78
|
+
-- not take a row out of a company's books.
|
|
79
|
+
if d.change = 'company_only' then
|
|
80
|
+
v_refused := v_refused || jsonb_build_object('object', d.object, 'key', d.key,
|
|
81
|
+
'change', d.change, 'rule', d.rule,
|
|
82
|
+
'detail', d.detail);
|
|
83
|
+
continue;
|
|
84
|
+
end if;
|
|
85
|
+
|
|
86
|
+
if d.rule = 'review' and not p_apply then
|
|
87
|
+
v_listed := v_listed || jsonb_build_object('object', d.object, 'key', d.key,
|
|
88
|
+
'change', d.change, 'rule', d.rule,
|
|
89
|
+
'detail', d.detail);
|
|
90
|
+
continue;
|
|
91
|
+
end if;
|
|
92
|
+
|
|
93
|
+
if d.object = 'account' and d.change = 'missing' then
|
|
94
|
+
insert into accounts (company_id, code, name, name_i18n, statement_hint, account_type, reconcilable)
|
|
95
|
+
select p_company_id, t.code, label_for(t.name, t.name_i18n, preferred_languages(p_company_id)),
|
|
96
|
+
t.name_i18n, t.statement_hint, t.account_type, t.reconcilable
|
|
97
|
+
from account_templates t
|
|
98
|
+
where t.country = v_country and t.chart_code = v_chart and t.code = d.key
|
|
99
|
+
on conflict (company_id, code) do nothing;
|
|
100
|
+
|
|
101
|
+
elsif d.object = 'account' and d.change = 'differs' then
|
|
102
|
+
update accounts a
|
|
103
|
+
set name = label_for(t.name, t.name_i18n, preferred_languages(p_company_id)),
|
|
104
|
+
name_i18n = t.name_i18n,
|
|
105
|
+
account_type = t.account_type
|
|
106
|
+
from account_templates t
|
|
107
|
+
where t.country = v_country and t.chart_code = v_chart and t.code = a.code
|
|
108
|
+
and a.company_id = p_company_id and a.code = d.key;
|
|
109
|
+
|
|
110
|
+
elsif d.object = 'journal' and d.change = 'missing' then
|
|
111
|
+
insert into journals (company_id, code, name, journal_type)
|
|
112
|
+
select p_company_id, t.code, t.name, t.journal_type
|
|
113
|
+
from journal_templates t
|
|
114
|
+
where t.country = v_country and t.code = d.key
|
|
115
|
+
on conflict (company_id, code) do nothing;
|
|
116
|
+
|
|
117
|
+
elsif d.object = 'journal' and d.change = 'differs' then
|
|
118
|
+
update journals j
|
|
119
|
+
set name = t.name, journal_type = t.journal_type
|
|
120
|
+
from journal_templates t
|
|
121
|
+
where t.country = v_country and t.code = j.code
|
|
122
|
+
and j.company_id = p_company_id and j.code = d.key;
|
|
123
|
+
|
|
124
|
+
elsif d.object = 'tax' and d.change = 'missing' then
|
|
125
|
+
select * into v_template from tax_templates where country = v_country and code = d.key;
|
|
126
|
+
insert into taxes (company_id, code, name, description, amount_type, amount,
|
|
127
|
+
applies_to, treatment, country, valid_from, valid_to,
|
|
128
|
+
legal_reference, vat_category, exemption_code, sequence,
|
|
129
|
+
tax_kind, recoverable, jurisdiction, price_include,
|
|
130
|
+
cash_basis, cash_basis_transition_account_id)
|
|
131
|
+
values (p_company_id, v_template.code, v_template.name, v_template.description,
|
|
132
|
+
v_template.amount_type, v_template.amount, v_template.applies_to,
|
|
133
|
+
v_template.treatment, v_country, v_template.valid_from, v_template.valid_to,
|
|
134
|
+
v_template.legal_reference, v_template.vat_category, v_template.exemption_code,
|
|
135
|
+
v_template.sequence, v_template.tax_kind, v_template.recoverable,
|
|
136
|
+
v_template.jurisdiction, v_template.price_include, v_template.cash_basis,
|
|
137
|
+
account_id_by_code(p_company_id, v_template.cash_basis_transition_account_code))
|
|
138
|
+
on conflict (company_id, code) do nothing
|
|
139
|
+
returning id into v_tax_id;
|
|
140
|
+
|
|
141
|
+
if v_tax_id is not null then
|
|
142
|
+
insert into tax_postings (tax_id, company_id, document_kind, posting_type,
|
|
143
|
+
factor_percent, account_id, declaration_box,
|
|
144
|
+
box_factor_percent, report_code, sequence)
|
|
145
|
+
select v_tax_id, p_company_id, tp.document_kind, tp.posting_type,
|
|
146
|
+
tp.factor_percent, account_id_by_code(p_company_id, tp.account_code),
|
|
147
|
+
tp.declaration_box, tp.box_factor_percent, tp.report_code, tp.sequence
|
|
148
|
+
from tax_posting_templates tp
|
|
149
|
+
where tp.tax_template_id = v_template.id
|
|
150
|
+
order by tp.sequence;
|
|
151
|
+
end if;
|
|
152
|
+
|
|
153
|
+
elsif d.object = 'tax' and d.change = 'valid_to' then
|
|
154
|
+
update taxes x
|
|
155
|
+
set valid_to = t.valid_to
|
|
156
|
+
from tax_templates t
|
|
157
|
+
where t.country = v_country and t.code = x.code
|
|
158
|
+
and x.company_id = p_company_id and x.code = d.key;
|
|
159
|
+
|
|
160
|
+
elsif d.object = 'tax' and d.change = 'differs' then
|
|
161
|
+
update taxes x
|
|
162
|
+
set name = t.name, description = t.description, amount = t.amount,
|
|
163
|
+
amount_type = t.amount_type, applies_to = t.applies_to,
|
|
164
|
+
treatment = t.treatment, valid_from = t.valid_from,
|
|
165
|
+
legal_reference = t.legal_reference, vat_category = t.vat_category,
|
|
166
|
+
exemption_code = t.exemption_code, tax_kind = t.tax_kind,
|
|
167
|
+
recoverable = t.recoverable, jurisdiction = t.jurisdiction,
|
|
168
|
+
price_include = t.price_include, cash_basis = t.cash_basis
|
|
169
|
+
from tax_templates t
|
|
170
|
+
where t.country = v_country and t.code = x.code
|
|
171
|
+
and x.company_id = p_company_id and x.code = d.key;
|
|
172
|
+
|
|
173
|
+
elsif d.object = 'tax_posting' and d.change = 'differs' then
|
|
174
|
+
select id into v_tax_id from taxes where company_id = p_company_id and code = d.key;
|
|
175
|
+
delete from tax_postings where tax_id = v_tax_id;
|
|
176
|
+
insert into tax_postings (tax_id, company_id, document_kind, posting_type,
|
|
177
|
+
factor_percent, account_id, declaration_box,
|
|
178
|
+
box_factor_percent, report_code, sequence)
|
|
179
|
+
select v_tax_id, p_company_id, tp.document_kind, tp.posting_type,
|
|
180
|
+
tp.factor_percent, account_id_by_code(p_company_id, tp.account_code),
|
|
181
|
+
tp.declaration_box, tp.box_factor_percent, tp.report_code, tp.sequence
|
|
182
|
+
from tax_posting_templates tp
|
|
183
|
+
join tax_templates t on t.id = tp.tax_template_id
|
|
184
|
+
where t.country = v_country and t.code = d.key
|
|
185
|
+
order by tp.sequence;
|
|
186
|
+
|
|
187
|
+
else
|
|
188
|
+
-- A difference this function does not know how to apply is listed
|
|
189
|
+
-- rather than guessed at. Raising here would make a new kind of
|
|
190
|
+
-- difference break every upgrade.
|
|
191
|
+
v_listed := v_listed || jsonb_build_object('object', d.object, 'key', d.key,
|
|
192
|
+
'change', d.change, 'rule', d.rule,
|
|
193
|
+
'detail', d.detail);
|
|
194
|
+
continue;
|
|
195
|
+
end if;
|
|
196
|
+
|
|
197
|
+
v_applied := v_applied || jsonb_build_object('object', d.object, 'key', d.key,
|
|
198
|
+
'change', d.change, 'rule', d.rule,
|
|
199
|
+
'detail', d.detail);
|
|
200
|
+
end loop;
|
|
201
|
+
|
|
202
|
+
-- The version moves only when nothing is left waiting. A company that still
|
|
203
|
+
-- holds a difference it has not decided on has not finished upgrading, and
|
|
204
|
+
-- saying otherwise would hide the difference at the next run.
|
|
205
|
+
if jsonb_array_length(v_listed) = 0 then
|
|
206
|
+
update company_packs
|
|
207
|
+
set version = v_to, upgraded_at = now()
|
|
208
|
+
where company_id = p_company_id and country = v_country;
|
|
209
|
+
end if;
|
|
210
|
+
|
|
211
|
+
perform audit_record(
|
|
212
|
+
p_company_id, 'company_packs', null, v_country, 'update', 'pack_upgraded',
|
|
213
|
+
jsonb_build_object('version', v_from),
|
|
214
|
+
jsonb_build_object('version', case when jsonb_array_length(v_listed) = 0 then v_to else v_from end,
|
|
215
|
+
'pack_version', v_to,
|
|
216
|
+
'chart_code', v_chart,
|
|
217
|
+
'applied', v_applied,
|
|
218
|
+
'listed', v_listed,
|
|
219
|
+
'never_applied', v_refused));
|
|
220
|
+
|
|
221
|
+
return jsonb_build_object(
|
|
222
|
+
'company_id', p_company_id,
|
|
223
|
+
'country', v_country,
|
|
224
|
+
'chart_code', v_chart,
|
|
225
|
+
'from_version', v_from,
|
|
226
|
+
'to_version', v_to,
|
|
227
|
+
'version_moved', jsonb_array_length(v_listed) = 0,
|
|
228
|
+
'applied', v_applied,
|
|
229
|
+
'listed', v_listed,
|
|
230
|
+
'never_applied', v_refused);
|
|
231
|
+
end;
|
|
232
|
+
$$;
|
|
233
|
+
|
|
234
|
+
comment on function pack_upgrade(uuid, char, boolean) is
|
|
235
|
+
'Moves a company to the country pack version this installation holds: additions copied in, closed validities applied, everything else listed and left alone unless the caller asks for it. Records what it did in the audit trail. The recorded version moves only when nothing is left waiting. Definer, because the line it records goes through audit_record(), which no client may call; the caller still needs company.write on the company.';
|
|
236
|
+
|
|
237
|
+
revoke execute on all functions in schema public from public;
|