ekwo-os 0.4.1 → 0.5.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.
Files changed (109) hide show
  1. package/README.md +54 -17
  2. package/dist/assets/expected-objects.json +306 -4
  3. package/dist/assets/migrations/20260919090000_a_posted_row_is_undone_in_one_gesture.sql +691 -0
  4. package/dist/assets/migrations/20260919190727_what_has_not_left_goes_back_to_draft.sql +817 -0
  5. package/dist/assets/migrations/20260921084142_filing_deadline_rule_depends_on_taxpayer.sql +23 -0
  6. package/dist/assets/migrations/20260921084143_a_silence_the_pack_states.sql +80 -0
  7. package/dist/assets/migrations/20260921145411_three_cadences_more.sql +21 -0
  8. package/dist/assets/migrations/20260921145412_a_cadence_of_any_months_and_a_box_at_its_unit.sql +440 -0
  9. package/dist/assets/migrations/20260921145425_a_supply_measured_against_its_seller.sql +1620 -0
  10. package/dist/assets/migrations/20260922072635_schema_version_0_5_0.sql +41 -0
  11. package/dist/assets/seed/00_currencies.sql +24 -2
  12. package/dist/assets/seed/00_territories.sql +411 -19
  13. package/dist/assets/seed/10_pack_be.sql +31 -26
  14. package/dist/assets/seed/11_pack_fr.sql +143 -39
  15. package/dist/assets/seed/12_pack_lu.sql +58 -43
  16. package/dist/assets/seed/13_pack_ee.sql +49 -34
  17. package/dist/assets/seed/14_pack_gb.sql +39 -30
  18. package/dist/assets/seed/15_pack_us.sql +33 -19
  19. package/dist/assets/seed/16_pack_ie.sql +958 -0
  20. package/dist/assets/seed/17_pack_nl.sql +1017 -0
  21. package/dist/assets/seed/18_pack_de.sql +826 -0
  22. package/dist/assets/seed/19_pack_es.sql +1120 -0
  23. package/dist/assets/seed/20_pack_sn.sql +1996 -0
  24. package/dist/assets/seed/21_pack_ci.sql +1984 -0
  25. package/dist/assets/seed/22_pack_bj.sql +1977 -0
  26. package/dist/assets/seed/23_pack_bf.sql +1990 -0
  27. package/dist/assets/seed/24_pack_cm.sql +1970 -0
  28. package/dist/assets/seed/25_pack_cf.sql +1964 -0
  29. package/dist/assets/seed/26_pack_km.sql +2001 -0
  30. package/dist/assets/seed/27_pack_cg.sql +1981 -0
  31. package/dist/assets/seed/28_pack_ga.sql +2003 -0
  32. package/dist/assets/seed/29_pack_gn.sql +1967 -0
  33. package/dist/assets/seed/30_pack_gw.sql +1997 -0
  34. package/dist/assets/seed/31_pack_gq.sql +1989 -0
  35. package/dist/assets/seed/32_pack_ml.sql +1988 -0
  36. package/dist/assets/seed/33_pack_ne.sql +1985 -0
  37. package/dist/assets/seed/34_pack_cd.sql +1980 -0
  38. package/dist/assets/seed/35_pack_td.sql +1996 -0
  39. package/dist/assets/seed/36_pack_tg.sql +1988 -0
  40. package/dist/assets/seed/37_pack_it.sql +660 -0
  41. package/dist/assets/seed/40_pack_au.sql +729 -0
  42. package/dist/assets/seed/41_pack_nz.sql +661 -0
  43. package/dist/assets/seed/42_pack_mx.sql +891 -0
  44. package/dist/assets/seed/43_pack_pt.sql +701 -0
  45. package/dist/assets/seed/50_pack_sg.sql +773 -0
  46. package/dist/assets/seed/51_pack_jp.sql +887 -0
  47. package/dist/assets/seed/52_pack_hk.sql +448 -0
  48. package/dist/assets/seed/53_pack_tw.sql +559 -0
  49. package/dist/assets/seed/54_pack_kr.sql +604 -0
  50. package/dist/assets/seed/55_pack_vn.sql +556 -0
  51. package/dist/assets/seed/56_pack_th.sql +579 -0
  52. package/dist/assets/seed/60_pack_ae.sql +588 -0
  53. package/dist/assets/seed/modules/assets/10_pack_be.sql +1 -1
  54. package/dist/assets/seed/modules/assets/11_pack_fr.sql +1 -1
  55. package/dist/assets/seed/modules/assets/14_pack_gb.sql +1 -1
  56. package/dist/assets/seed/modules/assets/15_pack_us.sql +1 -1
  57. package/dist/cli.d.ts +1 -1
  58. package/dist/cli.d.ts.map +1 -1
  59. package/dist/cli.js +44 -15
  60. package/dist/cli.js.map +1 -1
  61. package/dist/commands/document.d.ts +19 -5
  62. package/dist/commands/document.d.ts.map +1 -1
  63. package/dist/commands/document.js +75 -17
  64. package/dist/commands/document.js.map +1 -1
  65. package/dist/commands/entry.d.ts +14 -0
  66. package/dist/commands/entry.d.ts.map +1 -0
  67. package/dist/commands/entry.js +34 -0
  68. package/dist/commands/entry.js.map +1 -0
  69. package/dist/commands/init.d.ts +1 -1
  70. package/dist/commands/init.d.ts.map +1 -1
  71. package/dist/commands/init.js +13 -0
  72. package/dist/commands/init.js.map +1 -1
  73. package/dist/commands/pack.d.ts +3 -2
  74. package/dist/commands/pack.d.ts.map +1 -1
  75. package/dist/commands/pack.js +186 -6
  76. package/dist/commands/pack.js.map +1 -1
  77. package/dist/index.d.ts +2 -1
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +2 -1
  80. package/dist/index.js.map +1 -1
  81. package/dist/output.d.ts.map +1 -1
  82. package/dist/output.js +4 -3
  83. package/dist/output.js.map +1 -1
  84. package/dist/pack/compile.js +42 -10
  85. package/dist/pack/compile.js.map +1 -1
  86. package/dist/pack/describe.d.ts +267 -0
  87. package/dist/pack/describe.d.ts.map +1 -0
  88. package/dist/pack/describe.js +203 -0
  89. package/dist/pack/describe.js.map +1 -0
  90. package/dist/pack/filing.d.ts +6 -1
  91. package/dist/pack/filing.d.ts.map +1 -1
  92. package/dist/pack/filing.js +6 -1
  93. package/dist/pack/filing.js.map +1 -1
  94. package/dist/pack/lists.d.ts +44 -0
  95. package/dist/pack/lists.d.ts.map +1 -0
  96. package/dist/pack/lists.js +181 -0
  97. package/dist/pack/lists.js.map +1 -0
  98. package/dist/pack/read.d.ts +50 -9
  99. package/dist/pack/read.d.ts.map +1 -1
  100. package/dist/pack/read.js +124 -5
  101. package/dist/pack/read.js.map +1 -1
  102. package/dist/pack/territories.d.ts +17 -0
  103. package/dist/pack/territories.d.ts.map +1 -1
  104. package/dist/pack/territories.js +0 -0
  105. package/dist/pack/territories.js.map +1 -1
  106. package/dist/schema.d.ts +1 -1
  107. package/dist/schema.js +1 -1
  108. package/package.json +3 -3
  109. package/schema/output.1.json +48 -2
