BOM Management System - Frontend Architecture Unification Solution

BOM Management System - Frontend Architecture Unification Solution

Version: v3.3 | Date: 2026-06-22 | Author: QClaw | Review: QClaw

Status: In Progress (Phase 1-4 all completed, Phase 5 pending)

Changes: v3.3 ProductList.vue generateDemoData 8 instances of _SCSAIApiRequest migrated to rawQuery, getBomService() removed, ProductList.vue _SCSAIApiRequest count reduced to zero. Phase 4 fully completed.

v3.2 Comprehensive code verification of implementation status, corrected Phase 3/Phase 4 status; v3.1 Added overall progress overview, server-side mirroring & mini-program side, lessons learned; v2.1 Corrected line counts, added Phase 0 extraction plan


Background and Goals

Core Issues

The current frontend has three independent creation logics:

| System | Location | Method | Maintenance Status |

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

| useCapabilityCreate.js | composables | LLM → Cascading Creation → SCSAI | Good (complete, but heavy responsibility) |

| useItemTypeManagement.js | composables | AI Generation → Backend API → SCSAI | Medium (uses backend, logic scattered) |

| Inline in ProductList.vue | views | Manual AML → _SCSAIApiRequest | Poor (zero reuse, extensive duplication) |

40+ management pages each redundantly implement: query list → table display → create/edit/delete.

Goals

  1. Extract common components: Extract creation/query/edit logic into composables
  2. Gradual interface consolidation: Object class management and business object management internally share the same set of components, with separate interfaces (separate first, consider merging later)
  3. Eliminate handwritten AML: Pages like ProductList.vue no longer directly call SCSAI APIs.

I. SCSAI Object Model

SCSAI is a metadata-driven PLM system:

  • ItemType (Object Class): Defines an object's structure (attributes, relationships, permissions, lifecycle, etc.)
  • Any concrete object: is an instance of an ItemType.
  • A screw = a Part instance.
  • A project = a Project instance.
  • A new object class (e.g., MyObject) = an ItemType instance.
  • Attributes and relationships are also ItemType instances.

All operations are essentially the same: ApplyItem + the corresponding itemType + attributes/relationships. The only difference lies in the parameters.


II. Current Architecture

2.1 Existing Composables

FileLinesResponsibility
useCapabilityCreate.js1924Generic creation: LLM → attribute filtering → pre-creation → main object → relationship recursion → AI correction → system objects
useItemTypeManagement.js1503ItemType management: Get/create/delete ItemType, Property, RelationshipType
useCapability.js1071Capability entry: Identify → route to specific capability
useCapabilityWithRules.js1028Creation with rules: Load rule templates → validate → create
useCapabilityIdentify.js, etc.35-185 eachidentify/inspect/repair/optimize/compare/generate
useDataCollection.js474Data Collection
useRuleEngine.js463Rule Engine Invocation

2.2 Existing Views

FileLinesCore Function
ItemTypeManagement.vue2682Object Class Management
ProductList.vue1705Product/Part List, 26 direct calls to SCSAI API, handwritten AML
AiWorkbench.vue2938AI Dialog, partially calls SCSAI directly
ObjectDetailPanel.vue853Object Detail Edit/Delete Logic (located in src/components/)

2.3 Existing Utils

FileLinesResponsibility
SCSAI.js583SCSAI API Underlying Layer (_SCSAIApiRequest)
AmlBuilder.js219AML XML Construction (already supports item_properties and relationships)
PromptBuilder.js659LLM Prompt Construction

III. Target Architecture

