Files
skill-template/references/CELL_PRESENTATION.md
chendelian a70da6a076
All checks were successful
技能自动化发布 / release (push) Successful in 9s
feat: precipitate grid presentation (row/column/region) into skill contract
2026-09-20 21:08:23 +08:00

14 KiB
Raw Permalink Blame History

数据管理单元格呈现(Cell Presentation)契约(v1.0)

状态:正式契约 v1.0(cells[] 文档 schemaVersion 1)+ 加法 Grid Presentation。
目标: 冻结「技能声明语义呈现 → 宿主映射主题样式」的通用能力:某一格、整行、整列、若干行×若干列,供任意业务场景复用。
非目标: 超时/SLA 专用字段;技能下发任意 CSS / 任意色值;宿主实现业务规则引擎。
配套 Schema: ../assets/schemas/skill-cell-presentation.schema.json(格子)、../assets/schemas/skill-grid-presentation.schema.json(行/列/区域)。

相关正交轴见 ACTIONS.md、POLICY.md、SCHEMA.md。


0. 一句话

技能可以声明:哪张业务表上,哪些行 × 哪些列需要特殊标色/强调(语义 tone + 可选说明)。

想涂什么 怎么声明
某一格 一行 × 一列(v1 cells[] 或一条格子规则)
整行 若干行 × 该轴全部列
整列 该轴全部行 × 若干列
区域 若干行 × 若干列

用途不限:时效超时未填、库存预警、状态异常、必填缺失、审核驳回等。
不是「再加一列超时文字」;强调落在真正要关注的业务格子或行上。


0.1 能力档位

档位 技能行为 宿主行为
P0(默认) 不写呈现数据 / 未启用 数据管理表格与今日一致,无特殊标色
P1 按规则写入呈现文档或推荐旁路表 渲染对应格子 / 行 / 列 / 区域的语义样式;可选汇总 alert: true 做进页提醒

多数技能保持 P0。需要视觉强调时再启用。模板 actions.json 默认不启用。


0.2 宿主能力

能力 旁路表 宿主
格子着色 _jiangchang_cell_presentation 既有宿主即可
整行 / 整列 / 区域 _jiangchang_grid_presentation 需已读取该表(匠厂数据管理已支持)。旧宿主忽略该表,格子着色仍有效

同一开关 cellPresentation.enabled 同时打开两张旁路表。未建表 = 该通道为空,宿主忽略。


1. 职责边界

角色 负责 不负责
技能 按当前业务数据算出哪些格子/行/列要强调;在数据变更后重算并覆盖旧结果 不写宿主 CSS;不把强调文案污染进业务真值列冒充「变红」
宿主 读取呈现结果,按闭集 tone 映射主题样式;按几何涂表格;可选 Toast/提醒汇总 不理解「提前 3 天交单」等业务规则;不为单个技能写死样式

派生状态(重要): 呈现是计算结果,不是粘性开关。
用户补填数据 / 同步刷新后技能重算 → 该项消失 → 样式与提醒自然关闭。不要单独维护「已关闭提醒」状态机(除非产品另做「忽略此条」能力,本契约不冻结)。


2. 格子文档形状(冻,schemaVersion 1)

技能产出一份 Cell Presentation Document(可落库、可 CLI 打印,形状相同),须符合格子 Schema。v1 只描述某一格;整行/整列用 §2.1。

{
  "schemaVersion": 1,
  "skill": "your-skill-slug",
  "table": "business_records",
  "rowKey": "id",
  "generatedAt": "2026-08-10T06:00:00Z",
  "cells": [
    {
      "rowId": "42",
      "column": "qty",
      "tone": "danger",
      "message": "库存低于安全线",
      "alert": true
    },
    {
      "rowId": "42",
      "column": "status",
      "tone": "warning",
      "message": "待审核"
    }
  ]
}
字段 必填 说明
schemaVersion 是 固定 1(本形状不升版本)
skill 是 与 slug 一致
table 是 当前文档作用的业务表
rowKey 是 行匹配列(id / feishu_record_id 等)
generatedAt 否 排障用
cells 是 数组;空数组 = 该表清除全部格子呈现

2.0 cells[] 项

字段 必填 说明
rowId 是 rowKey 列值的字符串形式
column 是 要强调的业务列(snake_case),须真实存在
tone 是 见 §3
message 否 短说明(≤500);悬停 / 无障碍
alert 否 默认 false;true 可计入进页/同步提醒汇总

同一 (rowId, column) 多条:宿主可后者覆盖前者。
column 对用户不可见(policy 打码 / 列隐藏)时:宿主可仍应用样式,或跳过——推荐跳过不可见列的强调,避免泄露「有问题」的存在感(技能仍可写,宿主按可见性过滤)。

