Building a module without writing code
This whole tour assumes you write code. A good share of the people who deploy an ERP do not, and still have a precise business need to cover. The Builder is for them: describe a module in the interface and get it live, immediately.
It is not a degraded mode. A Builder module produces exactly the same objects as a hand-written one.
What a Builder module produces
Here, run on a real instance, is what creating a “bindery workshop” module with one model and three fields gives:
POST /api/v1/admin/builder/modules -> {"ok": true, "name": "reliure", "models": ["reliure_chantier"]}A real table, with all of the product’s system fields:
id name recu_le etatcreated_at created_by_id updated_at updated_by_id versiondeleted_at deleted_by_id kws_custom_dataTimestamps, authorship, the version number for concurrency, the recycle bin, and the column for fields added at runtime. You asked for none of it: that is what every Kewos model carries.
A complete API, immediately, with no restart:
POST /api/v1/reliure_chantier {"name": "Dune, broken spine", "recu_le": "2026-09-06"} -> {"id":1, "etat":"recu", "version":1, "created_by_id":1, ...}The state is recu: the default declared in the form was applied by the server.
A screen, generated from the model:
GET /api/v1/views/reliure_chantier/effective?kind=list -> columns: id, name, recu_le, etat ... each with its type and i18n keyNo view was written. It is the same engine that renders hand-written modules’ screens.
The AI proposes, a human confirms
The Builder can describe a module from a sentence, but it never installs one on its own. The flow has two steps:
POST .../modules/suggestreturns a proposal as declarative YAML, which you read;POST .../modulescreates and loads what you confirmed.
That is deliberate. An AI that creates tables without review is an AI that creates wrong tables without review. The intermediate YAML is the checkpoint: it is readable, editable, and it is what counts, not the original sentence.
Disabling deletes nothing
POST .../modules/reliure/disable -> {"state": "disabled"} the model's API : 404 the data in the database : still thereThe module disappears from the interface and the API, and the table stays intact. Enabling puts it back:
POST .../modules/reliure/enable -> {"state": "loaded"} the model's API : 200Same posture as suspending a customer: you cut access, you do not destroy data. A delete with purge exists, separately, and it is an explicit decision.
What the Builder does not do
- It does not run code. A Builder computed field is an expression in a closed grammar, not
Python (rule 37). There is no
eval, so there is no arbitrary execution to secure. - It does not bypass permissions. Creating a module requires the
kws_builder_editorgroup, and the models it produces go through the same record rules and ACLs as any other. - It is not sandbox-only. Creating tables is still a schema change: in development it applies directly, in production it takes the per-module migration path (rules 11 and 12).