Files
skill-template/references/SCHEMA.md
chendelian 49e4d6e9a6
All checks were successful
技能自动化发布 / release (push) Successful in 5s
docs: default visible columns contract (v1.0.79)
沉淀 _jiangchang_tables.default_visible_columns_json:技能声明默认展示列;未配置全显;用户改「列」后本机覆盖;与 visible=0 硬隐藏区分。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 10:17:17 +08:00

28 KiB
Raw Blame History

数据存储与数据管理展示规范

本文是 skill 本地 SQLite 与匠厂宿主「数据管理」页面展示契约的权威说明。 实现上的 DDL 与默认中文元数据种子见 scripts/db/display_metadata.py;scripts/db/connection.py 的 init_db() 会一并初始化。

职责边界

技能负责

  • 定义真实 SQLite 表结构
  • 使用英文 snake_case 表名和字段名
  • 使用 _jiangchang_tables 提供表级展示元数据
  • 使用 _jiangchang_columns 提供字段级展示元数据(含可选 description 字段说明)
  • 需要「新增表单预填」时,在物理列上声明 SQLite DEFAULT(勿把默认值只写在文案里)
  • 定义哪些字段可见、可搜索、可创建、可编辑
  • 定义字段展示类型和枚举选项
  • (可选)按业务规则维护单元格呈现旁路数据(语义 tone;见 CELL_PRESENTATION.md)
  • 保证元数据与真实数据库结构一致
  • 保证元数据初始化幂等

宿主负责

  • 读取 _jiangchang_* 元数据
  • 读取 SQLite PRAGMA table_info
  • 根据 schema 渲染数据管理页面
  • 根据 editable 推导字段是否可创建或编辑
  • 在新增 / 编辑表单中,若列有 _jiangchang_columns.description,在标签下方展示该说明(灰字;空则不显示)
  • 打开新增表单时,对可创建字段用 SQLite 列 DEFAULT(PRAGMA table_info.dflt_value)预填;无 DEFAULT 则留空
  • 执行通用查询、新增、编辑、删除、导入、导出
  • 对字段名、表名、类型和权限进行最终校验
  • 不猜测技能业务含义
  • 不根据具体技能名称写特殊逻辑
  • 可在技能安装/更新成功后静默调用 python scripts/main.py init-db 做幂等 ensure(内部即 init_db());失败不影响安装结果
  • 若技能启用了单元格呈现(见 CELL_PRESENTATION.md),读取旁路呈现数据并为单元格映射语义样式(tone);不猜测业务规则

初始化入口

幂等建库/迁移:python scripts/main.py init-db。业务仓储也可懒触发 init_db(),与 CLI 结果一致。

SQLite 没有可靠的 COMMENT ON TABLE/COLUMN;SQL 文件里的 -- 注释 也不会成为可查询结构。 因此中文展示名称必须写入元数据表;字段顺序必须写在 CREATE TABLE 的列定义顺序中(PRAGMA table_info 的 cid)。

禁止新技能使用宿主的旧版 _schema_meta 表。仅 _jiangchang_tables / _jiangchang_columns 为正式契约。

技能名称(SKILL.md)

---
name: 中文业务名称
description: 中文技能说明
metadata:
  openclaw:
    slug: english-kebab-slug
---
  • name:用户可见的中文业务名称。
  • description:能力说明,不是技能名称。
  • metadata.openclaw.slug:机器标识,kebab-case 英文;目录名与默认数据库文件名使用 slug。slug 语义规范见 ../development/NAMING.md。
  • 复制模板后不得将 your-skill-slug、My Skill 等占位内容作为正式技能发布名称。

数据库路径与命名

