BossAgents 六大能力增强 — 编码任务规划文档

BossAgents 六大能力增强 — 编码任务规划文档

版本:v1.0 | 日期:2026-06-25 | 基于 spec-六大能力增强.md + design-六大能力增强.md


项目约束提醒

  • 包管理:项目基于 pnpm,不涉及包管理变更
  • server.js:POST 路由需先 collectBody(req),本次不修改 server.js 路由层
  • 导出方式module.exports = CapabilityDispatcher(直接导出类),不修改
  • 前端构建:前端修改后需 npm run build,本次不涉及前端修改
  • 进程管理:不要用 Stop-Process -Name "node"
  • 关键模块行号
  • rule-engine.js(2384行):_loadBuiltinRules() 第300行附近,RULE_SCOPES 第120行
  • capability-runtime.jsidentify() 第504行,generate() 第660行
  • aml-generator.js_buildAML() 第347行
  • relationship-resolver.jsdiscoverRelations() 第247行
  • aml-builder.jsbuildItemElement() 第43行,buildRelationshipElement() 第99行

P0 优先级任务(核心能力,必须完成)


TASK-P0-01: generate 能力规则驱动

  • 对应需求:P0-1(spec §5.1)
  • 优先级:P0
  • 依赖任务:无
  • 预估工作量:2天

#### 实现步骤

步骤1:在 rule-engine.js 的 RULE_SCOPES 中确认 GENERATE/TRANSFORM 枚举

  • 文件:server/core/rule-engine.js
  • 位置:第120行附近 RULE_SCOPES 定义处
  • 操作:确认 RULE_SCOPES 中已包含 GENERATETRANSFORM 枚举值,如不存在则添加
  • 验证:console.log(RULE_SCOPES.GENERATE, RULE_SCOPES.TRANSFORM) 输出非 undefined

步骤2:在 _loadBuiltinRules() 中添加 GENERATE/TRANSFORM 内置规则

  • 文件:server/core/rule-engine.js
  • 位置:第300行附近 _loadBuiltinRules() 方法末尾
  • 操作:在方法末尾、return rules 之前,添加以下5条内置规则:
  1. builtin-generate-001:通用模板化生成(scope=GENERATE, item_type_name=null, action_type=suggest, priority=P1)
  2. builtin-transform-001:通用数据格式转换(scope=TRANSFORM, item_type_name=null, action_type=suggest, priority=P1)
  3. builtin-generate-eco-001:ECO工程变更单生成(scope=GENERATE, item_type_name='ECO', action_type=suggest, priority=P0)
  4. builtin-generate-bom-001:BOM物料清单生成(scope=GENERATE, item_type_name='BOM', action_type=suggest, priority=P0)
  5. builtin-generate-document-001:Document文档生成(scope=GENERATE, item_type_name='Document', action_type=suggest, priority=P0)
  • 关键实现:
  • 每条规则的 action_script 使用 vm.createContext 沙箱兼容语法(var 而非 let/const)
  • builtin-generate-001 需支持 prompt_template_id 字段,运行时从 context._promptTemplate 注入模板
  • builtin-transform-001 支持 aml/json 两种转换目标
  • ECO/BOM/Document 专用规则通过 item_type_name 字段自动过滤,条件为 { type: 'item_type_match', item_type: 'XXX' }
  • 参考代码:design §1.3.1 第148-283行的规则定义

步骤3:在 rule-engine.js 中新增 executeGenerate() 方法

  • 文件:server/core/rule-engine.js
  • 位置:在现有 executeIdentify() 方法之后添加
  • 操作:新增 async executeGenerate(context, options = {}) 方法,逻辑如下:
  1. 如果 context.template_id 存在且 this.db 可用,从 prompt_templates 表加载模板到 context._promptTemplate
  2. 如果未指定模板但有 item_type,尝试加载 prompt_type='creation' 的默认模板
  3. 匹配 GENERATE scope 规则,遍历并执行匹配的规则
  4. 如果 GENERATE 未命中,尝试 TRANSFORM scope 规则
  5. 结果按 priority 排序,返回最高优先级结果
  • 返回格式:{ executed, scope, item_type, generated_content, results, elapsed }
  • 参考代码:design §1.3.1 第287-371行

步骤4:修改 capability-runtime.js 的 generate() 方法集成规则引擎

  • 文件:server/core/capability-runtime.js
  • 位置:第660行附近 generate() 方法
  • 操作:重写 generate() 方法,实现规则驱动 + LLM降级双路径:
  1. 初始化规则引擎 const engine = await this._initRuleEngine()
  2. 调用 engine.executeGenerate({ item_type, data, template_id }, this._buildEngineOptions())
  3. 规则命中时返回 source: 'rule_engine'
  4. 规则未命中时降级到 _callLLMViaRouter(),返回 source: 'llm_router'
  5. 双路均不可用时返回错误
  • 参考代码:design §1.3.1 第376-418行

