@dainamite/cpq
v0.3.0
Published
Dainamite CPQ — Configure, Price, Quote engine for Open Mercato (configurable products, multi-charge pricing tables, guided quoting, customer inventory, orders).
Readme
@dainamite/cpq
Dainamite CPQ (Configure, Price, Quote) module for Open Mercato — configurable product attributes, multi-charge pricing tables, guided quoting wizards, customer inventory & subscription tracking, ARC (Amend / Renew / Cancel) flows, quote → order → activation pipeline.
Install
Published to the public npm registry — no scope auth or .npmrc
changes needed:
yarn add @dainamite/cpqRegister the module in your host app's src/modules.ts (after its
required core modules — see below):
{ id: 'cpq', from: '@dainamite/cpq' }Regenerate the module graph, then run framework migrations to install CPQ's schema:
yarn generate
yarn mercato db migrateCPQ admin pages appear under /backend/cpq/*.
What's inside
packages/cpq/src/modules/cpq/
├── index.ts module metadata + requires
├── acl.ts ACL feature definitions
├── ce.ts custom entity / field set declarations
├── di.ts Awilix DI registrations
├── setup.ts tenant init, role features, seed data
├── data/ entities, validators, enrichers
├── api/ REST routes (resource-style: api/<resource>/route.ts)
├── backend/ admin UI pages (auto-discovered)
├── services/ pricing, quoting, validation, product, wizard, inventory, order, bundle
├── widgets/ injection: customer-inventory, order-cpq-tab, quote-configurator
├── workflows/ quote → order step components
├── lib/seeds/ use-case registry API
└── migrations/ own MikroORM migrations (never hand-write — `yarn mercato db generate`)The package ships src/ (for TypeScript consumers' types) and
dist/ (esbuild-built JS for runtime). Following the
@open-mercato/core
build convention, no .d.ts is emitted — exports.types resolves
directly to source.
Distribution model (per SPEC-001)
- L1 — Open Mercato core consumed from
@open-mercato/*(npm). - L2 — Dainamite product modules (this package + sibling
@dainamite/*), published to public npm under the@dainamitescope. - L3 —
dainamite-coreis the first L3 customer app; other customer repos consume@dainamite/cpqviayarn addand register it the same way.
Hard rules (carried over from SPEC-001)
- No ORM relations across packages. Cross-module references are FK
strings only (
productId: string), never@ManyToOne. peerDependencies, neverdependenciesfor sibling@dainamite/*and@open-mercato/*— guarantees a single shared instance innode_modules.- Each major bump ships its own migrations under
src/modules/cpq/migrations/; document upgrade path inCHANGELOG.md. - No customer-specific logic here. Tenant-specific overrides live
in the consuming app under
src/modules/@app/<feature>/.
Required Open Mercato modules
CPQ declares the following in metadata.requires and will fail to
bootstrap if any are missing from the host app's src/modules.ts:
auth, directory, catalog, sales, customers, dictionaries.
Package isolation guard
Static lint test at
src/modules/cpq/__tests__/package-isolation.test.ts
asserts the package never imports from sibling app modules, never
deep-imports @open-mercato/core/modules/<x> for an undeclared
dependency, and contains zero cross-entity ORM relations. Runs on
every CI build — protects future contributors from accidentally
breaking the package boundary.
Versioning
Versioned via changesets.
Add a changeset alongside any change in packages/cpq/:
yarn changesetBumps and the public-npm publish are handled by the release workflow on
push to main.
License
MIT.
