cpq-builder

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CPQ Builder Skill

CPQ构建技能

What This Skill Does

该技能的作用

This skill tells the Builder Agent how to configure the Customware SPA as a Configure-Price-Quote system. It provides:
  1. Section definitions — the four views that make up a CPQ application
  2. Config schema — the data shape for products, options, dependencies, pricing, and quotes
  3. Deterministic mapping rules — if-then rules for transforming DOMAIN.md into config.json
  4. Business rule templates — patterns for the SPA's rules engine
  5. Vertical presets — defaults for Manufacturing, Wholesale, and Services verticals
The Builder Agent does NOT generate code. It generates a config object that the SPA renders.
该技能指导Builder Agent如何将Customware SPA配置为Configure-Price-Quote系统,它提供了:
  1. 板块定义——构成CPQ应用的四个视图
  2. 配置Schema——产品、选项、依赖关系、定价和报价的数据结构
  3. 确定性映射规则——将DOMAIN.md转换为config.json的if-then规则
  4. 业务规则模板——SPA规则引擎的模式模板
  5. 垂直领域预设——制造业、批发业和服务业垂直领域的默认配置
Builder Agent不会生成代码,它会生成供SPA渲染的配置对象。

When to Use This Skill

何时使用该技能

The Builder Agent should select this skill when the customer's DOMAIN.md contains:
  • Products or services that are quoted/priced for customers
  • Configuration options (sizes, models, variants, materials)
  • Dependencies between products (requires, recommends, excludes)
  • Markup or margin-based pricing (cost-plus, vendor list + percentage)
  • A quoting or proposal workflow (draft → review → approve → send)
  • Roles involved in pricing, approving, or sending quotes
Classification signals from the Clarence transcript:
  • "quoting is a mess," "inconsistent pricing," "reps don't know what goes with what"
  • "we copy paste from old quotes," "pricing is in someone's head"
  • "we mark up the vendor price," "cost plus 35-40%"
  • Products with accessories, parts, or services that must go together
Do NOT use this skill when the domain is primarily about inventory tracking (use ERP skill), online product sales (use e-commerce skill), or customer relationship management (use CRM skill). If the domain includes quoting AND inventory, use this skill — the quoting workflow is the primary interaction.

当客户的DOMAIN.md包含以下内容时,Builder Agent应选择该技能:
  • 为客户提供报价/定价的产品或服务
  • 配置选项(尺寸、型号、变体、材质)
  • 产品之间的依赖关系(必需、推荐、互斥)
  • 基于加价或利润率的定价(成本加成、供应商价+百分比)
  • 报价或提案工作流(草稿→审核→批准→发送)
  • 参与定价、审批或发送报价的角色
来自Clarence对话记录的分类信号:
  • "报价一团糟"、"定价不一致"、"销售代表不知道哪些产品能搭配"
  • "我们从旧报价里复制粘贴"、"定价全在某个人脑子里"
  • "我们在供应商价格基础上加价"、"成本加35-40%利润"
  • 产品带有必须搭配的配件、零部件或服务
请勿使用该技能的场景:如果业务域主要涉及库存追踪(使用ERP技能)、线上产品销售(使用电商技能)或客户关系管理(使用CRM技能)。如果业务域同时包含报价和库存功能,仍使用该技能——报价工作流是核心交互。

Section Definitions

板块定义