┌──────────────────────────────────────────────────────────┐
│                    页面层(views)                        │
│                                                          │
│  ┌─────────────────┐  ┌──────────────────────────────┐   │
│  │ ItemTypeManage  │  │   ProductList / 其他业务页面  │   │
│  │  ment.vue        │  │                              │   │
│  │  (保留界面)      │  │   (保留界面)                   │   │
│  │                 │  │                              │   │
│  │  ← 调用 useCreate / useQuery / useModify →        │   │
│  └────────┬────────┘  └──────────────┬───────────────┘   │
│           │                          │                   │
│  ┌────────┴──────────────────────────┴───────────────┐   │
│  │              通用组件层(composables)                │   │
│  │                                                    │   │
│  │  useCreate()   - 统一创建(ItemType/Part/任何对象)   │   │
│  │  useQuery()    - 统一查询(列表+详情)               │   │
│  │  useModify()   - 统一编辑/删除                     │   │
│  │  useObjectMeta() - 统一元数据(模板/属性/关系)       │   │
│  │  useCapabilities() - 统一能力路由                    │   │
│  └────────────────────┬───────────────────────────────┘   │
│                       │                                   │
│  ┌────────────────────┴───────────────────────────────┐   │
│  │              基础设施层(utils)                       │   │
│  │  SCSAI.js · AmlBuilder.js · PromptBuilder.js · ...   │   │
│  └────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────┘

核心原则:同一套组件,多个界面复用。

Separate interfaces for object class management and business object management, but share the same set of composables for business logic.

3.1 Implementation Progress Overview (As of 2026-06-21)

| Phase | Goal | Status | Description |

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

| Phase 0 | Extraction Plan | ✅ Completed | docs/phase0_extract_usecreate.md has recorded source line numbers |

| Phase 1 | Extract useCreate | ✅ Completed | useCreate.js (1336 lines) extracted, ItemTypeManagement.vue integrated |

| Phase 2 | ItemTypeManagement Integration | ✅ Completed | Frontend now connects directly to SCSAI, bypassing backend API |

| Phase 3 | useQuery/useModify/useObjectMeta | ✅ Completed | useQuery (14KB/6 interfaces), useModify (9KB/7 interfaces), and useObjectMeta (16KB/7 interfaces) all implemented and in use |

| Phase 4 | ProductList.vue Integration | ✅ Fully Completed | 5 read functions migrated to rawQuery, 8 write operations in generateDemoData also fully migrated to rawQuery, _SCSAIApiRequest reduced to zero, getBomService() removed |

| Phase 5 | Cleanup and Consolidation | ❌ Not Started | 55+ existing _SCSAIApiRequest calls across the entire project pending cleanup |

| Additional | Server Mirror + Mini-Program Client | ✅ Completed | server/routes/unified-create.js (1089 lines) + mini-program pages |

Current Status: The project's views/ directory contains 55+ _SCSAIApiRequest calls distributed across 14 vue files (see detailed implementation report). Among these, ProductList.vue now has only 8 remaining (in generateDemoData), and ItemTypeManagement.vue retains 2.


IV. Universal Component Design

4.1 useCreate() - Unified Creation

Source: Extracted and merged from useCapabilityCreate.js and useItemTypeManagement.js.