package/README.md CHANGED
@@ -112,8 +112,10 @@ the packs the database holds. A preselected country is a chart of accounts
112
112
  nobody chose.
113
113
 
114
114
  The same is true of the financial year: a pack that declares no usual opening
115
- month makes `--fiscal-year-start` required. Both packs shipped here open on the
116
- calendar year, so it rarely comes up.
115
+ month makes `--fiscal-year-start` required. Most packs name the calendar year
116
+ in `defaults.fiscal_year_default`; one that names none — the United Kingdom's,
117
+ where a company's year ends on the accounting reference date it chose — asks
118
+ for the day.
117
119
 
118
120
  ## Where table access comes from
119
121
 
@@ -158,7 +160,7 @@ migrations put the privileges back themselves, and they take away the blanket
158
160
  table access the project's defaults had handed `anon`. Dropping `public` is
159
161
  still not something to do on a project you intend to keep — it takes your books
160
162
  with it. The decision and what it changed are in
161
- [`docs/decisions.md`](../../docs/decisions.md).
163
+ [decision 0003](../../docs/decisions/0003-the-schema-grants-its-own-rights.md).
162
164
 
163
165
  ## Before you go live: four things on your project
164
166
 
@@ -217,7 +219,7 @@ and read by a person.
217
219
  | Step | What happens | Why it is done this way |