The CPQ application has four sections. These are fixed — the Builder Agent uses them as-is.
json
{
  "sections": [
    {
      "id": "configure",
      "label": "Configure",
      "icon": "Settings2",
      "order": 1,
      "component": "card-selector",
      "componentConfig": {
        "itemLayout": "grid",
        "showPrice": true,
        "showDescription": true,
        "showOptions": true,
        "selectionMode": "add-to-list",
        "groupBy": "category"
      },
      "dataSource": "data.products",
      "actions": [
        { "label": "Add to Quote", "action": "addSelected", "variant": "primary" }
      ]
    },
    {
      "id": "quote",
      "label": "Build Quote",
      "icon": "FileText",
      "order": 2,
      "component": "data-table",
      "componentConfig": {
        "columns": [
          { "key": "product", "label": "Product", "width": "auto" },
          { "key": "options", "label": "Configuration", "width": "auto" },
          { "key": "quantity", "label": "Qty", "width": "80px", "editable": true },
          { "key": "unitPrice", "label": "Unit Price", "width": "120px", "format": "currency" },
          { "key": "total", "label": "Total", "width": "120px", "format": "currency", "computed": true }
        ],
        "showRowActions": true,
        "rowActions": ["edit", "duplicate", "remove"]
      },
      "dataSource": "data.lineItems",
      "actions": [
        { "label": "Preview Quote", "action": "navigateTo:preview", "variant": "primary" },
        { "label": "Clear All", "action": "clearItems", "variant": "ghost", "confirm": true }
      ]
    },
    {
      "id": "preview",
      "label": "Preview",
      "icon": "Eye",
      "order": 3,
      "component": "summary",
      "componentConfig": {
        "showLineItems": true,
        "showSubtotal": true,
        "showMarkup": false,
        "showTax": true,
        "showTotal": true,
        "showTerms": true,
        "showNotes": true
      },
      "dataSource": "data.lineItems",
      "actions": [
        { "label": "Export PDF", "action": "exportPDF", "variant": "primary" },
        { "label": "Back to Quote", "action": "navigateTo:quote", "variant": "ghost" }
      ]
    },
    {
      "id": "approve",
      "label": "Approve",
      "icon": "CheckCircle",
      "order": 4,
      "component": "form",
      "componentConfig": {
        "fields": [
          { "key": "customerName", "label": "Customer Name", "type": "text", "required": true },
          { "key": "customerEmail", "label": "Customer Email", "type": "email" },
          { "key": "paymentTerms", "label": "Payment Terms", "type": "select", "default": "net30" },
          { "key": "notes", "label": "Notes", "type": "textarea" },
          { "key": "validUntil", "label": "Valid Until", "type": "date" }
        ]
      },
      "dataSource": "data.quoteSettings",
      "gated": {
        "requires": ["customerName", "hasLineItems", "noErrors"],
        "message": "Complete these before approving: customer name, at least one product, no unresolved dependency errors."
      },
      "actions": [
        { "label": "Approve & Send", "action": "approveQuote", "variant": "primary", "confirm": true },
        { "label": "Save Draft", "action": "saveDraft", "variant": "secondary" }
      ]
    }
  ],
  "navMode": "stepper"
}
Navigation mode is
stepper
— the sidebar shows all four sections as sequential steps. All steps are clickable at any time (not a wizard). The Approve step shows gating indicators when requirements aren't met.

