Generator engine that builds an installable Odoo 20.0 demo-data module (ZIP) from a customer specification (JSON).
- Workflow, verified patterns and protocols: skills/odoo-demo-data/SKILL.md
- Open items: ROADMAP.md
Pure Python stdlib, no dependencies, no pip install needed.
This is a public repository. Real customer specifications (names, addresses, VAT ids) must never be published. Enable the guard that blocks them at commit time:
git config core.hooksPath .githooks.gitignore additionally keeps every examples/*.json untracked except the
anonymized examples/muster_*.json; the pre-commit hook runs
engine/tests/test_examples_anonymized.py on any commit touching examples/.
Keep a real spec untracked and commit only an anonymized copy with a fictional
Muster... company name (see AGENTS.md).
python3 -m engine.cli generate --spec examples/muster_foerdertechnik.json --out outputBuilds the module directories (output/<technical_name>/, output/bt_demo_install_helper/)
and one delivery ZIP output/<technical_name>.zip that bundles the demo module and
its companion module(s) (see engine/companion_modules/README.md) - extract it once
into the addons path.
Static validation (engine/validate.py) runs automatically before zipping; on
errors no ZIP is built (--force forces it anyway, not recommended). The run also
warns when a used section is below the recommended "rich demo" volume
(engine/volume.py, see skills/odoo-demo-data/reference/spec-format.md) - a
warning never blocks the build.
Check an existing module (directory or ZIP) independently:
python3 -m engine.cli validate examples/reference/bt_demo_mfg.zipGenerate the JSON schema of the specification (new):
python3 -m engine.cli spec-schema --out engine/spec/spec.schema.jsonList the capability bundles / scaffold a spec skeleton (see
skills/odoo-demo-data/reference/capabilities.md):
python3 -m engine.cli capabilities
python3 -m engine.cli new --with mrp,sales --name "Muster AG" --country ch --out examples/muster.jsonFor a real customer, write the spec to any path under examples/ (it is
gitignored automatically) and commit only an anonymized copy named
examples/muster_<topic>.json with a fictional company name.
Copy examples/muster_foerdertechnik.json (manufacturing customer) or
examples/muster_handel.json (multi-app/Enterprise) as a template. Covers the verified
object types: res.company (incl. chart of accounts), res.partner,
product.product, mrp.bom, mrp.production, sale.order,
sale.order.template (quotation templates), crm.lead, purchase.order,
stock.quant/stock.warehouse, stock.picking/stock.move (incoming/
outgoing/internal movements, incl. multi-step warehouses), account.move,
helpdesk.ticket, project.project/project.task (incl. task stages).
Complete format: skills/odoo-demo-data/reference/spec-format.md.
Unknown fields are rejected on load (typo protection).
Every generated module creates, besides the administrator, a demo login
demo/demo (name = company, same rights as base.user_admin) in the
post_init_hook - no manual user setup after a demo appointment. If the login
already exists, creation is skipped (verified-patterns 4.18).
The post_init_hook also attributes the generated documents (quotes, invoices,
leads, POs, tickets, tasks, ...) to the UI admin Administrator instead of the
superuser "OdooBot" that loads the XML data (verified-patterns 4.28). With
accounting_app: "full" the module depends on the Enterprise accountant
app, so "Accounting" appears as an installed app (verified-patterns 4.15).
.opencode/agent/demo.md (the demo agent, used by the /new-demo command)
runs the whole pipeline without clarifying questions. opencode.json grants the
pipeline a broad bash/external_directory allowlist (destructive commands stay
ask) and allows doom_loop, so a full demo package is built and smoke-tested
without approval prompts. There is no need to start opencode with --auto.
The installation smoke test targets a local Odoo 20 Enterprise (trial) instance
in ../odoodemo-local-20 (outside this repo). There is no official odoo:20.0
Docker image yet, so that instance is built from source on top of the odoo:19.0
base image. Setup and usage: engine/docker/README.md.
One-shot smoke test (starts the instance, then runs the test with Postgres assertions) - use a long tool timeout (>= 30 min), the install takes minutes:
engine/docker/smoke.sh --module bt_demo_musterhandelpython3 -m unittest discover -s engine/tests -t .engine/
model.py data model (dataclasses) + validation of the specification itself
spec_loader.py JSON -> dataclasses (rejects unknown fields)
schema.py JSON schema from the dataclasses (single source of truth)
records.py dataclasses -> Odoo XML record elements (verified patterns)
xmlgen.py low-level XML helpers (ElementTree, guaranteed well-formed)
manifest.py __manifest__.py / hooks.py rendering
builder.py assemble module directory + ZIP
validate.py static check of a built module (no Odoo kernel needed)
volume.py recommended minimum demo-data volume per object type
verify.py spec-aware Postgres assertions for the install smoke test
cli.py CLI (generate / validate / capabilities / new / spec-schema)
spec/spec.schema.json generated JSON schema of the customer specification
tests/ engine tests (no Odoo needed)
docker/ installation smoke-test harness against the local Enterprise
instance ../odoodemo-local-20 (see its README)
skills/odoo-demo-data/ skill: workflow + reference (verified-patterns, spec-format, ...)
opencode.json/.opencode/ opencode adapter (registers skills/, /new-demo command,
autonomous `demo` agent, pipeline allowlist: no prompts)
examples/ anonymized example specifications (real specs are gitignored)
examples/reference/ historical reference modules (no longer a template)
.githooks/pre-commit blocks committing non-anonymized specs (enable: see Setup)
engine/validate.py only checks structure (well-formedness, xmlid references,
manifest consistency and the known landmines from
skills/odoo-demo-data/reference/verified-patterns.md). It is no substitute
for a real installation against an Odoo 20.0 kernel - for that see
skills/odoo-demo-data/reference/install-test-protocol.md.