// src/composables/useCreate.js
export function useCreate() {
  const loading = ref(false)
  const progress = ref({ percent: 0, message: '' })
  const result = ref(null)
  const error = ref('')

  /**
   * 统一创建入口
   * @param {Object} options
   * @param {string} options.itemType  - 对象类型(如 'Part', 'ItemType', 'Vendor')
   * @param {Object} options.properties - 主对象属性
   * @param {Array}  options.relationships - 关系列表
   * @param {Object} options.systemObjects - permission/lifecycle 等
   * @param {Object} options.itemProperties - 引用字段预创建
   * @param {boolean} options.useLLM - 是否用 LLM 生成
   * @param {string} options.llmPrompt - LLM 提示词
   */
  async function create(options) {
    const { itemType, properties, relationships, systemObjects,
            itemProperties, useLLM, llmPrompt } = options
    loading.value = true
    result.value = null
    error.value = ''

    try {
      // 流程1: 获取元数据(从本地库或 SCSAI)
      progress.value = { percent: 10, message: '加载对象模板...' }
      const meta = await loadObjectMeta(itemType)

      // 流程2: LLM 生成(可选)
      let finalProps = properties
      let finalRels = relationships || []
      let finalSys = systemObjects || {}
      let finalItemProps = itemProperties || {}

      if (useLLM && llmPrompt) {
        progress.value = { percent: 20, message: 'AI生成中...' }
        const llmResult = await generateWithLLM(itemType, llmPrompt, meta)
        finalProps = llmResult.main || finalProps
        finalRels = llmResult.relationships || finalRels
        finalSys = llmResult.systemObjects || finalSys
      }

      // 流程3: 属性过滤与补全
      progress.value = { percent: 35, message: '处理属性...' }
      const { sanitized, itemPropsToBuild } = sanitizeProperties(finalProps, meta)
      const keyedValues = await resolveSequences(itemType, meta, sanitized)

      // 流程4: 引用字段预创建(item_properties)
      progress.value = { percent: 50, message: '预创建引用对象...' }
      const resolvedItemProps = await precreateItemProperties(itemPropsToBuild)

      // 流程5: 主对象创建
      progress.value = { percent: 65, message: '创建主对象...' }
      const mainAml = buildAML({
        item_type: itemType, action: 'add',
        properties: { ...sanitized, ...keyedValues },
        item_properties: resolvedItemProps
      }, meta.propertyMap)
      const mainResult = await bomService._SCSAIApiRequest('ApplyItem', mainAml)
      const mainId = extractItemId(mainResult)

      if (!mainId) {
        // AI纠错重试(最多3次)
        const retryResult = await aiAutoCorrect(mainResult, itemType, sanitized, meta, 3)
        if (!retryResult.id) throw new Error('创建失败: ' + (retryResult.error || '未知'))
        result.value = retryResult
        return retryResult
      }

      // 流程6: 关系递归创建
      if (finalRels.length > 0 && mainId) {
        progress.value = { percent: 80, message: '创建关系...' }
        await createRelationshipsRecursive(finalRels, mainId, meta)
      }

      // 流程7: 系统对象(permission/lifecycle)
      if (Object.keys(finalSys).length > 0 && mainId) {
        progress.value = { percent: 90, message: '绑定系统对象...' }
        await bindSystemObjects(finalSys, mainId)
      }

      progress.value = { percent: 100, message: '创建完成' }
      result.value = { id: mainId, itemType, properties: sanitized }
      return result.value
    } catch (e) {
      error.value = e.message
      throw e
    } finally {
      loading.value = false
    }
  }

  return { create, loading, progress, result, error }
}

用法示例:

// 创建 Part(含 BOM 关系)
const { create } = useCreate()
await create({
  itemType: 'Part',
  properties: { name: '螺丝M6', item_number: 'P-001', cost: 0.5 },
  relationships: [
    { relationship_type: 'Part BOM', related_item_type: 'Part',
      related_items: [{ properties: { name: '钢材', item_number: 'M-S-001' } }] }
  ]
})

// 创建 ItemType(新建对象类)- 同一个方法,不同参数
await create({
  itemType: 'ItemType',
  properties: { name: 'MyObject', label: '我的对象', is_relationship: '0' },
  relationships: [
    // Property 关系
    { relationship_type: 'Property', related_item_type: 'Property',
      related_items: [
        { properties: { name: 'title', label: '标题', data_type: 'string', is_required: '1' } },
        { properties: { name: 'status', label: '状态', data_type: 'list' } }
      ] },
    // RelationshipType 关系
    { relationship_type: 'RelationshipType', related_item_type: 'RelationshipType',
      related_items: [
        { properties: { name: 'RelatedPart', related_item_type: 'Part' } }
      ] }
  ]
})

4.2 useQuery() - 统一查询

来源: 从各管理页面提取重复的查询逻辑。

// src/composables/useQuery.js
export function useQuery() {
  const loading = ref(false)

  /**
   * 查询对象列表
   */
  async function list(itemType, options = {}) {
    const { filters, sortBy, page = 1, pageSize = 50, select } = options
    loading.value = true
    try {
      const aml = buildQueryAML(itemType, { filters, sortBy, page, pageSize, select })
      const result = await bomService._SCSAIApiRequest('ApplyItem', aml)
      return parseItemList(result)
    } finally {
      loading.value = false
    }
  }

  /**
   * 查询对象详情(含关系)
   */
  async function detail(itemType, id, includeRels = []) {
    loading.value = true
    try {
      const aml = buildDetailAML(itemType, id, includeRels)
      const result = await bomService._SCSAIApiRequest('ApplyItem', aml)
      return parseItemDetail(result)
    } finally {
      loading.value = false
    }
  }

  /**
   * 搜索对象
   */
  async function search(itemType, keyword) {
    // ...
  }

  return { list, detail, search, loading }
}