CPQ应用有四个固定板块,Builder Agent直接使用即可,无需修改:
json
{
  "sections": [
    {
      "id": "configure",
      "label": "Configure",
      "icon": "Settings2",
      "order": 1,
      "component": "card-selector",
      "componentConfig": {
        "itemLayout": "grid",
        "showPrice": true,
        "showDescription": true,
        "showOptions": true,
        "selectionMode": "add-to-list",
        "groupBy": "category"
      },
      "dataSource": "data.products",
      "actions": [
        { "label": "Add to Quote", "action": "addSelected", "variant": "primary" }
      ]
    },
    {
      "id": "quote",
      "label": "Build Quote",
      "icon": "FileText",
      "order": 2,
      "component": "data-table",
      "componentConfig": {
        "columns": [
          { "key": "product", "label": "Product", "width": "auto" },
          { "key": "options", "label": "Configuration", "width": "auto" },
          { "key": "quantity", "label": "Qty", "width": "80px", "editable": true },
          { "key": "unitPrice", "label": "Unit Price", "width": "120px", "format": "currency" },
          { "key": "total", "label": "Total", "width": "120px", "format": "currency", "computed": true }
        ],
        "showRowActions": true,
        "rowActions": ["edit", "duplicate", "remove"]
      },
      "dataSource": "data.lineItems",
      "actions": [
        { "label": "Preview Quote", "action": "navigateTo:preview", "variant": "primary" },
        { "label": "Clear All", "action": "clearItems", "variant": "ghost", "confirm": true }
      ]
    },
    {
      "id": "preview",
      "label": "Preview",
      "icon": "Eye",
      "order": 3,
      "component": "summary",
      "componentConfig": {
        "showLineItems": true,
        "showSubtotal": true,
        "showMarkup": false,
        "showTax": true,
        "showTotal": true,
        "showTerms": true,
        "showNotes": true
      },
      "dataSource": "data.lineItems",
      "actions": [
        { "label": "Export PDF", "action": "exportPDF", "variant": "primary" },
        { "label": "Back to Quote", "action": "navigateTo:quote", "variant": "ghost" }
      ]
    },
    {
      "id": "approve",
      "label": "Approve",
      "icon": "CheckCircle",
      "order": 4,
      "component": "form",
      "componentConfig": {
        "fields": [
          { "key": "customerName", "label": "Customer Name", "type": "text", "required": true },
          { "key": "customerEmail", "label": "Customer Email", "type": "email" },
          { "key": "paymentTerms", "label": "Payment Terms", "type": "select", "default": "net30" },
          { "key": "notes", "label": "Notes", "type": "textarea" },
          { "key": "validUntil", "label": "Valid Until", "type": "date" }
        ]
      },
      "dataSource": "data.quoteSettings",
      "gated": {
        "requires": ["customerName", "hasLineItems", "noErrors"],
        "message": "Complete these before approving: customer name, at least one product, no unresolved dependency errors."
      },
      "actions": [
        { "label": "Approve & Send", "action": "approveQuote", "variant": "primary", "confirm": true },
        { "label": "Save Draft", "action": "saveDraft", "variant": "secondary" }
      ]
    }
  ],
  "navMode": "stepper"
}
导航模式为
stepper
——侧边栏将四个板块显示为连续步骤,所有步骤随时可点击(不是向导式流程)。当要求未满足时,审批步骤会显示准入提示。

Config Schema

配置Schema

See
references/config-schema.md
for full TypeScript interfaces. Summary:
config
├── app                    ← Branding, theme (from brandfetch)
├── sections[]             ← Fixed (from this skill, above)
├── data
│   ├── products[]         ← Catalog of available products with options
│   ├── lineItems[]        ← Current quote contents (starts empty)
│   └── quoteSettings      ← Currency, tax, terms, markup
├── rules[]                ← Business rules (dependencies, validations)
└── roles[]                ← User roles and permissions

完整TypeScript接口请参考
references/config-schema.md
,概要如下:
config
├── app                    ← 品牌信息、主题(来自brandfetch)
├── sections[]             ← 固定配置(来自本技能,见上文)
├── data
│   ├── products[]         ← 可用产品目录及对应选项
│   ├── lineItems[]        ← 当前报价内容(初始为空)
│   └── quoteSettings      ← 货币、税费、条款、加价比例
├── rules[]                ← 业务规则(依赖关系、校验规则)
└── roles[]                ← 用户角色和权限

Deterministic Mapping Rules

确定性映射规则

The Builder Agent follows these rules mechanically to transform DOMAIN.md into config.json. No reasoning, no interpretation — execute the rules.
Builder Agent严格遵循以下规则将DOMAIN.md转换为config.json,无需推理、无需解读,直接执行规则即可:

Entity → Product Mapping

实体→产品映射

