shutro-erp 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/README.md +74 -67
  2. package/dist/account_portal/.kosh/bindings.d.ts +22 -0
  3. package/dist/account_portal/.kosh/bindings.js +15 -0
  4. package/dist/account_portal/.kosh/schema.d.ts +1380 -0
  5. package/dist/account_portal/index.d.ts +3 -0
  6. package/dist/account_portal/index.js +73 -0
  7. package/dist/account_portal/module.d.ts +5983 -0
  8. package/dist/account_portal/module.js +18 -0
  9. package/dist/accounting/.kosh/bindings.js +1 -1
  10. package/dist/accounting/.kosh/schema.d.ts +172 -9
  11. package/dist/accounting/chart.d.ts +40 -8
  12. package/dist/accounting/chart.js +124 -30
  13. package/dist/accounting/closing.d.ts +6 -1
  14. package/dist/accounting/closing.js +5 -1
  15. package/dist/accounting/demo.js +6 -5
  16. package/dist/accounting/index.d.ts +3 -3
  17. package/dist/accounting/index.js +200 -23
  18. package/dist/accounting/module.d.ts +3326 -1086
  19. package/dist/accounting/module.js +408 -66
  20. package/dist/accounting/payments.d.ts +25 -0
  21. package/dist/accounting/payments.js +96 -4
  22. package/dist/accounting/web/RegisterPayment.d.ts +3 -2
  23. package/dist/accounting/web/RegisterPayment.js +39 -6
  24. package/dist/accounting/web/SettingsPage.js +5 -1
  25. package/dist/accounting/web/messages.js +10 -0
  26. package/dist/assistant/routes.js +1 -1
  27. package/dist/automation/engine.js +1 -1
  28. package/dist/automation/web/messages.js +2 -2
  29. package/dist/cli/apps.d.ts +1 -1
  30. package/dist/cli/apps.js +14 -14
  31. package/dist/cli/bin.js +3 -0
  32. package/dist/cli/index.js +11 -11
  33. package/dist/cli/init.d.ts +1 -1
  34. package/dist/cli/init.js +224 -78
  35. package/dist/cli/launch.d.ts +16 -0
  36. package/dist/cli/launch.js +138 -0
  37. package/dist/cli/project.d.ts +7 -7
  38. package/dist/cli/project.js +25 -25
  39. package/dist/cli/prompt.d.ts +35 -0
  40. package/dist/cli/prompt.js +48 -2
  41. package/dist/cli/templates.d.ts +14 -6
  42. package/dist/cli/templates.js +61 -34
  43. package/dist/cli/tui.d.ts +7 -0
  44. package/dist/cli/tui.js +254 -0
  45. package/dist/cli/ui.d.ts +21 -8
  46. package/dist/cli/ui.js +65 -19
  47. package/dist/contacts/.kosh/bindings.js +1 -1
  48. package/dist/contacts/.kosh/schema.d.ts +33 -1
  49. package/dist/contacts/index.js +24 -1
  50. package/dist/contacts/module.d.ts +42 -0
  51. package/dist/contacts/module.js +3 -1
  52. package/dist/import/convert.d.ts +55 -0
  53. package/dist/import/convert.js +224 -0
  54. package/dist/import/csv.d.ts +28 -0
  55. package/dist/import/csv.js +115 -0
  56. package/dist/import/index.d.ts +33 -0
  57. package/dist/import/index.js +60 -0
  58. package/dist/import/mapping.d.ts +15 -0
  59. package/dist/import/mapping.js +33 -0
  60. package/dist/import/match.d.ts +24 -0
  61. package/dist/import/match.js +60 -0
  62. package/dist/import/models.d.ts +2 -0
  63. package/dist/import/models.js +102 -0
  64. package/dist/import/routes.d.ts +13 -0
  65. package/dist/import/routes.js +392 -0
  66. package/dist/import/run.d.ts +131 -0
  67. package/dist/import/run.js +568 -0
  68. package/dist/import/service.d.ts +153 -0
  69. package/dist/import/service.js +367 -0
  70. package/dist/import/web/ImportButton.d.ts +7 -0
  71. package/dist/import/web/ImportButton.js +31 -0
  72. package/dist/import/web/ImportWizard.d.ts +75 -0
  73. package/dist/import/web/ImportWizard.js +217 -0
  74. package/dist/import/web/index.d.ts +13 -0
  75. package/dist/import/web/index.js +18 -0
  76. package/dist/import/web/messages.d.ts +2 -0
  77. package/dist/import/web/messages.js +139 -0
  78. package/dist/import/worker.d.ts +3 -0
  79. package/dist/import/worker.js +52 -0
  80. package/dist/import/xlsx.d.ts +20 -0
  81. package/dist/import/xlsx.js +192 -0
  82. package/dist/l10n_bd/.kosh/bindings.d.ts +22 -0
  83. package/dist/l10n_bd/.kosh/bindings.js +15 -0
  84. package/dist/l10n_bd/.kosh/schema.d.ts +1311 -0
  85. package/dist/l10n_bd/documents.d.ts +8 -0
  86. package/dist/l10n_bd/documents.js +183 -0
  87. package/dist/l10n_bd/index.d.ts +8 -0
  88. package/dist/l10n_bd/index.js +156 -0
  89. package/dist/l10n_bd/module.d.ts +5705 -0
  90. package/dist/l10n_bd/module.js +163 -0
  91. package/dist/l10n_bd/mushak.d.ts +67 -0
  92. package/dist/l10n_bd/mushak.js +139 -0
  93. package/dist/l10n_bd/routes.d.ts +3 -0
  94. package/dist/l10n_bd/routes.js +205 -0
  95. package/dist/l10n_bd/web/MushakPage.d.ts +7 -0
  96. package/dist/l10n_bd/web/MushakPage.js +53 -0
  97. package/dist/l10n_bd/web/index.d.ts +13 -0
  98. package/dist/l10n_bd/web/index.js +18 -0
  99. package/dist/l10n_bd/web/messages.d.ts +2 -0
  100. package/dist/l10n_bd/web/messages.js +101 -0
  101. package/dist/l10n_in/.kosh/bindings.d.ts +22 -0
  102. package/dist/l10n_in/.kosh/bindings.js +15 -0
  103. package/dist/l10n_in/.kosh/schema.d.ts +1373 -0
  104. package/dist/l10n_in/documents.d.ts +8 -0
  105. package/dist/l10n_in/documents.js +114 -0
  106. package/dist/l10n_in/einvoice.d.ts +253 -0
  107. package/dist/l10n_in/einvoice.js +485 -0
  108. package/dist/l10n_in/gstr.d.ts +109 -0
  109. package/dist/l10n_in/gstr.js +430 -0
  110. package/dist/l10n_in/index.d.ts +20 -0
  111. package/dist/l10n_in/index.js +232 -0
  112. package/dist/l10n_in/module.d.ts +7823 -0
  113. package/dist/l10n_in/module.js +427 -0
  114. package/dist/l10n_in/routes-einvoice.d.ts +15 -0
  115. package/dist/l10n_in/routes-einvoice.js +124 -0
  116. package/dist/l10n_in/routes.d.ts +17 -0
  117. package/dist/l10n_in/routes.js +282 -0
  118. package/dist/l10n_in/web/EInvoicePanel.d.ts +8 -0
  119. package/dist/l10n_in/web/EInvoicePanel.js +63 -0
  120. package/dist/l10n_in/web/GstPage.d.ts +7 -0
  121. package/dist/l10n_in/web/GstPage.js +57 -0
  122. package/dist/l10n_in/web/GstSettings.d.ts +10 -0
  123. package/dist/l10n_in/web/GstSettings.js +36 -0
  124. package/dist/l10n_in/web/index.d.ts +15 -0
  125. package/dist/l10n_in/web/index.js +22 -0
  126. package/dist/l10n_in/web/messages.d.ts +2 -0
  127. package/dist/l10n_in/web/messages.js +166 -0
  128. package/dist/mail/index.js +2 -2
  129. package/dist/modules-sdk/demo.d.ts +2 -0
  130. package/dist/modules-sdk/demo.js +7 -3
  131. package/dist/modules-sdk/index.d.ts +2 -2
  132. package/dist/modules-sdk/index.js +1 -1
  133. package/dist/modules-sdk/loader.js +2 -2
  134. package/dist/modules-sdk/manifest.d.ts +132 -0
  135. package/dist/modules-sdk/manifest.js +22 -0
  136. package/dist/notify/inbox.js +21 -0
  137. package/dist/notify/messages.js +7 -3
  138. package/dist/notify/models.d.ts +1 -1
  139. package/dist/notify/models.js +2 -0
  140. package/dist/notify/routes.js +1 -1
  141. package/dist/notify/web/messages.js +5 -1
  142. package/dist/portal/.kosh/bindings.d.ts +22 -0
  143. package/dist/portal/.kosh/bindings.js +15 -0
  144. package/dist/portal/.kosh/schema.d.ts +376 -0
  145. package/dist/portal/announce.d.ts +16 -0
  146. package/dist/portal/announce.js +117 -0
  147. package/dist/portal/documents.d.ts +17 -0
  148. package/dist/portal/documents.js +61 -0
  149. package/dist/portal/index.d.ts +20 -0
  150. package/dist/portal/index.js +65 -0
  151. package/dist/portal/module.d.ts +1405 -0
  152. package/dist/portal/module.js +84 -0
  153. package/dist/portal/routes-documents.d.ts +2 -0
  154. package/dist/portal/routes-documents.js +391 -0
  155. package/dist/portal/routes.d.ts +13 -0
  156. package/dist/portal/routes.js +313 -0
  157. package/dist/portal/rules.d.ts +11 -0
  158. package/dist/portal/rules.js +25 -0
  159. package/dist/portal/web/PortalAccess.d.ts +8 -0
  160. package/dist/portal/web/PortalAccess.js +66 -0
  161. package/dist/portal/web/index.d.ts +12 -0
  162. package/dist/portal/web/index.js +17 -0
  163. package/dist/portal/web/messages.d.ts +2 -0
  164. package/dist/portal/web/messages.js +33 -0
  165. package/dist/product/.kosh/bindings.js +1 -1
  166. package/dist/product/.kosh/schema.d.ts +42 -3
  167. package/dist/product/demo.js +6 -5
  168. package/dist/product/index.d.ts +1 -0
  169. package/dist/product/index.js +17 -4
  170. package/dist/product/module.d.ts +346 -14
  171. package/dist/product/module.js +48 -18
  172. package/dist/product/taxes.d.ts +59 -0
  173. package/dist/product/taxes.js +61 -0
  174. package/dist/project/.kosh/bindings.js +1 -1
  175. package/dist/project/.kosh/schema.d.ts +33 -1
  176. package/dist/project/module.d.ts +20 -0
  177. package/dist/project_portal/.kosh/bindings.d.ts +22 -0
  178. package/dist/project_portal/.kosh/bindings.js +15 -0
  179. package/dist/project_portal/.kosh/schema.d.ts +701 -0
  180. package/dist/project_portal/index.d.ts +9 -0
  181. package/dist/project_portal/index.js +42 -0
  182. package/dist/project_portal/module.d.ts +2142 -0
  183. package/dist/project_portal/module.js +22 -0
  184. package/dist/purchase/.kosh/bindings.js +1 -1
  185. package/dist/purchase/.kosh/schema.d.ts +45 -4
  186. package/dist/purchase/demo.js +3 -3
  187. package/dist/purchase/index.js +1 -1
  188. package/dist/purchase/module.d.ts +232 -8
  189. package/dist/purchase/module.js +51 -9
  190. package/dist/purchase_account/.kosh/bindings.js +1 -1
  191. package/dist/purchase_account/.kosh/schema.d.ts +174 -10
  192. package/dist/purchase_account/module.d.ts +2008 -641
  193. package/dist/purchase_account/module.js +2 -2
  194. package/dist/purchase_portal/.kosh/bindings.d.ts +22 -0
  195. package/dist/purchase_portal/.kosh/bindings.js +15 -0
  196. package/dist/purchase_portal/.kosh/schema.d.ts +852 -0
  197. package/dist/purchase_portal/index.d.ts +9 -0
  198. package/dist/purchase_portal/index.js +53 -0
  199. package/dist/purchase_portal/module.d.ts +2758 -0
  200. package/dist/purchase_portal/module.js +18 -0
  201. package/dist/reporting/documents.js +20 -3
  202. package/dist/reporting/index.d.ts +1 -0
  203. package/dist/reporting/index.js +1 -0
  204. package/dist/reporting/routes-documents.js +9 -2
  205. package/dist/reporting/words.d.ts +11 -0
  206. package/dist/reporting/words.js +229 -0
  207. package/dist/sale_account/.kosh/bindings.js +1 -1
  208. package/dist/sale_account/.kosh/schema.d.ts +174 -10
  209. package/dist/sale_account/module.d.ts +2008 -641
  210. package/dist/sale_account/module.js +3 -3
  211. package/dist/sale_portal/.kosh/bindings.d.ts +22 -0
  212. package/dist/sale_portal/.kosh/bindings.js +15 -0
  213. package/dist/sale_portal/.kosh/schema.d.ts +766 -0
  214. package/dist/sale_portal/index.d.ts +9 -0
  215. package/dist/sale_portal/index.js +71 -0
  216. package/dist/sale_portal/module.d.ts +2718 -0
  217. package/dist/sale_portal/module.js +19 -0
  218. package/dist/sale_project/.kosh/bindings.js +1 -1
  219. package/dist/sale_project/.kosh/schema.d.ts +45 -4
  220. package/dist/sale_project/module.d.ts +390 -10
  221. package/dist/sales/.kosh/bindings.js +1 -1
  222. package/dist/sales/.kosh/schema.d.ts +45 -4
  223. package/dist/sales/demo.js +3 -3
  224. package/dist/sales/index.js +67 -1
  225. package/dist/sales/module.d.ts +232 -8
  226. package/dist/sales/module.js +51 -12
  227. package/dist/server/api/client.js +1 -1
  228. package/dist/server/api/openapi.js +17 -1
  229. package/dist/server/apps.js +5 -5
  230. package/dist/server/auth/api-keys.d.ts +13 -0
  231. package/dist/server/auth/api-keys.js +65 -0
  232. package/dist/server/auth/base.js +26 -0
  233. package/dist/server/auth/crypto.js +1 -1
  234. package/dist/server/auth/scopes.d.ts +12 -0
  235. package/dist/server/auth/scopes.js +51 -0
  236. package/dist/server/auth/service.d.ts +59 -1
  237. package/dist/server/auth/service.js +236 -6
  238. package/dist/server/demo.d.ts +1 -1
  239. package/dist/server/demo.js +1 -1
  240. package/dist/server/env-names.d.ts +2 -0
  241. package/dist/server/env-names.js +16 -0
  242. package/dist/server/host.js +5 -1
  243. package/dist/server/identity.d.ts +7 -0
  244. package/dist/server/index.d.ts +2 -1
  245. package/dist/server/index.js +2 -1
  246. package/dist/server/registry.js +1 -1
  247. package/dist/server/server.d.ts +5 -0
  248. package/dist/server/server.js +71 -6
  249. package/dist/settings/routes.js +1 -1
  250. package/dist/settings/web/ApiKeysPage.d.ts +8 -0
  251. package/dist/settings/web/ApiKeysPage.js +70 -0
  252. package/dist/settings/web/index.d.ts +1 -0
  253. package/dist/settings/web/index.js +4 -0
  254. package/dist/settings/web/messages.js +62 -0
  255. package/dist/storage/routes.js +1 -1
  256. package/dist/studio/build.js +1 -1
  257. package/dist/studio/generate.js +4 -4
  258. package/dist/studio/module.js +5 -5
  259. package/dist/studio/web/messages.js +2 -2
  260. package/dist/ui/api.d.ts +2 -0
  261. package/dist/ui/app.js +27 -4
  262. package/dist/ui/context.d.ts +3 -1
  263. package/dist/ui/context.js +2 -2
  264. package/dist/ui/i18n/messages.js +2 -2
  265. package/dist/ui/index.d.ts +1 -1
  266. package/dist/ui/index.js +1 -1
  267. package/dist/ui/lib/format.d.ts +2 -0
  268. package/dist/ui/lib/format.js +3 -1
  269. package/dist/ui/pwa/worker.js +2 -2
  270. package/dist/ui/registry.d.ts +15 -0
  271. package/dist/ui/registry.js +20 -0
  272. package/dist/ui/views/FormView.js +19 -6
  273. package/package.json +52 -4
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # shutro-erp
2
2
 
