对象类型:一类业务对象

第 1 课 · 共 7 课 约 8 分钟

对象类型、对象、对象集;主键和标题键的规则;API name、显示名、状态、可见性;写出第一份定义。

本课目标

读完这一课,你将能够

  • 分清对象类型、对象和对象集,并对应到数据表
  • 为一类业务对象选出主键和标题键
  • 写出一份 objectType 定义,说出 API name、显示名、状态和可见性各管什么

对象类型、对象、对象集

上一门课把示例工厂的 13 个对象类型画在了同一张图上。这一节先挑「工单」,把它写成一份能提交的定义。

对象类型(Object Type)是对一类真实事物或事件的定义,比如工单。一张具体的工单是一个对象,「所有正在运行的工单」是一个对象集。它们和你熟悉的数据表一一对应:

数据表里本体(Ontology)里
整张表的结构工单表的表头和列定义对象类型 WorkOrder
一行表里的一行数据一个对象,比如工单 WO-20260901-017
筛出来的几行「状态 = 运行中」的若干行一个对象集
一列goodQty 这一列一个属性

对象大多来自数据源里的行,也可以完全由 Action 的 createObject 规则新建。数据源接入只读。普通 Action 规则只改语义层。配置 writeback webhook 的 Action 还能修改外部系统。

两把钥匙:主键和标题键

每个对象类型都要指定两个属性。主键让每个对象唯一,标题键是给人看的名字。WorkOrder 用 workOrderNo 做主键;Customer 的主键是 customerId,标题键是 name,因为人认的是公司名,不是编号。

  • 每个对象类型都必须有主键;新建的类型只写一个主键属性。存量复合主键原样保留时给警告。新建类型或修改主键时,平台拒收复合主键。
  • 主键值不能重复,也不能变。编辑和关系都挂在主键值上,主键一变,人改过的值和已有的关系就对不上了。
  • 改主键属于破坏性改动,要走分支和提案,不能悄悄改。
  • 标题键只管显示,不要求唯一;不写就用主键。
随口一问

用 ERP 导出文件里的行号当工单主键。下一次导出,行号变了,人在工单上做的标记全部对不上。

好的交代

用 ERP 里本来就有的工单号 workOrderNo:唯一、稳定,业务人员也认识。

有了主键,取回一个对象只要「类型 + 主键」。读回的每个对象都带着 __primaryKey、__apiName 和 __title,最后一个就是标题键的值。

const client = semantic.ontology();
const order = await client.objects("WorkOrder").fetchOne("WO-20260901-017");
// order.__primaryKey, order.__apiName === "WorkOrder", order.__title

名字与元数据

对象类型有两套名字:写给代码的,和写给人的。

API NAME

给代码用的名字

Object Type 用 PascalCase,例如 WorkOrder;属性用 camelCase,例如 goodQty。Object Type 的 API name 最多 100 个字符。Postgres 视图名称另限 63 字节。Action、SQL 的表名和应用都在引用它,起好就不要改。

DISPLAY

给人看的名字

显示名 title、复数显示名 pluralDisplayName、说明,还有同义词 synonyms:智能体和搜索按业务说法找到它。

STATUS

状态

active、experimental、deprecated、example:告诉别的建模者和应用,这一类现在能不能依赖。约定是:active 的类型不能直接删除或改 API name,example 只用于演示,不进正式流程。

VISIBILITY

可见性与类型组

visibility 取 NORMAL、PROMINENT、HIDDEN:重要的先显示,隐藏的不显示。groups 给类型打标签,类型多了好筛选。

同义词值得认真写。业务里有人说「生产单」,有人说「作业单」,把它们都写成 WorkOrder 的同义词,智能体按哪种说法问都能找到。每个类型最多写 12 个,每个不超过 40 个字符。

下面是 WorkOrder 的一份最小定义(省略了 sku、orderNo 两个外键)。columns 里每一项是一个属性,titleColumn 指定标题键,references 是外键,下一门课会把它变成关系。外键指向的类型(这里是 ProductionLine)要么已经存在,要么在同一批里一起提交。

{
  "kind": "objectType",
  "apiName": "WorkOrder",
  "title": "Work order",
  "description": "One production run of one product on one line.",
  "schema": {
    "pluralDisplayName": "Work orders",
    "visibility": "PROMINENT",
    "synonyms": ["job", "production order"],
    "groups": ["production"],
    "titleColumn": "workOrderNo",
    "columns": [
      { "name": "workOrderNo", "type": "string", "primaryKey": true, "title": "Work order no." },
      { "name": "status", "type": "string", "title": "Status" },
      { "name": "plannedQty", "type": "integer", "title": "Planned quantity", "unit": "pcs" },
      { "name": "goodQty", "type": "integer", "title": "Good quantity", "unit": "pcs" },
      { "name": "scrapQty", "type": "integer", "title": "Scrap quantity", "unit": "pcs" },
      { "name": "startAt", "type": "timestamp", "title": "Start" },
      { "name": "dueAt", "type": "timestamp", "title": "Due" },
      { "name": "lineCode", "type": "string", "title": "Line", "references": { "entity": "ProductionLine", "column": "lineCode" } }
    ]
  }
}

提交前先只检查:--dry-run 会告诉你引用是否闭合、相对上一个语义版本有哪些破坏性改动。智能体不直接改 main,要先开分支。

# check only: do the references close? any breaking changes?
aidc semantic define ontology/ --dry-run

# an agent works on a branch instead of main
aidc semantic branch create add-work-order
aidc semantic branch modify add-work-order ontology/ --dry-run

# read the definition back
aidc semantic object-types WorkOrder

下一节讲属性:每个属性该选什么类型,哪些类型能做主键和标题键。

要点

  • 对象类型是一类事物的定义,对象是其中一个,对象集是满足条件的一组。
  • 主键要唯一、稳定,标题键给人看;新建类型只写一个主键属性。
  • API name 给代码用,起好别改;显示名、同义词、状态、可见性给人和应用看。
  • 先 --dry-run 检查再提交;智能体在分支上写定义,不直接改 main。

练一练

把「设备」写成一个对象类型

示例工厂的设备 Machine 有 machineId、lineCode、model、installedOn 等属性。

为 Machine 选出主键和标题键,各写一句理由。再想一想:如果 MES 里的设备编号有时会重新编排,该怎么办?

小测

选一个答案,马上看解析。

Q1工单数据源里每行有一个自增行号,还有 ERP 的工单号 WO-20260901-017。主键该用哪个?

Q2「所有状态为运行中的工单」在 Semantic 里是什么?

Q3下面哪一个符合新建 Object Type 的 API name 命名标准?

延伸阅读