4.3 useModify() - 统一编辑/删除

来源: 从 ObjectDetailPanel.vue 和各管理页面提取。

// src/composables/useModify.js
export function useModify() {
  /**
   * 编辑对象属性
   */
  async function update(itemType, id, properties) {
    const aml = `<Item type="${itemType}" id="${id}" action="edit">
      ${Object.entries(properties).map(([k, v]) => `<${k}>${escXml(v)}</${k}>`).join('\n')}
    </Item>`
    return await bomService._SCSAIApiRequest('ApplyItem', aml)
  }

  /**
   * 删除对象
   */
  async function remove(itemType, id) {
    const aml = `<Item type="${itemType}" id="${id}" action="delete" />`
    return await bomService._SCSAIApiRequest('ApplyItem', aml)
  }

  /**
   * 编辑关系行
   */
  async function updateRelationship(relType, relId, properties) { /* ... */ }

  /**
   * 删除关系行
   */
  async function removeRelationship(relType, relId) { /* ... */ }

  return { update, remove, updateRelationship, removeRelationship }
}

4.4 useObjectMeta() - 统一元数据

来源: 从 useCapabilityCreate.js 的 schema 获取逻辑和 useItemTypeManagement.js 的类型加载逻辑提取。

// src/composables/useObjectMeta.js
export function useObjectMeta() {
  /**
   * 获取对象类型列表
   */
  async function listTypes(options = {}) {
    // 优先从本地库,回退到 SCSAI
  }

  /**
   * 获取对象类型模板(属性 + 关系 + 规则)
   */
  async function getTypeTemplate(itemType) {
    // GET /api/aml/unified/schema/{itemType} 或 /api/sciot/type-template/{itemType}
  }

  /**
   * 获取属性定义
   */
  async function getPropertyDefs(itemType) { /* ... */ }

  /**
   * 获取关系类型定义
   */
  async function getRelationshipTypes(itemType) { /* ... */ }

  return { listTypes, getTypeTemplate, getPropertyDefs, getRelationshipTypes }
}

五、实施计划(渐进式)

总原则:小步前进,每步可验证。

First validate the generic component in the object class management (ItemType) scenario, then extend to business objects (Part/Vendor/...).


Phase 0: Extraction Plan - From which file and line number (Required Reading)

Goal: Clarify the origin of each function to eliminate search time.

#### useCreate.js Extraction Sources

Source A: useCapabilityCreate.js (Line 1924)

| Function Name | Line Number | Purpose |

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

| getBomService() | ~12 | Get SCSAI service instance |

| extractItemId(item) | ~23 | Extract ID from SCSAI response |

| extractItemKeyedName(item) | ~32 | Extract keyed_name |

| shouldIncludeInAml(prop, itemType) | ~64 | Determine if property goes into AML |

| _dualDbDedupCheck(...) | ~82 | SQLite + SCSAI deduplication check |

| precreateNestedItem(...) | ~178 | Pre-create referenced fields (core) |

| submitAml(permId) | ~286 | Send AML to SCSAI |

| filterAndSanitize(...) | ~406 | Property filtering and sanitization |

| extractJsonBlock(text) | ~439 | Extract JSON from LLM output |

| create(itemType, description, options) | ~448 | Main entry point (use as framework) |

| _processRelsRecursive(...) | ~1458 | Recursive Relationship Creation (Most Complex) |

Source B: useItemTypeManagement.js (Line 1503)

| Function Name | Line Number | Purpose |

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

| capabilityCreate(description) | ~1227 | LLM generates ItemType definition |