3
- **Kosh** is an ERP framework for Node.js, TypeScript and PostgreSQL, built on the
3
+ **Shutro ERP** is an ERP framework for Node.js, TypeScript and PostgreSQL, built on the
4
4
  [Shutro](https://www.npmjs.com/package/shutro) ORM. Define a model once and get a REST API with OpenAPI, a typed
5
5
  client, list / form / kanban / pivot / graph / calendar / gantt / map / dashboard views, exports, PDF documents and a
6
6
  chatter on every record. Permissions are checked on the server on every route.
@@ -20,13 +20,13 @@ chatter on every record. Permissions are checked on the server on every route.
20
20
  ## Requirements
21
21
 
22
22
  - **Node.js 24** or later (`node --version`)
23
- - **PostgreSQL 16** or later, or **Docker** (Kosh can start PostgreSQL for you)
23
+ - **PostgreSQL 16** or later, or **Docker** (Shutro ERP can start PostgreSQL for you)
24
24
  - An authenticator app for the administrator's second factor (Google Authenticator, Microsoft Authenticator,
25
25
  1Password, …)
26
26
 
27
27
  ## Install with the terminal
28
28
 
29
- One command creates the project, installs Kosh and asks for everything it needs:
29
+ One command creates the project, installs Shutro ERP and asks for everything it needs:
30
30
 