FOR EACH entity in DOMAIN.md Entity Registry
  WHERE entity description suggests a sellable product, equipment, service, or part:
    → CREATE config.data.products[] entry
    → SET id = slugify(entity name)
    → SET name = entity name (exact, from DOMAIN.md)
    → SET category = entity parent grouping or category (from Entity Registry or Relationship Map)
    → SET basePrice = entity price if stated (number, no currency symbol)
    → SET pricingSource = determine from context:
        IF "price list" or "vendor list" or "catalog price" → "catalog"
        IF "get a quote from vendor" or "depends on specs" → "vendor_rfq"
        IF "we know our cost and mark it up" → "cost_plus"
        IF no pricing discussed → "tbd"
    → SET options[] = from entity's "what varies" attributes:
        FOR EACH variation mentioned (size, model, capacity, material, type):
          → CREATE option entry
          → SET option.id = slugify(variation name)
          → SET option.label = variation name
          → SET option.type = "select" (default for enumerated choices)
          → SET option.choices = the specific values mentioned

  WHERE entity has NO price, NO options, and is NOT referenced in a relationship:
    → SKIP — it's probably not a product (may be a role, process, or system)
    → ADD to Open Questions: "Is [entity] a quotable product?"
FOR EACH entity in DOMAIN.md Entity Registry
  WHERE entity description suggests a sellable product, equipment, service, or part:
    → CREATE config.data.products[] entry
    → SET id = slugify(entity name)
    → SET name = entity name (exact, from DOMAIN.md)
    → SET category = entity parent grouping or category (from Entity Registry or Relationship Map)
    → SET basePrice = entity price if stated (number, no currency symbol)
    → SET pricingSource = determine from context:
        IF "price list" or "vendor list" or "catalog price" → "catalog"
        IF "get a quote from vendor" or "depends on specs" → "vendor_rfq"
        IF "we know our cost and mark it up" → "cost_plus"
        IF no pricing discussed → "tbd"
    → SET options[] = from entity's "what varies" attributes:
        FOR EACH variation mentioned (size, model, capacity, material, type):
          → CREATE option entry
          → SET option.id = slugify(variation name)
          → SET option.label = variation name
          → SET option.type = "select" (default for enumerated choices)
          → SET option.choices = the specific values mentioned

  WHERE entity has NO price, NO options, and is NOT referenced in a relationship:
    → SKIP — it's probably not a product (may be a role, process, or system)
    → ADD to Open Questions: "Is [entity] a quotable product?"

Relationship → Rule Mapping

关系→规则映射

FOR EACH relationship in DOMAIN.md Relationship Map:

  IF relationship type = "requires":
    → CREATE config.rules[] entry
    → SET type = "requires"
    → SET severity = "error"
    → SET trigger = "addItem"
    → SET condition = { "item.category": [source entity category] }
    → SET action = { "suggest": [target entity id] }
    → IF relationship mentions size/model matching:
        → SET action.matchField = the matching attribute
    → SET message = relationship rationale from DOMAIN.md (the "because")
    → IF no rationale captured:
        → SET message = "[source] requires [target] — rationale not captured"

  IF relationship type = "recommends":
    → CREATE config.rules[] entry
    → SET type = "recommends"
    → SET severity = "warning"
    → SET trigger = "addItem"
    → SET condition = { "item.category": [source entity category] }
    → SET action = { "suggest": [target entity id] }
    → SET message = relationship rationale from DOMAIN.md

  IF relationship type = "excludes":
    → CREATE config.rules[] entry
    → SET type = "excludes"
    → SET severity = "error"
    → SET trigger = "addItem"
    → SET condition = { "item.category": [source entity category] }
    → SET action = { "block": [target entity id] }
    → SET message = relationship rationale from DOMAIN.md
