# 数据管理单元格呈现(Cell Presentation)契约(v1.0) > **状态:正式契约 v1.0(`schemaVersion` 1)。** > **目标:** 冻结「技能声明某表某行某列的语义呈现 → 宿主映射主题样式」的通用能力,供任意业务场景复用。 > **非目标:** 超时/SLA 专用字段;技能下发任意 CSS / 任意色值;宿主实现业务规则引擎。 > **配套 Schema:** [`../assets/schemas/skill-cell-presentation.schema.json`](../assets/schemas/skill-cell-presentation.schema.json)。 相关正交轴见 [`ACTIONS.md`](ACTIONS.md)、[`POLICY.md`](POLICY.md)、[`SCHEMA.md`](SCHEMA.md)。 --- ## 0. 一句话 技能可以声明:**哪张业务表、哪一行、哪一列**需要特殊标色/强调(语义 `tone` + 可选说明)。 用途不限:时效超时未填、库存预警、状态异常、必填缺失、审核驳回等。 **不是**「再加一列超时文字」;强调落在**真正要关注的业务格子**上。 --- ## 0.1 能力档位 | 档位 | 技能行为 | 宿主行为 | |------|----------|----------| | **P0(默认)** | 不写呈现数据 / 未启用 | 数据管理表格与今日一致,无特殊标色 | | **P1** | 按规则写入呈现文档或推荐旁路表 | 渲染对应单元格的语义样式;可选汇总 `alert: true` 做进页提醒 | 多数技能保持 **P0**。需要视觉强调时再启用。 --- ## 1. 职责边界 | 角色 | 负责 | 不负责 | |------|------|--------| | **技能** | 按**当前业务数据**算出哪些格子要强调;在数据变更后**重算**并覆盖旧结果 | 不写宿主 CSS;不把强调文案污染进业务真值列冒充「变红」 | | **宿主** | 读取呈现结果,按闭集 `tone` 映射主题样式;可选 Toast/提醒汇总 | 不理解「提前 3 天交单」等业务规则;不为单个技能写死样式 | **派生状态(重要):** 呈现是计算结果,不是粘性开关。 用户补填数据 / 同步刷新后技能重算 → 该项消失 → **样式与提醒自然关闭**。不要单独维护「已关闭提醒」状态机(除非产品另做「忽略此条」能力,本契约不冻结)。 --- ## 2. 文档形状(冻) 技能产出一份 **Cell Presentation Document**(可落库、可 CLI 打印,形状相同),须符合 Schema。 ```json { "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.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 **推荐**技能将「当前表」的呈现写入用户库旁路表(与业务表分离,**不是**多余业务超时列): ```sql 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` 类似,顶层可选: ```json { "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` 的条数;**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`](../assets/examples/skill-cell-presentation.example.json)。