关于 grid-validator
grid-validator 是用于上传前审计单个 Datex Studio 网格配置的只读技能。它按严重程度列出问题,重点检查通用组件验证器可能遗漏的网格专属契约与数据形状规则。
主要功能
- 01只读审计网格配置
- 02按严重程度列出问题
- 03检查内嵌数据源标识与结构
- 04检查文本转换及实体字段同步
- 05区分网格检查与跨组件连线
适用场景
- 01上传到分支前检查网格
- 02发现数据源封装或实体结构偏差
- 03导入前检查非字符串网格值
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ datex/ skills --skill grid-validator安装后在 Claude Code 中输入/grid-validator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonevals/files/carrier_rates_grid-grid.jsondock_appointments_grid-grid.jsonshipment_exceptions_grid-grid.jsonwave_pick_summary_grid-grid.json详细介绍
网格验证器
针对网格专用编写规则,审查单个 Datex Studio 网格文件(*-grid.json)——这是 grid-creator 编写或修改网格后、将更改合并到分支之前必须通过的最终关卡。此技能仅针对网格:它涵盖通用 component-validator 无法检测到的注意事项(外层结构与主体结构的形状差异、文本显示强制转换、动态筛选器在五处同步、命令式单元格 API 不匹配,以及定制版本与自定义版本的来源)。对于非网格组件文件,请改用 component-validator。
此验证器只读取,不会编辑。它会返回结构化的待办清单(阻断项 / 警告 / 小问题),绝不会重写文件。修复工作由父级(通常是 grid-creator,也可能是用户本人)负责。
另请参阅:
component-validator— 用于非网格组件文件(actions、functions、forms、editors、hubs、storage、selectors、customTypes、backendTests、datasources)的通用分发器。如果grid-validator不可用,则会回退到grid-creator/references/grids.md来处理网格,但通用分发器不涵盖下方列出的网格专用注意事项。另请参阅:
component-wiring-check— 跨组件引用约定(一个组件指向另一个组件)。此验证器只会独立审查单个网格文件;它会标记能在该文件中发现的明显连接漂移(例如,configParameters块未镜像文件自身的inParams),但不会追踪外部引用。
参考资料
- ../grid-creator/references/grids.md — 权威网格参考(外层结构、列、数据源、queryOptions、动态筛选器、命令式单元格 API)
- ../tailoring-overlay/references/tailoring.md — 网格为定制变体(
tailored_*-grid.json)时的覆盖层影子标记规则 - ../datasource-creator/references/odata-datasources.md — 嵌入
datasources[0]的后端数据源的 OData 外层结构规则 - ../datasource-creator/references/flow-datasources.md — 流后端数据源的外层结构规则(网格由函数而非 OData 提供数据时)
- ../component-wiring-check/references/component-wiring.md —
configParameters↔inParams镜像规则和moduleId一致性要求 - ../datex-studio-conventions/file-format.md —
configurationTypeId表、单行压缩 JSON 规则、TypeScript 表达式编码('literal'引号、反引号包裹) - ../datex-studio-conventions/naming-conventions.md — 后缀表、
referenceName↔ 文件名主体规则、tailored_/custom_前缀一致性要求 - ../datex-studio-runtime/runtime-globals.md — 网格 TS 表达式中可用的
$grid.*、$row.*、$col.*运行时全局变量 - ../collection-filter-authoring/SKILL.md — 嵌套筛选器约定、量词模式、运行时执行,以及经过验证的 CLI 行为和仍待完成的实时检查
依赖项
grid-creator— 创建者技能,其references/grids.md是本验证器审核所依据的权威规则手册。更新该文档后,验证器会自动采用新规则。tailoring-overlay— 当网格是定制变体而非基础网格时调用的覆盖层专属影子标记规则。datasource-creator— 应用于嵌入式datasources[0]区块的后端数据源规则(OData 和 flow)。component-wiring-check— 当问题清单发现连线偏差,且父级希望进一步追查时调用的跨组件审核。datex-studio-conventions— 通用的跨领域规则(文件格式、命名、默认值),在网格专属检查清单之上应用。datex-studio-shared/datex-studio-runtime— 网格规则文档中引用的分支设置基础项和平台运行时全局项。component-validator— 用于非网格组件文件的同级通用分发器。二者互斥:网格文件由grid-validator负责;其他任何后缀的文件都交由component-validator处理。
工作流
此技能通常由 grid-creator 在编写流程结束时调用,也可由用户直接调用,例如“在合并前审核此网格”。调用方式是通过 Task 工具分派子 Agent——将下方 ## Sub-agent 部分中的提示词模板与目标文件路径一并提供给子 Agent。
调用(编排端)
- 确认目标是网格主体 — 即父级刚刚编写或修改的网格。分支是事实来源,因此目标应为即将执行
dxs configuration upsert的暂存草稿body.json,或新获取的文件(dxs source explore config <referenceName> --branch <id>,或dxs configuration get grid <id> -b <id> -O envelope.json && jq .json envelope.json > body.json)。其referenceName必须以-grid结尾(覆盖层变体则为tailored_*-grid/custom_*-grid)。如果是其他组件类型,请停止并改由component-validator处理。切勿将持久化的本地src/副本视为权威版本。 - 分派子 Agent — 使用 Task 工具,并采用
## Sub-agent部分中的提示词模板。子 Agent 具有Read、Grep、Glob访问权限;它不会编辑文件。 - 处理问题清单 — 子 Agent 会按严重程度返回 Markdown 问题清单。按以下方式处理每项发现:
- 阻断项 — 必须在执行 upsert 前修复。将修复工作交回
grid-creator。 - 警告项 — 进行审核并决定如何处理。可能是有意为之;子 Agent 不会自行假定意图。
- 细节项 — 可选清理。除非父级正在处理相关区域,否则暂缓处理。
- 阻断项 — 必须在执行 upsert 前修复。将修复工作交回
- 修复后重新验证 — 如果已修复阻断项,请再次运行验证器。验证器开销很低(读取一次并在规则文档中 Grep 一次),应作为推送前的最后一步。
范围约定(验证器的职责)
- 验证器只负责读取,不会编辑。修复由父级负责。
- 验证器返回的是问题清单,不是重写后的内容。
- 验证器审核单个网格文件,不会追查跨组件引用(这属于
component-wiring-check的职责)。 - 验证器不会加载原始 OData 架构文档。如果需要根据实时架构验证嵌入式后端数据源中的实体或属性,验证器会建议父级另行调用
schema-explorer。 - 验证器不会猜测意图。如果规则违规可能是有意为之,会附注并标记为警告项,而不是阻断项。
子 Agent
以下提示词模板由编排器传递给通过 Task 工具分派的子 Agent。子 Agent 为只读模式(Read、Grep、Glob)。
你将依据平台的网格编写规则,验证单个 Datex Studio 网格组件文件(*-grid.json)。你不会编辑文件,而是返回问题清单。
工作流
-
加载目标网格主体。 父级会提供一个 JSON 文件的路径——待暂存以供 upsert 的临时
body.json,或刚从分支获取的配置(其referenceName为<name>-grid、tailored_<name>-grid或custom_<name>-grid)。这是一次性临时文件,不是持久的事实来源副本。请完整读取。压缩后的 JSON 封套是你依据清单进行审查的对象。 -
加载网格规则手册。 阅读
../grid-creator/references/grids.md——其中的检查清单部分就是规则手册。如果文件是定制或自定义来源的叠加层,还要阅读../tailoring-overlay/references/tailoring.md。文档解释了每条规则背后的原因;不要凭记忆重新推导。 -
逐项检查清单。 对于每个问题,记录:
- 严重程度——
blocker(运行时静默失败、导入错误或明确违反规则)、warning(偏差或不一致,可能造成影响,也可能不会)、nit(风格/命名/可选清理)。 - 规则——对应的检查清单条目。
- 位置——
<filename>:<line>或 JSON 路径(例如datasources[0].queryOptionsObjectTypeDef)。 - 证据——简短引文或描述。
- 严重程度——
-
**如果网格由 OData 提供数据,**请验证
queryOptions.selects是否包含实体形状定义位置中声明的所有字段。有关 OData 封套规则,请查阅../datasource-creator/references/odata-datasources.md。如果父级授权调用schema-explorer技能,请用它对照实时 OData 架构确认实体/属性/导航名称;否则,将未经验证的名称标记为警告。如果网格由流程提供数据(后备数据源解析为函数,而非 OData 实体),请查阅
../datasource-creator/references/flow-datasources.md,了解流程数据源封套规则。 -
务必明确检查以下网格特有的故障模式——随意检查清单时可能遗漏这些问题,通用的
component-validator也不会检查:a. 嵌入式数据源组件标识封套(封套形状)。 确认
datasources[0]包含以下所有字段:referenceName(必须与datasourceConfig.configId完全一致)、title、description、hasKey、hasResult、id、linkedDatasources、customColumns、inParams、outParams、vars、events、accessModifier,以及../datex-studio-conventions/file-format.md规定的正确configurationTypeId。同时确认datasourceConfigs数组和componentReference(如存在)与网格自身的封套一致。缺少referenceName属于 blocker——这会导致Invalid contract. Referenced own configuration <name> does not exist or has been renamed,并在导入时连带触发Cannot find name 'get'/'getList'/'inParams'/'refresh'TS 错误。b. 文本显示的字符串强制转换。 对于每个
displayControl.type: "text"且textConfig.value引用$row.entity.<Field>的列,请在最终的outParams[result].objectTypeDef中查找<Field>声明的type。如果类型不是string,绑定必须进行强制转换(例如,数字用"$row.entity.Id?.toString()",组合值用反引号括起的模板字面量,日期用$utils.date.format(...))。未进行强制转换的非字符串绑定属于 blocker——导入会因Type '<number|boolean|...>' is not assignable to type 'string'而失败。请遵循../datex-studio-conventions/file-format.md中的 TS 表达式编码规则:只包含字面文本的声明式字符串槽需要用单引号写成'literal';组合值需要用反引号括起。 c. 实体形状的五处同步。 当网格中的任何位置绑定了基础实体字段时,确认该字段出现在 grids.md → Datasource Wiring — Five Places Must Stay in Sync 所述的五个实体形状位置中:(1)datasources[0].queryOptionsObjectTypeDef,(2)datasources[0].outParams[result].objectTypeDef,(3)datasources[0].getListFlow.outParams[result].objectTypeDef,(4)datasources[0].getByKeysFlow.outParams[result].objectTypeDef,(5)datasourceConfig.configOutParameters[result].objectTypeDef。对于 OData 支持的数据源,位置 3 和 4 为null——跳过这两处,但该字段还必须出现在datasources[0].queryOptions.selects中(第六处,仅运行时使用,负责实际获取字段的位置)。任何必需位置存在偏差都是阻断问题——$row.entity上的字段将为undefined,或导入失败并出现契约错误。对于关联/自定义输出字段,请根据 output-contracts.md 检查最终公开结果及其使用方快照,而不是将派生字段插入基础实体。使用服务器生成的上下文检查方法结果形状。Flow 分页的
totalCount属于getListFlow,而非顶层组件/引用。d. 动态筛选/排序注册同步。 当列声明了动态筛选或排序时,确认 grids.md → Dynamic Filters and Sorting 中所述的两部分均已就绪:(1)字段已在两个顶层位置注册——
datasources[0].dynamicFilters/dynamicOrderBys(嵌入式数据源侧)以及datasourceConfig.dynamicFilters/dynamicOrderBys(使用方侧),且条目完全一致;(2)列包含其逐列接线配置(dynamicFilter、dynamicOrderBy、dynamicFilterType、dynamicFilterControl),其中dynamicFilter使用已注册的普通属性路径(例如Lines.Quantity),而dynamicOrderBy与标量排序注册/上下文一致。对于集合导航筛选,请遵循 collection-filter-authoring:验证嵌套对象边界、保留的标志、生成的量词常量、网格模式和实际 Flow 执行情况;不要将生成的$any/$all运行时常量放入持久化属性 ID 或网格列的普通路径dynamicFilter中。两个注册位置之间存在偏差是阻断问题——导入失败并出现Outdated contract. Type mismatch for dynamic filtering/sorting。不要因为任何inParams列表中缺少$filter/$orderby而标记问题——这些参数会根据注册信息自动注入,手动添加本身才是错误。e. 命令式单元格 API 不匹配。 配置为单元格点击的列会触发其
onCellClickFlowConfig中指定的 Flow(通常位于rowFlows下);确认该 Flow 存在于网格的flows/rowFlows块中(或关联的 Flow 文件中)。行/网格 Flow 中的命令式写入使用 grids.md → Imperative Cell API 中所述的单元格接口:$row.cells.<col>.displayControl.text/.displayControl.value、$row.cells.<col>.editControl.value,以及只读的$row.cells.<col>.editControl.isChanged。引用了不存在定义的单元格点击 Flow 是阻断问题;向不存在的单元格接口或列执行命令式写入则是警告。 f. Tailored 与 custom 来源规范一致性。 如果文件名主体以tailored_开头,则该文件是覆盖文件,除基础网格的检查清单外,还须遵循../tailoring-overlay/references/tailoring.md中的阴影标记规则。如果文件名主体以custom_开头,则该文件是客户专用变体,须遵循../datex-studio-conventions/naming-conventions.md中的custom_来源规则。混用两个前缀(例如tailored_custom_foo-grid.json)或在 tailored 变体中省略前缀,均属于阻断项。g.
$grid.*运行时用法。 如果网格在 TS 表达式中使用$grid.*/$row.*/$col.*全局变量,请根据../datex-studio-runtime/runtime-globals.md确认这些全局变量存在且用法正确。未知的全局标识符属于阻断项(导入时会出现 TS 错误);已弃用的全局变量属于警告。 -
始终检查通用的跨领域故障模式,即使网格检查清单没有重述这些内容。这些规则统一列于
../datex-studio-conventions/universal-checklist.md中——逐项检查(描述 ≤ 100 个字符,已设置accessModifier,referenceName↔ 文件名主体,单行压缩 JSON,正确的configurationTypeId,新建inParams/outParamsID 使用 snake_case,若为全新项目则id: 0)。另加一项与网格相关的连线检查:- 存在
configParameters块时,它应与文件自身的inParams保持一致,具体参见../component-wiring-check/references/component-wiring.md。如果验证器仅凭网格文件就能发现不一致,则标记为警告(建议让父级调用component-wiring-check执行完整的跨组件审计)。
- 存在
-
报告。 返回按严重程度分组的简短 Markdown 问题清单,每项一到两行。不要添加前言,不要改写文件,也不要提供代码建议(单行指引除外)。如果没有问题,请回复
No issues found.
范围限制
- 只读,不编辑。
- 返回问题清单,不返回改写后的文件。
- 不要追查其他组件文件中的引用——跨组件连线属于
component-wiring-check的职责。如果仅凭网格文件就能明显发现连线问题,请标记出来,由父级决定是否跟进。 - 不要加载原始 OData 架构文档。如果需要验证实体 / 属性 / 导航,请建议父级单独调用
schema-explorer技能。 - 不要臆测意图——如果违规可能是有意为之(例如合法地通过命令式方式填充空的
displayControl.value),请附注标记为警告,而非阻断项。 - 如果该文件不是网格(后缀不是
-grid.json,也不是覆盖变体tailored_*-grid.json/custom_*-grid.json),请回复Cannot validate: file is not a grid. Route to component-validator instead.并停止。
输出格式
## Blockers
- [`datasources[0].queryOptionsObjectTypeDef`] `warehouse_id` missing (present in locations 2, 3, 4, 5). Entity-shape five-location sync drift.
- [`datasourceConfig.dynamicFilters`] `warehouse_id` registered on `datasources[0].dynamicFilters` but missing here. Dynamic-filter registration drift.
- [`columns[2].textConfig.value`] `$row.entity.OrderTotal` is `number`; needs `.toString()` coercion or template-literal wrapping.
## Warnings
- [`columns[3].dynamicFilter`] targets `accounts` (primitive array) directly; needs a scalar sidecar for joined-display matching. Object-collection scalar leaves use the quantified-filter workflow instead.
- [`columns[5].onCellClickFlowConfig`] references flow `confirmDelete`, which is not defined in `flows` / `rowFlows`.
## Nits
- [`description`] 118 chars — exceeds the ≤100-char soft limit.
- [`title`] equals `referenceName`; a human-readable title is more discoverable in Datex Studio listings.
省略任何内容为空的类别。如果三个类别都为空,请返回 No issues found.