{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/{skill-slug}/{skill-slug}.db
  • 数据库文件:英文 slug,例如 your-skill-slug.db(默认 {skill-slug}.db)。
  • 业务表、字段:英文 snake_case 物理名,例如 demo_items、task_logs、created_at。
  • 禁止用中文作为 SQLite 真实表名或字段名。

外部来源只读与本地数据可写

某些技能会从外部系统读取数据并写入技能自己的本地数据库。需要区分:

外部来源数据库:
  可能只读,不应被修改

技能本地数据库:
  可以根据业务语义允许新增、编辑或删除

不要把「外部来源只读」错误理解成「技能本地数据库一定只读」。技能通过 _jiangchang_tables.readonly 与 _jiangchang_columns.editable 声明本地表的实际写权限。

若创建/更新/删除带有领域副作用(自动建目录、加密、级联清理),不要依赖宿主默认直写:在 assets/actions.json 用可选字段 replaces: create|update|delete 接管默认按钮,详见 ACTIONS.md。

标准数据同步语义(外源 → 本地库)

适用于「同步 / refresh / collect」类能力。使用通用名称表述,勿把具体平台表名写进模板实现。

要求 说明
外部来源默认只读 技能不得修改外源
本地 SQLite 可事务写入 写入走 repository + 事务
幂等 同一业务键重复同步结果稳定
稳定唯一业务键 明确 upsert / 匹配字段
全量或增量 在实现与文档中显式声明
完整快照才提交 完整性校验通过后再 commit;调用方必须显式提供完整性状态(如 keyword-only 必填的 snapshot_complete),禁止默认视为完整,禁止靠数据条数猜测
空结果 / 读取失败保护 读取失败、分页不完整或不可信空结果(snapshot_complete=False)不得清库或误删;仅当完整快照显式确认为空(snapshot_complete=True 且结果为空)时,才可按全量失效策略处理旧数据
全量失效策略 物理删除、removed/is_active 标记、或保留历史——必须三选一并写清
部分失败 不得伪装成整体成功
半成品 事务失败不得留下可见不一致状态

建议统一返回统计:

{
  "total": 100,
  "inserted": 10,
  "updated": 20,
  "unchanged": 65,
  "removed": 5
}

同步数据 vs 导出当前数据表 vs 特殊业务报告

能力 语义 负责方
同步数据 外部来源 → 技能本地数据库 技能 Action / domain service
导出当前数据表 本地库 → CSV/Excel 等 数据管理页宿主统一导出
生成特殊业务报告 多表合并、特殊排版或附加计算 仅当系统导出无法满足时,才提供独立 export-*

同步型 Action 默认只写库、不生成导出文件。兼容旧 export 命令需要刷新时,必须调用同一 sync 内核。可复用测试范式见 tests/samples/test_sync_contract.py.sample。

元数据表(宿主兼容)

宿主读取字段(与匠厂 metadata-resolver 一致):

_jiangchang_tables 表级标准

字段 必填 说明
table_name 是 真实英文表名
display_name 是 用户可见的中文业务名称
description 否 表说明
sort_order 否 兼容保留字段,不用于替代物理字段顺序
visible 是 1 在宿主数据管理中展示 / 0 隐藏
readonly 是 1 整张表只读;0 允许宿主根据字段权限执行写操作
default_sort_json 否 数据管理默认行排序(见下节);空则宿主用内置默认
default_visible_columns_json 否 数据管理默认展示列(见下节);空则全显

表级默认排序 default_sort_json(宿主支持)

技能可声明该表在数据管理中的默认排序;宿主优先采用,未声明或声明无效时回退:

updated_at DESC → created_at DESC → 主键 DESC。

JSON 数组(可多字段,按顺序):

[{"column":"sent_at","direction":"desc"},{"column":"id","direction":"desc"}]

规则:

  • column 必须是该表真实列名;敏感列会被宿主忽略
  • direction 仅 asc / desc(缺省按 desc)
  • 用户在 UI 上手动改排序后,以用户选择为准;声明只影响未选择时的默认
  • 通过 upsert_table_metadata(..., default_sort_json=...) 写入;旧库由 init_display_metadata_tables 幂等 ALTER 补列

示例(消息时间线):

upsert_table_metadata(
    cursor,
    table_name="messages",
    display_name="消息",
    readonly=0,
    default_sort_json='[{"column":"sent_at","direction":"desc"},{"column":"id","direction":"desc"}]',
)

表级默认展示列 default_visible_columns_json(宿主支持)

技能可声明该表在数据管理表格中的默认展示列(软默认,不是硬隐藏):

  • 已配置:首次打开(用户尚未改过「列」)只显示名单中的列;其余列仍在「列」面板中,用户可勾回
  • 未配置 / 空 / 无效:显示全部 schema 可见列(与今日行为一致)
  • 用户改过「列」或表头「隐藏此列」后:以本机偏好为准;「恢复默认列布局」后重新回到技能默认(若有)

JSON 数组(物理列名;也可写 {"column":"col"} 对象,宿主同样接受):

["stat_type","period","stage","ops_count","timeout_ratio"]

规则:

  • 列名必须是该表真实列,且 _jiangchang_columns.visible=1(硬隐藏列本来就不进表格)
  • 与 visible=0 不同:visible=0 = 列从数据管理 schema /「列」面板移除;本字段只影响默认勾选状态
  • 名单为空或全部无效时,宿主 fail-open:全显
  • 通过 upsert_table_metadata(..., default_visible_columns_json=...) 写入;旧库由 init_display_metadata_tables 幂等 ALTER 补列

示例(时效统计:默认不展示编号与时间戳列):

upsert_table_metadata(
    cursor,
    table_name="timeliness_stats",
    display_name="时效统计",
    readonly=1,
    default_visible_columns_json=(
        '["stat_type","period","stage","ops_count",'
        '"timeout_open","timeout_done","timeout_total","timeout_ratio"]'
    ),
)

禁止:

  • 使用中文真实表名
  • 使用 _schema_meta 作为新的正式契约
  • 只写英文物理名而不写中文 display_name
  • 让元数据引用不存在的表
  • 用 visible=0 假装「默认不展示但用户还能勾出来」(那是硬隐藏,勾不回来)

_jiangchang_columns 字段级标准

字段 必填 说明
table_name 是 所属物理表
column_name 是 真实英文字段名
display_name 是 用户可见的中文字段名(表头与表单标签);保持简短
description 否 字段说明(给人看的短文案);宿主在新增/编辑表单标签下方展示(见下节);不要塞进 display_name
display_order 否 兼容字段,默认保持 NULL
visible 是 是否进入数据管理 schema /「列」面板(0 = 硬隐藏,用户无法勾回;默认不展示但可勾回请用表级 default_visible_columns_json)
searchable 是 是否参与搜索
editable 是 1 业务字段允许宿主用于新增和编辑;0 系统/只读字段
display_type 否 字段渲染类型;稳定取值见下节「表单与展示:稳定字段类型」
options_json 否 枚举选项 JSON

这两张表是数据字典,不是业务数据;宿主不会把它们当作普通业务表展示。

表单与展示:稳定字段类型(宿主支持,须与 Action 对称)

数据管理「新增 / 编辑」表单与 Skill Action 参数表单应使用同一套控件语义(配置入口不同,见 ACTIONS.md)。新技能只使用下表;宿主须两边都实现,避免「Action 有、CRUD 没有」。

本版稳定支持(须齐):

display_type(CRUD) 物理类型建议 列表展示 新增/编辑控件 存库约定
text(或缺省) TEXT / 一般标量 原文 单行文本 原文
textarea TEXT 原文(可截断) 多行文本 原文
json TEXT 原文 多行文本(JSON 字符串) 原文;提交时宿主可做基础 JSON 合法性校验
number INTEGER / REAL / NUMERIC 原文 数字输入(type=number) 数字;无 display_type 时,物理类型为 INT/REAL/NUMERIC 也应走数字控件
boolean INTEGER 0/1 或 BOOL 开关语义展示 开关 0 / 1
(枚举) 任意 + options_json 数组 标签映射 下拉选择 选项 value
lookup 外键式标量 + options_json 对象 标签映射 下拉选择(查关联表) 关联键值
(敏感) 任意;列 sensitive=1 掩码/隐藏策略由宿主定 新建可用密码框;编辑策略与既有宿主一致 原文(勿日志明文)
date TEXT 推荐 YYYY-MM-DD,或可安全归一的值 日期 日期选择(日) YYYY-MM-DD
datetime_unix_seconds INTEGER YYYY-MM-DD HH:mm:ss 日期时间选择;提交写回 Unix 秒 Unix 秒整数;禁止改成 ISO 字符串
url TEXT 原文(可作链接) 单行输入 type=url(薄层;校验从宽) 原文
email TEXT 原文 单行输入 type=email(薄层;校验从宽) 原文

说明灰字与创建默认值见下一小节;与 Action 的对照写在 ACTIONS.md「表单字段类型对照」。

明确不在本版稳定范围(勿在新技能宣传为已支持):

  • 文件 / 图片上传
  • 多选、标签数组、复杂 oneOf / nested object 表单
  • 把业务可编辑时间存成毫秒、ISO 文本或 SQLite datetime 文本(审计字段规范见「标准时间字段」)

datetime_unix_milliseconds:仅兼容列表展示旧数据;新技能不要用;可编辑时间一律 datetime_unix_seconds。

新增/编辑表单:字段说明与默认值(宿主支持)

数据管理「新增记录 / 编辑记录」与 Skill Action 弹窗是两套表单;CRUD 侧约定如下(交互对齐 Action 的 inputSchema.description / default,但配置入口不同)。

能力 技能写什么 宿主做什么
字段说明 _jiangchang_columns.description(可选) 新增/编辑表单中,在标签下方以灰字展示;空则不显示
创建默认值 物理列 SQLite DEFAULT(如 limit_n INTEGER NOT NULL DEFAULT 0) 打开「新增」时,对可创建字段预填该默认值;无 DEFAULT 则留空
编辑已有行 — 不用 DEFAULT 覆盖已有行数据
表格列头 只用 display_name 长说明不进入列头

规则与禁止:

  • 推荐对易填错、语义特殊的可编辑字段写 description(示例链接、0 表示不限制等);非强制每个字段都有
  • 禁止把说明硬塞进 display_name(如 评论上限(0不限));表头会变脏,也无法与 Action 说明对齐
  • 业务语义(如「0 = 不限制」)写在 description 里;宿主只展示,不解读业务含义
  • 第一期不新增元数据「表单默认值」列;CRUD 默认值 = DDL DEFAULT,与 Action 的 inputSchema.default 分开配置
  • 同一业务字段若同时出现在 Action 与新增表单,文案应对齐(短标题 + 说明),但分别写在 actions.json 与 _jiangchang_columns / DDL
  • 数字类可编辑列推荐 display_type: "number"(或依赖 INT/REAL/NUMERIC 推断)并在 DDL 写清 DEFAULT(如条数上限默认 0)

示例(可编辑列种子 + DDL 默认):

-- 物理列:创建默认 0
comment_limit INTEGER NOT NULL DEFAULT 0
seed_column_metadata_batch(
    cursor,
    table_name="videos",
    columns=(
        {
            "column_name": "video_url",
            "display_name": "视频链接",
            "editable": 1,
            "display_type": "url",
            "description": "填平台视频页链接;需包含可识别的视频路径片段。",
        },
        {
            "column_name": "comment_limit",
            "display_name": "采集评论条数",
            "editable": 1,
            "display_type": "number",
            "description": "最多采多少条。填 0 = 不限制;填正整数则按该数量封顶。",
        },
    ),
    valid_column_names=physical,
)

Action 参数表单的 title / description / default / display_type 见 ACTIONS.md;勿与本节 CRUD 配置入口混用。

editable 与 createable 的关系

技能模板只维护 editable 这一份字段权限声明:

skill metadata:
  editable

host runtime:
  createable / editable

宿主根据以下因素计算字段是否能够出现在新增或编辑表单中:

  • 表级 readonly
  • 字段 editable
  • 主键
  • generated 字段
  • sensitive 字段
  • BLOB 类型
  • not-null 约束
  • default value

通用规则:

新增表单:
  editable = 1
  且不是主键
  且不是 generated
  且不是敏感字段
  且不是 BLOB

编辑表单:
  editable = 1
  且不是主键
  且不是 generated
  且不是敏感字段
  且不是 BLOB

若一张表:

readonly = 0
但所有字段 editable = 0

则:

  • 这张表技术上可写,但不适合手工新增或编辑
  • 宿主不应打开空白新增表单
  • 技能应通过自身业务流程产生数据
  • 这不是宿主猜测业务,而是技能通过元数据声明的结果

系统字段标准

通常保持 editable = 0 的字段类型包括:

  • 自增主键
  • generated 字段
  • created_at / updated_at
  • 同步时间戳
  • 内容哈希
  • 计算结果
  • 内部状态
  • 删除标记
  • 审计字段
  • 敏感凭据或密钥字段

不要把具体业务字段名写死;按字段类型和职责设置 editable。

表结构标准

  • 业务表和字段使用英文 snake_case
  • 可写表优先使用单字段主键
  • 自增主键优先放在 CREATE TABLE 第一列
  • created_at 和 updated_at 放在业务字段末尾
  • 字段展示顺序以 CREATE TABLE 和 PRAGMA table_info(cid) 为准
  • 不依赖 display_order 重新排列字段
  • 不要让宿主通过英文字段名推断展示顺序
  • 复杂字段需要通过 display_type 或 visible 明确处理

推荐顺序(可按业务裁剪,但已有字段应遵守相对位置):

1. 主键 id
2. 关联标识与核心业务字段
3. 普通业务字段
4. 状态、结果、错误等辅助字段
5. created_at(如有)
6. updated_at(如有)

标准时间字段(新技能统一规范)

新技能业务表若需要时间审计字段,统一采用 Unix 秒级时间戳,不要使用毫秒时间戳、ISO 字符串或 SQLite 文本 datetime。

项目 规范
物理字段 created_at INTEGER、updated_at INTEGER
存储格式 Unix 秒级整数
展示元数据 display_type datetime_unix_seconds
中文名 created_at → 创建时间;updated_at → 更新时间
用户编辑 审计字段 editable = 0(系统维护,列表只展示格式化结果,不进可编辑表单)
字段顺序 位于业务字段末尾:… → created_at → updated_at
排序 不使用 display_order;顺序仅来自 PRAGMA table_info

业务可编辑时间 vs 审计时间

场景 editable 列表 新增/编辑表单
created_at / updated_at 等审计列 0 格式化为 YYYY-MM-DD HH:mm:ss 不出现(或只读,由宿主既有规则)
业务时间列(预约、截止、活动开始等) 1 同上格式化 日期时间控件;提交写入 Unix 秒整数

宿主对 display_type = datetime_unix_seconds:

  • 列表:格式化为 YYYY-MM-DD HH:mm:ss 展示,不改库内原始整数
  • 可编辑表单:提供日期时间选择;保存时写回 Unix 秒(不要写 ISO 字符串、不要写毫秒)

自动生成与维护

  • created_at:INTEGER NOT NULL DEFAULT (unixepoch());插入时可省略,由数据库生成。
  • updated_at:INTEGER NOT NULL DEFAULT (unixepoch());插入时同样可省略。
  • updated_at 更新:模板默认表 task_logs 通过 SQLite trigger {table}_set_updated_at 在业务字段更新后自动刷新。

实现参考:

  • DDL 与 trigger:scripts/db/connection.py、scripts/db/timestamp_columns.py
  • 中文元数据种子:scripts/db/display_metadata.py
  • 自检:scripts/db/display_metadata_validator.py

模板默认:task_logs

task_logs 是技能内部系统自动写入的任务审计日志(由 task_logs_repository INSERT/UPDATE),不是供用户在宿主数据管理中手工维护的业务表。

权限设计:

层级 值 说明
表级 readonly 1 宿主数据管理只读展示,不提供新增/编辑/删除表单
所有业务字段 editable 0 含 task_type、status、error_msg、result_summary 等
技能内部 repository 正常 INSERT/UPDATE 元数据权限只约束宿主 UI,不限制技能代码写库

物理定义(权威顺序):

CREATE TABLE IF NOT EXISTS task_logs (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    task_type TEXT NOT NULL,
    target_id TEXT,
    input_id TEXT,
    input_title TEXT,
    status TEXT NOT NULL,
    error_msg TEXT,
    result_summary TEXT,
    created_at INTEGER NOT NULL DEFAULT (unixepoch()),
    updated_at INTEGER NOT NULL DEFAULT (unixepoch())
);

对应中文展示(由 init_db() 写入元数据表):

物理字段 中文名 editable
id 编号 0
task_type 任务类型 0
target_id 目标编号 0
input_id 输入编号 0
input_title 输入标题 0
status 状态 0
error_msg 错误信息 0
result_summary 结果摘要 0
created_at 创建时间 0
updated_at 更新时间 0

表中文名:任务日志;表级 readonly = 1(宿主只读;技能 repository 仍可写入)。

通用示例:demo_items(测试 fixture 参考)

以下表结构用于模板测试演示数据管理契约,不是模板默认业务表:

CREATE TABLE demo_items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT NOT NULL,
    description TEXT,
    status TEXT NOT NULL DEFAULT 'draft',
    generated_value TEXT,
    created_at INTEGER NOT NULL DEFAULT (unixepoch()),
    updated_at INTEGER NOT NULL DEFAULT (unixepoch())
);

