第一个 Action:新建一个对象

第 3 课 · 共 7 课 约 6 分钟

参数、规则、日志三样东西;先只校验、再执行;读懂逐项结果和改动清单;到 Action Log 和编辑历史里找到这一次。

本课目标

读完这一课,你将能够

  • 写出一个 createObject 的 Action:参数、规则、日志
  • 先只校验再执行,读懂返回的逐项结果和改动清单
  • 在 Action Log 和编辑历史里找到这一次执行

一个 Action 的三个部件

最小的 Action 只需要三样东西。把下面的文件存成 starter/02-register-customer.json:

{
  "kind": "actionType",
  "apiName": "register-customer",
  "title": "登记客户",
  "description": "新建一家客户公司。第一个 Action:只有参数、一条规则和一份记录。",
  "schema": {
    "parameters": [
      { "name": "customerId", "type": "string", "title": "公司 ID", "required": true, "maxLength": 40 },
      { "name": "name", "type": "string", "title": "名称", "required": true, "maxLength": 60 },
      { "name": "stage", "type": "string", "valueType": "customerStage", "title": "阶段", "required": true },
      { "name": "seats", "type": "integer", "title": "座位数", "required": true, "min": 1, "max": 10000 },
      { "name": "members", "type": "integer", "title": "成员数", "required": true, "min": 0, "max": 10000 }
    ],
    "rules": [
      {
        "type": "createObject",
        "objectType": "customer",
        "values": { "customerId": "$customerId", "name": "$name", "stage": "$stage", "seats": "$seats", "members": "$members" }
      }
    ],
    "summary": "登记客户 {name}",
    "actionLog": true
  }
}
  1. 参数 parameters

    调用方要填什么。类型、必填、取值范围(min、max、maxLength)、Value Type 的约束,都在入口处检查。

  2. 规则 rules

    改什么。这里一条 createObject:用参数拼出一个新的客户公司。规则一共六种,下一课会用到 modifyObject。

  3. 日志 actionLog

    actionLog: true 让每次成功执行都留一个日志对象;summary 是写进日志的一句话,{name} 取参数的值。

规则的值里,$customerId 是取参数。能写的还有:$参数.属性(取对象参数的某个属性)、$now(当前时间)、$user(执行人的账号 ID)和 $userName(执行人的名字)、$uuid(一个新的主键);其他都是字面量,比如 "submitted"。

放进去,先只校验

aidc semantic define starter && aidc semantic publish --notes "登记客户"

aidc semantic apply register-customer \
  --param customerId=acme-east --param name="ACME East" --param stage=试点 \
  --param seats=0 --param members=14 --validate-only --json

座位数填了 0,不在 1 到 10000 之间。只校验不写入,返回每个参数的结果,出错的那一项带着信息,命令行退出码是 2:

{
  "validation": {
    "result": "INVALID",
    "submissionCriteria": [],
    "parameters": {
      "customerId": { "result": "VALID", … },
      "seats": {
        "result": "INVALID",
        "evaluatedConstraints": [{ "type": "range", "gte": 1, "lte": 10000 }],
        "required": true,
        "message": "座位数 要在 1–10000 之间"
      },
      "members": { "result": "VALID", … }
    }
  }
}

执行,读结果

改成合格的数,去掉 --validate-only,加上 --return-edits(要求把改动一起返回):

aidc semantic apply register-customer \
  --param customerId=acme-east --param name="ACME East" --param stage=试点 \
  --param seats=20 --param members=14 --return-edits --json
{
  "operationId": "ri.actions.aidc.action.cmuni87b5000d01alepn05gf9",
  "validation": { "result": "VALID", … },
  "edits": {
    "type": "edits",
    "edits": [{ "type": "addObject", "primaryKey": "acme-east", "objectType": "customer" }],
    "addedObjectCount": 1,
    "modifiedObjectsCount": 0,
    "deletedObjectsCount": 0,
    "addedLinksCount": 0,
    "deletedLinksCount": 0
  }
}
VALIDATION

validation

逐项的结果:每个参数、每条提交条件,通过还是不通过。

EDITS

edits

这一次到底改了什么:新建、修改、删除了哪些对象和关系。

OPERATION

operationId

这一次执行的编号,Action Log 和编辑历史里都能凭它找到。

找到这一次

aidc semantic objects customer                       # 现在的客户
aidc semantic objects log.register-customer --json   # Action Log
aidc semantic edits-history customer --pk acme-east  # 这个对象的每一次修改

Action Log 本身也是对象:类型叫 log.register-customer,主键就是 operationId,里面有时间、执行人、summary、改了哪些对象(editedObjects),以及这次的参数值。编辑历史里同一个 operationId 会出现在这个对象的 createEdit 上。

{
  "__primaryKey": "ri.actions.aidc.action.cmuni87b5000d01alepn05gf9",
  "__apiName": "log.register-customer",
  "timestamp": "2026-09-30T02:46:58.040Z",
  "summary": "登记客户 ACME East",
  "editedObjects": ["customer:acme-east"],
  "customerId": "acme-east", "name": "ACME East", "stage": "试点", "seats": 20, "members": 14
}

再登记三家,后面几课都要用。它们的座位数和成员数各不相同,第 4 课的提交条件会用到:

aidc semantic apply register-customer --param customerId=acme-west  --param name="ACME West"  --param stage=试点 --param seats=48 --param members=41
aidc semantic apply register-customer --param customerId=acme-north --param name="ACME North" --param stage=试点 --param seats=36 --param members=33
aidc semantic apply register-customer --param customerId=acme-pause --param name="ACME Pause" --param stage=暂停 --param seats=10 --param members=4

要点

  • 一个 Action = 参数 + 规则 + 日志;createObject 用参数和 $now、$uuid 这类内置值拼出新对象。
  • 先 --validate-only,再执行;不通过退出码是 2,信息指到具体的参数。
  • 返回里三样:validation(逐项)、edits(改了什么)、operationId(这一次的编号)。
  • 每次成功执行都进 Action Log(也是对象,可查)和编辑历史,用同一个编号。

练一练

登记四家客户

在你自己的公司里做;执行过的客户会留在数据里,后面几课接着用。

分别试 seats=0、stage=不存在、漏掉 name,各加 --validate-only:每种提示指到哪个参数?

小测

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

Q1校验不通过时,命令行的退出码是多少?

Q2用一个已经存在的 customerId 再登记一次,会怎样?

Q3Action Log 里每条记录的主键,和什么对得上?

延伸阅读