dodil/erp-method

node_modules/.cache/erp-method/v0.1.21/erp/build.md

Building a business system on DODIL: the map

For the agent building sales, HR, contracts, invoicing or the books for a customer, whatever they call it ("an app", "a system", "something to replace the spreadsheet"). Read this page, then one card per phase, in order. Each card is short: numbered steps, an example, "done when".

The mindset, in one paragraph

Most modules already exist as bricks: public git repos on erp-platform, pinned at release tags. You compose them for this customer; you do not rewrite them. Everything is customizable, at three depths: 1 configure (rows, through the brick's use cases), 2 extend (a capability in the customer's own small brick), 3 own (a fork of the brick in the customer's org, its intent recorded and re-applied on each upgrade). A small foundation is kept and refused if broken: stable ids (process and step keys, APQC PCF ids, use-case names), shared keys and data integrity, the security model, and erp-platform itself. Best practices are defaults with warnings: a deviation is shown, signed, then built. The customer sees their business as BPMN generated from the configuration; their stories are paths on it; the signed diagram is the contract.

Phases 0-3 are documents. The customer signs before any code.

#PhaseProduceToolCard
0Framea scope note: modules, first module, how involved they want to bedodil ignite app list, ERP_*.md in their repododil://erp/phase/frame
1Discovercandidate modules, bricks and tags, the reference processindex.json, modules/<id>/module.yaml reference.reposdodil://erp/phase/discover
2Show (understand)actors, stories with Given/When/Then and a path each, entities, master data; the diagram IN your messageuvx --from git+https://git.dodil.io/dodil/erp-platform.git@v0.8.2 erp-compose process (HR) or erp-compose bpmn --from ERP_<MODULE>.mddodil://erp/phase/show
3Fit (design)ERP_<MODULE>.md and the change list, each item with its depthmodules/template.md; HR: config/hr.calls.yaml + erp-compose processdodil://erp/phase/fit
3sSign offsignoff/<module>/<process>.json, one per process + Processes/Scenarios/Deviations rowsuvx --from git+https://git.dodil.io/dodil/erp-platform.git@v0.8.2 erp-compose signoff recorddodil://erp/phase/signoff
4Builda customer repo composing the bricks; rows; own brick or fork if signeduvx --from git+https://git.dodil.io/dodil/erp-platform.git@v0.8.2 erp-compose init <module>dodil://erp/phase/build
5Testthe composition's own tests/, scenarios in process and livepytest, erp-scenarios rundodil://erp/phase/test
6-8Deploytest copy then live; pool, roles, SA; a real sign-inerp-compose plan/migrate, git push, dodil ignite invokedodil://erp/phase/deploy
9Operatefindings against the signed processprocess mining not built yetdodil://erp/phase/operate
9cChangev2 of the process: diff, impact with counts, migration, new sign-offerp-migrate; up/down not built yetdodil://erp/phase/change

The rules that hold in every phase

  1. Interactive by default. One topic per turn, one to three questions, each with choices and a recommended default. Say back what you recorded.
  2. The repo remembers, not you. Start every session by reading every ERP_*.md (Status, People, Change requests, Decisions) and open with a three-line "where we are".
  3. Test copy first; live only on an explicit "go live". <customer>-dev and <customer>. Local .env points at the test copy only. Say which one you touch, every time.
  4. Show it on localhost before anything goes live.
  5. An approval is words the customer typed, naming the version. Never your summary of one.
  6. The signed artifact is the BPMN. Generate it (erp-compose process / bpmn), then paste its step names in order, with who does each, into your message: never prose in your own words, never "open it in bpmn.io" (lab, 2026-10-18: Sonnet did both and the customer had seen nothing).
  7. The gate holds the build: erp-compose plan / migrate refuse an unsigned or changed process; CI runs erp-compose signoff verify --all; a change is erp-compose change propose.

Working signed out

Phases 0-5 need no DODIL login: the bricks clone anonymously, and the composition runs in process on SQLite. Do not create buckets, pools or apps before phase 6. If a dodil command says you are not signed in, do not try to sign in from a headless session: ask the person to run dodil auth login, and carry on with what needs no login.

Facts to copy, not re-derive

  • Compose with one command, never by hand: erp-compose init <module> (the build card) pins the bricks at their tags (never branches) in requirements.txt, makes .venv, writes compose.yaml and the composition test, and runs the checks. --read-copy clones them to bricks/ so you can read each brick's README.md and AGENTS.md before writing anything.
  • The composition ships its own test (modules/test_composition.py → tests/): the bricks' suites prove the bricks, not your assembly (lab, 2026-10-17).
  • Claims are a plain INSERT: under concurrency one writer wins and the rest get 23505. Never claim with an upsert (tables 0.2.1, measured 2026-10-17).
  • 64-bit ids travel as JSON strings (Brick(ids_as_strings=True)); JavaScript rounds past 2^53.
  • No lost updates: an edit sends the version it loaded (If-Match: "3"); stale is 409.
  • TLS: sslmode=require (verify-full + sslrootcert in production) and bolt+s://; never prefer or neo4j+s://.
  • Natural keys, no SERIAL; money NUMERIC(18,2); DELETE needs a WHERE; no read-your-writes inside an open transaction.
  • Verify a deploy with POST / (dodil ignite invoke), not the public URL: a 401 there proves only that the gateway is up.

Where the rest is

Read any of these as an MCP resource dodil://erp/file/<path>, or from git.dodil.io/dodil/erp-method: modules/lifecycle.md (the method with its reasons), modules/pattern.md (the anatomy of a module and a brick), modules/template.md (ERP_<MODULE>.md, v3), modules/module.template.yaml (a new spec), modules/shared.yaml (keys that cross modules), index.json (everything, by tag). Module catalogue and specs: dodil://erp/modules/index.json, dodil://erp/modules/<id>/spec.yaml.