对应元数据要点:

物理字段 editable 说明
id 0 自增主键
title 1 业务字段
description 1 业务字段
status 1 枚举,options_json 演示
generated_value 0 系统/计算字段
created_at 0 系统时间
updated_at 0 系统时间

枚举字段 options_json

options_json 支持两种形态:

1)静态枚举(数组)

每项包含 value 与 label:

[
  {"value": "draft", "label": "草稿"},
  {"value": "published", "label": "已发布"},
  {"value": "archived", "label": "已归档"}
]

宿主据此渲染选择框;技能侧负责保证 JSON 合法且与物理字段取值一致。

2)表关联 lookup(对象,推荐用于外键式字段)

当字段取值依赖同库另一张业务表时,display_type 设为 lookup,options_json 写对象(不是数组):

{
  "ref_table": "platforms",
  "value_column": "platform_key",
  "label_column": "display_name",
  "filter_column": "enabled",
  "filter_value": 1
}
字段 必填 说明
ref_table 是 同库被引用表名(snake_case 标识符)
value_column 是 写入当前字段的值列
label_column 是 下拉展示名列
filter_column / filter_value 否 等值过滤(如只列出 enabled=1)

宿主在加载表 schema 时查询 ref_table,把结果展开成 {value,label} 下拉选项;物理列仍存标量(如 platform_key 文本、account_id 整数),不做嵌套子表。