218
220
  |---|---|---|
219
221
  | 1 | Applies `supabase/migrations/*.sql` in order | Recorded in `supabase_migrations.schema_migrations`, the Supabase CLI's own history table, so `supabase db push` and `ekwo migrate` stay interchangeable |
220
- | 2 | Applies the six reference seeds, in file-name order: `00_currencies.sql`, `05_framework_generic.sql`, `10_pack_be.sql`, `11_pack_fr.sql`, `12_pack_lu.sql`, `13_pack_ee.sql` | The currencies, the country-less financial statements every chart falls back on, and the four country packs. They are exactly the six `supabase/config.toml` lists, so `supabase db push` installs the same set; a test compares both paths row by row. `90_demo_company.sql` is sample data and is never applied here |
222
+ | 2 | Applies every reference seed of `supabase/seed/`, in file-name order: `00_currencies.sql`, `00_territories.sql`, `05_framework_generic.sql`, then one `<n>_pack_<cc>.sql` per country pack, in the order of the number each pack declares | The currencies, the territories the tax rules name, the country-less financial statements every chart falls back on, and every country pack of the release so a company in any of them can be created later without installing anything. They are exactly the seeds `supabase/config.toml` lists (a list `ekwo pack build` writes from `packs/`), so `supabase db push` installs the same set; a test compares both paths row by row. `90_demo_company.sql` is sample data and is never applied here |
221
223
  | 3 | Creates the first administrator through the Supabase Auth admin API | See below: a database connection cannot be a signed-in user |
222
224
  | 4 | `init_instance()`, `claim_instance_admin()`, the company, `company_members` as owner, `install_country_template()`, the first financial year, and the bank account when an IBAN was given | The six steps of the root README, in the same order, plus the one thing nobody can derive |
223
225
  | 5 | Writes `ekwo.json` | Project URL, country, schema version. Nothing else, ever |
@@ -248,7 +250,7 @@ instead if the account already exists, and no key is needed.
248
250
 
249
251
  | Command | What it does |
250
252
  |---|---|
251
- | `ekwo init` | The whole installation, interactive or not. |
253
+ | `ekwo init` | The whole installation, interactive or not: the socle's migrations, the reference seeds, then the modules', as `ekwo migrate` applies them. |
252
254
  | `ekwo migrate` | Applies the migrations this release adds, after showing the gap — the socle's, then the modules'. Re-applies the reference seeds, which are idempotent. `--no-modules` leaves the modules alone. |
253
255
  | `ekwo status` | Schema version installed against available, pending migrations, the instance, its administrators, the country packs it holds and, per company, the pack version it copied. Exits 1 when something is pending. |
254
256
  | `ekwo doctor` | Every object this release defines and every privilege it grants, against what the database holds; row level security on every table, a policy on every protected table, no pending migration, no membership pointing at a deleted user, every company with a bank account, statements that tie to their lines, posted entries that balance. Exits 1 on a problem, 0 on warnings. |
@@ -263,8 +265,10 @@ instead if the account already exists, and no key is needed.
263
265
  | `ekwo use <company>` | Picks the company the next commands run on. |
264
266
  | `ekwo whoami` | Who you are on which instance, the companies you can see, and what you may do on the one in use. |
265
267
  | `ekwo contact add` / `list` | A customer or a supplier, and finding one again. |
266
- | `ekwo invoice new` / `invoice line add` | A draft document — any kind, with `--type` — and one more line on it. A draft books nothing. |
268
+ | `ekwo doc new` / `doc line add` | A draft document — any kind, with `--type` — and one more line on it. A draft books nothing. `ekwo invoice` is the old name of `ekwo doc`, kept as an alias. |
267
269
  | `ekwo post <document>` | Books it, through `post_document()`. `--dry-run` shows the entry the database would write and writes nothing. |
270
+ | `ekwo cancel <document>` | Undoes a posted invoice, and says how. Back to draft, through `unpost_document()`, where its country allows it and nothing about it has left; otherwise through `cancel_document()`: the credit note that names it, posted and matched against it, and the invoice cancelled. `--date` books the credit note on another day than the invoice's, which is how a locked period is stepped over; `--credit` asks for the note where a draft was possible. |
271
+ | `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`. |
268
272
  | `ekwo payment record` | Money in or out, booked and matched. With `--doc`, against that document. |