| createItemTypeInSCSAI(name, def) | ~1252 | Create ItemType in SCSAI (with attributes/relationships) |

⚠️ The two functions from Source B are used in Phase 2 (LLM generation + data transformation). Phase 1 only mentions the SCSAI execution layer.


Phase 1: Extract useCreate (3 days) ⚠️ Partially completed

Goal: Extract useCreate from existing code, first validate in the ItemType scenario.

Completed:

  • [x] src/composables/useCreate.js (1336 lines) created
  • [x] Exported main entry points: create(), createWithLLM()
  • [x] Exported utility functions: filterAndSanitize, precreateNestedItem, createRelationshipsRecursive, normalizeRelationships, fetchTypeTemplate
  • [x] SYSTEM_MANAGED_FIELDS constant, shouldIncludeInAml filtering, Type A/Type B relationship patterns
  • [x] AI auto-correction (aiAutoCorrect) retained within useCreate.js

Incomplete:

  • [ ] No view imports useCreate — grep 'from.*useCreate' src/views/ returns 0 results
  • [ ] Test 1 (Create ItemType with Property relationships) not executed
  • [ ] Test 2 (Create Part and BOM relationships) not executed

Steps:

  1. Create src/composables/useCreate.js
  • Use the create() function from line 448 of useCapabilityCreate.js as the main framework
  • Follow the order of 'Process 1-7', gradually introducing helper functions from the same file
  1. Extract createRelationshipsRecursive
  • Extract from _processRelsRecursive at line 1458 of useCapabilityCreate.js
  • Support Type A (relationship itself is an Item) and Type B (relationship references parent via source_id) modes, supporting multi-level recursion
  1. Extract sanitizeProperties + resolveSequences
  • Extract from filterAndSanitize at line 406 of useCapabilityCreate.js
  1. Extract precreateItemProperties
  • Extract from precreateNestedItem at line 178 of useCapabilityCreate.js
  • Support multi-level nested reference fields
  1. Extract aiAutoCorrect
  • Extract AI correction and retry logic from the end of useCapabilityCreate.js (around line 1700)
  1. Assemble + Test
  • Test 1: Create ItemType (with Property relationships)
  • Test 2: Create Part and BOM relationships (verify compatibility with other ItemTypes)

Acceptance:

  • [ ] useCreate({ itemType: 'Part', properties: {...}, relationships: [...] }) successfully creates Part and BOM
  • [ ] useCreate({ itemType: 'ItemType', properties: {...}, relationships: [...] }) normally creates an ItemType (including Property and RelationshipType)
  • [ ] Creating objects with multi-level relationships works normally

Phase 2: ItemTypeManagement.vue integrated with useCreate (2 days) ✅ Completed

Goal: The object class management interface remains unchanged, but the internal logic is migrated to useCreate.

Completed:

  • [x] ItemTypeManagement.vue imports useCreate
  • [x] The createItemTypeInSCSAI function is internally replaced with createViaUseCreate()
  • [x] End-to-end validation passed: LLM generates definition → data conversion → useCreate creation → SCSAI verification
  • [x] The old backend API /api/sciot/create-itemtype-in-SCSAI is no longer called by the frontend
  • [x] UI end-to-end validation: SupplierEvaluation (5 properties + 2 relationship types) created successfully

Current creation process in ItemTypeManagement.vue (after refactoring):

用户点击"创建对象类"
  → capabilityCreate(description)  // LLM 生成对象类定义
  → 将 definition 转换为 useCreate 格式(properties + relationships)
  → createViaUseCreate({ itemType: 'ItemType', properties, relationships })
  → 前端直接 ApplyItem(含内嵌 Property/RelationshipType 关系)

数据转换示例(LLM 返回 → useCreate 格式):

// LLM 返回的 definition(Phase 0 来源B)
const def = {
  name: 'MyObject', label: '我的对象',
  properties: [
    { name: 'title', label: '标题', data_type: 'string', is_required: true },
    { name: 'status', label: '状态', data_type: 'list' }
  ],
  relationships: [{ name: 'RelatedPart', related_item_type: 'Part' }]
}