示例:账号表的平台字段 → 平台信息表;凭据表的账号编号 → 账号信息表。

幂等初始化标准

  • _jiangchang_tables 和 _jiangchang_columns 必须通过 upsert 初始化
  • 多次执行初始化不能重复记录
  • 重新初始化可以更新展示名、描述、visible、searchable、editable、display_type、options_json
  • 元数据不能残留旧字段(删除或重命名字段时必须同步清理)
  • 元数据不能引用不存在的表或字段
  • 新增字段或表时必须同步增加元数据
  • 不要直接修改用户真实数据库作为迁移方式

实现 helper:

  • upsert_table_metadata / upsert_column_metadata — 幂等写入
  • seed_column_metadata_batch — 批量 upsert;可选传入 valid_column_names 时在 upsert 后自动 prune
  • prune_stale_column_metadata — 清理已删除物理字段的元数据

新增业务表时如何初始化

  1. 在 connection.py(或迁移脚本)中 CREATE TABLE 真实物理表。
  2. 用 PRAGMA table_info 或 list_physical_column_names 取得真实物理字段列表(顺序以 cid 为准)。
  3. 调用 upsert_table_metadata 写入表级元数据。
  4. 调用 seed_column_metadata_batch,并传入 valid_column_names=physical_column_names:
from db.display_metadata import list_physical_column_names, seed_column_metadata_batch, upsert_table_metadata