31
31
  ```sh
32
32
  npx shutro-erp@latest init my-erp # the project my-erp
@@ -37,54 +37,61 @@ npx shutro-erp@latest init # asks for the project name first
37
37
 
38
38
  ```sh
39
39
  npm install shutro-erp # Shutro, the ORM, comes with it
40
- npx kosh init
40
+ npx shutro-erp init
41
41
  ```
42
42
 
43
- The setup asks for what the installation needs. Press **Enter** to keep the value in `[brackets]`:
43
+ The setup asks for what the installation needs, one question at a time: type an answer or press **Enter** for
44
+ the default shown, pick from lists with **↑ ↓** and **Enter**, tick apps with **Space**, stop with **Ctrl+C**
45
+ (piped or scripted, the same questions are asked line by line):
44
46
 
45
47
  | Question | Example | Notes |
46
48
  |---|---|---|
47
- | PostgreSQL | `1` your server, `2` start one in Docker | `2` needs Docker Desktop running; it writes `compose.yaml` and starts the `db` service |
49
+ | PostgreSQL | your server, or start one in Docker | Docker needs Docker Desktop running; it writes `compose.yaml` and starts the `db` service |
48
50
  | Username, password, port, host, database name | `postgres`, (hidden), `5432`, `localhost`, `my_erp` | for `1`; a missing database is created after you confirm; if nothing answers, it offers Docker instead |
49
- | Company name, currency | `Padma Traders`, `BDT` | the first company; more companies later |
51
+ | Company name, currency, country | `Padma Traders`, `BDT`, Bangladesh | the first company; a country with a localization gets its taxes, chart and returns |
50
52
  | Language, time zone | `bn`, `Asia/Dhaka` | the administrator's |
51
53
  | Administrator login, name, email, password | `admin`, …, 12+ characters | the password is typed hidden and stored only as a hash |
52
- | Apps | `permissions,reporting,messaging` | roles and approvals, reports and documents, chatter and attachments |
53
- | File storage | `1` a folder, `2` S3-compatible | S3, SeaweedFS, MinIO; the bucket is created |
54
+ | Apps | all ticked; untick what you do not need | roles and approvals, reports, chatter, the business apps |
55
+ | File storage | a folder, or S3-compatible | S3, SeaweedFS, MinIO; the bucket is created |
54
56
  | Valkey/Redis URL | empty | optional: rate limits and caches shared by several servers |
55
- | API port | `3000` | |
57
+ | API port, back-office (web) port | `3000`, `5173` | the next free ones are proposed |
56
58
  | Authenticator code | `123456` | scan the printed secret, type a code; **keep the recovery codes** it prints |
57
59
 
58
60
  Then it writes the project, creates the database tables (`migrations/0001_init.sql`), the company and the
59
- administrator, and loads the apps' default data. Run `npm install` once in the project, then start it:
61
+ administrator, and loads the apps' default data. **Then it starts Shutro ERP for you**: it installs the project's
62
+ dependencies (with the package manager you ran it with: npm, pnpm, yarn or bun), starts the API and the
63
+ back-office, waits until both answer, and opens the back-office in your browser on the web port. Both keep
64
+ running in that terminal; **Ctrl+C** stops them. Sign in with the administrator's login, password and a code from
65
+ the authenticator app.
66
+
67
+ To start it again later (or after `--no-start`, which only sets up):
60
68
 
61
69
  ```sh