FOR EACH relationship in DOMAIN.md Relationship Map:

  IF relationship type = "requires":
    → CREATE config.rules[] entry
    → SET type = "requires"
    → SET severity = "error"
    → SET trigger = "addItem"
    → SET condition = { "item.category": [source entity category] }
    → SET action = { "suggest": [target entity id] }
    → IF relationship mentions size/model matching:
        → SET action.matchField = the matching attribute
    → SET message = relationship rationale from DOMAIN.md (the "because")
    → IF no rationale captured:
        → SET message = "[source] requires [target] — rationale not captured"

  IF relationship type = "recommends":
    → CREATE config.rules[] entry
    → SET type = "recommends"
    → SET severity = "warning"
    → SET trigger = "addItem"
    → SET condition = { "item.category": [source entity category] }
    → SET action = { "suggest": [target entity id] }
    → SET message = relationship rationale from DOMAIN.md

  IF relationship type = "excludes":
    → CREATE config.rules[] entry
    → SET type = "excludes"
    → SET severity = "error"
    → SET trigger = "addItem"
    → SET condition = { "item.category": [source entity category] }
    → SET action = { "block": [target entity id] }
    → SET message = relationship rationale from DOMAIN.md

Business Rule → Validation Mapping

业务规则→校验映射

FOR EACH rule in DOMAIN.md Business Rules:

  IF rule mentions "approval" or "requires authorization":
    → CREATE config.rules[] entry
    → SET type = "validates"
    → SET trigger = the action being gated (e.g., "setTerms", "approveQuote")
    → SET condition = the triggering condition
    → SET action = { "requireApproval": [role] }
    → SET severity = "warning"
    → SET message = rule rationale

  IF rule mentions "cannot" or "must not" or "not allowed":
    → CREATE config.rules[] entry
    → SET type = "validates"
    → SET trigger = the blocked action
    → SET condition = the triggering condition
    → SET action = { "block": true }
    → SET severity = "error"
    → SET message = rule rationale

  IF rule mentions pricing constraint (markup, margin, discount limit):
    → CREATE config.rules[] entry
    → SET type = "computes"
    → SET trigger = "priceCalculation"
    → SET condition = the pricing formula or constraint
    → SET action = { "compute": [formula description] }
    → SET message = rule rationale
FOR EACH rule in DOMAIN.md Business Rules:

  IF rule mentions "approval" or "requires authorization":
    → CREATE config.rules[] entry
    → SET type = "validates"
    → SET trigger = the action being gated (e.g., "setTerms", "approveQuote")
    → SET condition = the triggering condition
    → SET action = { "requireApproval": [role] }
    → SET severity = "warning"
    → SET message = rule rationale

  IF rule mentions "cannot" or "must not" or "not allowed":
    → CREATE config.rules[] entry
    → SET type = "validates"
    → SET trigger = the blocked action
    → SET condition = the triggering condition
    → SET action = { "block": true }
    → SET severity = "error"
    → SET message = rule rationale

  IF rule mentions pricing constraint (markup, margin, discount limit):
    → CREATE config.rules[] entry
    → SET type = "computes"
    → SET trigger = "priceCalculation"
    → SET condition = the pricing formula or constraint
    → SET action = { "compute": [formula description] }
    → SET message = rule rationale

State Model → Quote Settings Mapping

状态模型→报价设置映射

IF DOMAIN.md State Models contains payment terms or approval statuses:
  → MAP to config.data.quoteSettings.availableTerms[]
  → SET config.data.quoteSettings.defaultTerms = the default mentioned

IF DOMAIN.md State Models contains quote statuses:
  → MAP to section gating logic
  → The CPQ skill handles this through the fixed section definitions (Configure → Quote → Preview → Approve)
IF DOMAIN.md State Models contains payment terms or approval statuses:
  → MAP to config.data.quoteSettings.availableTerms[]
  → SET config.data.quoteSettings.defaultTerms = the default mentioned

IF DOMAIN.md State Models contains quote statuses:
  → MAP to section gating logic
  → The CPQ skill handles this through the fixed section definitions (Configure → Quote → Preview → Approve)

Branding → Theme Mapping

品牌→主题映射

