ekwo-os 0.7.0 → 0.9.0
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 +10 -5
- package/dist/assets/expected-objects.json +132 -2
- package/dist/assets/migrations/20260922143000_a_version_anybody_signed_in_may_read.sql +52 -0
- package/dist/assets/migrations/20260922144500_a_balance_sheet_without_knowing_the_pack.sql +117 -0
- package/dist/assets/migrations/20260922160000_a_key_reaches_the_api.sql +265 -0
- package/dist/assets/migrations/20260922161500_the_version_answers_a_key_as_well.sql +42 -0
- package/dist/assets/migrations/20260922162500_reference_data_for_a_caller_this_installation_knows.sql +127 -0
- package/dist/assets/migrations/20260922171000_a_key_is_presented_in_a_read_only_transaction.sql +82 -0
- package/dist/assets/migrations/20260923093000_schema_version_0_8_0.sql +42 -0
- package/dist/assets/migrations/20260923110000_an_archive_survives_being_printed_again.sql +648 -0
- package/dist/assets/migrations/20260928100000_schema_version_0_9_0.sql +42 -0
- package/dist/assets/modules/assets/supabase/migrations/20260922162600_assets_reference_for_a_known_caller.sql +24 -0
- package/dist/assets/seed/00_currencies.sql +42 -1
- package/dist/assets/seed/00_territories.sql +1264 -1
- package/dist/assets/seed/100_pack_uy.sql +735 -0
- package/dist/assets/seed/101_pack_ec.sql +534 -0
- package/dist/assets/seed/102_pack_bo.sql +565 -0
- package/dist/assets/seed/103_pack_py.sql +576 -0
- package/dist/assets/seed/104_pack_do.sql +539 -0
- package/dist/assets/seed/105_pack_cr.sql +581 -0
- package/dist/assets/seed/106_pack_gt.sql +601 -0
- package/dist/assets/seed/107_pack_pa.sql +634 -0
- package/dist/assets/seed/108_pack_in.sql +890 -0
- package/dist/assets/seed/109_pack_cn.sql +775 -0
- package/dist/assets/seed/110_pack_ge.sql +536 -0
- package/dist/assets/seed/111_pack_md.sql +672 -0
- package/dist/assets/seed/112_pack_rs.sql +761 -0
- package/dist/assets/seed/113_pack_ba.sql +638 -0
- package/dist/assets/seed/114_pack_al.sql +734 -0
- package/dist/assets/seed/115_pack_mk.sql +591 -0
- package/dist/assets/seed/116_pack_me.sql +673 -0
- package/dist/assets/seed/117_pack_bh.sql +561 -0
- package/dist/assets/seed/118_pack_om.sql +606 -0
- package/dist/assets/seed/119_pack_gh.sql +622 -0
- package/dist/assets/seed/120_pack_tz.sql +583 -0
- package/dist/assets/seed/121_pack_ug.sql +582 -0
- package/dist/assets/seed/122_pack_rw.sql +588 -0
- package/dist/assets/seed/123_pack_xk.sql +567 -0
- package/dist/assets/seed/124_pack_kz.sql +600 -0
- package/dist/assets/seed/38_pack_id.sql +531 -0
- package/dist/assets/seed/39_pack_my.sql +625 -0
- package/dist/assets/seed/44_pack_ph.sql +553 -0
- package/dist/assets/seed/45_pack_ar.sql +587 -0
- package/dist/assets/seed/46_pack_cl.sql +746 -0
- package/dist/assets/seed/47_pack_co.sql +579 -0
- package/dist/assets/seed/48_pack_pe.sql +632 -0
- package/dist/assets/seed/49_pack_ng.sql +616 -0
- package/dist/assets/seed/57_pack_ua.sql +654 -0
- package/dist/assets/seed/58_pack_ca.sql +768 -0
- package/dist/assets/seed/61_pack_se.sql +784 -0
- package/dist/assets/seed/65_pack_dk.sql +595 -0
- package/dist/assets/seed/66_pack_no.sql +584 -0
- package/dist/assets/seed/67_pack_fi.sql +611 -0
- package/dist/assets/seed/68_pack_cz.sql +679 -0
- package/dist/assets/seed/69_pack_sk.sql +662 -0
- package/dist/assets/seed/70_pack_hu.sql +628 -0
- package/dist/assets/seed/72_pack_ro.sql +754 -0
- package/dist/assets/seed/73_pack_bg.sql +561 -0
- package/dist/assets/seed/74_pack_hr.sql +716 -0
- package/dist/assets/seed/75_pack_si.sql +656 -0
- package/dist/assets/seed/76_pack_gr.sql +597 -0
- package/dist/assets/seed/77_pack_lt.sql +611 -0
- package/dist/assets/seed/78_pack_lv.sql +564 -0
- package/dist/assets/seed/79_pack_cy.sql +685 -0
- package/dist/assets/seed/80_pack_mt.sql +833 -0
- package/dist/assets/seed/81_pack_is.sql +532 -0
- package/dist/assets/seed/82_pack_tr.sql +663 -0
- package/dist/assets/seed/83_pack_eg.sql +546 -0
- package/dist/assets/seed/84_pack_ma.sql +666 -0
- package/dist/assets/seed/85_pack_tn.sql +609 -0
- package/dist/assets/seed/86_pack_dz.sql +693 -0
- package/dist/assets/seed/87_pack_il.sql +568 -0
- package/dist/assets/seed/88_pack_za.sql +666 -0
- package/dist/assets/seed/89_pack_ke.sql +596 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -6
- package/dist/cli.js.map +1 -1
- package/dist/commands/import.d.ts +16 -0
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +4 -0
- package/dist/commands/import.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +40 -0
- package/dist/doctor.js.map +1 -1
- package/dist/pack/describe.d.ts +1 -1
- package/dist/pack/upgrade.d.ts +1 -1
- package/dist/pack/upgrade.js +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/schema.js +1 -1
- package/package.json +37 -10
package/README.md
CHANGED
|
@@ -65,9 +65,10 @@ either.
|
|
|
65
65
|
three questions whose wrong answer is expensive: the country, the chart and
|
|
66
66
|
the language.
|
|
67
67
|
|
|
68
|
-
4. **Sign in** to your project as that administrator and start booking
|
|
69
|
-
the
|
|
70
|
-
generates from the schema,
|
|
68
|
+
4. **Sign in** to your project as that administrator and start booking — in
|
|
69
|
+
the web application, [Ekwo Cloud](https://cloud.ekwo.ai), which opens your
|
|
70
|
+
own instance, or through the REST API Supabase generates from the schema,
|
|
71
|
+
`psql` or `@ekwo-ai/core`.
|
|
71
72
|
|
|
72
73
|
5. **Do the four things below**, while the dashboard is still open. The
|
|
73
74
|
installer prints them at the end of a successful run, because three of them
|
|
@@ -323,7 +324,7 @@ instead if the account already exists, and no key is needed.
|
|
|
323
324
|
| `ekwo reverse <entry>` | Undoes a posted entry keyed by hand, through `reverse_entry()`: its mirror, posted and matched against it. By id or by number; `--date` as for `cancel`. |
|
|
324
325
|
| `ekwo payment record` | Money in or out, booked and matched. With `--doc`, against that document. |
|
|
325
326
|
| `ekwo match <transaction> <document>` | A bank statement line pays a document, through `settle_from_statement()`. |
|
|
326
|
-
| `ekwo import <source> <file>…` | Books kept elsewhere — `trial-balance`, `fec`, `journal-items`, `journal-report` — whole or not at all, through `import_books()`, with a correspondence of accounts and journals you save and give back; or a bank statement — `camt.053`, `coda`, `cfonb120` — as pending lines. `--dry-run` rehearses. See [taking over books](#taking-over-books-ekwo-import). |
|
|
327
|
+
| `ekwo import <source> <file>…` | Books kept elsewhere — `trial-balance`, `fec`, `journal-items`, `journal-report`, `transaction-journal`, `xaf` — whole or not at all, through `import_books()`, with a correspondence of accounts and journals you save and give back; or a bank statement — `camt.053`, `coda`, `cfonb120` — as pending lines. `--dry-run` rehearses. See [taking over books](#taking-over-books-ekwo-import). |
|
|
327
328
|
| `ekwo doc list` / `show` | What exists, and with `--unpaid` what is posted and still owed. See [keeping books](#keeping-books). |
|
|
328
329
|
|
|
329
330
|
There is no `eject`, because there is nothing to eject from. The schema is in
|
|
@@ -338,7 +339,7 @@ place, so the output reads the same in a file or a CI log — and takes `--json`
|
|
|
338
339
|
for a program.
|
|
339
340
|
|
|
340
341
|
`ekwo help --json` answers the list of commands and, in `usage`, the whole
|
|
341
|
-
text of `--help` without colour: every flag and variable, for an
|
|
342
|
+
text of `--help` without colour: every flag and variable, for an agent
|
|
342
343
|
that reads one document rather than a terminal.
|
|
343
344
|
|
|
344
345
|
Under `--json` the standard output is **one JSON document and nothing else**;
|
|
@@ -572,6 +573,8 @@ ekwo import fec 123456789FEC20251231.txt --mapping map.json --open-years
|
|
|
572
573
|
ekwo import trial-balance balance.csv --opening-date 2026-01-01 --dry-run --save-mapping map.json
|
|
573
574
|
ekwo import journal-items items.csv accounts.csv partners.csv --dry-run --save-mapping map.json
|
|
574
575
|
ekwo import journal-report report.csv chart.csv --date-order dmy --dry-run --save-mapping map.json
|
|
576
|
+
ekwo import transaction-journal journal.csv account-list.csv --date-order mdy --dry-run --save-mapping map.json
|
|
577
|
+
ekwo import xaf books.xaf --open-years --dry-run --save-mapping map.json
|
|
575
578
|
ekwo import camt.053 statement.xml # or coda, cfonb120: pending lines for `ekwo match`
|
|
576
579
|
```
|
|
577
580
|
|
|
@@ -581,6 +584,8 @@ ekwo import camt.053 statement.xml # or coda, cfonb120: pending
|
|
|
581
584
|
| `fec` | A *fichier des écritures comptables*: the eighteen columns of the arrêté of 29 July 2013, tab or bar separated |
|
|
582
585
|
| `journal-items` | The lines of every entry exported as CSV from the list view of an ERP whose ledger is a table of lines, with the chart of accounts and the partners exported beside it |
|
|
583
586
|
| `journal-report` | A journal report or a general ledger detail, saved as CSV from a cloud service's spreadsheet export, with its Journal ID and Account Code columns, and the chart and the contacts beside it |
|
|
587
|
+
| `transaction-journal` | A transaction journal, saved as CSV from a spreadsheet export: each transaction a run of rows under one date, type and number, closed by its total; the list of accounts beside it |
|
|
588
|
+
| `xaf` | An XML Audit File Financial, version 3.2 or 4.0: the accounts, the parties, the opening balance — on the day the file gives it — and every transaction of a year, in one file |
|
|
584
589
|
| `camt.053`, `coda`, `cfonb120` | A bank statement: its lines, pending, ready for `ekwo match` |
|
|
585
590
|
|
|
586
591
|
Each reader is a brick of [`packages/formats/`](../formats/README.md), named
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion": "0.
|
|
3
|
-
"migration": "
|
|
2
|
+
"schemaVersion": "0.9.0",
|
|
3
|
+
"migration": "20260928100000",
|
|
4
4
|
"socle": {
|
|
5
5
|
"schema": "public",
|
|
6
6
|
"tables": [
|
|
@@ -3743,6 +3743,10 @@
|
|
|
3743
3743
|
"name": "amount_text_format",
|
|
3744
3744
|
"arguments": "p_rounding money_rounding"
|
|
3745
3745
|
},
|
|
3746
|
+
{
|
|
3747
|
+
"name": "api_key_company",
|
|
3748
|
+
"arguments": ""
|
|
3749
|
+
},
|
|
3746
3750
|
{
|
|
3747
3751
|
"name": "assert_may_close_year",
|
|
3748
3752
|
"arguments": ""
|
|
@@ -3815,6 +3819,10 @@
|
|
|
3815
3819
|
"name": "cancel_document",
|
|
3816
3820
|
"arguments": "p_document_id uuid, p_date date"
|
|
3817
3821
|
},
|
|
3822
|
+
{
|
|
3823
|
+
"name": "canonical_json",
|
|
3824
|
+
"arguments": "p_value jsonb"
|
|
3825
|
+
},
|
|
3818
3826
|
{
|
|
3819
3827
|
"name": "catch_up_journal_sequence",
|
|
3820
3828
|
"arguments": "p_journal_id uuid, p_date date, p_number text"
|
|
@@ -3931,6 +3939,10 @@
|
|
|
3931
3939
|
"name": "declaration_period_start",
|
|
3932
3940
|
"arguments": "p_period declaration_period, p_day date"
|
|
3933
3941
|
},
|
|
3942
|
+
{
|
|
3943
|
+
"name": "default_statement_code",
|
|
3944
|
+
"arguments": "p_company_id uuid, p_kind text, p_at date"
|
|
3945
|
+
},
|
|
3934
3946
|
{
|
|
3935
3947
|
"name": "disable_module",
|
|
3936
3948
|
"arguments": "p_company_id uuid, p_code text"
|
|
@@ -3999,6 +4011,10 @@
|
|
|
3999
4011
|
"name": "ec_sales_list",
|
|
4000
4012
|
"arguments": "p_company_id uuid, p_from date, p_to date, p_report_code text"
|
|
4001
4013
|
},
|
|
4014
|
+
{
|
|
4015
|
+
"name": "ekwo_pre_request",
|
|
4016
|
+
"arguments": ""
|
|
4017
|
+
},
|
|
4002
4018
|
{
|
|
4003
4019
|
"name": "ekwo_schema_version",
|
|
4004
4020
|
"arguments": ""
|
|
@@ -4095,6 +4111,10 @@
|
|
|
4095
4111
|
"name": "financial_statement",
|
|
4096
4112
|
"arguments": "p_company_id uuid, p_statement_code text, p_from date, p_to date"
|
|
4097
4113
|
},
|
|
4114
|
+
{
|
|
4115
|
+
"name": "financial_statement_of_kind",
|
|
4116
|
+
"arguments": "p_company_id uuid, p_kind text, p_from date, p_to date"
|
|
4117
|
+
},
|
|
4098
4118
|
{
|
|
4099
4119
|
"name": "fiscal_year_at",
|
|
4100
4120
|
"arguments": "p_company_id uuid, p_date date"
|
|
@@ -4151,6 +4171,10 @@
|
|
|
4151
4171
|
"name": "install_country_template",
|
|
4152
4172
|
"arguments": "p_company_id uuid, p_country character, p_language character, p_chart_code text"
|
|
4153
4173
|
},
|
|
4174
|
+
{
|
|
4175
|
+
"name": "installed_schema_version",
|
|
4176
|
+
"arguments": ""
|
|
4177
|
+
},
|
|
4154
4178
|
{
|
|
4155
4179
|
"name": "instance_has_no_admin",
|
|
4156
4180
|
"arguments": ""
|
|
@@ -4183,6 +4207,10 @@
|
|
|
4183
4207
|
"name": "is_instance_admin",
|
|
4184
4208
|
"arguments": ""
|
|
4185
4209
|
},
|
|
4210
|
+
{
|
|
4211
|
+
"name": "is_known_caller",
|
|
4212
|
+
"arguments": ""
|
|
4213
|
+
},
|
|
4186
4214
|
{
|
|
4187
4215
|
"name": "label_for",
|
|
4188
4216
|
"arguments": "p_name text, p_i18n jsonb, p_languages text[]"
|
|
@@ -4315,6 +4343,10 @@
|
|
|
4315
4343
|
"name": "prepare_filing",
|
|
4316
4344
|
"arguments": "p_company_id uuid, p_from date, p_to date, p_report_code text"
|
|
4317
4345
|
},
|
|
4346
|
+
{
|
|
4347
|
+
"name": "present_api_key",
|
|
4348
|
+
"arguments": "p_secret text"
|
|
4349
|
+
},
|
|
4318
4350
|
{
|
|
4319
4351
|
"name": "purge_audit_log",
|
|
4320
4352
|
"arguments": "p_before date"
|
|
@@ -6817,6 +6849,19 @@
|
|
|
6817
6849
|
"execute"
|
|
6818
6850
|
]
|
|
6819
6851
|
},
|
|
6852
|
+
{
|
|
6853
|
+
"name": "api_key_company",
|
|
6854
|
+
"arguments": "",
|
|
6855
|
+
"anon": [
|
|
6856
|
+
"execute"
|
|
6857
|
+
],
|
|
6858
|
+
"authenticated": [
|
|
6859
|
+
"execute"
|
|
6860
|
+
],
|
|
6861
|
+
"service_role": [
|
|
6862
|
+
"execute"
|
|
6863
|
+
]
|
|
6864
|
+
},
|
|
6820
6865
|
{
|
|
6821
6866
|
"name": "assert_may_close_year",
|
|
6822
6867
|
"arguments": "",
|
|
@@ -6985,6 +7030,17 @@
|
|
|
6985
7030
|
"execute"
|
|
6986
7031
|
]
|
|
6987
7032
|
},
|
|
7033
|
+
{
|
|
7034
|
+
"name": "canonical_json",
|
|
7035
|
+
"arguments": "p_value jsonb",
|
|
7036
|
+
"anon": [],
|
|
7037
|
+
"authenticated": [
|
|
7038
|
+
"execute"
|
|
7039
|
+
],
|
|
7040
|
+
"service_role": [
|
|
7041
|
+
"execute"
|
|
7042
|
+
]
|
|
7043
|
+
},
|
|
6988
7044
|
{
|
|
6989
7045
|
"name": "catch_up_journal_sequence",
|
|
6990
7046
|
"arguments": "p_journal_id uuid, p_date date, p_number text",
|
|
@@ -7281,6 +7337,17 @@
|
|
|
7281
7337
|
"execute"
|
|
7282
7338
|
]
|
|
7283
7339
|
},
|
|
7340
|
+
{
|
|
7341
|
+
"name": "default_statement_code",
|
|
7342
|
+
"arguments": "p_company_id uuid, p_kind text, p_at date",
|
|
7343
|
+
"anon": [],
|
|
7344
|
+
"authenticated": [
|
|
7345
|
+
"execute"
|
|
7346
|
+
],
|
|
7347
|
+
"service_role": [
|
|
7348
|
+
"execute"
|
|
7349
|
+
]
|
|
7350
|
+
},
|
|
7284
7351
|
{
|
|
7285
7352
|
"name": "disable_module",
|
|
7286
7353
|
"arguments": "p_company_id uuid, p_code text",
|
|
@@ -7441,6 +7508,19 @@
|
|
|
7441
7508
|
"execute"
|
|
7442
7509
|
]
|
|
7443
7510
|
},
|
|
7511
|
+
{
|
|
7512
|
+
"name": "ekwo_pre_request",
|
|
7513
|
+
"arguments": "",
|
|
7514
|
+
"anon": [
|
|
7515
|
+
"execute"
|
|
7516
|
+
],
|
|
7517
|
+
"authenticated": [
|
|
7518
|
+
"execute"
|
|
7519
|
+
],
|
|
7520
|
+
"service_role": [
|
|
7521
|
+
"execute"
|
|
7522
|
+
]
|
|
7523
|
+
},
|
|
7444
7524
|
{
|
|
7445
7525
|
"name": "ekwo_schema_version",
|
|
7446
7526
|
"arguments": "",
|
|
@@ -7684,6 +7764,17 @@
|
|
|
7684
7764
|
"execute"
|
|
7685
7765
|
]
|
|
7686
7766
|
},
|
|
7767
|
+
{
|
|
7768
|
+
"name": "financial_statement_of_kind",
|
|
7769
|
+
"arguments": "p_company_id uuid, p_kind text, p_from date, p_to date",
|
|
7770
|
+
"anon": [],
|
|
7771
|
+
"authenticated": [
|
|
7772
|
+
"execute"
|
|
7773
|
+
],
|
|
7774
|
+
"service_role": [
|
|
7775
|
+
"execute"
|
|
7776
|
+
]
|
|
7777
|
+
},
|
|
7687
7778
|
{
|
|
7688
7779
|
"name": "fiscal_year_at",
|
|
7689
7780
|
"arguments": "p_company_id uuid, p_date date",
|
|
@@ -7834,6 +7925,19 @@
|
|
|
7834
7925
|
"execute"
|
|
7835
7926
|
]
|
|
7836
7927
|
},
|
|
7928
|
+
{
|
|
7929
|
+
"name": "installed_schema_version",
|
|
7930
|
+
"arguments": "",
|
|
7931
|
+
"anon": [
|
|
7932
|
+
"execute"
|
|
7933
|
+
],
|
|
7934
|
+
"authenticated": [
|
|
7935
|
+
"execute"
|
|
7936
|
+
],
|
|
7937
|
+
"service_role": [
|
|
7938
|
+
"execute"
|
|
7939
|
+
]
|
|
7940
|
+
},
|
|
7837
7941
|
{
|
|
7838
7942
|
"name": "instance_has_no_admin",
|
|
7839
7943
|
"arguments": "",
|
|
@@ -7932,6 +8036,19 @@
|
|
|
7932
8036
|
"execute"
|
|
7933
8037
|
]
|
|
7934
8038
|
},
|
|
8039
|
+
{
|
|
8040
|
+
"name": "is_known_caller",
|
|
8041
|
+
"arguments": "",
|
|
8042
|
+
"anon": [
|
|
8043
|
+
"execute"
|
|
8044
|
+
],
|
|
8045
|
+
"authenticated": [
|
|
8046
|
+
"execute"
|
|
8047
|
+
],
|
|
8048
|
+
"service_role": [
|
|
8049
|
+
"execute"
|
|
8050
|
+
]
|
|
8051
|
+
},
|
|
7935
8052
|
{
|
|
7936
8053
|
"name": "label_for",
|
|
7937
8054
|
"arguments": "p_name text, p_i18n jsonb, p_languages text[]",
|
|
@@ -8294,6 +8411,19 @@
|
|
|
8294
8411
|
"execute"
|
|
8295
8412
|
]
|
|
8296
8413
|
},
|
|
8414
|
+
{
|
|
8415
|
+
"name": "present_api_key",
|
|
8416
|
+
"arguments": "p_secret text",
|
|
8417
|
+
"anon": [
|
|
8418
|
+
"execute"
|
|
8419
|
+
],
|
|
8420
|
+
"authenticated": [
|
|
8421
|
+
"execute"
|
|
8422
|
+
],
|
|
8423
|
+
"service_role": [
|
|
8424
|
+
"execute"
|
|
8425
|
+
]
|
|
8426
|
+
},
|
|
8297
8427
|
{
|
|
8298
8428
|
"name": "purge_audit_log",
|
|
8299
8429
|
"arguments": "p_before date",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
-- Ekwo OS — the version of the schema, for somebody who is on no company yet.
|
|
2
|
+
--
|
|
3
|
+
-- A client of this schema has one question to ask before it draws anything:
|
|
4
|
+
-- is this installation new enough for the code I ship? The answer is
|
|
5
|
+
-- `instance.schema_version`, and the policy on that table admits members of
|
|
6
|
+
-- at least one company and instance administrators — for the reason written
|
|
7
|
+
-- in `20260911140000`: self sign-up is on by default on a Supabase project,
|
|
8
|
+
-- so a signed-in stranger is ordinary and the organisation's name, its country
|
|
9
|
+
-- and the day it was installed are not theirs to read.
|
|
10
|
+
--
|
|
11
|
+
-- A freshly created account is exactly that stranger. It signs in, reads no
|
|
12
|
+
-- row, and the client cannot tell an instance behind its schema from one
|
|
13
|
+
-- whose row it was never allowed to see. Both are silence, and the two call
|
|
14
|
+
-- for opposite behaviour: print `ekwo migrate`, or say nothing and carry on.
|
|
15
|
+
-- A web application meets this on its first screen, with an account whose
|
|
16
|
+
-- invitation has not arrived yet.
|
|
17
|
+
--
|
|
18
|
+
-- So the version leaves the table and becomes a question of its own.
|
|
19
|
+
-- `installed_schema_version()` is definer — it reads the singleton row past a
|
|
20
|
+
-- policy that was written about the rest of it — and it returns two fields
|
|
21
|
+
-- and no others: the version the migrations wrote, and the edition, which is
|
|
22
|
+
-- `community` or `cloud` and gates nothing anywhere in this repository.
|
|
23
|
+
-- Whoever the caller is, what they learn is what release this software is at.
|
|
24
|
+
-- Nothing about the customer comes with it.
|
|
25
|
+
--
|
|
26
|
+
-- **`anon` does not get it**, and the exception is not worth making. Decision
|
|
27
|
+
-- 0002 keeps the anonymous surface closed, and the list of what `anon` may
|
|
28
|
+
-- execute is the policy helpers, which answer about `auth.uid()` and therefore
|
|
29
|
+
-- say nothing, plus `shared_document()`, which somebody was handed a link to.
|
|
30
|
+
-- The version is not in that shape: nobody asks it before signing in — the
|
|
31
|
+
-- client asks it *after*, which is the moment the old answer went missing —
|
|
32
|
+
-- and granting it would hand an unauthenticated scanner the exact release an
|
|
33
|
+
-- installation runs, for a convenience nothing needs. A reader who needs it
|
|
34
|
+
-- signs in first.
|
|
35
|
+
|
|
36
|
+
create or replace function installed_schema_version()
|
|
37
|
+
returns table (schema_version text, edition text)
|
|
38
|
+
language sql
|
|
39
|
+
stable
|
|
40
|
+
security definer
|
|
41
|
+
set search_path = public, pg_temp
|
|
42
|
+
as $$
|
|
43
|
+
select i.schema_version, i.edition::text from instance i where i.id = 1;
|
|
44
|
+
$$;
|
|
45
|
+
|
|
46
|
+
comment on function installed_schema_version() is
|
|
47
|
+
'The schema version this installation runs, and its edition. Definer, so a signed-in account that is on no company yet can still tell an instance behind its schema from one it may not read the row of — which is the same silence otherwise. Nothing else of the instance row comes with it.';
|
|
48
|
+
|
|
49
|
+
revoke execute on all functions in schema public from public;
|
|
50
|
+
|
|
51
|
+
revoke execute on function installed_schema_version() from public, anon;
|
|
52
|
+
grant execute on function installed_schema_version() to authenticated, service_role;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
-- Ekwo OS — asking for a balance sheet without knowing which pack answers.
|
|
2
|
+
--
|
|
3
|
+
-- `financial_statement()` takes `p_statement_code`, and a code belongs to a
|
|
4
|
+
-- country pack: `BE-BNB-ABBR-BS`, `FR-2050`, the generic `IFRS-SME-BS`. A
|
|
5
|
+
-- client that knows which company it is looking at does not know that string,
|
|
6
|
+
-- and it must not learn it — writing `FR-2050` into an application is writing
|
|
7
|
+
-- a country into code, one screen at a time, which is the thing
|
|
8
|
+
-- `docs/decisions/0025` exists to stop.
|
|
9
|
+
--
|
|
10
|
+
-- `available_statements(company, at)` has been the way out since the day the
|
|
11
|
+
-- statements landed: it gives every scheme that company may ask for, with its
|
|
12
|
+
-- kind and whether its chart declares it. What was missing is the step after
|
|
13
|
+
-- it — going from *a balance sheet* to the one statement that answers, and
|
|
14
|
+
-- doing it the same way twice. Every caller that wanted one wrote its own
|
|
15
|
+
-- choice: take the first row, prefer `is_default`, prefer the country over the
|
|
16
|
+
-- generic. Three readers, three orders, and the day a pack carries two balance
|
|
17
|
+
-- sheets they disagree about which is the company's.
|
|
18
|
+
--
|
|
19
|
+
-- Two functions, and no new rule about accounting:
|
|
20
|
+
--
|
|
21
|
+
-- `default_statement_code(company, kind, at)` — the one scheme of that kind
|
|
22
|
+
-- this company reports on. The order is the pack's own preferences,
|
|
23
|
+
-- stated once: a statement the company's chart declares
|
|
24
|
+
-- (`chart_templates.statements`, which is what `is_default` marks) comes
|
|
25
|
+
-- first; then one of the company's country, because a national scheme is
|
|
26
|
+
-- what an administration reads; then the generic framework, which fits
|
|
27
|
+
-- any chart and is the fallback and never the first answer. `code`
|
|
28
|
+
-- settles a tie, so the answer does not depend on the order rows were
|
|
29
|
+
-- loaded in.
|
|
30
|
+
--
|
|
31
|
+
-- `financial_statement_of_kind(company, kind, from, to)` — the same table
|
|
32
|
+
-- `financial_statement()` returns, resolved that way, with the code it
|
|
33
|
+
-- chose in the first column. The code comes back because a reader has to
|
|
34
|
+
-- be able to say which scheme it is printing, and because the next call
|
|
35
|
+
-- — `unmapped_accounts()`, an XBRL export — takes the code.
|
|
36
|
+
--
|
|
37
|
+
-- The kind is the one the schema already has: `balance_sheet`,
|
|
38
|
+
-- `income_statement`, `allocation`, `cash_flow` — the vocabulary of
|
|
39
|
+
-- `statement_templates.kind`, not a new one. A company with no statement of
|
|
40
|
+
-- the kind asked for is told so, and told what it does have; a company that
|
|
41
|
+
-- installed no pack at all has the generic framework and so has both of the
|
|
42
|
+
-- two that are produced.
|
|
43
|
+
--
|
|
44
|
+
-- The date the validity is read at is `p_to`: a statement is the one that was
|
|
45
|
+
-- in force at the end of the period being reported, not the one in force
|
|
46
|
+
-- today. A scheme replaced last month still prints last year.
|
|
47
|
+
|
|
48
|
+
create or replace function default_statement_code(
|
|
49
|
+
p_company_id uuid,
|
|
50
|
+
p_kind text,
|
|
51
|
+
p_at date default null
|
|
52
|
+
)
|
|
53
|
+
returns text
|
|
54
|
+
language sql
|
|
55
|
+
stable
|
|
56
|
+
as $$
|
|
57
|
+
select s.code
|
|
58
|
+
from available_statements(p_company_id, p_at) s
|
|
59
|
+
where s.kind = p_kind
|
|
60
|
+
order by s.is_default desc, (s.country is null), s.code
|
|
61
|
+
limit 1;
|
|
62
|
+
$$;
|
|
63
|
+
|
|
64
|
+
comment on function default_statement_code(uuid, text, date) is
|
|
65
|
+
'The statement of a kind this company reports on: one its chart declares, else one of its country, else the generic framework. Null when it has none of that kind. The one place that choice is made, so two readers cannot disagree about which balance sheet is the company''s.';
|
|
66
|
+
|
|
67
|
+
create or replace function financial_statement_of_kind(
|
|
68
|
+
p_company_id uuid,
|
|
69
|
+
p_kind text,
|
|
70
|
+
p_from date,
|
|
71
|
+
p_to date
|
|
72
|
+
)
|
|
73
|
+
returns table (
|
|
74
|
+
statement_code text,
|
|
75
|
+
line_code text,
|
|
76
|
+
parent_code text,
|
|
77
|
+
name text,
|
|
78
|
+
sequence integer,
|
|
79
|
+
is_total boolean,
|
|
80
|
+
amount numeric,
|
|
81
|
+
xbrl_element text
|
|
82
|
+
)
|
|
83
|
+
language plpgsql
|
|
84
|
+
stable
|
|
85
|
+
as $$
|
|
86
|
+
declare
|
|
87
|
+
v_code text;
|
|
88
|
+
v_kinds text;
|
|
89
|
+
begin
|
|
90
|
+
if not exists (select 1 from companies c where c.id = p_company_id) then
|
|
91
|
+
raise exception 'unknown_company: %', p_company_id;
|
|
92
|
+
end if;
|
|
93
|
+
|
|
94
|
+
v_code := default_statement_code(p_company_id, p_kind, p_to);
|
|
95
|
+
if v_code is null then
|
|
96
|
+
select string_agg(distinct s.kind, ', ' order by s.kind) into v_kinds
|
|
97
|
+
from available_statements(p_company_id, p_to) s;
|
|
98
|
+
raise exception 'unknown_statement: this company reports no % — it reports %. available_statements() names each one by code.',
|
|
99
|
+
p_kind, coalesce(v_kinds, 'nothing');
|
|
100
|
+
end if;
|
|
101
|
+
|
|
102
|
+
return query
|
|
103
|
+
select v_code, f.line_code, f.parent_code, f.name, f.sequence,
|
|
104
|
+
f.is_total, f.amount, f.xbrl_element
|
|
105
|
+
from financial_statement(p_company_id, v_code, p_from, p_to) f;
|
|
106
|
+
end;
|
|
107
|
+
$$;
|
|
108
|
+
|
|
109
|
+
comment on function financial_statement_of_kind(uuid, text, date, date) is
|
|
110
|
+
'One financial statement of a company by kind — balance_sheet, income_statement, allocation, cash_flow — for a caller that does not know which scheme its country pack carries. Resolves through default_statement_code() at the end date of the period, then answers as financial_statement() does, with the code it chose in the first column.';
|
|
111
|
+
|
|
112
|
+
revoke execute on all functions in schema public from public;
|
|
113
|
+
|
|
114
|
+
revoke execute on function default_statement_code(uuid, text, date) from public, anon;
|
|
115
|
+
grant execute on function default_statement_code(uuid, text, date) to authenticated, service_role;
|
|
116
|
+
revoke execute on function financial_statement_of_kind(uuid, text, date, date) from public, anon;
|
|
117
|
+
grant execute on function financial_statement_of_kind(uuid, text, date, date) to authenticated, service_role;
|