// 转换为 useCreate 格式
const options = {
  itemType: 'ItemType',
  properties: { name: def.name, label: def.label },
  relationships: [
    { relationship_type: 'Property', related_item_type: 'Property',
      related_items: def.properties.map(p => ({
        properties: { name: p.name, label: p.label, data_type: p.data_type,
                      is_required: p.is_required ? '1' : '0' }
      }))
    },
    { relationship_type: 'RelationshipType', related_item_type: 'RelationshipType',
      related_items: def.relationships.map(r => ({
        properties: { name: r.name, related_item_type: r.related_item_type }
      }))
    }
  ]
}

步骤:

  1. Import useCreate in ItemTypeManagement.vue
  2. Replace createItemTypeInSCSAI with: definition → data conversion → useCreate().create()
  3. Retain existing UI interactions (pop-ups, forms, result display) and LLM-generated content
  4. Remove the backend /api/sciot/create-itemtype-in-SCSAI interface (no longer needed)

Acceptance criteria:

  • [ ] Create a new ItemType from ItemTypeManagement.vue with functionality identical to the original
  • [ ] Show progress during creation (10%→65%→100%)
  • [ ] Properties and RelationshipType associations are created correctly

Phase 3: Extract useQuery + useModify + useObjectMeta ✅ Completed

Goal: Unify query/edit/metadata logic.

Status: All three composables have been created and implement full interfaces.

Implemented:

useQuery (src/composables/useQuery.js, 14KB, 6 interfaces)

  • list(itemType, options) — Query object list (supports filters/sortBy/page/select)
  • detail(itemType, id, options) — Query object details
  • search(itemType, keyword, options) — Search objects
  • count(itemType, filters) — Count objects
  • listRelationships(relType, sourceId, options) — Query relationship list
  • query(aml, options) — rawQuery: Native AML query (used by migrated ProductList read function)

useModify (src/composables/useModify.js, 9KB, 7 interfaces)

  • update(itemType, id, properties, options) — Edit object properties
  • remove(itemType, id) — Delete object
  • batchRemove(itemType, ids, options) — Batch delete
  • updateRelationship(relType, relId, properties) — Edit relationship row
  • removeRelationship(relType, relId) — Delete relationship row
  • batchRemoveRelationships(relType, relIds, options) — Batch delete relationships
  • addRelationship(relType, sourceId, relatedId, properties) — Add relationship

useObjectMeta (src/composables/useObjectMeta.js, 16KB, 7 interfaces)

  • getSchema(itemType, options) — Get object type schema
  • getTypeTemplate(itemType, options) — Get type template
  • getPropertyDefs(itemType, options) — Get property definitions
  • getRelationshipTypes(itemType, options) — Get relationship type definitions
  • listTypes(options) — Get object type list
  • getFullMeta(itemType, options) — Get full metadata
  • clearCache(itemType) — Clear local cache

Acceptance (code completed):

  • [x] useQuery file exists, 6 exported interfaces
  • [x] useModify file exists, 7 exported interfaces
  • [x] useObjectMeta file exists, 7 exported interfaces
  • [ ] Runtime verification of each interface's functionality (requires end-to-end testing)

Phase 4: ProductList.vue Integration with Generic Components (3 days) ✅ All Completed

Objective: Eliminate handwritten AML in the Part/Product management page, using generic components.

Result: ProductList.vue has been fully migrated, with zero residual _SCSAIApiRequest calls and getBomService() removed.

Migrated Items:

  • [x] import { useQuery } from '../composables/useQuery.js' + useModify
  • [x] 5 read functions → rawQuery (6 call sites: L394,458,517,1160,1207,1237)
  • [x] 8 write operations in generateDemoData → rawQuery (Create Part×13, Create Product×1, Create BOM/Model relationships×13)
  • [x] getBomService() function removed (L1083-1087 replaced with deprecation comment)

Migration Pattern:

// 旧:
const bomService = getBomService();
const res = await bomService._SCSAIApiRequest('ApplyItem', aml);
const item = res?.Item ? (Array.isArray(res.Item) ? res.Item[0] : res.Item) : null;