70
+ cd my-erp
62
71
  npm start # the API on http://localhost:3000
63
72
  npm run web # the back-office on http://localhost:5173, in a second terminal
64
73
  ```
65
74
 
66
- Sign in with the administrator's login, password and a code from the authenticator app.
67
-
68
75
  **Without questions** (scripts, CI): pass the answers as flags.
69
76
 
70
77
  ```sh
71
78
  npx shutro-erp@latest init my-erp --yes --docker-db --admin-password "a long passphrase here"
72
79
 
73
- npx kosh init --yes \
80
+ npx shutro-erp init --yes \
74
81
  --database-url postgres://postgres:postgres@localhost:5432/my_erp --create-database \
75
82
  --company "Padma Traders" --currency BDT --lang bn --tz Asia/Dhaka \
76
83
  --admin-login admin --admin-password "a long passphrase here" \
77
- --apps permissions,reporting,messaging --storage-dir ./var/attachments --port 3000
84
+ --apps permissions,reporting,messaging --storage-dir ./var/attachments --port 3000 --web-port 5173
78
85
  ```
79
86
 
80
- With `--yes` nothing is asked, so the authenticator is not enrolled: run `npx kosh init` again in a terminal to
81
- enrol it (administrator rights wait for it). `npx kosh init --help` lists every flag. Replies by email: set `MAIL_INBOUND_DOMAIN` in `.env` (the secrets are generated) and point your email provider's inbound webhook at `/api/v1/mail/inbound` with the `MAIL_INBOUND_WEBHOOK_SECRET`. `--demo` (or a yes to the
87
+ With `--yes` nothing is asked, so the authenticator is not enrolled: run `npx shutro-erp init` again in a terminal to
88
+ enrol it (administrator rights wait for it). `npx shutro-erp init --help` lists every flag. Replies by email: set `MAIL_INBOUND_DOMAIN` in `.env` (the secrets are generated) and point your email provider's inbound webhook at `/api/v1/mail/inbound` with the `MAIL_INBOUND_WEBHOOK_SECRET`. `--demo` (or a yes to the
82
89
  question after the apps) loads a sample company with contacts, products, orders, invoices and projects, made by
83
90
  the demo users `dina`, `rahim`, `karim` and `sumi` (one shared password, printed at the end); not for production.
84
91
 
85
92
  ## Install with Docker
86
93
 
87
- `kosh init` writes `Dockerfile`, `compose.yaml`, `nginx.conf` and `.dockerignore` into every project.
94
+ `shutro-erp init` writes `Dockerfile`, `compose.yaml`, `nginx.conf` and `.dockerignore` into every project.
88
95
 
89
96
  **PostgreSQL in Docker, the app on your machine** (development):
90
97
 
@@ -110,21 +117,21 @@ docker compose up -d --build # db + api + web; the back-office on http://
110
117
  | Service | What | Port |
111
118
  |---|---|---|
112
119
  | `db` | PostgreSQL 18, data in the `db` volume | `127.0.0.1:5432` (`POSTGRES_PORT`) |
113
- | `api` | the Kosh API; runs `kosh migrate` on every start, then serves | inside the network (`api:3000`) |
120
+ | `api` | the Shutro ERP API; runs `shutro-erp migrate` on every start, then serves | inside the network (`api:3000`) |
114
121
  | `web` | nginx with the built back-office, `/api` proxied to `api` | `8080` (`WEB_PORT`) |
115
122
 
116
123
  Useful commands:
117
124
 
118
125
  ```sh