2.1 Grid 文档形状(加法,独立 Schema)

整行 / 整列 / 区域用 Grid Presentation Document(rules[])。与 cells[] 并存,不替代、不升 cells 的 schemaVersion。

统一几何:rows × columns。某一侧为 "all"(或省略,落库时写成 JSON "all")= 该轴全部。禁止两侧都是全部(见 §4.2)。

{
  "schemaVersion": 1,
  "skill": "your-skill-slug",
  "table": "business_records",
  "rowKey": "id",
  "generatedAt": "2026-08-10T06:00:00Z",
  "rules": [
    {
      "ruleKey": "qty-low-rows",
      "rows": ["42", "99"],
      "columns": "all",
      "tone": "danger",
      "message": "库存低于安全线",
      "alert": true
    },
    {
      "ruleKey": "status-column",
      "rows": "all",
      "columns": ["status"],
      "tone": "warning",
      "message": "待审核"
    },
    {
      "ruleKey": "overdue-print-region",
      "rows": ["7", "8"],
      "columns": ["print_done_at", "ship_done_at"],
      "tone": "danger",
      "message": "环节到期未填",
      "alert": true
    }
  ]
}
字段 必填 说明
schemaVersion 是 固定 1
skill / table / rowKey 是 同格子文档;rowKey 用于匹配 rows 里的 id
rules 是 数组;空数组 = 该表清除全部 grid 规则

rules[] 项

字段 必填 说明
ruleKey 是 本表内唯一(建议稳定业务键,便于重算覆盖)
rows 是 "all" 或行 id 字符串数组(对应 rowKey 列值)
columns 是 "all" 或业务列名数组
tone 是 见 §3
message 否 ≤500
alert 否 默认 false;按规则条数计提醒,不按命中格子数
rows × columns 宿主 scope
1 行 × 1 列 cell
若干行 × 若干列(非单格) region
若干行 × "all" row(整行)
"all" × 若干列 column(整列)
"all" × "all" 禁止,宿主丢弃该规则

完整 JSON 例见 ../assets/examples/skill-grid-presentation.example.json。


3. tone 闭集(冻)

tone 语义(技能怎么选) 宿主怎么呈现(示例,主题可调)
danger 必须立刻处理 / 已违规 / 严重超时 强强调(如浅红底)
warning 即将到期 / 需注意 中等强调(如浅黄)
info 提示性标记 轻强调(如浅蓝)
success 正向完成态(少用在「待填」场景) 浅绿等
muted 弱化 / 次要 灰底或灰字

禁止: 技能下发原始 #RRGGBB、任意 CSS class、内联 style。
以后若扩展色板,只能追加新 tone token 并升契约,不能开放任意色值。

「技能配置什么就显示什么」在本契约中的含义是:技能选择 哪一格/行/列 + 哪个 tone + 什么说明;像素级颜色由宿主主题决定,以保证多技能 UI 一致与安全。


4. 推荐持久化(给宿主实现)

v1 推荐技能将「当前表」的格子呈现写入用户库旁路表(与业务表分离,不是多余业务超时列):

CREATE TABLE IF NOT EXISTS _jiangchang_cell_presentation (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  table_name TEXT NOT NULL,
  row_key TEXT NOT NULL,
  row_id TEXT NOT NULL,
  column_name TEXT NOT NULL,
  tone TEXT NOT NULL,
  message TEXT,
  alert INTEGER NOT NULL DEFAULT 0,
  generated_at TEXT,
  updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
  UNIQUE (table_name, row_id, column_name)
);

4.1 整行 / 整列 / 区域(_jiangchang_grid_presentation)

CREATE TABLE IF NOT EXISTS _jiangchang_grid_presentation (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  table_name TEXT NOT NULL,
  rule_key TEXT NOT NULL,
  row_key TEXT NOT NULL DEFAULT '',
  rows_json TEXT NOT NULL,
  columns_json TEXT NOT NULL,
  tone TEXT NOT NULL,
  message TEXT,
  alert INTEGER NOT NULL DEFAULT 0,
  generated_at TEXT,
  updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
  UNIQUE (table_name, rule_key)
);

rows_json / columns_json 存 JSON:字符串 "all",或 id / 列名数组(如 ["42","99"])。
row_key:有限行集合时必填(与文档 rowKey 相同,如 id);整列(rows_json = "all")可空字符串。