步骤5:添加 generate_pre/generate_post 生命周期钩子(可选)

  • 文件:server/core/rule-engine.js
  • 位置:executeGenerate() 方法内部
  • 操作:在规则匹配前检查 GENERATE_PRE scope 规则,在规则执行后检查 GENERATE_POST scope 规则(当前阶段仅预留接口,不注册具体规则)
  • 说明:此步骤为扩展预留,P0阶段可跳过

#### 验证方法

  1. 启动服务 node server.js,确认无启动报错
  2. 调用 POST /api/capability,body 为 { "capability": "generate", "params": { "item_type": "ECO", "data": { "title": "测试变更单" } } }
  3. 验证返回结果 source: 'rule_engine'generated_content 包含 ECO 结构化模板
  4. 调用 { "capability": "generate", "params": { "item_type": "UnknownType", "data": {} } },验证降级到 source: 'llm_router'
  5. 检查 sciot_rules_v2 表中已同步5条 builtin-generate/builtin-transform 规则

TASK-P0-02: AMLGenerator Relationships 支持

  • 对应需求:P0-2(spec §5.2)
  • 优先级:P0
  • 依赖任务:无
  • 预估工作量:1.5天

#### 实现步骤

步骤1:修改 aml-generator.js 的 _buildAML() 方法

  • 文件:server/core/aml-generator.js
  • 位置:第347行附近 _buildAML(data, schema, options) 方法
  • 操作:
  1. Object.entries(data).filter() 中排除 relationships_relationships 键,避免关系数据被当作普通属性输出
  2. 在属性XML构建之后、 之前,添加 Relationships XML 构建逻辑
  3. data.relationships || data._relationships || [] 获取关系数据
  4. 调用新增的 _buildRelationshipsXml() 方法生成关系XML
  5. 将关系XML拼接到属性XML之后
  • 参考代码:design §1.3.2 第488-532行

步骤2:新增 _buildRelationshipsXml() 方法

  • 文件:server/core/aml-generator.js
  • 位置:在 _buildAML() 方法之后添加
  • 操作:新增 _buildRelationshipsXml(relationships) 方法:
  1. 遍历 relationships 数组
  2. 格式1(AMLBuilder标准格式):{ relationship_type, related_item_type, related_items } → 调用 _buildAmlBuilderStyleRelation()
  3. 格式2/3(简化格式):{ type, action, related_id, properties } → 调用 _buildSimpleStyleRelation()
  4. 缺少必要字段(type/action)的关系项跳过,记录 WARNING 日志
  5. 有内容时输出 \n ...内容...\n ,无内容时返回空字符串
  • 参考代码:design §1.3.2 第543-567行

步骤3:新增 _buildAmlBuilderStyleRelation() 方法

  • 文件:server/core/aml-generator.js
  • 位置:在 _buildRelationshipsXml() 方法之后添加
  • 操作:新增 _buildAmlBuilderStyleRelation(rel) 方法,逻辑与 aml-builder.jsbuildRelationshipElement() 保持一致:
  1. 遍历 rel.related_items,为每个 item 生成 节点
  2. related_id 处理:
  • 引用类型(Identity/User/Group/Team):通过 name 或 id 查询引用
  • 嵌套创建类型:在 内创建新 Item
  • 已有对象引用:通过 id 或 item_number 引用
  1. 关系级别附加属性(item.relItemProps):遍历输出嵌套 Item
  • 参考代码:design §1.3.2 第573-633行,同时对照 server/core/aml-builder.js 第99行 buildRelationshipElement()

步骤4:新增 _buildSimpleStyleRelation() 方法

  • 文件:server/core/aml-generator.js
  • 位置:在 _buildAmlBuilderStyleRelation() 方法之后添加
  • 操作:新增 _buildSimpleStyleRelation(rel) 方法:
  1. 生成 节点
  2. related_id 处理:
  • 对象类型(含 item_type):嵌套创建
  • 字符串类型:GUID 直接引用
  1. 关系属性:遍历 rel.properties 输出非对象字段
  • 参考代码:design §1.3.2 第639-672行

步骤5:确认 _escapeXml() 方法可用

  • 文件:server/core/aml-generator.js
  • 操作:确认 _escapeXml() 方法已存在且可被新方法调用;如不存在,从 aml-builder.js 中复制实现

#### 验证方法

  1. 构造包含 relationships 的测试数据:
   const data = {
     item_number: 'P-001', name: '零件A',
     relationships: [{
       relationship_type: 'Part BOM', related_item_type: 'Part',
       related_items: [{ properties: { item_number: 'P-002', name: '子零件B' } }]
     }]
   };
   
  1. 调用 amlGenerator._buildAML(data, schema, { action: 'add' })
  2. 验证输出 AML 包含 节点,且格式与 amlBuilder.buildRelationshipElement() 输出一致
  3. 测试空关系数据(无 relationships 字段),验证不输出 标签
  4. 测试简化格式关系数据,验证两种格式均可正确输出