119
126
  docker compose logs -f api # the API's log
120
- docker compose exec api npx kosh migrate status # any kosh command inside the container
121
- docker compose exec api npx kosh seed
127
+ docker compose exec api npx shutro-erp migrate status # any shutro-erp command inside the container
128
+ docker compose exec api npx shutro-erp seed
122
129
  docker compose up -d --build api # after changing modules: rebuild and migrate
123
130
  docker compose down # stop (volumes keep the data)
124
- docker compose exec db pg_dump -U kosh my_erp > backup.sql # a backup
131
+ docker compose exec db pg_dump -U shutro my_erp > backup.sql # a backup
125
132
  ```
126
133
 
127
- Behind HTTPS, set `KOSH_SECURE_COOKIES: "true"` in `compose.yaml`. To use a PostgreSQL server outside Docker, set
134
+ Behind HTTPS, set `SHUTRO_ERP_SECURE_COOKIES: "true"` in `compose.yaml`. To use a PostgreSQL server outside Docker, set
128
135
  `DOCKER_DATABASE_URL` in `.env` (an address the container can reach, not `localhost`).
129
136
 
130
137
  ## Project structure
@@ -137,7 +144,7 @@ my-erp/
137
144
  ├── src/
138
145
  │ ├── modules.ts the installed modules: base, the apps, your modules
139
146
  │ ├── server.ts the API server (npm start)
140
- │ ├── modules/ your modules (kosh module create <name>)
147
+ │ ├── modules/ your modules (shutro-erp module create <name>)
141
148
  │ │ └── library/
142
149
  │ │ ├── index.ts the module: groups, access levels, app, menus, actions, views
143
150
  │ │ ├── models.ts its models (fields, access per group, record rules)
@@ -145,7 +152,7 @@ my-erp/
145
152
  │ │ └── migrations.ts its data migrations
146
153
  │ └── web/
147
154
  │ ├── main.tsx the back-office (React): renderers of each installed app
148
- │ └── index.css Tailwind + Kosh's design tokens
155
+ │ └── index.css Tailwind + Shutro ERP's design tokens
149
156
  ├── index.html, vite.config.ts the back-office build (npm run web / build:web)
150
157
  ├── Dockerfile, compose.yaml, nginx.conf, .dockerignore
151
158
  └── var/attachments/ uploaded files (with folder storage)
@@ -156,8 +163,8 @@ my-erp/
156
163
  A module is a folder with its models and a manifest. Create one:
157
164
 
158
165
  ```sh