269
273
  | `ekwo match <transaction> <document>` | A bank statement line pays a document, through `settle_from_statement()`. |
270
274
  | `ekwo doc list` / `show` | What exists, and with `--unpaid` what is posted and still owed. See [keeping books](#keeping-books). |
@@ -280,6 +284,10 @@ a terminal and never when `NO_COLOR` is set, no spinner and no line redrawn in
280
284
  place, so the output reads the same in a file or a CI log — and takes `--json`
281
285
  for a program.
282
286
 
287
+ `ekwo help --json` answers the list of commands and, in `usage`, the whole
288
+ text of `--help` without colour: every flag and variable, for an assistant
289
+ that reads one document rather than a terminal.
290
+
283
291
  Under `--json` the standard output is **one JSON document and nothing else**;
284
292
  the prose still goes by, on the standard error. The document has the same
285
293
  shape whatever happened:
@@ -423,11 +431,12 @@ them as it reads a driver's.
423
431
 
424
432
  ```bash
425
433
  ekwo contact add "Client Example" --country <cc> --ref crm-42
426
- ekwo invoice new --contact client --date 2026-06-15 --ref job-7 \
434
+ ekwo doc new --contact client --date 2026-06-15 --ref job-7 \
427
435
  --line "name=Audit,price=1500.00,account=<account code>,tax=<tax code>"
428
- ekwo invoice line add job-7 --name Travel --price 250.00 --account <account code>
436
+ ekwo doc line add job-7 --name Travel --price 250.00 --account <account code>
429
437
  ekwo post job-7 --dry-run # the entry the database would write; nothing is written
430
438
  ekwo post job-7 # post_document()
439
+ ekwo cancel job-7 # back to draft where the country allows it, else the credit note
431
440
  ekwo payment record --doc job-7 --amount 1750.00 --date 2026-06-30 --bank-account <id> --ref bank-1
432
441
  ekwo match <bank transaction id> job-9
433
442
  ekwo doc list --unpaid --since 2026-06-01 --json
@@ -439,8 +448,9 @@ and none is ever picked for you: with no company in use a verb ends on
439
448
 
440
449
  **Each verb is one function, and it is not ours.** The functions live in
441
450
  `@ekwo-ai/core` and the MCP server calls the same ones: `contact add` is
442
- `create_contact`, `invoice new` is `create_document`, `post` is
443
- `post_document`, `payment record` is `record_payment`, `doc list` and
451
+ `create_contact`, `doc new` is `create_document`, `post` is
452
+ `post_document`, `cancel` is `unpost_document` or `cancel_document` `unpost_refusal` chooses —, `reverse` is `reverse_entry`,
453
+ `payment record` is `record_payment`, `doc list` and
444
454
  `doc show` are `list_documents` and `get_document`. Underneath them the rules
445
455
  are the schema's — the balance, the numbering, the locks, the taxes, the
446
456
  territory, the tax point. **This CLI computes no amount**: what you type goes
@@ -456,7 +466,7 @@ not a draft, a document with nothing open — is exit code 2: the call has to
456
466
  change.
457
467
 
458
468
  **`--ref`, so that nothing is created twice.** On what creates (`contact add`,
459
- `invoice new`, `payment record`), `--ref <your reference>` is kept on the row,
469
+ `doc new`, `payment record`), `--ref <your reference>` is kept on the row,
460
470
  unique per company. The same reference a second time returns what the first
461
471
  call created, with `"replayed": true`, and writes nothing — and finishes what
462
472
  a dropped connection left half done: a draft whose lines never arrived, a
@@ -481,7 +491,7 @@ given beside it win.
481
491
  ```bash
482
492
  echo '{"contact":"client","document_date":"2026-06-15","client_ref":"job-8",
483
493
  "lines":[{"name":"Review, \"urgent\"","unit_price":"200.00","account_code":"<code>"}]}' \
484
- | ekwo invoice new --stdin --json
494
+ | ekwo doc new --stdin --json
485
495
  ```
486
496
 
487
497
  **`--line`, for a person.** Named fields, never positions: `name`, `price`,
@@ -637,12 +647,38 @@ migration runner and by nothing else.
637
647
 
638
648
  ```sh
639
649
  ekwo pack list # the packs this checkout carries, and their certification