TASK-P0-03: identify 关系发现集成

  • 对应需求:P0-3(spec §5.3)
  • 优先级:P0
  • 依赖任务:无
  • 预估工作量:1.5天

#### 实现步骤

步骤1:修改 capability-runtime.js 的 identify() 方法

  • 文件:server/core/capability-runtime.js
  • 位置:第504行附近 identify(context, options = {}) 方法
  • 操作:
  1. 在方法参数中解析 includeRelationsconst includeRelations = options.includeRelations !== false(默认开启)
  2. 保留现有规则引擎识别和 LLM 降级逻辑不变
  3. 在识别结果返回前,添加关系发现集成逻辑(步骤2-4)

步骤2:添加关系发现调用(非阻塞,2秒超时)

  • 文件:server/core/capability-runtime.js
  • 位置:identify() 方法内,识别结果获取之后、return 之前
  • 操作:
  1. 检查 includeRelations && item_type 条件
  2. 调用 this._getRelationshipCapability() 获取 RelationshipCapability 实例
  3. 从识别结果中提取对象数据(identifyResult.result?.query_result?.itemsidentifyResult.result?.items
  4. 使用 Promise.race 实现2秒超时:
     const relationPromise = relCap.identifyRelations(item_type, itemData);
     const timeoutPromise = new Promise((_, reject) =>
       setTimeout(() => reject(new Error('关系发现超时')), 2000)
     );
     const relations = await Promise.race([relationPromise, timeoutPromise]);
     
  1. 超时或异常时,related_objects 为空数组,不影响主查询返回

步骤3:格式化关系发现结果

  • 文件:server/core/capability-runtime.js
  • 位置:关系发现调用成功后
  • 操作:
  1. 将关系发现结果映射为标准格式:
     { relationship_type, related_item: { type, hint }, direction, confidence, method }
     
  1. 截取前20个关联对象,超过时标记 has_more: true
  2. 初始化 identifyResult.related_objects = []identifyResult.has_more = false

步骤4:新增 _getRelationshipCapability() 懒加载方法

  • 文件:server/core/capability-runtime.js
  • 位置:在 identify() 方法之后添加
  • 操作:新增 _getRelationshipCapability() 方法:
  _getRelationshipCapability() {
    try {
      const { getRelationshipCapability } = require('./relationship-capability');
      return getRelationshipCapability();
    } catch (e) {
      this._log('identify', '*', 'RelationshipCapability不可用', e.message);
      return null;
    }
  }
  
  • 参考代码:design §1.3.3 第829-837行

步骤5:异常处理与 source 标记

  • 文件:server/core/capability-runtime.js
  • 位置:关系发现 try-catch 块
  • 操作:
  1. catch 块中记录日志 this._log('identify', item_type, '关系发现失败(非阻塞)', e.message)
  2. 关系发现失败时,将 source 标记为 rule_engine_only(仅规则引擎结果)或保持 llm_router

#### 验证方法

  1. 调用 POST /api/capability,body 为 { "capability": "identify", "params": { "item_type": "Part", "query_type": "list", "filters": {} } }
  2. 验证返回结果包含 related_objects 数组(可能为空,取决于 RelationshipCapability 状态)
  3. 传入 options: { includeRelations: false },验证跳过关系发现
  4. 模拟 RelationshipCapability 不可用,验证主查询正常返回,related_objects 为空数组
  5. 验证关系发现超时(2秒)不影响主查询返回

P1 优先级任务(增强能力,重要但非紧急)


TASK-P1-01: compare 关系层对比

  • 对应需求:P1-1(spec §5.4)
  • 优先级:P1
  • 依赖任务:TASK-P0-02(关系数据格式定义)
  • 预估工作量:2天

#### 实现步骤

步骤1:修改 rule-engine.js 的 executeCompare() 方法

  • 文件:server/core/rule-engine.js
  • 位置:第1961行附近 executeCompare() 方法
  • 操作:
  1. _computeFieldDiffs() 调用后,添加 _computeRelationDiffs() 调用
  2. 从查询结果中提取 Relationships 数据:
     const relationDiffs = this._computeRelationDiffs(
       dataA.item?.Relationships || dataA.Relationships || {},
       dataB.item?.Relationships || dataB.Relationships || {}
     );
     
  1. 合并属性差异和关系差异:const allDiffs = [...fieldDiffs, ...relationDiffs]
  2. 后续规则匹配和影响分析使用 allDiffs 替代 fieldDiffs
  3. 在 summary 中添加关系差异统计:relation_addedrelation_removedrelation_modified
  • 参考代码:design §1.3.4 第896-957行

步骤2:新增 _computeRelationDiffs() 方法

  • 文件:server/core/rule-engine.js
  • 位置:在 _computeFieldDiffs() 方法之后添加
  • 操作:新增 _computeRelationDiffs(relsA, relsB) 方法:
  1. 解析 SCSAI 返回的 Relationships 格式(rels.Item 可能是数组或单个对象)
  2. 构建 Map 索引:以 type|related_id 为唯一键
  3. 检测新增关系(B有A无)→ change_type: 'relation_added'
  4. 检测删除关系(A有B无)→ change_type: 'relation_removed'
  5. 检测修改关系(同一key但属性不同)→ change_type: 'relation_modified',复用 _computeFieldDiffs() 做属性级对比
  6. 每个差异项包含:change_typerelationship_typerelated_item_typerelated_item_idvalue_avalue_b
  • 参考代码:design §1.3.4 第972-1053行

步骤3:新增 _flattenRelItem() 辅助方法

  • 文件:server/core/rule-engine.js
  • 位置:在 _computeRelationDiffs() 方法之后添加
  • 操作:新增 _flattenRelItem(item) 方法:
  1. 遍历关系项属性,排除 related_idRelationships@_typetype 字段
  2. 非对象值直接映射,_text 属性取其文本值
  3. 返回扁平化属性对象,供 _computeFieldDiffs() 复用
  • 参考代码:design §1.3.4 第1058-1066行

#### 验证方法

  1. 准备两个包含 Relationships 的 Part 对象数据
  2. 调用 POST /api/capability,body 为 { "capability": "compare", "params": { "item_type": "Part", "item_a": {...}, "item_b": {...}, "mode": "object" } }
  3. 验证 field_diffs 中包含 relation_added/relation_removed/relation_modified 类型的差异项
  4. 验证 summary 中包含 relation_added/relation_removed/relation_modified 计数
  5. 测试无 Relationships 的对象对比,验证仅返回属性差异

TASK-P1-02: optimize 自动执行

  • 对应需求:P1-2(spec §5.5)
  • 优先级:P1
  • 依赖任务:TASK-P1-03(_buildRepairAML 增强,auto_fix 需要调用它构建 AML)
  • 预估工作量:1.5天

#### 实现步骤

步骤1:修改 rule-engine.js 的 executeOptimize() 方法

  • 文件:server/core/rule-engine.js
  • 位置:executeOptimize() 方法
  • 操作:
  1. 定义受保护字段常量:const PROTECTED_FIELDS = ['id', 'config_id', 'created_by_id', 'created_on', 'modified_by_id', 'modified_on', 'lock_state']
  2. 在规则匹配循环中,对 rule.action_type === 'auto_fix' 的规则添加特殊处理:
  • 检查 optimizeResult.changesoptions.SCSAIClient 是否存在
  • 调用 _executeOptimizeAction() 执行自动修复
  • 将结果附加到 optimization 对象:auto_applieditem_iderror
  1. 非 auto_fix 规则保持原有 suggest 逻辑
  • 参考代码:design §1.3.5 第1146-1195行

步骤2:新增 _executeOptimizeAction() 方法

  • 文件:server/core/rule-engine.js
  • 位置:在 executeOptimize() 方法之后添加
  • 操作:新增 async _executeOptimizeAction(itemType, itemId, changes, options, protectedFields) 方法:
  1. 前置校验:检查 changes 中是否包含受保护字段,包含则降级为 suggest,返回 { auto_applied: false, error: '涉及受保护字段(...), 需人工确认' }
  2. 构建 AML:调用 this._buildRepairAML(itemType, itemId, changes) 构建 edit AML
  3. 提交 SCSAI:调用 options.SCSAIClient.applyAML(aml) 提交
  4. 成功处理:返回 { auto_applied: true, item_id: returnedId },记录审计日志
  5. 失败处理:SCSAI 返回 fault 或异常时,返回 { auto_applied: false, error, original_changes }
  • 参考代码:design §1.3.5 第1206-1244行

步骤3:在 _loadBuiltinRules() 中添加 auto_fix 类型优化规则(可选)

  • 文件:server/core/rule-engine.js
  • 位置:_loadBuiltinRules() 方法末尾
  • 操作:添加1-2条 action_type: 'auto_fix' 的 OPTIMIZE scope 示例规则,用于验证 auto_fix 流程
  • 说明:此步骤为测试验证用,可根据实际需要决定是否添加

#### 验证方法

  1. 调用 POST /api/capability,body 为 { "capability": "optimize", "params": { "item_type": "Part", "item_id": "TEST_ID", "data": { "unit_cost": 1500 } } }
  2. 验证 suggest 类型规则返回建议,auto_fix 类型规则自动执行并返回 auto_applied: true
  3. 构造涉及受保护字段的变更,验证降级为 suggest
  4. 模拟 SCSAI 提交失败,验证返回 auto_applied: false 和错误信息
  5. 验证 suggest 和 auto_fix 规则可共存并按优先级依次执行

TASK-P1-03: repair 关系修复

  • 对应需求:P1-3(spec §5.6)
  • 优先级:P1
  • 依赖任务:无(与 TASK-P0-02 共享关系 XML 构建模式,但独立实现)
  • 预估工作量:2天

#### 实现步骤

步骤1:修改 rule-engine.js 的 _buildRepairAML() 方法

  • 文件:server/core/rule-engine.js
  • 位置:第2015行附近 _buildRepairAML() 方法
  • 操作:
  1. 方法签名扩展:_buildRepairAML(itemType, itemId, changes, relationChanges = null),新增第四个参数 relationChanges,默认 null 保持向后兼容
  2. 属性 XML 构建逻辑保持不变
  3. 新增关系 XML 构建逻辑:如果 relationChanges 非空,调用 _buildRepairRelationshipsXml(relationChanges) 生成关系 XML
  4. 将关系 XML 拼接到属性 XML 之后,在 之前
  • 参考代码:design §1.3.6 第1325-1339行

步骤2:新增 _buildRepairRelationshipsXml() 方法

  • 文件:server/core/rule-engine.js
  • 位置:在 _buildRepairAML() 方法之后添加
  • 操作:新增 _buildRepairRelationshipsXml(relationChanges) 方法:
  1. 解构 relationChanges{ add_relations = [], edit_relations = [], delete_relations = [] }
  2. 新增关系:遍历 add_relations,生成 节点
  • related_id 为对象且含 item_type:嵌套创建
  • related_id 为字符串:GUID 直接引用
  • 输出关系属性 properties
  1. 修改关系:遍历 edit_relations,生成 节点
  • 必须包含 typeid,否则跳过
  • 输出关系属性 properties
  1. 删除关系:遍历 delete_relations,生成 自闭合节点
  • 必须包含 typeid,否则跳过
  1. 有内容时输出 ...内容...,无内容时返回空字符串
  • 参考代码:design §1.3.6 第1346-1407行

步骤3:修改 executeRepair() 中的 _buildRepairAML 调用

  • 文件:server/core/rule-engine.js
  • 位置:约第1926行 executeRepair() 方法中
  • 操作:
  1. _buildRepairAML 调用前,提取关系变更:const relationChanges = this._extractRelationChanges(repairs)
  2. 修改调用:const aml = this._buildRepairAML(item_type, item_id, changes, relationChanges)
  • 参考代码:design §1.3.6 第1414-1421行

步骤4:新增 _extractRelationChanges() 辅助方法

  • 文件:server/core/rule-engine.js
  • 位置:在 _buildRepairRelationshipsXml() 方法之后添加
  • 操作:新增 _extractRelationChanges(repairs) 方法:
  1. 初始化三个数组:addRelationseditRelationsdeleteRelations
  2. 遍历 repairs 数组,从两个来源提取关系变更:
  • repair.action_config 中的 add_relations/edit_relations/delete_relations
  • repair.result 中的 add_relations/edit_relations/delete_relations(action_script 动态返回)
  1. 返回 { add_relations, edit_relations, delete_relations }
  • 参考代码:design §1.3.6 第1431-1465行

#### 验证方法

  1. 构造包含关系修复的 repair 请求,验证生成的 AML 包含 节点
  2. 测试 add/edit/delete 三种关系操作,验证 AML 格式正确
  3. 测试无关系变更的修复(relationChanges = null),验证向后兼容,AML 与修改前一致
  4. 测试属性修复+关系修复合并输出,验证在同一个 节点内
  5. 提交到 SCSAI 验证端到端流程(如有测试环境)

TASK-P1-04: create_post 规则扩展

  • 对应需求:P1-4(spec §5.7)
  • 优先级:P1
  • 依赖任务:TASK-P1-03(ECO 的 auto_fix 需要关系 AML 支持)
  • 预估工作量:1.5天

#### 实现步骤

步骤1:确认 CREATE_POST scope 和执行流程已存在

  • 文件:server/core/rule-engine.js
  • 操作:
  1. 确认 RULE_SCOPES.CREATE_POST 枚举值已定义
  2. 确认 createItem() 方法中已有 CREATE_POST 规则执行流程(约第2241-2246行)
  3. 如果 CREATE_POST 执行流程不存在,需补充:在 SCSAI 主对象创建成功后、返回结果前,匹配并执行 CREATE_POST scope 规则

步骤2:在 _loadBuiltinRules() 中添加 CREATE_POST 内置规则

  • 文件:server/core/rule-engine.js
  • 位置:_loadBuiltinRules() 方法末尾
  • 操作:添加以下5条 CREATE_POST 内置规则:
  1. builtin-create-post-eco-001:ECO 自动创建 Affected Item 关系(scope=CREATE_POST, item_type_name='ECO', action_type=auto_fix, priority=P0)
  • action_script:从 context.properties.affected_items 提取受影响项,生成 add_relations 数组
  • 返回 { modified: true, add_relations: [...], message: '...' }
  1. builtin-create-post-bom-001:BOM 结构完整性验证(scope=CREATE_POST, item_type_name='BOM', action_type=suggest, priority=P1)
  • action_script:检查 bom_number、product_name 是否缺失,返回建议
  1. builtin-create-post-document-001:Document 自动关联项目/产品(scope=CREATE_POST, item_type_name='Document', action_type=suggest, priority=P1)
  • action_script:检查 project_name/product_id,返回关联建议
  1. builtin-create-post-part-001:Part 编号规范验证与默认关系(scope=CREATE_POST, item_type_name='Part', action_type=suggest, priority=P1)
  • action_script:验证 item_number 格式(正则 /^[A-Z]{2,4}-\d{3,}$/),检查 classification 是否为装配件
  1. builtin-create-post-vendor-001:Vendor 供应商分类关系(scope=CREATE_POST, item_type_name='Vendor', action_type=suggest, priority=P2)
  • action_script:检查 classification/vendor_type/category,返回分类建议
  • 参考代码:design §1.3.7 第1499-1643行

步骤3:确认 CREATE_POST auto_fix 规则的关系提交路径

  • 文件:server/core/rule-engine.js
  • 操作:确认 ECO 的 auto_fix CREATE_POST 规则返回的 add_relations 能被正确处理:
  1. 检查 createItem() 中 CREATE_POST 规则执行后的结果处理逻辑
  2. 如果 auto_fix 规则返回 add_relations,需要通过 _buildRepairAML() 构建关系 AML 并提交 SCSAI
  3. 确保 _buildRepairAML() 已支持关系参数(TASK-P1-03 完成)

步骤4:CREATE_POST 失败不回滚主对象

  • 文件:server/core/rule-engine.js
  • 操作:确认 CREATE_POST 规则执行异常时:
  1. 主对象创建不回滚
  2. 返回结果中包含 post_action_warning 提示后置操作失败
  3. 记录后置规则失败日志

#### 验证方法

  1. 调用 POST /api/capability,body 为 { "capability": "create", "params": { "item_type": "ECO", "data": { "title": "测试ECO", "affected_items": [{ "id": "ITEM001" }] } } }
  2. 验证 ECO 创建成功后,CREATE_POST 规则自动执行,返回结果中包含后置操作信息
  3. 测试 BOM/Document/Part/Vendor 的 CREATE_POST suggest 规则,验证返回建议
  4. 模拟 CREATE_POST 规则执行失败,验证主对象不回滚,返回 post_action_warning
  5. 检查 sciot_rules_v2 表中已同步5条 builtin-create-post 规则

P2 优先级任务(扩展能力,可延后实施)


TASK-P2-01: identify 内置规则扩展

  • 对应需求:P2-1(spec §5.8)
  • 优先级:P2
  • 依赖任务:无
  • 预估工作量:1天

#### 实现步骤

步骤1:在 _loadBuiltinRules() 中添加 ItemType 专用 IDENTIFY 规则

  • 文件:server/core/rule-engine.js
  • 位置:_loadBuiltinRules() 方法末尾
  • 操作:添加以下5条 IDENTIFY 内置规则:
  1. builtin-identify-part-001:Part 零件属性模板识别(scope=IDENTIFY, item_type_name='Part', priority=P0)
  • action_script:返回 { template: { required_fields, optional_fields, classification_options } }
  1. builtin-identify-vendor-001:Vendor 供应商评分识别(scope=IDENTIFY, item_type_name='Vendor', priority=P0)
  • action_script:计算综合评分,返回评级(A/B/C/D)和资质字段列表
  1. builtin-identify-bom-001:BOM 结构层级识别(scope=IDENTIFY, item_type_name='BOM', priority=P0)
  • action_script:返回 { structure: { bom_number, product_name, version, component_count, hierarchy_type } }
  1. builtin-identify-eco-001:ECO 变更影响范围识别(scope=IDENTIFY, item_type_name='ECO', priority=P0)
  • action_script:返回 { change_info: { title, state, change_type, affected_count, priority } }
  1. builtin-identify-document-001:Document 文档分类识别(scope=IDENTIFY, item_type_name='Document', priority=P0)
  • action_script:返回 { doc_info: { title, document_type, classification, related_objects } }
  • 参考代码:design §1.3.8 第1690-1835行

步骤2:确认专用规则优先级高于通用规则

  • 文件:server/core/rule-engine.js
  • 操作:确认 ItemType 专用规则(priority=P0)优先于通用 builtin-identify-001(priority=P1)执行,通过 getRules() 的排序逻辑保证

#### 验证方法

  1. 调用 POST /api/capability,body 为 { "capability": "identify", "params": { "item_type": "Part", "query_type": "list" } }
  2. 验证返回结果匹配 Part 专用规则,包含 template 字段
  3. 分别测试 Vendor/BOM/ECO/Document 类型,验证专用规则正确匹配
  4. 测试未知 ItemType,验证降级到通用识别规则
  5. 检查 sciot_rules_v2 表中已同步5条 builtin-identify 规则

TASK-P2-02: RelationshipResolver SCSAI 关系查询

  • 对应需求:P2-2(spec §5.9)
  • 优先级:P2
  • 依赖任务:无
  • 预估工作量:2天

#### 实现步骤

步骤1:修改 relationship-resolver.js 的 discoverRelations() 方法

  • 文件:server/core/relationship-resolver.js
  • 位置:第247行附近 discoverRelations(itemType, items) 方法
  • 操作:
  1. 在方法开头(本地关系发现之前)添加 SCSAI 已有关系查询:
     let existingRelations = [];
     try {
       existingRelations = await this._queryExistingRelations(type, items);
     } catch (e) {
       console.warn('[discoverRelations] SCSAI关系查询失败(非阻塞):', e.message);
     }
     
  1. 保留现有本地关系发现逻辑不变
  2. 在本地关系发现结果之后,添加去重逻辑(步骤2)
  3. 修改返回值,新增 existing_relationsnew_relations 字段

步骤2:添加去重逻辑

  • 文件:server/core/relationship-resolver.js
  • 位置:discoverRelations() 方法内,本地关系发现结果之后
  • 操作:
  1. 遍历本地发现的 relations 数组
  2. 对每个候选关系,检查 existingRelations 中是否存在相同 relationship_type + related_id 的关系
  3. 不重复的加入 newRelations 数组
  4. 重复的标记 rel.already_exists = true
  5. 返回值中包含 existing_relations: existingRelationsnew_relations: newRelations

步骤3:新增 _queryExistingRelations() 方法

  • 文件:server/core/relationship-resolver.js
  • 位置:在 discoverRelations() 方法之后添加
  • 操作:新增 async _queryExistingRelations(itemType, items) 方法:
  1. 获取 SCSAI 客户端:const client = getSCSAIClient(),不可用时返回空数组
  2. 定义超时常量:const SCSAI_QUERY_TIMEOUT = 3000(3秒)
  3. 遍历 items 数组,逐对象查询 SCSAI 已有关系:
  • id 时:
  • 仅有 item_number 时:通过 item_number 查询
  1. 使用 Promise.race 实现3秒超时
  2. 解析 SCSAI 返回的 Relationships 数据(rels.Item 可能是数组或单个对象)
  3. 提取关系信息:relationship_typerelationship_idrelated_idrelated_item_typerelated_item_numbersource_item_id
  4. 单个对象查询失败不阻断,继续处理下一个
  • 参考代码:design §1.3.9 第1930-1990行

步骤4:确认 getSCSAIClient() 和 escapeXml() 可用

  • 文件:server/core/relationship-resolver.js
  • 操作:
  1. 确认 getSCSAIClient() 函数已导入或可从模块中获取
  2. 确认 escapeXml() 函数已导入或可从工具模块中获取
  3. 如不存在,需添加导入语句

#### 验证方法

  1. 调用 discoverRelations('Part', [{ id: 'TEST_ID', item_number: 'P-001' }, { id: 'TEST_ID2', item_number: 'P-002' }])
  2. 验证返回结果包含 existing_relations(SCSAI已有关系)和 new_relations(待创建关系)
  3. 验证重复关系被标记 already_exists: true,不纳入 new_relations
  4. 模拟 SCSAI 查询超时/失败,验证 existing_relations 为空,本地发现继续执行
  5. 验证 SCSAI 返回格式异常时,跳过解析错误,不影响整体流程

验证与集成测试


TASK-VAL-01: 端到端集成验证

  • 对应需求:全部
  • 优先级:P0(与最后一个P0任务同步完成)
  • 依赖任务:TASK-P0-01, TASK-P0-02, TASK-P0-03
  • 预估工作量:1天

#### 实现步骤

步骤1:启动服务验证

  • 操作:
  1. 执行 node server.js,确认无启动报错
  2. 检查控制台日志中规则引擎初始化成功,内置规则数量正确
  3. 确认 sciot_rules_v2 表中新增的内置规则已同步

步骤2:generate 能力端到端验证

  • 操作:
  1. 调用 generate ECO,验证规则驱动返回
  2. 调用 generate 未知类型,验证 LLM 降级
  3. 调用 generate + template_id,验证模板加载

步骤3:AMLGenerator Relationships 端到端验证

  • 操作:
  1. 通过 create 能力创建包含关系的数据,验证 AMLGenerator 输出正确
  2. 对比 AMLGenerator 和 AMLBuilder 对同一数据的输出,验证一致性

步骤4:identify 关系发现端到端验证

  • 操作:
  1. 调用 identify Part,验证返回 related_objects
  2. 测试 includeRelations: false,验证跳过关系发现
  3. 测试关系发现超时场景

步骤5:回归测试

  • 操作:
  1. 验证现有 create/repair/optimize/compare 能力不受影响
  2. 验证现有数据库规则的执行优先级不受内置规则影响
  3. 验证规则命中统计正常更新

TASK-VAL-02: P1 集成验证

  • 对应需求:P1-1, P1-2, P1-3, P1-4
  • 优先级:P1
  • 依赖任务:TASK-P1-01, TASK-P1-02, TASK-P1-03, TASK-P1-04
  • 预估工作量:0.5天

#### 实现步骤

步骤1:compare 关系差异验证

  • 操作:对比两个包含不同关系的 Part 对象,验证关系差异正确输出

步骤2:optimize auto_fix 验证

  • 操作:触发 auto_fix 优化规则,验证自动提交 SCSAI 成功;测试受保护字段拒绝场景

步骤3:repair 关系修复验证

  • 操作:执行包含关系修复的 repair,验证 AML 中同时包含属性和关系变更

步骤4:create_post 规则验证

  • 操作:创建 ECO/BOM/Document/Part/Vendor 对象,验证 CREATE_POST 规则自动执行

依赖关系图

TASK-P0-01 (generate规则驱动) ────────────────────── 无前置依赖
TASK-P0-02 (AMLGenerator Relationships) ──────────── 无前置依赖
TASK-P0-03 (identify关系发现) ───────────────────── 无前置依赖
    │
    ├────→ TASK-P1-01 (compare关系差异) ── 依赖 P0-02
    │
    ├────→ TASK-P1-03 (repair关系修复) ─── 无前置依赖
    │         │
    │         └────→ TASK-P1-02 (optimize自动执行) ── 依赖 P1-03
    │         │
    │         └────→ TASK-P1-04 (create_post规则扩展) ── 依赖 P1-03
    │
    ├────→ TASK-P2-01 (identify内置规则扩展) ── 无前置依赖
    │
    └────→ TASK-P2-02 (RelationshipResolver SCSAI查询) ── 无前置依赖

建议实施顺序

P0-1 → P0-2 → P0-3 → P1-3 → P1-2 → P1-1 → P1-4 → P2-1 → P2-2

修改文件汇总

| 文件路径 | 涉及任务 | 修改要点 |

|---------|---------|---------|

| server/core/rule-engine.js | P0-01, P1-01, P1-02, P1-03, P1-04, P2-01 | 新增内置规则、executeGenerate、_computeRelationDiffs、_executeOptimizeAction、_buildRepairAML增强、_buildRepairRelationshipsXml、_extractRelationChanges |

| server/core/capability-runtime.js | P0-01, P0-03 | generate()集成规则引擎、identify()集成关系发现、_getRelationshipCapability() |

| server/core/aml-generator.js | P0-02 | _buildAML()添加Relationships、_buildRelationshipsXml、_buildAmlBuilderStyleRelation、_buildSimpleStyleRelation |

| server/core/relationship-resolver.js | P2-02 | discoverRelations()添加SCSAI查询、_queryExistingRelations()、去重逻辑 |

新增内置规则汇总(15条)

规则IDscopeitem_type_nameaction_type任务
builtin-generate-001generatenullsuggestP0-01
builtin-transform-001transformnullsuggestP0-01
builtin-generate-eco-001generateECOsuggestP0-01
builtin-generate-bom-001generateBOMsuggestP0-01
builtin-generate-document-001generateDocumentsuggestP0-01
builtin-create-post-eco-001create_postECOauto_fixP1-04
builtin-create-post-bom-001create_postBOMsuggestP1-04
builtin-create-post-document-001create_postDocumentsuggestP1-04
builtin-create-post-part-001create_postPartsuggestP1-04
builtin-create-post-vendor-001create_postVendorsuggestP1-04
builtin-identify-part-001identifyPartsuggestP2-01
builtin-identify-vendor-001identifyVendorsuggestP2-01
builtin-identify-bom-001identifyBOMsuggestP2-01
builtin-identify-eco-001identifyECOsuggestP2-01
builtin-identify-document-001identifyDocumentsuggestP2-01
← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