// 新:
const { items } = await rawQuery(aml);
const item = items[0];

手写 AML 字符串现状: 仍在 generateDemoData 中存在,但通过 rawQuery() 统一路由,AML 不再直接依赖 SCSAI 底层实现,可后续替换为 useCreate/useModify 纯 API。

Acceptance Criteria:

  • [x] No _SCSAIApiRequest calls in ProductList.vue
  • [x] No getBomService() / window._bomService in ProductList.vue
  • [x] Write operations uniformly routed through rawQuery
  • [ ] Runtime validation (requires end-to-end testing)

Phase 5: Cleanup and Consolidation (1 day) ❌ Not Started

Objective: Delete redundant code and update architecture documentation.

  1. Delete replaced legacy functions (after confirming new code stability)
  2. Update routing configuration
  3. Confirm that SCSAI calls in AiWorkbench.vue also use generic components
  4. Update documentation

VIII. Server-Side Image and Mini-Program Client (Already Implemented)

This section, added in v3.0, documents the server-side/mini-program implementations completed in parallel during Phase 1.

8.1 Architectural Approach

The web-side useCreate.js is a Vue composable (ESM) and cannot be used directly in the Node.js backend.

Therefore, a server-side mirror server/routes/unified-create.js (CommonJS, 1089 lines) was created,

implementing a fully equivalent 7-step creation process, accessible to mini-programs/mobile clients via HTTP API calls.

┌────────────┐     ┌──────────────────────┐     ┌─────────────┐
│  Web 前端   │ ──→ │  useCreate.js (ESM)  │ ──→ │  SCSAI SOAP  │
│  (浏览器)   │     │  composable 直接调用   │     │             │
└────────────┘     └──────────────────────┘     └─────────────┘
                                                         ↑