→ SET config.app.companyName = DOMAIN.md Project Overview company name
→ SET config.app.theme.primaryColor = from brandfetch (or fallback "#1a1a2e")
→ SET config.app.theme.accentColor = from brandfetch (or fallback "#3b82f6")
→ SET config.app.theme.logoUrl = from brandfetch
→ SET config.app.theme.mode = "light"
→ SET config.app.companyName = DOMAIN.md Project Overview company name
→ SET config.app.theme.primaryColor = from brandfetch (or fallback "#1a1a2e")
→ SET config.app.theme.accentColor = from brandfetch (or fallback "#3b82f6")
→ SET config.app.theme.logoUrl = from brandfetch
→ SET config.app.theme.mode = "light"

Quote Settings Mapping

报价设置映射

→ SET config.data.quoteSettings.currency = from DOMAIN.md (or default "USD")
→ SET config.data.quoteSettings.taxEnabled = true/false based on DOMAIN.md
→ SET config.data.quoteSettings.taxLabel = from DOMAIN.md (e.g., "HST", "GST", "Sales Tax")
→ SET config.data.quoteSettings.taxRate = from DOMAIN.md (decimal, e.g., 0.13 for 13%)
→ SET config.data.quoteSettings.defaultTerms = from DOMAIN.md (e.g., "net30")
→ SET config.data.quoteSettings.markup = from DOMAIN.md (decimal, e.g., 0.375 for 37.5%)
→ SET config.data.quoteSettings.quoteFormat = "itemized" (default, unless DOMAIN.md says otherwise)
→ SET config.data.quoteSettings.currency = from DOMAIN.md (or default "USD")
→ SET config.data.quoteSettings.taxEnabled = true/false based on DOMAIN.md
→ SET config.data.quoteSettings.taxLabel = from DOMAIN.md (e.g., "HST", "GST", "Sales Tax")
→ SET config.data.quoteSettings.taxRate = from DOMAIN.md (decimal, e.g., 0.13 for 13%)
→ SET config.data.quoteSettings.defaultTerms = from DOMAIN.md (e.g., "net30")
→ SET config.data.quoteSettings.markup = from DOMAIN.md (decimal, e.g., 0.375 for 37.5%)
→ SET config.data.quoteSettings.quoteFormat = "itemized" (default, unless DOMAIN.md says otherwise)

Role Mapping

角色映射

FOR EACH role in DOMAIN.md User Roles:
  → CREATE config.roles[] entry
  → SET id = slugify(role name)
  → SET label = role name (exact, from DOMAIN.md)
  → SET permissions = infer from DOMAIN.md role description:
      IF role creates quotes → ["createQuote", "editQuote", "selectProducts"]
      IF role approves → ["approveQuote", "approveTerms", "viewReports"]
      IF role manages catalog → ["editCatalog", "editPricing"]
      IF role is view-only → ["viewQuotes"]
  → IF permissions cannot be inferred → SET permissions = ["createQuote", "editQuote"] (safe default)
FOR EACH role in DOMAIN.md User Roles:
  → CREATE config.roles[] entry
  → SET id = slugify(role name)
  → SET label = role name (exact, from DOMAIN.md)
  → SET permissions = infer from DOMAIN.md role description:
      IF role creates quotes → ["createQuote", "editQuote", "selectProducts"]
      IF role approves → ["approveQuote", "approveTerms", "viewReports"]
      IF role manages catalog → ["editCatalog", "editPricing"]
      IF role is view-only → ["viewQuotes"]
  → IF permissions cannot be inferred → SET permissions = ["createQuote", "editQuote"] (safe default)

Edge Cases

边缘情况处理

