Wraps odoo-demo-architect for BuildEase (callista-tools/mev) construction demos: discovery brief from any source instead of Knowcap, pain-to-module routing onto the 33 BuildEase modules, parallel instance-prep/research agents, throwaway-record verification with a full purge, and the post-demo follow-through set. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
209 lines
11 KiB
Markdown
209 lines
11 KiB
Markdown
---
|
||
name: buildease-demo
|
||
description: Wraps odoo-demo-architect for BuildEase (callista-tools/mev) construction demos. Builds the discovery brief from any source — transcript file, notes, email thread, or a live interview — instead of requiring Knowcap, routes client pains onto BuildEase modules before considering custom work, and after the demo generates the follow-through set (objection sheet, scoped quote, implementation timeline, SOW). Use for "BuildEase demo", "QTO demo", "construction Odoo demo", "prep a demo from these notes", or "write the follow-up after the demo".
|
||
---
|
||
|
||
# BuildEase Demo
|
||
|
||
Three phases. `odoo-demo-architect` does the middle one; this skill owns the ends.
|
||
|
||
**Requires** `odoo-demo-architect` installed (`~/.claude/skills/odoo-demo-architect/`,
|
||
from github.com/Smetools/odoo-demo-architect). If it is missing, say so and stop —
|
||
do not reimplement its XML-RPC connector or data builder.
|
||
|
||
---
|
||
|
||
## Phase A — Discovery brief (no Knowcap)
|
||
|
||
Goal: produce `discovery_brief.md` in exactly the shape odoo-demo-architect's step 1
|
||
would have emitted, from whatever the user actually has.
|
||
|
||
**Source, in order of preference:**
|
||
1. A transcript, meeting notes, or email thread — read it.
|
||
2. Knowcap MCP, if it happens to be available and the user wants it.
|
||
3. Nothing written down → interview the user (see intake below).
|
||
|
||
### Intake — infer first, ask only the gaps
|
||
|
||
Before asking anything, **look**: glob the working directory for a transcript, notes,
|
||
brief, or `.md`/`.txt`/`.docx` that plausibly is the source, and read it. Then answer
|
||
each item below from what you read. Only the items you genuinely cannot answer go to
|
||
the user, in **one** `AskUserQuestion` batch — never a serial interrogation, never a
|
||
question whose answer is sitting in the file you just read.
|
||
|
||
| Item | Infer from | Ask only if |
|
||
|---|---|---|
|
||
| **Source brief location** | A single obvious candidate file in the working directory | Zero or several candidates — ask which, or paste |
|
||
| **Odoo UI language** | Language the brief is written in; client country; `l10n_*` in scope | Brief is English but the client clearly isn't anglophone — ask (nl_BE / fr_BE / en_US / other) |
|
||
| **Client website / company info** | URL or company name in the brief — fetch the site, mine it for what they build, size, regions, branding | No name or URL anywhere in the source |
|
||
| **Odoo instance** | `demo_config.json`, prior session, the brief | Not found — always ask, never guess a URL or API key |
|
||
| **Demo audience** | Attendee list in a transcript header or email thread | Source is notes with no names |
|
||
| **Rate card** | A rates file in the project | Only needed at Phase C — don't ask now |
|
||
|
||
Anything still missing after that batch: write it into the brief as `(unknown)` and
|
||
carry on. One unknown does not block building the demo.
|
||
|
||
If nothing written down exists at all, the interview replaces the table — still one
|
||
batch: who the client is, what they build, how they quote today, how they invoice,
|
||
the top 3 complaints they voiced, who is in the room.
|
||
|
||
**Write `discovery_brief.md` with these six sections and no others:**
|
||
|
||
```markdown
|
||
## Business shape
|
||
Entities, product/customer types, volumes, shared financials.
|
||
Company name, website, country, what they actually build — from the site if you fetched it.
|
||
|
||
## Top pains
|
||
3–5 items. Direct client quotes where you have them. Mark anything you inferred as (inferred).
|
||
|
||
## Hero features
|
||
1–2. Each names the pain it kills and the decision-maker it lands on.
|
||
|
||
## Phase 1 scope
|
||
Odoo apps + BuildEase modules, from reference/buildease.md.
|
||
|
||
## Odoo instance
|
||
URL, database, login, API key. Ask if absent — do not guess.
|
||
UI language + `l10n_*` localisation to install.
|
||
|
||
## Demo audience
|
||
Who is in the room and what each one needs to hear.
|
||
```
|
||
|
||
Never invent a pain quote. An inferred pain marked `(inferred)` is fine; a fabricated
|
||
quote read back to the client in the demo is not.
|
||
|
||
Show the brief to the user and get a yes before Phase B.
|
||
|
||
---
|
||
|
||
## Phase B — Build, via odoo-demo-architect
|
||
|
||
Hand `discovery_brief.md` to `odoo-demo-architect` and let it run its pipeline
|
||
(research → connect → install → data → heroes → test → sales docs).
|
||
|
||
### Fork the slow half
|
||
|
||
Module installation and client research are independent — the install list comes from the
|
||
brief plus the routing table, the research feeds hero *building* which happens after both.
|
||
Installing over XML-RPC is minutes of waiting and produces log spew nobody needs in context.
|
||
So run them as two parallel subagents, launched in **one** message:
|
||
|
||
**Agent 1 — instance prep.** Give it the Odoo credentials, the routed module list, and
|
||
odoo-demo-architect's `scripts/odoo_connect.py`. It sets the company, currency, UoM and
|
||
UI language, installs the localisation, installs `buildease` + the routed modules, then
|
||
walks Settings for the BuildEase toggles that default off. It loads **no data** — that is
|
||
the join step's job. Returns: what installed, what failed, the settings it changed.
|
||
|
||
**Agent 2 — client research.** Give it the brief. It fetches the client's website, and
|
||
researches each hero feature **BuildEase → native Odoo 19 → custom**, in that order.
|
||
Returns: per hero, which of the three it lands in, and the click-path if it already exists.
|
||
|
||
**Join.** Both done → install any module Agent 2's research turned up that Agent 1 didn't
|
||
know about (incremental, cheap), then generate and load the client-specific dataset into
|
||
the empty database, then build and test heroes.
|
||
|
||
Two agents, not five. Do not fan out further — hero building is sequential against one
|
||
database and parallel writes will fight.
|
||
|
||
Two things to inject before it starts:
|
||
|
||
1. **Read `reference/buildease.md`** and pass the routed module list. The research step's
|
||
native-vs-custom question becomes **BuildEase → native Odoo → custom**, in that order.
|
||
Most construction pains are already solved in mev; custom work is the last resort.
|
||
2. **This skill is the demo data loader.** Do not install `buildease_demo_data` — that is
|
||
the old, one-size-fits-all Belgian dataset it replaces. The database starts empty and
|
||
gets a dataset generated from the brief: the client's own partners, articles, projects
|
||
and orders, staged so each hero feature has a record to fire on. Install it only if the
|
||
user explicitly asks for the generic sandbox.
|
||
|
||
Its step 7 (test every hero on throwaway records) is not optional here either. A QTO →
|
||
sale order → project → progress statement → invoice chain that breaks mid-demo is the
|
||
one failure mode that loses the deal.
|
||
|
||
### Verify on throwaway records, then delete them
|
||
|
||
Test against a partner named `ZZ Test…`, never against the client's own records — a hero
|
||
you tested is a hero you consumed, and the demo needs its first click to be the first click.
|
||
|
||
**Then purge. A demo environment ships with zero test residue.** Debugging the chain takes
|
||
several runs, each leaving a full take-off → order → project → statement → invoice trail;
|
||
"it's cancelled and the partner is archived" is not clean, those records still list on
|
||
screen. Write the purge as a function in the test script and run it until the counts are
|
||
zero — not as a one-off you improvise at the end.
|
||
|
||
Odoo blocks most of this unless you go in order:
|
||
|
||
```
|
||
transient wizard rows → statements (cancelled only, newest first) → invoices
|
||
→ timesheet lines → tasks → projects → sale orders → take-offs → the partner
|
||
```
|
||
|
||
The traps, all of which cost a debugging round:
|
||
- **A take-off with no sale order cannot be deleted at all.** Its state is derived from the
|
||
order, so there is nothing to cancel. Convert it to a quotation, cancel that, then delete.
|
||
- `search` will not find the partner once archived — pass `context={"active_test": False}`
|
||
or the purge silently no-ops and reports success.
|
||
- Statements cancel newest-first only; invoices must go to draft before cancel; leftover
|
||
`add.dynamic.article.template.line` rows pin take-offs.
|
||
- **Delete the partner last, and only once nothing references it.** Deleting it first nulls
|
||
`partner_id` on whatever survived, so a `partner_id`-based purge can no longer see those
|
||
records and a `partner_id`-based assertion reports clean over an environment that isn't.
|
||
Sweep by name as well, and assert on both.
|
||
- Anything the tests **copy** inherits the source record's customer, not the throwaway one.
|
||
Repoint copies at the throwaway partner or they escape the purge.
|
||
- Make every step best-effort with its own `try`, and **print what it kept** — a silent
|
||
purge that skipped nine records reads exactly like one that worked.
|
||
|
||
Finish by reading back the counts of every model you touched and putting them in the
|
||
verification log. "No test residue" is a claim; the counts are the evidence.
|
||
|
||
### Sanity-check the staged numbers before calling it done
|
||
|
||
A chain that passes every assertion can still look broken on screen. Check the staged data
|
||
reads plausibly: **booked hours well under ordered hours** (over 100% makes the progress
|
||
statement look wrong), costs under selling prices, dates in the past. Derive staged
|
||
quantities from the ordered quantity rather than hard-coding them, so they cannot drift
|
||
when a formula changes.
|
||
|
||
---
|
||
|
||
## Phase C — Follow-through
|
||
|
||
Runs after the demo happened. Needs: the built demo, the verification log, and what
|
||
actually came up in the room. Ask the user for the room notes — objections raised,
|
||
who pushed back, what they asked for that wasn't there.
|
||
|
||
Generate four documents. Reuse odoo-demo-architect's `templates/` branding and its
|
||
self-contained-HTML rule (no external assets, single file, prints to A4).
|
||
|
||
| Document | Contents |
|
||
|---|---|
|
||
| **Objection sheet** | Every objection raised → the honest answer. Where BuildEase already covers it, name the module and the screen. Where it doesn't, say so and give the workaround or the build estimate. |
|
||
| **Scoped quote** | Line items from the Phase 1 scope: modules, configuration, data migration, custom work, training. Days and rate per line. Flag assumptions separately from committed lines. |
|
||
| **Implementation timeline** | Phased, with the client's own dependencies on it (data extraction, sign-offs, who from their side). Weeks, not dates, unless a start date is agreed. |
|
||
| **Statement of work** | Deliverables, acceptance criteria, out-of-scope list, change-request process. The out-of-scope list is the point — write it properly. |
|
||
|
||
Rules:
|
||
- Every number traces to something. No invented day-rates, no invented licence costs —
|
||
ask the user for the rate card.
|
||
- Anything the demo *didn't* prove goes in the quote as build work, not as "included".
|
||
Cross-check against the verification log from step 7.
|
||
- The out-of-scope list is where the follow-through earns its keep. Anything discussed
|
||
and not quoted goes in it explicitly.
|
||
|
||
Show all four to the user before anything leaves the machine.
|
||
|
||
---
|
||
|
||
## Guardrails
|
||
|
||
- Never claim a BuildEase feature works without having seen it work in the demo DB.
|
||
- Never hand over an environment holding test records. Purge them and read back the counts;
|
||
do not settle for "cancelled and archived" and do not write the leftovers off as a note
|
||
in the verification log.
|
||
- Never send anything client-facing without the user reading it first.
|
||
- `discovery_brief.md`, `demo_config.json` and the follow-through docs hold client data
|
||
and API keys — keep them in the project directory, never in a scratchpad you'd forget.
|