640
- ekwo pack build be # write supabase/seed/10_pack_be.sql from packs/be
650
+ ekwo pack describe # everything each of them says; one country with `describe <cc>`
651
+ ekwo pack build be # write supabase/seed/10_pack_be.sql from packs/be, and the lists of packs
641
652
  ekwo pack build --all
642
- ekwo pack check be # validate one pack and compare its seed
643
- ekwo pack check --all # exit 1 if a committed seed is not the output of its pack
653
+ ekwo pack check be # validate one pack, compare its seed and the lists of packs
654
+ ekwo pack check --all # exit 1 if a committed seed or list is not the output of the packs
655
+ ```
656
+
657
+ The lists are the blocks of other files that name every pack — the seeds of
658
+ `supabase/config.toml` and of the root README, the `/packs/<cc>/` lines of
659
+ `.github/CODEOWNERS`, the table of `docs/packs.md` — each between a
660
+ `generated:<name>` marker and `/generated`. They are written from `packs/` the
661
+ way a seed is, so a country is added in `packs/<cc>/` and nowhere else.
662
+
663
+ `list` is a line per country. `describe` is the whole of one: the charts and
664
+ who each is published for, the taxes and their distinct rates, the periodic
665
+ declaration with its cadences and its boxes, whether the country states a rule
666
+ for when the return is due, the brick that writes the file it is deposited as
667
+ or that it is filed by hand on a portal, the e-invoicing profile and the day it
668
+ starts, the accounts the tax balance lands on, every bank statement format the
669
+ country names and whether anything here reads it, the financial statements, and
670
+ the texts the pack was built from with the day each was last opened. Every
671
+ answer is read from the pack, and a "not yet" is printed rather than left out.
672
+
673
+ ```sh
674
+ ekwo pack describe --json | jq '.data.packs[] | {country, version}'
644
675
  ```
645
676
 
677
+ Under `--json` the whole description of every pack is the result. It is the
678
+ same object the site at [ekwo.ai](https://ekwo.ai/countries/) builds each
679
+ country's page from, so the site and the command line cannot come to say
680
+ different things about a country.
681
+
646
682
  `check` validates every file of the pack against
647
683
  [`packs/schema/pack.1.json`](../../packs/schema/pack.1.json) and against the
648
684
  rest of the pack, then compares the committed seed with what the compiler makes
@@ -704,8 +740,8 @@ dashboard under Connect → Session pooler, is the form that is never derived.
704
740
  | `--admin-password <pw>` | Their password. Omitted, an invite link is generated and printed. |
705
741
  | `--admin-user-id <uuid>` | Use an account that already exists, instead of creating one. |
706
742
  | `--fiscal-year <year>` | Calendar year of the first financial year. Defaults to this year. |
707
- | `--fiscal-year-start <date>` | The day that year opens, as `YYYY-MM-DD`. Needed only where the pack names no usual opening month; the two packs shipped both open on the calendar year. |
708
- | `--currency <code>` | Currency of the company. Defaults to what the country model says: `EUR` for both countries shipped. |
743
+ | `--fiscal-year-start <date>` | The day that year opens, as `YYYY-MM-DD`. Needed only where the pack names no usual opening month (`defaults.fiscal_year_default`). |
744
+ | `--currency <code>` | Currency of the company. Defaults to the pack's `defaults.currency`. |
709
745
  | `--language <xx>` | Language of the books, two letters. Defaults to `country_defaults.language_default`, which the pack fills. It decides which label of the pack lands on each account; the others are kept in `name_i18n`. |
710
746
  | `--iban <iban>` | Creates the main bank account, wired to the bank journal and its ledger account. Omitted, no bank account is created and `ekwo doctor` says so. |
711
747
  | `--bic <bic>` | Optional, on that account. |
@@ -713,6 +749,7 @@ dashboard under Connect → Session pooler, is the form that is never derived.
713
749
  | `--demo` | Also load the sample company. |
714
750
  | `--register` | Register without being asked. `--register-email` sets the address. |
715
751
  | `--registry-url <url>` | Where the registration is announced. |
752
+ | `--no-modules` | Leave the modules out. By default `init` installs them, as `ekwo migrate` does — empty schemas until a company enables one. |
716
753
 
717
754
  Every command takes `--json`; see [what a command answers](#what-a-command-answers---json-and-the-exit-codes).
718
755
  `ekwo migrate` takes `--skip-seeds`.