Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DywdYrFTrWa4h1T3ZykPBX
160 lines
8.6 KiB
Markdown
160 lines
8.6 KiB
Markdown
---
|
|
name: buildease-demo
|
|
description: BuildEase (callista-tools/mev) construction overlay for the callista-odoo-demo skill. Routes the client's pains onto the 34 BuildEase Odoo 19 modules before any custom work is considered, replaces the generic teardown with the take-off → progress-statement chain, and keeps the per-client dataset instead of the old buildease_demo_data bundle. Use for "BuildEase demo", "QTO demo", "quantity take-off demo", "construction Odoo demo", "vorderingsstaat demo", or a follow-up after one.
|
|
---
|
|
|
|
# BuildEase Demo
|
|
|
|
A **vertical overlay** on `callista-odoo-demo`. That skill owns the pipeline — discovery
|
|
brief, build, test, purge, sales docs, follow-through. This one supplies the five things
|
|
that are specific to construction, and nothing else.
|
|
|
|
**Requires** `callista-odoo-demo` installed at `~/.claude/skills/callista-odoo-demo/`
|
|
(Callista's fork of Smetools/odoo-demo-architect). If it is missing, say so and stop —
|
|
do not reimplement its JSON-2 connector, data builder, or pipeline here.
|
|
|
|
> Do **not** substitute an `odoo-demo-architect` install for it. That is upstream, without
|
|
> Phase A's source-agnostic discovery, without Phase C, and without the extension points
|
|
> this file plugs into.
|
|
|
|
**Run `callista-odoo-demo` and apply the overlays below at the named steps.** Everything
|
|
not listed here is that skill's job — follow it as written.
|
|
|
|
---
|
|
|
|
## Overlay 1 — Module routing
|
|
|
|
*Applies at:* **Install modules**, and Phase A's `## Phase 1 scope`.
|
|
|
|
Read `reference/buildease.md` and route the client's pains onto BuildEase modules using
|
|
its pain → module table. Match on **the client's own words** — the table is keyed on what
|
|
they actually say ("we measure in Excel then re-type it into the quote"), not on module
|
|
names they will never utter.
|
|
|
|
Install the routed set **explicitly**, module by module. `buildease` is a marker whose
|
|
manifest depends on `base` alone — it installs none of the other 33, so installing it and
|
|
stopping there leaves an empty database and no error to catch it. Install it alongside the
|
|
routed set if you want the marker; never instead of it.
|
|
|
|
Verify afterwards: read back `ir.module.module` state for every routed name and fail loudly
|
|
on anything not `installed`. `button_immediate_install` also dies on a transient
|
|
`ir_cron` row lock (`LockNotAvailable`) when a cron is mid-run — back off and retry, it is
|
|
not a real failure.
|
|
|
|
## Overlay 2 — Solution precedence
|
|
|
|
*Applies at:* **Research native-vs-custom**.
|
|
|
|
The precedence becomes **BuildEase → native Odoo 19 → custom**, in that order. Most
|
|
construction pains are already solved in mev; custom work is the last resort, and native
|
|
Odoo is the middle tier, not the first question.
|
|
|
|
Odoo 19 only — every mev manifest is `19.0.x`. Do not attempt this against 17 or 18.
|
|
|
|
## Overlay 3 — Demo data policy
|
|
|
|
*Applies at:* **Load demo data**.
|
|
|
|
**Do not install `buildease_demo_data` or `buildease_demo_data_sale_progress`.** They are
|
|
the previous generation of environment setup: one fixed Belgian construction dataset, the
|
|
same for every prospect, dragging in `l10n_be` and `accountant` whether or not the client
|
|
is Belgian. The per-client dataset generated from the discovery brief replaces them — the
|
|
client's own partners, articles, projects and orders, staged so each hero has a record to
|
|
fire on.
|
|
|
|
Install them only if the user explicitly asks for the generic sandbox. The app-level
|
|
dependencies that bundle used to drag in (`sale_management`, `project`, `purchase_stock`,
|
|
`sale_timesheet`, `industry_fsm`, `accountant`, `uom`) still need installing — route them
|
|
from the pain table, not from the demo bundle.
|
|
|
|
**Read `reference/buildease_demo_data.md` before writing the staging script.** It carries
|
|
the QTO → sale order → project → progress statement → invoice object graph from mev source:
|
|
required fields per model, creation order, which transitions are button methods rather than
|
|
writes, and the seven guards that will otherwise stop the chain mid-build.
|
|
|
|
`scripts/build_demo.py` is a per-engagement template, not an engine — it knows nothing about
|
|
take-offs, and it ignores config keys it doesn't recognise. Adapt it; do not assume a
|
|
BuildEase-shaped config will drive it.
|
|
|
|
## Overlay 4 — Purge chain
|
|
|
|
*Applies at:* **Purge test residue**, replacing the generic chain.
|
|
|
|
```
|
|
transient wizard rows → invoices (draft → cancel → unlink)
|
|
→ statements (cancelled only, newest first) → timesheet lines → tasks
|
|
→ projects → sale orders → take-offs → the partner
|
|
```
|
|
|
|
The generic traps still apply. These are the BuildEase-specific ones, each of which cost
|
|
a debugging round:
|
|
|
|
- **Invoices go before statements.** An `invoiced` `sale.progress` refuses `action_cancel`
|
|
outright; cancelling its invoice is what reverts it to `approved`, the first state it can
|
|
be cancelled from. Statements-then-invoices deadlocks on the one statement you invoiced.
|
|
- **Cancel before deleting, on all three.** `unlink()` refuses unless `quantity.take.off` is
|
|
`cancel`, a QTO-linked `sale.order` is `cancel`, and `sale.progress` is `cancelled`.
|
|
- **Guard each step separately and loop until a pass keeps nothing.** One `try` around
|
|
draft → cancel → unlink lets a raise on an already-draft invoice skip the unlink beneath
|
|
it, and the purge then reports success over residue.
|
|
- **Button methods return an action dict, not `True`.** Over JSON-2 it comes back as plain
|
|
JSON, so a returned dict is not a failure and not proof of success — read the state back.
|
|
(On a legacy XML-RPC connection the same dict raises a `Fault` mentioning `Marshal`/`dumps`
|
|
*after* the transition committed: catch it and move on, never retry, because the retry
|
|
fails on a state guard and reads like a real error.)
|
|
- **Deleting the take-off deletes its sale order** — `quantity.take.off.unlink()` unlinks
|
|
`sale_order_ids` first. The take-off is the handle for both.
|
|
- A take-off with **no** sale order still cancels and deletes normally: call `cancel()`, which
|
|
writes the state directly and no-ops on the empty order. No convert-to-quotation dance.
|
|
- **Statements cancel newest-first only** — `action_cancel` refuses unless it is the last one,
|
|
and `action_draft` refuses if a newer statement exists.
|
|
- Leftover `add.dynamic.article.template.line` rows pin take-offs. Clear them first.
|
|
|
|
Full field-level detail, including the guards, is in `reference/buildease_demo_data.md`.
|
|
|
|
## Overlay 5 — Follow-through framing
|
|
|
|
*Applies at:* **Phase C**.
|
|
|
|
Where an objection is already covered by BuildEase, name the **module and the screen** on
|
|
the objection sheet — "that's `sale_progress_revision_formula`, on the statement's Revision
|
|
tab" lands better than "yes, we support that". Where mev does not cover it, say so and give
|
|
the workaround or the build estimate.
|
|
|
|
Check the scoped quote against `reference/buildease.md`'s gotchas before pricing:
|
|
`custom_product_sale`, `custom_product_bom` and `bom_on_sale_order_line` are **not in the
|
|
mev repo**, so anything under `buildease_custom_product*` is not a "just install it" line.
|
|
|
|
---
|
|
|
|
## Step-local notes
|
|
|
|
Domain detail hung off substrate steps that need no overlay — they change no mechanism, so
|
|
they are not gaps in `callista-odoo-demo` (see its [Extension points](../callista-odoo-demo/SKILL.md#extension-points)).
|
|
|
|
- *At **Fork the slow half**, agent 1:* after installing, **walk Settings once**.
|
|
`res.config.settings` and `res.company` are extended by 8 modules each and several
|
|
BuildEase behaviours default to off.
|
|
- *At **Sanity-check the staged numbers**:* **booked hours well under ordered hours**. Over
|
|
100% makes the progress statement look wrong on screen even when every assertion passed.
|
|
- *At **Test heroes**:* the spine of every BuildEase demo is QTO → sale order → project →
|
|
progress statement → invoice. If that chain breaks mid-demo you lose the deal, so it is
|
|
the chain the tests must exercise end to end.
|
|
- *At **Build heroes**:* `quantity.take.off` inherits `mail.thread` + `mail.activity.mixin`
|
|
— chatter and activities work for free. Cheap demo beats.
|
|
|
|
## Guardrails
|
|
|
|
- Never claim a BuildEase feature works without having seen it work in the demo DB.
|
|
- Never invent a pain quote. `(inferred)` is fine; a fabricated quote read back to the
|
|
client in the demo is not.
|
|
- If something you need is new **mechanism** — a step that doesn't exist, an override the
|
|
five overlays don't offer — that is a gap in `callista-odoo-demo`. Fix it there, so the
|
|
next vertical gets it free; do not work around it here. Construction detail that hangs
|
|
off an existing named step is not a gap: it goes under *Step-local notes*.
|
|
|
|
## Files
|
|
|
|
- `reference/buildease.md` — the module map, the pain → module routing table, and the mev
|
|
gotchas. Read it at Phase A.
|