→ IF entity has no price → SET pricingSource = "tbd", ADD to config metadata openQuestions
→ IF relationship rationale is missing → SET message = "[source] [relationship] [target] — rationale not captured"
→ IF entity cannot be classified as a product → SKIP, ADD to config metadata openQuestions
→ IF DOMAIN.md has Open Questions → COPY to config.metadata.openQuestions for reference
→ IF no roles are defined in DOMAIN.md → CREATE one default role: { id: "user", label: "User", permissions: ["createQuote", "editQuote", "selectProducts"] }
→ IF no pricing information at all → SET quoteSettings.markup = 0, quoteSettings.currency = "USD", ADD note to openQuestions

→ IF entity has no price → SET pricingSource = "tbd", ADD to config metadata openQuestions
→ IF relationship rationale is missing → SET message = "[source] [relationship] [target] — rationale not captured"
→ IF entity cannot be classified as a product → SKIP, ADD to config metadata openQuestions
→ IF DOMAIN.md has Open Questions → COPY to config.metadata.openQuestions for reference
→ IF no roles are defined in DOMAIN.md → CREATE one default role: { id: "user", label: "User", permissions: ["createQuote", "editQuote", "selectProducts"] }
→ IF no pricing information at all → SET quoteSettings.markup = 0, quoteSettings.currency = "USD", ADD note to openQuestions

Business Rule Templates

业务规则模板

Common CPQ rule patterns the Builder Agent can use when DOMAIN.md describes rules in natural language:
当DOMAIN.md用自然语言描述规则时,Builder Agent可以使用以下通用CPQ规则模式:

Product Dependency (hard)

产品强制依赖(硬规则)