physical = list_physical_column_names(cursor, "demo_items")
upsert_table_metadata(cursor, table_name="demo_items", display_name="示例记录", readonly=0)
seed_column_metadata_batch(
    cursor,
    table_name="demo_items",
    columns=DEMO_ITEMS_COLUMN_METADATA,
    valid_column_names=physical,
)

传入 valid_column_names 时:先 upsert,再删除不在物理表中的陈旧 _jiangchang_columns 行。

字段删除或重命名时如何清理

  1. 在 DDL / 迁移中完成物理字段删除或重命名。
  2. 重新执行 seed_column_metadata_batch(..., valid_column_names=当前物理字段列表),自动 prune 旧字段元数据。
  3. 或单独调用 prune_stale_column_metadata(cursor, table_name, valid_column_names)。

不传入 valid_column_names 时不会自动 prune——模板不会猜测真实物理字段,避免误删;文档与实现均以此为准。

不要直接修改用户真实数据库作为迁移方式;元数据初始化必须使用真实物理字段列表。

中文命名质量

  • 使用普通用户能理解的业务用语:task_logs → 任务日志,error_msg → 错误信息。
  • 禁止:Task Logs、input编号、errormsg、直接把物理名当 display_name。
  • 不宜向用户暴露的实现细节(如 payload_json、selector)应设 visible = 0 或给出可理解中文名。

