ItemType Registry Refactoring Implementation Document
2026-06-22 | Root Cause: Previous 22 core types were hard-coded arbitrarily, not connected to SCSAI for real data validation
Architecture Overview
Core Principle: SCSAI is the data source, seed data is only for offline fallback and Chinese enhancement.
┌──────────────────────────────────────────────────────┐
│ 三层数据源 │
│ │
│ 1. SCSAI 实时查询(~1000+ 类型) │
│ └─ name, label, description 从 SCSAI ItemType 表 │
│ └─ 5分钟缓存,每次 intent 识别时自动刷新 │
│ └─ 过滤 is_relationship=true 的关系类型 │
│ └─ 最大 2000 条 │
│ │ │
│ ▼ │
│ 2. 种子类型增强(22个核心类型) │
│ └─ 中文标签、别名、图标、Category 从种子数据补充 │
│ └─ 仅在 SCSAI 有同名类型时生效(name 匹配) │
│ └─ SCSAI 有但种子没有的类型 → 自动分类(模式匹配) │
│ │ │
│ ▼ │
│ 3. 离线兜底 │
│ └─ SCSAI 不可达 → 只返回 22 个种子类型 │
│ └─ 带 connected:false 标记 │
└──────────────────────────────────────────────────────┘
文件清单
| 文件 | 角色 | 关键变更 |
|------|------|----------|
| server/config/item-type-registry.js | Data Layer — Three-tier registry (SCSAI+Seed+Fallback) | Completely rewritten, total 14KB |
| server/core/smart-intent-recognizer.js | Recognition Layer — Natural language → Structured intent | Completely rewritten, asynchronous, 4.8KB |
| server/routes/capability-pipeline.js | Routing Layer — Pipeline execution + REST API | Fixed 9 missing await issues, corrected 6 old field references |
Data Layer: item-type-registry.js
Exposed API
// 核心查询(All async,内部自动尝试 SCSAI 连接)
registry.getAllTypes() → [{ name, label, labelEn, aliases, icon, category, description, source }]
registry.findType("零件") → { type, confidence, matchField }
registry.searchTypes("变更") → 按相关性排序的 type 数组
registry.getStats() → { total, SCSAI, seed, connected, byCategory }
registry.getSeedInfo() → 22个种子类型的元信息
// 同步能力识别(不依赖 SCSAI)
registry.recognizeCapability("创建一个零件") → { capability, confidence }
registry.listCapabilities() → 10个能力定义
registry.listCategories() → 5个分类定义 + 各分类下种子数
// 缓存管理
registry.invalidateCache() → 强制下次重新拉取 SCSAI
// 常量导出(前端/测试用)
registry.categories → 分类分组定义
registry.capabilities → 能力定义(含 keywords + requiresItemType)
registry.seeds → 22个种子类型原始数据
类型匹配优先级(findType)
| 优先级 | 匹配方式 | 置信度 | 示例 |
|--------|----------|--------|------|
| 1 | Exact match on name | 1.0 | "Part" → Part |
| 2 | Exact match on label/labelEn | 0.95 | "零件" → Part |
| 3 | Alias match | 0.9 | "物料" → Part |
| 4 | Substring match on name | 0.7 | "Part BOM" contains "Part" |
| 5 | label substring | 0.6 | fuzzy matching |
Automatic classification (classifyByPattern)
When the ItemType returned by SCSAI has no seed coverage, automatically guess the category by name:
- business: part, product, document, vendor, customer, project, task, order, material, component, assembly...
- process: ecr, ecn, eco, bom, manufacturing, inspection, workflow, quality, ncr, capa...
- system: user, role, permission, identity, config, group, lifecycle, state, template, method...
- report: report, log, history, metric, kpi, dashboard...
- other: when none of the above match
Recognition layer: smart-intent-recognizer.js
Data flow
用户输入
│
▼
recognize(input, context?)
│
├─ 1. registry.recognizeCapability(input) ← 同步
│ → { capability, confidence }
│ → 降级:从 context.capability 补位
│
├─ 2. await registry.findType(input) ← 异步(触发 SCSAI 拉取)
│ → { type, confidence, matchField }
│ → 降级:从 context.itemType 补位
│
├─ 3. _extractParams(input)
│ → 提取数量、ID等参数
│
├─ 4. _calcConfidence()
│ → 加权(能力0.4 + 类型0.6)
│
└─ 5. 返回结构
{
capability, // 能力名称
itemType, // 类型名称
params, // 提取的参数
confidence, // 综合置信度 0~1
requiresItemType, // 此能力是否需要类型
typeDetails, // { name, label, category, icon, description }
typeResult, // { confidence, matchField }
capResult, // { confidence }
}
上下文补位(recognizeWithContext)
从最近5条会话历史中提取已知类型和能力,在二次识别时透传:
recognize("修改", {
itemType: "Part", // 上一条已知类型
capability: "update" // 上一条已知能力(可选)
})
路由层:capability-pipeline.js 的修复
修复摘要
| # | 问题 | Repair |
|---|------|------|
| 1 | identifyIntent calls smartRecognizer.recognize() without await | add await |
| 2 | getObjectTypePatterns iterates over smartRecognizer.registry (non-existent property) | Change to directly require('item-type-registry').seeds |
| 3 | getCapabilityKeywords iterates over smartRecognizer.registry.capabilities | Change to registry.capabilities |
| 4 | handleGetAllItemTypes synchronously calls smartRecognizer.getAllItemTypes() (now async) | Change to async function + await |
| 5 | handleGetTypeDetails calls smartRecognizer.getTypeDetails() (non-existent) | Change to registry.findType() |
| 6 | handleQuickSearch calls smartRecognizer.quickSearch() (non-existent) | Change to smartRecognizer.searchTypes() |
| 7 | handleGetHelp calls smartRecognizer.getHelp() (non-existent) | Change to query registry.getStats() + listCategories() |
| 8 | handleValidateIntent calls smartRecognizer.validateRecognition() (does not exist) | Use requiresItemType for validity check |
| 9 | identifyIntent returns smartResult.itemTypeConfidence (new format does not have this field) | Change to smartResult.typeResult?.confidence |
| 10 | identifyIntent returns smartResult.suggestedItemTypes/supportedCapabilities (do not exist) | Remove, replace with typeDetails + frontend autonomously queries /registry/all-types |
Routing Endpoints
/api/capability/pipeline/
├─ identify-intent POST 意图识别
├─ fetch-schema POST 获取Schema
├─ build-prompt POST 构建Prompt
├─ execute POST 同步执行pipeline
├─ execute-async POST 异步执行pipeline
├─ status GET 查询pipeline状态
├─ item-types GET 可用类型列表
├─ item-type-exists POST 检查类型是否存在
├─ item-type-valid POST 检查类型是否完整
├─ create-item-type POST 创建对象类
├─ repair-item-type POST 修复对象类
├─ generate-rules POST 生成规则
├─ save-rules POST 保存规则
├─ check-duplicate POST 查重
├─ registry/all-types GET 完整类型列表(含分类)
├─ registry/all-capabilities GET 所有能力定义
├─ registry/type-details POST 类型详情
├─ registry/quick-search POST 快捷搜索
├─ registry/help GET 系统帮助信息
└─ registry/validate POST 意图验证
Pipeline 执行流程(11步)
Step 1: 意图识别 → findType + recognizeCapability
Step 2: 对象类检查 → 不存在则标记自动创建
Step 3: 对象类创建/Repair → 自动生成Property+Rule
Step 4: Schema 发现 → 从本地DB获取
Step 5: 规则检查/Generate → 缺则自动创建
Step 6: Prompt 构建 → 模板+注入
Step 7: LLM 执行 → 带重试(2次)
Step 8: 规则验证 → 必填检查+自动修复
Step 9: 查重检测 → 按 keyed_name 模糊匹配
Step 10: 执行器 → create/update/reference
Step 11: 反馈学习 → 记录成功/失败
构建验证
vite v5.4.21, 769 modules transformed, build 23s
exit code 1(仅chunk >500KB警告,不影响产出)
SCSAI 连接状态测试
认证信息为空时预期行为:
→ fetchFromSCSAI() 返回 []
→ getAllTypes() 返回 22 个种子类型
→ getStats() 返回 { total:22, SCSAI:0, seed:22, connected:false }
→ findType("零件") 正常返回 Part (置信度 0.95)
认证信息配置在 config.yaml:
SCSAI:
server: https://ylxt.chat/scplm
database: SCPLM
username: '' # ← 当前为空
password: '' # ← 当前为空
Pending Tasks
- Configure SCSAI Credentials — After entering username/password, automatically discover all ~1000+ ItemTypes
- Frontend searchTypes Integration — Real-time search box for SCSAI's real type list
- Revalidate Node — Add a /registry/revalidate endpoint for administrators to manually refresh SCSAI cache
- Seed Contribution Mechanism — Allow users to add aliases/tags via UI for unmatched SCSAI types
BossAgents