两张表都列入技能 INTERNAL_METADATA_TABLES(见 scripts/db/display_metadata.py),不得作为业务表出现在数据管理侧栏。模板 不在 init_db() 里默认建这两张表;技能用到时再 CREATE。

4.2 冲突与特异性

同一格被多条规则命中时,宿主按 格子 > 区域 > 行 > 列 取胜。同级后者覆盖前者。

宿主先加载 grid 规则,再加载 v1 cells[](同级时 v1 格子仍赢),因此旧技能只写 cells[] 的行为不变。

禁止 all × all(会把整张表涂满)。技能不要写;宿主遇到则丢弃该规则。

4.3 表格 vs 详情

表面 整行(scope=row) 格子 / 列 / 区域
数据管理表格 给整行(<tr>)上色 给对应单元格上色
行详情 不把行色铺到每个字段 对应字段可保留 tone

整行强调的是「这一行在表里扎眼」,不是「打开详情后每个值都变色」。

约定:

  • 重算某表时:先删该 table_name 在两张旁路表中的全部行,再插入新结果(或等价事务替换),保证填完后旧 danger 不会残留。只维护其中一张时,至少清掉自己负责的那张,并删掉已迁走的旧行(例如从格子改成整行后,删掉对应 _jiangchang_cell_presentation)。
  • 宿主打开数据管理某表时:若该技能启用了呈现(见 §5)且存在旁路表,则按当前页行的 rowKey 值匹配并着色。
  • 也允许技能用 CLI 打印整份 Document 供调试;运行时以库内旁路表为准(除非后续宿主另定拉取入口)。

未创建该旁路表 = 该通道 P0,宿主忽略。


5. 在 actions.json 中启用(可选,推荐)

与 policy 类似,顶层可选。一份开关同时启用格子与 grid:

{
  "schemaVersion": 1,
  "skill": "your-skill-slug",
  "cellPresentation": {
    "enabled": true
  },
  "actions": []
}
字段 说明
cellPresentation 省略 = P0
cellPresentation.enabled 仅 true 表示宿主应尝试加载呈现(两张旁路表);false/缺省等同 P0

v1 不要求单独 CLI entrypoint(与 policy 不同);技能在 sync / 写路径 / init-db 后自行维护旁路表即可。若未来需要「仅刷新呈现」Action,用普通 Skill Action 即可,不必扩展本启用块。


6. 何时重算(技能必须遵守)

至少在以下时机用同一套 domain 规则重算并覆盖该表呈现:

  1. 全量/增量把外部数据写入本地投影之后(如同步成功)
  2. 会改变「是否仍需强调」的写路径成功之后(新建、更新、登记等)
  3. (可选)用户显式「刷新呈现」类 Action

进页 Toast:宿主可在加载表后统计当前页或全表 alert=1 的规则条数(grid 按规则计,不按命中格子数);0 则不打扰。
提醒关闭 = 重算后没有对应 cell/rule,而不是用户点「我知道了」写死关闭(除非另做忽略列表,本契约不冻)。


7. 与其它契约的关系

契约 关系
SCHEMA / _jiangchang_columns 管列是否可见、类型、中文名;不管条件标色。呈现旁路表须进内部隐藏表集合
POLICY Snapshot 管谁能看哪些 Action/行列;呈现仍建议按可见列过滤
hostEffects / steps 管 Action 跑完后是否 reloadTable;重载后宿主应重新读呈现
业务列真值 保持干净;不要把 【超时】 写进业务字段冒充变色

8. 反模式

  • 为标色新增「超时环节」「时效状态」等业务展示冗余列当作终态方案
  • 技能下发 CSS / 内联颜色
  • 只在首次超时时打标、填完不重算导致红字残留
  • 宿主写死某个技能 slug 的特殊染色逻辑
  • 把 Cell Presentation 做成仅服务 SLA 的专用协议
  • 写 rows: "all" 且 columns: "all" 企图整表变色
  • 假定打开行详情后,整行色会铺到每一个字段
  • 把某一业务技能的检查逻辑(例如「检查列 → 整行」)复制进模板当通用运行时

9. 示例场景(说明用途不限)

场景 几何 tone message 例
打单超时未填 格子 print_done_at danger 打单已超 1 天未填
库存低于安全线 整行(该行 × all) warning 低于安全库存
审核驳回 格子或整列 status danger 已驳回,请修改
选填备注缺失但不紧急 格子 notes muted 建议补充备注
两个日期列同时逾期 区域:若干行 × print_done_at+ship_done_at danger 环节到期未填

格子 JSON 例见 ../assets/examples/skill-cell-presentation.example.json。
Grid JSON 例见 ../assets/examples/skill-grid-presentation.example.json。