元数据同步规则

  1. 新增用户可见业务表 → 同步 _jiangchang_tables。
  2. 新增用户可见字段 → 同步 _jiangchang_columns。
  3. 删除/重命名表或字段 → 同步清理或迁移元数据。
  4. 初始化脚本必须幂等。
  5. 元数据中的表、字段必须在库中真实存在;可见项不得缺少中文 display_name。

不同业务的 task_logs 映射

业务场景 task_type target_id input_id
发布类 publish 账号 ID 内容 ID
工资代发 disburse 付款账户 批次 ID
对账 reconcile 平台标识 对账批次 ID
发票验真 verify 税务地区 发票批次 ID

业务特有字段优先放入 result_summary(JSON 字符串),避免随意加列;若确需新列,必须同步元数据并保持合理物理顺序。

开发自检

  • init_db() 后运行 tests/test_display_metadata.py 与 tests/test_data_management_contract.py。
  • 若提供宿主 Action 入口,运行 tests/test_actions_manifest.py。
  • 复制为真实技能后,使用 scripts/db/display_metadata_validator.py 中的校验函数检查 SKILL 名称、slug 与元数据完整性。

模板原则

  • 模板不做复杂历史迁移框架;新 skill 从当前 schema 起步。
  • 元数据 DDL 与 task_logs 中文种子以 scripts/db/display_metadata.py 为单一权威来源。
  • 模板定义「如何声明能力」;具体技能定义「声明什么业务能力」;宿主负责「如何通用渲染和执行」。