关于 selector-creator
selector-creator 用于在分支上创建和修改 Datex Studio 下拉选择器及自动补全选择器,并指导数据源接线、配置验证和安全往返编辑。
主要功能
- 01创建和修改选择器配置
- 02连接选择器与数据源
- 03配置全文搜索
- 04推送前验证配置
适用场景
- 01构建实体数据下拉列表
- 02创建枚举选项列表
- 03为表单或筛选器添加自动补全
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ datex/ skills --skill selector-creator安装后在 Claude Code 中输入/selector-creator确认已加载。
附带文件evals/evals.jsonreferences/selectors.md
详细介绍
Selector 创建器
在分支上创建或修改 Datex Studio selector(configurationTypeId=7)——平台的下拉列表/自动补全控件。Selector 定义了由数据源支持的选项列表、用于显示每个选项标签的表达式,以及一个内置的全文搜索框,该搜索框会将输入内容转发到后端数据源。它们会挂载在表单字段、hub 筛选器下拉列表和网格筛选单元格中;不会独立渲染。
参考资料
- ../datex-studio-shared/branch-setup.md — 分支/连接选择(多个技能共用)
- references/selectors.md — 权威的 selector 编写参考:组件变体规则、文件结构、数据源连接、全文搜索三部分约定、getList ↔ getByKeys 一致性
- ../datex-studio-conventions/file-format.md —
configurationTypeId表和 TypeScript 表达式编码规则 - ../datex-studio-conventions/naming-conventions.md —
_dd后缀约定、文件名主体匹配、显示名称规则 - ../datex-studio-runtime/runtime-globals.md — Selector 代码中可用的平台注入全局变量(
$selector、$option、$flows、$utils等) - ../datex-studio-runtime/calling-conventions.md — UI 层调用规则(调用函数,绝不调用操作)
- ../datasource-creator/references/datasources.md — 数据源分类(组件变体
-datasource.json与 FPDS-footprintDatasource.json) - ../datasource-creator/references/flow-datasources.md — 流类型数据源结构(枚举下拉列表、计算得出的选项集)
- ../datasource-creator/references/odata-datasources.md — OData 类型数据源结构(实体驱动的下拉列表)
- ../component-wiring-check/references/component-wiring.md — 调用方约定规则、moduleId 规则
- ../form-creator/references/forms.md — 典型挂载位置(表单字段)
- ../hub-creator/references/hubs.md — 典型挂载位置(hub 筛选器下拉列表)
依赖项
requirements-gathering技能 — 如果当前对话上下文中尚无需求简介,则调用此技能生成一份datasource-creator技能 — 当 selector 需要新的后端数据源时调用(即尚无可供其封装的-datasource.json的 selector)。提醒:后端必须是-datasource.json,绝不能是-footprintDatasource.jsonschema-explorer技能 — 在编写 OData 后端 selector 之前调用,以确认实体、显示标签字段以及任何筛选字段均存在于 Footprint 架构中form-creator/hub-creator技能 — 当 selector 的宿主(表单字段或 hub 筛选器下拉列表)需要设置configParameters约定以挂载 selector 时调用component-wiring-check技能 — 推送前调用,以审计 selector 宿主(外层)和 selector 后端数据源(内层)的configParameters↔ 目标inParams约定,尤其是full_text_search连接type-definition-creator技能 — 当 selector 的选项实体结构需要新增或扩展接口时调用(较少见;大多数 selector 会沿用现有数据源的outParams)
CLI 生命周期
选择器编写通过 dxs configuration 完成——这是适用于所有平台配置类型的通用 CRUD 基元。没有 dxs selector 子命令,也不支持字段级别的补丁;你需要构建(或获取并提取)完整的 JSON 正文,编辑后再将其整体推回。CLI 中的类型标识符为 selector(小写,与 ConfigurationEndpoints.normalize_type 的输出一致),对应 configurationTypeId: 7。
创建新的选择器:
# 1. Build body.json from scratch (see references/selectors.md → Datasource-Backed Selector)
# 2. Validate — gates the push. Exit 1 = errors found (read validation_errors, fix, re-run), not a broken CLI
dxs configuration validate selector -b <branchId> -D body.json
# 3. Create
dxs configuration upsert selector -b <branchId> -D body.json
编辑现有选择器:
# 1. Fetch — note the envelope wrapper
dxs configuration get selector <configId> -b <branchId> -O envelope.json
# 2. EXTRACT THE INNER BODY (round-trip footgun guard — see "Round-trip rule" below)
jq .json envelope.json > body.json
# 3. Edit body.json
# 4. Validate — gates the push. Exit 1 = errors found (read validation_errors, fix, re-run), not a broken CLI
dxs configuration validate selector -b <branchId> -D body.json
# 5. Push
dxs configuration upsert selector -b <branchId> -D body.json
往返规则(重要)
编辑现有配置时,绝不要将 envelope.json 直接传递给 dxs configuration upsert——这会悄无声息地破坏配置内容。上面的更正后流程(先用 jq 提取内部的 .json,再进行编辑)对任何往返操作都是强制要求。规范的往返流程及其底层 Bug,请参阅 ../datex-studio-shared/configuration-roundtrip.md。
与网格或表单相比,选择器的结构更精简——正文主要包含 datasourceConfig(含 configId、moduleId、datasourceKeyDef、configParameters、configOutParameters)、作为显示标签表达式的 text、字符串 top,以及组件标识信封。全文搜索的接线贯穿选择器及其底层数据源——两者都必须遵循往返规范(获取 → jq 提取 → 编辑 → 验证 → 推送)。
工作流
[Phase 1: Setup + Requirements]
Follow branch-setup.md for branch/connection selection
|
[requirements brief in context?]
+-----+-----+
| |
YES NO -> invoke `requirements-gathering`
| |
+-----+------+
|
[Phase 2: Decide selector shape + backing source]
Consult references/selectors.md:
- datasource-backed dropdown (most common) — wraps an existing or new
`-datasource.json` (flow-type or OData-type query inside)
- autocomplete — same shape; the dropdown's built-in full-text search
box plus the three-piece contract makes it an autocomplete
- enum dropdown — flow-type backing iterating $types.<Package>.<enum>
with formatKey helpers, getList/getByKeys parity required
Backing-datasource source:
- existing `-datasource.json` -> wrap it; verify keyDef/outParams; flow-type
backing must be the keyed-collection shape (getListFlow + getByKeysFlow
populated, non-empty keyDef) — getList-only cannot resolve selected labels
- existing `-footprintDatasource.json` (FPDS) -> NOT ALLOWED as backing;
wrap the FPDS in a flow-type `-datasource.json` that calls through,
or invoke `datasource-creator` for a fresh one
- no datasource yet -> invoke `datasource-creator`; for OData-backed
options invoke `schema-explorer` first to confirm the entity
|
[Phase 3: Author selector body]
Build body.json:
- File shape (configurationTypeId=7, *-selector.json suffix,
referenceName typically ends _dd, snake_case matches filename stem)
- Hard component-variant rule — datasourceConfig.configId points to a
`-datasource.json` (configurationTypeId=6), NEVER a
`-footprintDatasource.json` (configurationTypeId=19); query type
inside the backing is unconstrained (flows or oDataQuery)
- Key wiring — datasourceKeyDef mirrors the datasource's keyDef;
configId + moduleId resolve to the backing; moduleId is the
DATASOURCE's package, not the selector's caller
- configOutParameters mirrors the datasource's outParams shape with
full property-descriptor boilerplate on every objectTypeDef entry
- text — display-label expression on $option.entity.<DisplayField>
- top — STRING ("25"), not a number
- Sort by display label — when authoring the backing datasource for
this selector, sort by the field referenced in text (OData orderBys
or in-code sort for flow-type)
- Full-text-search three-piece contract (when backing exists solely
for this selector): (1) backing declares full_text_search inParam
(string, required: false); (2) backing applies conditional
contains-filter on the display-label field gated on
$utils.isDefined; (3) selector wires $selector.fullTextSearch into
the datasource's full_text_search via configParameters
- getList ↔ getByKeys parity — if getListFlow applies a Key transform
(formatKey, etc.), getByKeysFlow MUST apply the identical transform
(duplicate the helper definitions inside both code bodies — flows
don't share scope)
- No $types.<Package>.e_<enum> in vars/inParams/outParams — primitives
only at the param layer; cast at usage in flow code
- Sibling *Config keys explicitly null
- Invoke `schema-explorer` for OData entity / display-label / filter
field validation before authoring OData-backed selectors
- Invoke `component-wiring-check` to audit BOTH the outer host
contract (form field / hub filter / grid filter cell) AND the inner
selector → datasource contract (every declared backing inParam,
including full_text_search, needs an explicit configParameters
entry)
|
[Phase 4: Validate + push]
dxs configuration validate selector -b <branchId> -D body.json
|
+----+----+
| |
CREATE MODIFY-EXISTING
| |
| use the corrected round-trip
| (get -O envelope -> jq .json -> body)
| |
+----+----+
|
v
dxs configuration upsert selector -b <branchId> -D body.json
(upsert creates or updates by referenceName — one command for both)
|
[Phase 5: Verify in Studio (optional)]
Open the selector through its normal mount (form field / hub filter);
confirm option population, alphabetized order by display label,
full-text-search filtering live as you type, saved-selection re-hydration
shows the same display label getList showed (getByKeys parity)
|
[invoke `post-edit-verification`; then `component-validator`]
阶段详情
阶段 1:设置 + 需求
- 按照 ../datex-studio-shared/branch-setup.md 选择分支和连接。绝不要假定分支 ID——请用户确认。
- 检查对话上下文中是否已有需求简报(由
requirements-gathering或其他调用技能生成)。- 已有简报——使用该简报。简报应说明下拉列表表示什么(实体、枚举或计算列表)、用户看到的显示标签、保存的选择所持久化的底层 Key/Value、选择器的挂载位置(表单字段 / 中心筛选器 / 网格筛选单元格),以及是否需要自动补全行为。
- 没有简报——先调用
requirements-gathering技能。事先确认显示标签、保存的 Key 和挂载位置,可以避免重新编写text、datasourceKeyDef和宿主的configParameters。
阶段 2:确定选择器形态和后端数据源
编写前请参阅 references/selectors.md。需要确定两项内容。
选择器形态。 三种常见形态:
- 数据源支持的下拉菜单 — 标准形态。包装现有或新建的
-datasource.json,并将其outParams呈现为选项。通过text: "$option.entity.<DisplayField>"设置显示标签。 - 自动补全 — 与数据源支持的下拉菜单形态相同;其自动补全特性来自下拉菜单内置的全文搜索框和三部分契约(参见 references/selectors.md → Full-Text Search Wiring),使输入的字符能够实时筛选选项。
- 枚举下拉菜单 — 流程类型后端数据源遍历
$types.<Package>.<enum>并输出{ Key, Value }行;formatKey/capitalize辅助函数用于构造显示标签。要求getList与getByKeys保持一致(参见 references/selectors.md → getList ↔ getByKeys Key Transformation Parity)。
后端数据源。 选项集来自哪里?
- 现有的
-datasource.json— 将其包装起来。验证keyDef和outParams的形态;选择器的datasourceKeyDef和configOutParameters必须与其一致。分支中的服务器端使用门禁会阻止发布不实现getList和getByKeys的后端数据源——本节要求的也是这种键控集合形态。 - 现有的
-footprintDatasource.json(FPDS) — 不得用作选择器的后端数据源。这是平台硬性规则。请将 FPDS 包装在一个通过调用 FPDS 获取数据的流程类型-datasource.json中,或者调用datasource-creator创建一个返回相同形态的新数据源。 - 尚无数据源 — 调用
datasource-creator。对于基于 OData 的数据源,请先调用schema-explorer,确认 Footprint 架构中存在该实体、显示标签字段以及任何筛选字段。
阶段 3:编写选择器主体
根据 references/selectors.md → Datasource-Backed Selector 中的骨架构建 body.json。要点如下:
-
文件基础要求。 遵循下方的 飞行前检查清单和 ../datex-studio-conventions/universal-checklist.md;有关
-selector.json文件形态,请参阅 references/selectors.md → Datasource-Backed Selector。referenceName上的_dd下拉菜单指示符是选择器专用的命名提示。 -
组件变体硬性规则。
datasourceConfig.configId+moduleId必须指向一个-datasource.json(configurationTypeId: 6),绝不能指向-footprintDatasource.json(FPDS,configurationTypeId: 19)。这是没有例外的平台硬性规则。后端数据源中的查询类型不受限制——可以是流程类型(type: "flows",用于枚举下拉菜单和计算列表),也可以是 OData 类型(type: "oDataQuery",用于从数据库实体获取选项)。简而言之:选择器关注的是组件变体,而不是查询类型。如果现有 FPDS 已提供所需数据,请将其包装在一个通过调用 FPDS 获取数据的流程类型-datasource.json中;不要让选择器直接指向 FPDS。参见 references/selectors.md → Backing Datasource Variant — Hard Rule。 -
关键连线。
datasourceConfig.configId+moduleId用于标识底层数据源;moduleId是数据源的包,而不是选择器调用方的包。datasourceConfig.datasourceKeyDef与数据源的keyDef保持一致(id 相同、类型相同)——这里不一致会导致通过getByKeys重新填充已保存的选择项失败。datasourceConfig.configParameters将选择器输入(例如$selector.fullTextSearch)连线到数据源的 inParams。datasourceConfig.configOutParameters与数据源的outParams结构保持一致——使用相同的objectTypeDef条目,并包含完整的参数描述符样板代码。请参阅 references/selectors.md → Key Points。 -
text是显示标签表达式。 通常为"$option.entity.<DisplayField>"(例如"$option.entity.Name"、"$option.entity.Key")。下拉列表渲染时,会为每个选项执行一次该表达式。对于底层返回由formatKey定义的{ Key, Value }行的枚举下拉列表,规范的显示表达式是"$option.entity.Key"。 -
top是字符串,不是数字。"25"控制下拉列表显示的项目数量。JSON 数字25会导致导入失败——平台的参数槽位需要 TS 表达式字符串字面量。 -
按显示标签排序。 如果你是专门为此选择器编写底层数据源,请按
text中引用的字段对结果排序。对于 OData 类型的底层数据源,请在该字段上添加orderBys条目;对于流程类型的底层数据源,请在返回前于代码中对数组排序。显示Name的task_status_dd选择器,其数据源应按Name升序排序——用户会立即看到按字母顺序排列的选项,而不是按插入顺序或数据库返回的顺序排列。请参阅 references/selectors.md → Key Points。 -
全文搜索三部分约定。 适用于底层数据源专门用于为此选择器提供支持的情况。供其他流程/操作使用的独立数据源不受此约定约束。以下三个相互关联的要求缺一不可,否则下拉列表的内置搜索会显得失效:
- 底层数据源将
full_text_search声明为 inParam——id 必须恰好为该值,type: "string",required: false。 - 底层数据源对显示标签字段(即
text中引用的字段)应用条件 contains 筛选器,并以$utils.isDefined($datasource.inParams.full_text_search)作为条件,这样输入为空时会停用筛选器。OData 类型:采用规范的contains(<LabelField>, ${$utils.odata.formatString(...)})形式,并设置hasCondition: true和条件表达式。流程类型:在getListFlow代码中通过以下方式添加保护:if ($utils.isDefined($flow.inParams.full_text_search)) { rows = rows.filter(r => r.<LabelField>.toLowerCase().includes((... as string).toLowerCase())); }。 - 选择器将
$selector.fullTextSearch连线到数据源的full_text_search输入,通过datasourceConfig.configParameters条目实现,其value为"$selector.fullTextSearch"。
配合
top: "25"和“按显示标签排序”,这构成了自动补全行为的基准。遗漏任何部分都会导致用户输入时下拉列表响应迟缓。请参阅 references/selectors.md → Full-Text Search Wiring。 - 底层数据源将
-
getListFlow↔getByKeysFlow的 Key 转换一致性。 用户打开下拉列表时,平台会调用getListFlow填充选项;对于之前保存的 Value,平台会调用getByKeysFlow重新获取可显示的记录。如果getListFlow应用了 Key 转换(例如,使用formatKey将ParentOfTarget转换为Parent of target,或进行其他标签调整),getByKeysFlow必须应用相同的转换——否则,保存的选项会在通过getByKeys往返后返回原始枚举 ID,导致下拉控件在编辑时显示ParentOfTarget,重新加载后却显示Parent of target。formatKey/capitalize辅助函数是在每个 flow 的code主体内声明的嵌套函数——两个 flow 中都要重复定义相同的函数;平台会分别编译每个 flow,它们的作用域不共享。基于 OData 类型的数据源很少会遇到这种情况(其getByKeys根据keyDef自动生成,并选择原始列),但如果 OData 查询选项包含计算列或列别名,列表加载时使用的投影必须与键查找时使用的投影一致。请参阅 references/selectors.md → getList ↔ getByKeys Key 转换一致性。 -
vars/inParams/outParams中不能使用自定义枚举 FQN。 选择器无法解析参数声明中的$types.<Package>.e_<enum>——请将这些字段声明为原始类型(字符串值枚举使用string,数值枚举使用number),并在 flow 代码中使用时进行类型转换。枚举数据源选择器最容易遇到这个问题,因为作者最希望将枚举类型用于数据源的outParams.result.objectTypeDef[Value]。 -
同级的
*Config键显式设为 null。 标准的数据源选择器中,customOptionsConfig、actionConfig、onInitFlowConfig和所有其他未启用的子配置都应显式设为null。遵循此约定以便进行结构差异比较——现有选择器组件会保留所有同级槽位,并将其设为 null。 -
遵循调用层级规范。 选择器代码(
onInitFlowConfig、flows[]中的任何条目)通过$flows.<Package>.<fn>调用函数;函数将任何 CRUD 操作调用封装为$apis.<Package>.FootprintApi.extendedActions.<action_name>({...})。选择器代码不得直接调用操作。请参阅 ../datex-studio-runtime/calling-conventions.md。 -
审核宿主契约。 每个挂载此选择器的宿主(表单字段、中心筛选器下拉列表、网格筛选单元格)都必须声明完整的
configParameters契约——选择器声明的每个inParam都必须在宿主上有对应条目,包括未使用且value: null的条目。运行component-wiring-check,审核两侧的引用契约——外层宿主 → 选择器契约,以及内层选择器 → 数据源契约(选择器读取的每个数据源inParam,包括full_text_search,都需要在选择器上有显式的configParameters条目,不得自动连线)。请参阅 ../component-wiring-check/references/component-wiring.md。
阶段 4:验证并推送
# Validate the body locally against the branch. Exit 1 = validation found errors
# (read validation_errors, fix body.json, re-run) — not a broken CLI. Do not push on exit 1.
dxs configuration validate selector -b <branchId> -D body.json
# For a new selector
dxs configuration upsert selector -b <branchId> -D body.json
# For modify-existing (round-trip — never skip the jq extract)
dxs configuration get selector <configId> -b <branchId> -O envelope.json
jq .json envelope.json > body.json
# ... edit body.json ...
dxs configuration upsert selector -b <branchId> -D body.json
验证会在推送前发现缺少必填字段、参数描述符格式错误、未定义的 flow ID 引用以及引用错误。但它无法捕获组件变体规则(指向 -footprintDatasource.json 的选择器会通过架构验证,却会在上传时或运行时失败)、未排序选项问题、未完整连线的全文搜索契约,或 getList ↔ getByKeys Key 转换不一致——这些都是行为问题,只有在上传时验证或下拉列表的运行时才会显现。推送前请逐项检查下方的预检清单。
阶段 5:在 Studio 中验证(可选)
通过常规挂载方式打开选择器(表单字段、hub 筛选器下拉菜单或网格筛选单元格),并确认:
- 选项从后端数据源填充,而不是空白、不是本应由
formatKey处理却仍为原始枚举 ID,也没有重复项。 - 选项按显示标签字段(
text引用的字段)按字母顺序排列,从而确认后端的orderBys/ 代码内排序已生效。 - 在搜索框中输入内容可实时筛选选项集,从而确认全文搜索契约的三个部分均已接通(数据源声明了 inParam、应用了条件筛选,选择器通过
configParameters接通$selector.fullTextSearch)。 - 保存所选项,关闭表单/对话框后重新打开——已保存的 Value 会重新载入,并显示与
getListFlow所呈现的相同显示标签(确认getByKeysFlow的 Key 转换一致)。 - 挂载中的
moduleId能解析到选择器——导入日志中没有Referenced configuration <name> does not exist错误。
如果无法使用正在运行的应用,请重新获取配置(使用修正后的 jq .json 提取模式),并与 body.json 比较差异,以确认推送已生效。
推送前检查清单
推送前,请逐项检查此清单。快速版如下:
- 组件变体。 后端文件是
-datasource.json(configurationTypeId: 6),而不是-footprintDatasource.json(configurationTypeId: 19)。其中的查询类型可以是 flows 或 oDataQuery。 - 文件基本信息。 后缀为
-selector.json;configurationTypeId: 7;referenceName通常以_dd结尾——并且符合通用检查项(../datex-studio-conventions/universal-checklist.md)。 - 数据源接线契约。
configId+moduleId解析到真实数据源(moduleId= 数据源所属的包)。datasourceKeyDef与数据源的keyDef保持一致。configOutParameters与outParams保持一致,并包含完整的参数描述符样板代码。 - 显示表达式。
text引用$option.entity.<field>上的真实字段。 top是字符串("25"),而不是数字。- 数据源按显示标签字段排序(OData
orderBys或流程代码中的排序)——选项默认按字母顺序排列。 - 当后端数据源仅供此选择器使用时,须完整接通全文搜索。 包含三个部分:后端声明
full_text_searchinParam(字符串,required: false);后端对显示标签字段应用以$utils.isDefined为条件的 contains 筛选;选择器通过configParameters将$selector.fullTextSearch接通到后端的full_text_search。 getListFlow↔getByKeysFlow的 Key 转换一致性。 如果getListFlow应用了 Key 转换(formatKey等),getByKeysFlow也应用相同的转换。辅助函数(formatKey、capitalize)需在两个code主体中重复定义——flows 会独立编译。vars/inParams/outParams中没有$types.<Package>.e_<enum>——参数层仅使用基本类型;在流程代码中使用时再进行类型转换。- 同级的
*Config键显式设为 null——标准的基于数据源的选择器中,customOptionsConfig、actionConfig、onInitFlowConfig等保持为null。 - 符合调用层级要求——选择器代码通过
$flows.<Package>.<fn>调用函数;函数通过$apis.<Package>.FootprintApi.extendedActions.<action_name>({...})包装 CRUD 操作;选择器不直接调用操作。 - 宿主包含完整的
configParameters契约——选择器声明的每个 inParam 在宿主(表单字段 / hub 筛选器 / 网格筛选单元格)上都有对应条目;未使用的参数使用value: null。使用component-wiring-check进行审计。 - 内部数据源契约。 选择器自身的
datasourceConfig.configParameters覆盖后端数据源声明的每个 inParam——包括full_text_search(不会自动接线;需要显式添加value: "$selector.fullTextSearch"条目)。
常见错误
| 错误 | 修正方法 |
|---|---|
选择器指向了 -footprintDatasource.json(FPDS,configurationTypeId: 19) | 硬性平台规则:底层配置必须是 -datasource.json(configurationTypeId: 6)。如果 FPDS 中包含所需数据,请将其封装在一个会调用 FPDS 的 flow 类型 -datasource.json 中;不要让选择器指向 FPDS。 |
| 混淆组件变体与查询类型——认为“OData 下拉框意味着底层配置是 FPDS” | 选择器关注的是组件变体,而不是查询类型。基于 OData 的下拉框完全没问题,但 OData 查询必须位于 -datasource.json(type: "oDataQuery")中,而不是 FPDS 中。 |
使用 top: 25(JSON 数字),而不是 top: "25"(TS 表达式字符串) | 该槽位要求字符串字面量。数字 25 会导致导入失败。始终加引号。 |
text: "$option.entity.<field>" 中的 <field> 在数据源的 outParams 中不存在 | text 针对 $option.entity 执行——选项行的结构由数据源的 outParams[result].objectTypeDef 决定。选择实际存在的字段,或将该字段添加到数据源中。 |
| 底层数据源按插入顺序返回选项;用户抱怨下拉框顺序“随机” | 在显示标签字段上添加 orderBys(OData),或在代码中排序(flow 类型)。用户期望选项按字母顺序排列。 |
fullTextSearch 已挂载,但输入字符后选项集没有筛选 | 三部分约定只接通了一部分。请确认:(1) 底层配置声明了 full_text_search inParam;(2) 底层配置对显示标签字段应用了条件筛选;(3) 选择器的 datasourceConfig.configParameters 中包含 full_text_search 条目,且其值为 value: "$selector.fullTextSearch"。这三部分都不会自动接通。 |
getListFlow 对 Key 投影使用 formatKey(key),但 getByKeysFlow 返回原始 camelCase 枚举 ID | 已保存的选择往返后会以原始值呈现,而下拉框选项显示的是格式化后的值。在 getByKeysFlow.code 中复制完全相同的 formatKey 表达式(以及辅助函数定义)——各 flow 独立编译,不共享作用域。 |
在选择器的 vars / inParams / outParams 中引用 $types.<Package>.e_<enum> | UI 组件无法在参数层解析自定义枚举 FQN。请将其声明为基本类型(字符串值枚举用 string,数值枚举用 number),并在 flow 代码中使用时进行类型转换。 |
datasourceKeyDef 与底层配置的 keyDef 不一致(ID 或类型不同) | 通过 getByKeysFlow 重新加载已保存选择时会失败或返回错误记录。这两个 keyDef 必须完全一致。 |
configOutParameters 将描述符样板精简为只有 {id, type} | 平台要求每个条目都具有完整的属性描述符结构(required、description、oneOf、fromBaseConfiguration、objectTypeDef、objectType、isCollection、isSecured、isConstant、constantValue)。请使用与底层配置 outParams 相同的结构。 |
选择器 datasourceConfig 上的 moduleId 被设为选择器所在的包,而不是数据源所在的包 | 跨组件引用规则——moduleId 始终指向目标组件所在的包。数据源位于其注册位置。请参阅 ../component-wiring-check/references/component-wiring.md。 |
选择器自身的 vars / inParams / outParams 字段在 flow 代码中使用,却未在顶层声明 | 导入错误:Property 'vars' does not exist on type 'ISelector'。请在对应的顶层数组中声明每个 var / inParam / outParam,并使用标准属性描述符结构。 |
遗漏了同级的 *Config 槽位(例如,只填充了 datasourceConfig,完全缺少 customOptionsConfig / actionConfig / onInitFlowConfig) | 现有选择器会保留所有同级槽位,并将其设为 null,以便进行结构差异比较。请遵循此约定。 |
| 选择器代码直接调用操作 | UI 层规则:选择器只能调用函数。该函数通过 $apis.<Package>.FootprintApi.extendedActions.<action_name>({...}) 包装操作。 |
将 dxs configuration get -O envelope.json 的输出直接传入 dxs configuration upsert -D envelope.json | 这会悄无声息地破坏配置内容。编辑前务必运行 jq .json envelope.json > body.json。请参阅上文“往返规则”。 |
description 超过 100 个字符 | SQL 列长度限制——推送时会验证失败。请精简。 |
referenceName 不以 _dd 结尾(当选择器是下拉框指示器时),或与文件名主干不一致 | 约定偏差会破坏查找,以及依赖 _dd 后缀的下游调用。使用 snake_case,在适用时添加 _dd 后缀,并确保文件名主干一致。 |
编辑完成后,请调用 post-edit-verification,以发现描述、JSON 或架构违规。进行最终审核时,请调用 component-validator。 |