┌────────────┐     ┌──────────────────────┐              │
│  小程序端   │ ──→ │  /api/unified/*      │ ────────────┘
│  (移动端)   │     │  服务端镜像 (CJS)     │
└────────────┘     └──────────────────────┘

8.2 服务端 API 端点

| 端点 | 方法 | 功能 |

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

| /api/unified/create | POST | Core Creation (7-step process) |

| /api/unified/generate-props | POST | LLM Property Generation (including relationship discovery) |

| /api/unified/type-template/:name | GET | Get Type Template |

| /api/unified/item-types | GET | List of Creatable Types |

8.3 Implemented File List

FileLinesDescription
server/routes/unified-create.js1089Server-side 7-step creation mirror
server.js (L1996)-/api/unified/ route registration
bossagents-miniapp/src/api/unified-create.js30Mini-program API wrapper
bossagents-miniapp/src/pages/workbench/SCSAI-create.vue5174-step wizard creation page
server/digital-staff/staff-manager.js-⟦DS-SCSAI-001⟧ SCSAI Engineer Seed

8.4 Differences Between Server-Side Image and Web Composable

DimensionuseCreate.js (Web)unified-create.js (Server)
Module FormatESM (import/export)CommonJS (require/module.exports)
ReactivityVue ref()Plain variables, HTTP JSON response
SCSAI CommunicationbomService._SCSAIApiRequest()SCSAI-client.getSharedClient().sendAML()
DatabaseNot involveddb-adapter reads sciot_import.db (not better-sqlite3)
LLM GenerationControlled by callerBuilt-in generate-props endpoint (includes relationship discovery)
Relationship NormalizationnormalizeRelationships()Same function name, consistent logic

8.5 Lessons Learned

  1. DB Adapter Layer: Server side must use db-adapter (underlying sql.js/MySQL), cannot use better-sqlite3 (not installed in the project)
  2. LLM Prompt Quality: Initial prompt only listed field names, LLM could not generate reasonable relationship data; enhanced version injects associated object field list + child_objects configuration
  3. normalizeRelationships Necessary: LLM output relationship format is unstable (mixed array/object usage), must be standardized
  4. createRelationshipsRecursive: Must include child template property filtering + keyed field auto-filling + hidden default values

Seven. Key Design Decisions

7.1 Why Start with ItemType?

ItemType is the most generic object class:

  • All other objects (Part/Vendor/Project) are instances of ItemType.
  • ItemType's relationships (Property/RelationshipType) are more complex than other objects.
  • Once validated in the ItemType scenario, extending it to other objects is a natural progression.

Successful Phase 1 validation on ItemType = component reliability.

7.2 Why Separate Interfaces?

User requirements:

Although theoretically the object class ItemType and any other business object could use the same Vue component (the original SCSAI implementation was a single HTML page), they are separated for convenience. The object class retains its original interface, but the business logic uses a shared set of components.

Therefore:

  • The ItemTypeManagement.vue interface is retained, internally using useCreate/useQuery/useModify.
  • The ProductList.vue interface is retained, internally using useCreate/useQuery/useModify.
  • Both interfaces share the same set of components but are not forcibly merged.

7.3 How to Handle the Backend /api/sciot/create-itemtype-in-SCSAI?

After Phase 2 completion, this backend API is no longer needed.

Creating ItemType becomes a pure frontend operation via useCreate().create({ itemType: 'ItemType', ... }).

However, /api/sciot/apply-item is retained (sends AML directly to SCSAI for scenarios requiring browser bypass).

7.4 How to Handle Digital Employees (CapabilityRuntime)?

Remain unchanged:

  • Frontend: Browser user → composables → SCSAI
  • Backend: Digital worker/cron/Feishu → CapabilityRuntime → SCSAI

Consider extracting DOM‑independent logic from composables into pure JS modules for sharing between frontend and backend later.

7.5 How to handle demo data in ProductList.vue?

Keep the generateDemoData() function (~200 lines) as a standalone utility, not inside a generic component.

Use only during development/demonstration.


Appendix: Differences between ItemType creation and Part creation

| Dimension | Create ItemType | Create Part |

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

| Primary object | ItemType instance | Part instance |

| Main relationships | Property + RelationshipType | Part BOM + AML_BOM, etc. |

| Relationship direction | ItemType is the source of the relationship | Part can be parent or child in BOM |

| item_properties | Usually not required | Often used for pre‑creating keyed_name |

| permission/lifecycle | Must be set (otherwise invisible) | Optional |

| LLM generation | Required (user only provides description) | Optional |

| Core commonality | Both are ApplyItem + action=add + relationships embedded | |

Conclusion: The essence of SCSAI relationships is that related_id points to another Item. Regardless of whether the relationship type is Property, RelationshipType, or Part BOM, the AML structure is identical: ...... The generic component only needs to differentiate logic based on the relatedItemType and createRelated fields.


9. Acceptance Criteria (Including Actual Progress)

PhaseAcceptance ItemStatus
Phase 1useCreate can create ItemType (including Property + RelationshipType)⚠️ Code written, not tested
Phase 1useCreate can create Part and BOM relationships⚠️ Code written, not tested
Phase 1At least one view imports and uses useCreate✅ ItemTypeManagement.vue L975/L1063/L1306
Phase 2ItemTypeManagement.vue interface unchanged, internally uses useCreate✅ Completed
Phase 3useQuery/useModify/useObjectMeta three components available✅ Completed (code implemented, requires runtime verification)
Phase 4ProductList.vue eliminates handwritten AML✅ Completed (read+write fully migrated, _SCSAIApiRequest reduced to zero)
Phase 5Code cleanup completed, documentation updated❌ Not started (13 other views still have 55+ _SCSAIApiRequest calls)
AdditionalServer-side /api/unified/create available✅ Implemented (1089 lines)
AdditionalMini-program SCSAI-create.vue 4-step wizard✅ Implemented (517 lines)
← 返回案例列表

左帮右臂工业智能体,把刚读到的方法跑起来

微信扫小程序、打开网页版 ylxt.chat,或下载桌面客户端,三种方式任选,马上用上。

🌐 网页版 ylxt.chat 💻 桌面版下载 📞 电话咨询
左帮右臂小程序码
微信扫码,体验小程序
分享:
🤖 Try Now →
🤖
🎁