json
{
  "id": "BR-XXX",
  "type": "requires",
  "trigger": "addItem",
  "condition": { "item.category": "[source_category]" },
  "action": { "suggest": "[target_product_id]", "matchField": "[matching_attribute]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "error"
}
json
{
  "id": "BR-XXX",
  "type": "requires",
  "trigger": "addItem",
  "condition": { "item.category": "[source_category]" },
  "action": { "suggest": "[target_product_id]", "matchField": "[matching_attribute]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "error"
}

Product Recommendation (soft)

产品推荐(软规则)

json
{
  "id": "BR-XXX",
  "type": "recommends",
  "trigger": "addItem",
  "condition": { "item.category": "[source_category]" },
  "action": { "suggest": "[target_product_id]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "warning"
}
json
{
  "id": "BR-XXX",
  "type": "recommends",
  "trigger": "addItem",
  "condition": { "item.category": "[source_category]" },
  "action": { "suggest": "[target_product_id]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "warning"
}

Product Exclusion

产品互斥

json
{
  "id": "BR-XXX",
  "type": "excludes",
  "trigger": "addItem",
  "condition": { "item.category": "[source_category]" },
  "action": { "block": "[target_product_id]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "error"
}
json
{
  "id": "BR-XXX",
  "type": "excludes",
  "trigger": "addItem",
  "condition": { "item.category": "[source_category]" },
  "action": { "block": "[target_product_id]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "error"
}

Approval Gate

审批关口

json
{
  "id": "BR-XXX",
  "type": "validates",
  "trigger": "[gated_action]",
  "condition": { "[field]": { "$ne": "[default_value]" } },
  "action": { "requireApproval": "[role_id]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "warning"
}
json
{
  "id": "BR-XXX",
  "type": "validates",
  "trigger": "[gated_action]",
  "condition": { "[field]": { "$ne": "[default_value]" } },
  "action": { "requireApproval": "[role_id]" },
  "message": "[rationale from DOMAIN.md]",
  "severity": "warning"
}

Price Computation

价格计算

json
{
  "id": "BR-XXX",
  "type": "computes",
  "trigger": "priceCalculation",
  "condition": { "item.pricingSource": "cost_plus" },
  "action": { "compute": "sellingPrice = cost * (1 + markup)" },
  "message": "Cost-plus pricing: [markup]% markup applied",
  "severity": "info"
}

json
{
  "id": "BR-XXX",
  "type": "computes",
  "trigger": "priceCalculation",
  "condition": { "item.pricingSource": "cost_plus" },
  "action": { "compute": "sellingPrice = cost * (1 + markup)" },
  "message": "Cost-plus pricing: [markup]% markup applied",
  "severity": "info"
}

Vertical Presets

垂直领域预设

See
references/vertical-presets.md
for full details. Summary:
VerticalProducts ArePricing ModelKey Dependency PatternQuote Style
Manufacturing / BOMFabricated equipment, assembliesCost-plus or vendor RFQEquipment requires accessories, parts, installationItemized with scope of work
Wholesale / DistributionCatalog items, bulk goodsPrice list with volume tiersProduct bundles, case/pallet quantitiesItemized with quantity breaks
Services / Equipment IntegratorEquipment + installation + PMMixed (catalog + vendor RFQ + labor rates)Equipment requires service, service includes consumablesItemized with service schedule
The Builder Agent uses the vertical preset as a starting point, then overrides with specifics from DOMAIN.md.

完整详情请参考
references/vertical-presets.md
,概要如下:
垂直领域产品类型定价模式核心依赖模式报价风格
制造业/物料清单(BOM)加工设备、组装件成本加成或供应商询价设备需要搭配配件、零部件、安装服务带工作范围的明细报价
批发/分销目录商品、大宗商品带数量阶梯的价目表产品捆绑、箱/托装数量要求带数量折扣的明细报价
服务/设备集成商设备+安装+项目管理混合模式(目录价+供应商询价+人工费率)设备需要搭配服务,服务包含耗材带服务计划的明细报价
Builder Agent以垂直领域预设为起点,再根据DOMAIN.md中的具体内容进行覆盖调整。

Mapping Log

映射日志

After executing the mapping rules, the Builder Agent should produce a brief mapping log as an audit trail:
markdown
undefined
执行完映射规则后,Builder Agent应生成一份简短的映射日志作为审计追踪:
markdown
undefined

Mapping Log

映射日志

Skill: cpq-builder v3.0 DOMAIN.md: [company name] Vertical preset: [manufacturing / wholesale / services / none]
技能: cpq-builder v3.0 DOMAIN.md所属: [公司名称] 垂直领域预设: [manufacturing / wholesale / services / none]

Products mapped: [N]

已映射产品:[N]

  • [entity name] → config.data.products[0] ([pricingSource], [N] options)
  • [entity name] → config.data.products[1] ([pricingSource], [N] options)
  • [实体名称] → config.data.products[0] ([pricingSource], [N]个选项)
  • [实体名称] → config.data.products[1] ([pricingSource], [N]个选项)

Rules mapped: [N]

已映射规则:[N]

  • BR-001: [source] requires [target] → severity: error
  • BR-002: [source] recommends [target] → severity: warning
  • BR-001: [源实体] requires [目标实体] → 严重级别:error
  • BR-002: [源实体] recommends [目标实体] → 严重级别:warning

Skipped entities: [N]

已跳过实体:[N]

  • [entity name] — not a quotable product (added to openQuestions)
  • [实体名称] — 不是可报价产品(已添加到待确认问题)

Open questions carried forward: [N]

结转的待确认问题:[N]

  • [question from DOMAIN.md]

This log is NOT part of the config. It's a separate output that can be reviewed if the config seems wrong.

---
  • [来自DOMAIN.md的问题]

该日志不属于配置的一部分,是单独的输出文件,当配置看起来有问题时可以用于排查。

---

Reference Files

参考文件

  • references/config-schema.md
    — Full TypeScript interfaces for the CPQ config shape
  • references/vertical-presets.md
    — Detailed presets for Manufacturing, Wholesale, and Services
  • references/example-config.json
    — Fully populated Total Water example config
  • references/config-schema.md
    — CPQ配置结构的完整TypeScript接口
  • references/vertical-presets.md
    — 制造业、批发业、服务业的详细预设配置
  • references/example-config.json
    — 完整填充的Total Water示例配置