159
- npx kosh module create library
160
- npx kosh migrate # creates its tables, records it, loads its seed data
166
+ npx shutro-erp module create library
167
+ npx shutro-erp migrate # creates its tables, records it, loads its seed data
161
168
  ```
162
169
 
163
170
  It writes `src/modules/library/` and adds `library` to `src/modules.ts`. After `npm start` and a reload of the
@@ -191,7 +198,7 @@ export const Book = defineModel('library.book', {
191
198
  ```
192
199
 
193
200
  **`index.ts`**: the module: its Shutro part (name, version, groups, models, seed data, data migrations) and its
194
- Kosh part (access levels, app, menus, actions, views):
201
+ Shutro ERP part (access levels, app, menus, actions, views):
195
202
 
196
203
  ```ts
197
204
  import { base, baseShutro } from 'shutro-erp';
@@ -252,29 +259,29 @@ export const modules = [base, messaging, library];
252
259
  ```
253
260
 
254
261
  ```sh
255
- npx kosh migrate # tables, the module's version (shutro_module), its seed data
262
+ npx shutro-erp migrate # tables, the module's version (shutro_module), its seed data
256
263
  ```
257
264
 
258
265
  A module published on npm installs the same way: `npm install <package>`, import it in `src/modules.ts`, then
259
- `npx kosh migrate`. Installing does not give anyone access: grant its roles to users ([Users and roles](#users-and-roles)).
266
+ `npx shutro-erp migrate`. Installing does not give anyone access: grant its roles to users ([Users and roles](#users-and-roles)).
260
267
 
261
- **Remove a module**: take it out of `src/modules.ts`; `npx kosh migrate` then plans dropping its tables, which is
262
- destructive: it stops for review, and `npx kosh migrate --allow-destructive` applies it. Back up first.
268
+ **Remove a module**: take it out of `src/modules.ts`; `npx shutro-erp migrate` then plans dropping its tables, which is
269
+ destructive: it stops for review, and `npx shutro-erp migrate --allow-destructive` applies it. Back up first.
263
270
 
264
271
  ## Migrations
265
272
 
266
273
  ```sh
267
- npx kosh migrate # plan + apply + seed
268
- npx kosh migrate --plan # only write the plan, to review it
269
- npx kosh migrate --name add_isbn # name the new file (migrations/0002_add_isbn.sql)
270
- npx kosh migrate status # applied and pending files
271
- npx kosh migrate --allow-destructive
274
+ npx shutro-erp migrate # plan + apply + seed
275
+ npx shutro-erp migrate --plan # only write the plan, to review it
276
+ npx shutro-erp migrate --name add_isbn # name the new file (migrations/0002_add_isbn.sql)
277
+ npx shutro-erp migrate status # applied and pending files
278
+ npx shutro-erp migrate --allow-destructive
272
279
  ```
273
280
 
274
- - **Schema migrations** are SQL files in `migrations/`. `kosh migrate` compares your modules with the live database
281
+ - **Schema migrations** are SQL files in `migrations/`. `shutro-erp migrate` compares your modules with the live database
275
282
  and writes the differences as the next file (`0002_update.sql`), applies every pending file in order (each in its
276
283
  own transaction, recorded in `shutro_migration`), then loads the seed data. Commit the files: a deployment runs the
277
- same ones (the Docker `api` service runs `kosh migrate` on start).
284
+ same ones (the Docker `api` service runs `shutro-erp migrate` on start).
278
285
  - **Destructive changes** (dropping a column or a table, narrowing a type) are written but not applied without
279
286
  `--allow-destructive`. A file written earlier and not applied yet is applied first.
280
287
  - **Per-module data migrations** change existing data when a module is upgraded. Declare them in the module's
@@ -298,7 +305,7 @@ export const migrations: DataMigration[] = [
298
305
 
299
306
  ```sh
300
307
  # index.ts: version: '0.2.0'
301
- npx kosh migrate # … module library: 0.1.0 → 0.2.0, data migration library@0.2.0
308
+ npx shutro-erp migrate # … module library: 0.1.0 → 0.2.0, data migration library@0.2.0
302
309
  ```
303
310
 
304
311
  ## Seed data
@@ -322,18 +329,18 @@ export const data = [
322
329
  ```
323
330
 
324
331
  ```sh
325
- npx kosh seed # every module's seed data, and the apps' defaults
326
- npx kosh seed library # one module (or several: kosh seed library inventory)
332
+ npx shutro-erp seed # every module's seed data, and the apps' defaults
333
+ npx shutro-erp seed library # one module (or several: shutro-erp seed library inventory)
327
334
  ```
328
335
 
329
- `kosh migrate` seeds too (skip with `--no-seed`). The apps' defaults are also seeded: approval policies
336
+ `shutro-erp migrate` seeds too (skip with `--no-seed`). The apps' defaults are also seeded: approval policies
330
337
  (permissions), document templates (reporting), activity types (messaging); users may edit them afterwards.
331
338
 
332
339
  ## Users and roles
333
340
 
334
341
  ```sh
335
- npx kosh user create rahim --name "Rahim Uddin" --email rahim@example.com --roles library.user,messaging.user
336
- npx kosh user password rahim # a new password (asked, hidden)
342
+ npx shutro-erp user create rahim --name "Rahim Uddin" --email rahim@example.com --roles library.user,messaging.user
343
+ npx shutro-erp user password rahim # a new password (asked, hidden)
337
344
  ```
338
345
 
339
346
  Roles are the groups of the installed modules' access levels (`library.user`, `library.manager`,
@@ -347,31 +354,31 @@ their roles grants it. Administrators manage roles, field security and grants in
347
354
  |---|---|
348
355
  | `DATABASE_URL` | PostgreSQL: `postgres://user:password@host:5432/database` |
349
356
  | `PORT`, `HOST` | the API's port (3000) and address (127.0.0.1; 0.0.0.0 in Docker) |
350
- | `KOSH_STORAGE_DIR` | attachments in this folder, or: |
357
+ | `SHUTRO_ERP_STORAGE_DIR` | attachments in this folder, or: |
351
358
  | `S3_ENDPOINT`, `S3_BUCKET`, `S3_ACCESS_KEY`, `S3_SECRET_KEY`, `S3_REGION` | S3-compatible storage |
352
- | `KOSH_ATTACHMENT_MAX_BYTES` | upload limit (25 MB) |
359
+ | `SHUTRO_ERP_ATTACHMENT_MAX_BYTES` | upload limit (25 MB) |
353
360
  | `VALKEY_URL` | optional Valkey/Redis: rate limits and caches across servers |
354
- | `KOSH_SECURE_COOKIES` | `true` behind HTTPS (default in production), `false` for plain HTTP |
355
- | `KOSH_SCHEDULES` | `off` stops the scheduled-report ticker on this server |
361
+ | `SHUTRO_ERP_SECURE_COOKIES` | `true` behind HTTPS (default in production), `false` for plain HTTP |
362
+ | `SHUTRO_ERP_SCHEDULES` | `off` stops the scheduled-report ticker on this server |
356
363
  | `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB`, `POSTGRES_PORT` | the Docker `db` service |
357
364
  | `DOCKER_DATABASE_URL`, `WEB_PORT` | Docker: another database for `api`; the back-office's port (8080) |
358
365
 
359
366
  ## Command reference
360
367
 
361
- Run them in the project folder (`npx kosh …`, or `npm run migrate` / `npm run seed`). They read `.env` and
368
+ Run them in the project folder (`npx shutro-erp …`, or `npm run migrate` / `npm run seed`). They read `.env` and
362
369
  `src/modules.ts` (`--modules <file>` for another list).
363
370
 
364
371
  | Command | What |
365
372
  |---|---|
366
- | `kosh init [folder]` | set up an installation (questions, or flags with `--yes`); again later to enrol 2FA |
367
- | `kosh migrate` | apply pending files, plan what is missing into a new file and apply it, run data migrations, seed |
368
- | `kosh migrate --plan` · `--name <n>` · `--allow-destructive` · `--no-seed` | review only · file name · drops · no seeding |
369
- | `kosh migrate status` | applied and pending migration files |
370
- | `kosh seed [module …]` | seed data of all modules, or of those named |
371
- | `kosh module create <name>` | a new module in `src/modules/<name>/`, listed in `src/modules.ts` |
372
- | `kosh user create <login>` | a user: `--name`, `--email`, `--roles`, `--password` (asked when missing) |
373
- | `kosh user password <login>` | a new password |
374
- | `kosh generate client` | a typed API client for your front-end (`--out src/api/kosh.gen.ts`) |
373
+ | `shutro-erp init [folder]` | set up an installation (questions, or flags with `--yes`); again later to enrol 2FA |
374
+ | `shutro-erp migrate` | apply pending files, plan what is missing into a new file and apply it, run data migrations, seed |
375
+ | `shutro-erp migrate --plan` · `--name <n>` · `--allow-destructive` · `--no-seed` | review only · file name · drops · no seeding |
376
+ | `shutro-erp migrate status` | applied and pending migration files |
377
+ | `shutro-erp seed [module …]` | seed data of all modules, or of those named |
378
+ | `shutro-erp module create <name>` | a new module in `src/modules/<name>/`, listed in `src/modules.ts` |
379
+ | `shutro-erp user create <login>` | a user: `--name`, `--email`, `--roles`, `--password` (asked when missing) |
380
+ | `shutro-erp user password <login>` | a new password |
381
+ | `shutro-erp generate client` | a typed API client for your front-end (`--out src/api/shutro-erp.gen.ts`) |
375
382
  | `npm start` · `npm run web` · `npm run build:web` | the API · the back-office (dev) · the back-office build (`dist/`) |
376
383
  | `npm run docker:up` | `docker compose up -d --build` |
377
384
 
@@ -380,26 +387,26 @@ Run them in the project folder (`npx kosh …`, or `npm run migrate` / `npm run
380
387
  | Import | What |
381
388
  |---|---|
382
389
  | `shutro-erp` | the server: `createServer`, `startServer`, `base`, REST + OpenAPI, sessions and 2FA |
383
- | `shutro-erp/orm` | Shutro (models, fields, groups, records, migrations) as Kosh uses it |
390
+ | `shutro-erp/orm` | Shutro (models, fields, groups, records, migrations) as Shutro ERP uses it |
384
391
  | `shutro-erp/modules-sdk` | `defineModule`: manifests, access levels, menus, actions |
385
392
  | `shutro-erp/views`, `shutro-erp/search` | view definitions (`list`, `form`, `kanban`, `pivot`, …) and the search layer |
386
393
  | `shutro-erp/permissions` | roles, field security, approvals (`/web`: the approval panel) |
387
394
  | `shutro-erp/reporting` | pivots, exports, documents, scheduled reports (`/web`: the report views) |
388
395
  | `shutro-erp/messaging`, `shutro-erp/storage` | the chatter, activities, attachments (`/web`: the chatter) |
389
396
  | `shutro-erp/ui` | the React app shell, design system and renderers; `shutro-erp/ui/styles.css` the tokens |
390
- | `shutro-erp/cli` | the `kosh` command's functions |
397
+ | `shutro-erp/cli` | the `shutro-erp` command's functions |
391
398
 
392
399
  ## Troubleshooting
393
400
 
394
401
  - **"PostgreSQL did not answer"**: nothing listens at that host and port. Start your PostgreSQL service, or
395
402
  answer `2` (Docker) to the first question; Docker Desktop must be running.
396
403
  - **"password authentication failed"**: the user or password in `DATABASE_URL` is wrong.
397
- - **Signed in but no apps**: the user has no role granting them (`kosh user create … --roles`); administrators need
398
- their authenticator enrolled (`npx kosh init` again).
399
- - **Sign-in works on the API but not in the browser over plain HTTP**: `KOSH_SECURE_COOKIES=false`.
400
- - **Lost the phone**: sign in with one of the recovery codes `kosh init` printed.
401
- - **"It drops or changes existing data"**: `kosh migrate` found a destructive change; read the new file in
402
- `migrations/`, back up, then `npx kosh migrate --allow-destructive`.
404
+ - **Signed in but no apps**: the user has no role granting them (`shutro-erp user create … --roles`); administrators need
405
+ their authenticator enrolled (`npx shutro-erp init` again).
406
+ - **Sign-in works on the API but not in the browser over plain HTTP**: `SHUTRO_ERP_SECURE_COOKIES=false`.
407
+ - **Lost the phone**: sign in with one of the recovery codes `shutro-erp init` printed.
408
+ - **"It drops or changes existing data"**: `shutro-erp migrate` found a destructive change; read the new file in
409
+ `migrations/`, back up, then `npx shutro-erp migrate --allow-destructive`.
403
410
 
404
411
  Documentation, design notes and the source: https://github.com/isahaq1/kosh
405
412
 
@@ -0,0 +1,22 @@
1
+ export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
2
+ import { type DefinitionHelpers } from '../../server/orm.js';
3
+ import type { DefaultLoaded, Env as CoreEnv, RecordSet as CoreRecordSet, Shutro as CoreShutro } from '../../server/orm.js';
4
+ import type { SchemaView } from './schema.js';
5
+ export type { SchemaView };
6
+ /** Every model visible in this view. */
7
+ export type ModelName = keyof SchemaView & string;
8
+ /** `Env` typed to this view. */
9
+ export type Env = CoreEnv<SchemaView>;
10
+ /** `Shutro` typed to this view. */
11
+ export type Shutro = CoreShutro<SchemaView>;
12
+ /** A recordset of `M`, with the default loaded shape unless `L` is given. */
13
+ export type Records<M extends ModelName, L = DefaultLoaded<SchemaView, M>> = CoreRecordSet<SchemaView, M, L>;
14
+ export declare const compute: DefinitionHelpers<SchemaView>['compute'];
15
+ export declare const check: DefinitionHelpers<SchemaView>['check'];
16
+ export declare const onchange: DefinitionHelpers<SchemaView>['onchange'];
17
+ export declare const records: DefinitionHelpers<SchemaView>['records'];
18
+ export declare const method: DefinitionHelpers<SchemaView>['method'];
19
+ /** Module data (RFC 0017): records, overrides of dependencies' records, and references, typed like creates. */
20
+ export declare const record: DefinitionHelpers<SchemaView>['record'];
21
+ export declare const override: DefinitionHelpers<SchemaView>['override'];
22
+ export declare const ref: DefinitionHelpers<SchemaView>['ref'];
@@ -0,0 +1,15 @@
1
+ // GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: 0ea5d21ac5b24166
2
+ // Bindings of module `account_portal`: import the definition API from here to get types scoped to what it can see.
3
+ export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
4
+ import { definitions } from '../../server/orm.js';
5
+ /** Definition callbacks typed against this module's view: no casts in computes, checks, onchange, methods. */
6
+ const helpers = definitions();
7
+ export const compute = helpers.compute;
8
+ export const check = helpers.check;
9
+ export const onchange = helpers.onchange;
10
+ export const records = helpers.records;
11
+ export const method = helpers.method;
12
+ /** Module data (RFC 0017): records, overrides of dependencies' records, and references, typed like creates. */
13
+ export const record = helpers.record;
14
+ export const override = helpers.override;
15
+ export const ref = helpers.ref;