8.3 KiB
数据管理单元格呈现(Cell Presentation)契约(v1.0)
状态:正式契约 v1.0(
schemaVersion1)。
目标: 冻结「技能声明某表某行某列的语义呈现 → 宿主映射主题样式」的通用能力,供任意业务场景复用。
非目标: 超时/SLA 专用字段;技能下发任意 CSS / 任意色值;宿主实现业务规则引擎。
配套 Schema:../assets/schemas/skill-cell-presentation.schema.json。
相关正交轴见 ACTIONS.md、POLICY.md、SCHEMA.md。
0. 一句话
技能可以声明:哪张业务表、哪一行、哪一列需要特殊标色/强调(语义 tone + 可选说明)。
用途不限:时效超时未填、库存预警、状态异常、必填缺失、审核驳回等。
不是「再加一列超时文字」;强调落在真正要关注的业务格子上。
0.1 能力档位
| 档位 | 技能行为 | 宿主行为 |
|---|---|---|
| P0(默认) | 不写呈现数据 / 未启用 | 数据管理表格与今日一致,无特殊标色 |
| P1 | 按规则写入呈现文档或推荐旁路表 | 渲染对应单元格的语义样式;可选汇总 alert: true 做进页提醒 |
多数技能保持 P0。需要视觉强调时再启用。
1. 职责边界
| 角色 | 负责 | 不负责 |
|---|---|---|
| 技能 | 按当前业务数据算出哪些格子要强调;在数据变更后重算并覆盖旧结果 | 不写宿主 CSS;不把强调文案污染进业务真值列冒充「变红」 |
| 宿主 | 读取呈现结果,按闭集 tone 映射主题样式;可选 Toast/提醒汇总 |
不理解「提前 3 天交单」等业务规则;不为单个技能写死样式 |
派生状态(重要): 呈现是计算结果,不是粘性开关。
用户补填数据 / 同步刷新后技能重算 → 该项消失 → 样式与提醒自然关闭。不要单独维护「已关闭提醒」状态机(除非产品另做「忽略此条」能力,本契约不冻结)。
2. 文档形状(冻)
技能产出一份 Cell Presentation Document(可落库、可 CLI 打印,形状相同),须符合 Schema。
{
"schemaVersion": 1,
"skill": "add-todo-all",
"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.1 cells[] 项
| 字段 | 必填 | 说明 |
|---|---|---|
rowId |
是 | rowKey 列值的字符串形式 |
column |
是 | 要强调的业务列(snake_case),须真实存在 |
tone |
是 | 见 §3 |
message |
否 | 短说明(≤500);悬停 / 无障碍 |
alert |
否 | 默认 false;true 可计入进页/同步提醒汇总 |
同一 (rowId, column) 多条:宿主可后者覆盖前者。
column 对用户不可见(policy 打码 / 列隐藏)时:宿主可仍应用样式,或跳过——推荐跳过不可见列的强调,避免泄露「有问题」的存在感(技能仍可写,宿主按可见性过滤)。
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)
);
约定:
- 重算某表时:先删该
table_name全部行,再插入新结果(或等价事务替换),保证填完后旧danger不会残留。 - 宿主打开数据管理某表时:若该技能启用了呈现(见 §5)且存在此表,则按当前页行的
rowKey值匹配并着色。 - 也允许技能用 CLI 打印整份 Document 供调试;运行时以库内旁路表为准(除非后续宿主另定拉取入口)。
未创建该旁路表 = P0,宿主忽略。
5. 在 actions.json 中启用(可选,推荐)
与 policy 类似,顶层可选:
{
"schemaVersion": 1,
"skill": "add-todo-all",
"cellPresentation": {
"enabled": true
},
"actions": []
}
| 字段 | 说明 |
|---|---|
cellPresentation |
省略 = P0 |
cellPresentation.enabled |
仅 true 表示宿主应尝试加载呈现;false/缺省等同 P0 |
v1 不要求单独 CLI entrypoint(与 policy 不同);技能在 sync / 写路径 / init-db 后自行维护旁路表即可。若未来需要「仅刷新呈现」Action,用普通 Skill Action 即可,不必扩展本启用块。
6. 何时重算(技能必须遵守)
至少在以下时机用同一套 domain 规则重算并覆盖该表呈现:
- 全量/增量把外部数据写入本地投影之后(如同步成功)
- 会改变「是否仍需强调」的写路径成功之后(新建、更新、登记等)
- (可选)用户显式「刷新呈现」类 Action
进页 Toast:宿主可在加载表后统计当前页或全表 alert=1 的条数;0 则不打扰。
提醒关闭 = 重算后没有对应 cell,而不是用户点「我知道了」写死关闭(除非另做忽略列表,本契约不冻)。
7. 与其它契约的关系
| 契约 | 关系 |
|---|---|
SCHEMA / _jiangchang_columns |
管列是否可见、类型、中文名;不管条件标色 |
| POLICY Snapshot | 管谁能看哪些 Action/行列;呈现仍建议按可见列过滤 |
| hostEffects / steps | 管 Action 跑完后是否 reloadTable;重载后宿主应重新读呈现 |
| 业务列真值 | 保持干净;不要把 【超时】 写进业务字段冒充变色 |
8. 反模式
- 为标色新增「超时环节」「时效状态」等业务展示冗余列当作终态方案
- 技能下发 CSS / 内联颜色
- 只在首次超时时打标、填完不重算导致红字残留
- 宿主写死某个技能 slug 的特殊染色逻辑
- 把 Cell Presentation 做成仅服务 SLA 的专用协议
9. 示例场景(说明用途不限)
| 场景 | column | tone | message 例 |
|---|---|---|---|
| 打单超时未填 | print_done_at |
danger |
打单已超 1 天未填 |
| 库存低于安全线 | qty |
warning |
低于安全库存 |
| 审核驳回 | status |
danger |
已驳回,请修改 |
| 选填备注缺失但不紧急 | notes |
muted |
建议补充备注 |
完整 JSON 例见 ../assets/examples/skill-cell-presentation.example.json。