Files
flow-center-service/docs/schema-extension-compatibility-next-tasks.md
T
chenxing 4b4d63e3ba
build / build-push (push) Successful in 1m10s
t1~t2+精修+TASK_4: 定义绑定表单UUID/版本成对核验、发起恢复守卫、schema兼容边界草案
含10-22精修: 保存/发布/启用按确切uuid+version远端核验、升版继承两列、取消关联清空版本、缺版本不回落最新。TASK_4=docs/schema-extension-compatibility-next-tasks.md(纯文档)。
2026-10-22 10:03:28 +08:00

10 KiB
Raw Blame History

FL公共schema扩展兼容边界与下一批任务草案(TASK_4)

日期:2026-10-22。状态:文档检查完成;没有实施显隐/矩阵/量表,也没有放宽FC白名单或修改路由算法。伴随契约:FC草案。本相对链接跨目录时应以工作区根目录的 form-center/service/docs/schema-extension-draft.md 为准。

1. HEAD与当前锚点

FL后端HEAD=2f54f37ab34ca71410ec854f1adcc1da7c4dbe5f;FC后端HEAD=b2437a20742bfbfe38a564134904f3e0d7d931a3;FC前端HEAD=2e406a88b1d9e09b2ca54a8cf68a3726174f49c0。均有任务实施后的未提交工作区内容,不能写成已合入。

FL / src/main/java/com/yunhai/flowcenter/service/FormCenterSchemaClient.java / FormCenterSchemaClient#toSnapshot(Map):下段已与当前HEAD的git show重新对照,当前工作区仍保留这段搬运规则:

field.put("key", f.path("key").asText(null));
field.put("type", f.path("type").asText(null));
JsonNode required = f.get("required");
field.put("required", required == null ? Boolean.FALSE : required.asBoolean(false));

同方法对数组options搬运value(缺value时回落label)为enum;顶层快照为formUuid/formVersion/audience/fields。它没有完整保留field.valueSchema、visible_when、pattern、min/max、precision或复合值声明;更没有执行这些规则。type字符串被带入不能证明引擎支持复杂值。

FL / service/FlowDefAdminService#save/#publish/#enable:当前工作区在保存绑定前核验确切版本,升版继承formUuid/formVersion,取消关联清空坐标;发布以 fetchSchema(schId,uuid,version) 核对返回坐标后嵌入contentJson.formContract。此管理行为属于Task1及本轮代码修复,不能声称存在于上述HEAD。已发布/停用版本的快照不能原地重写;修改关联走新草稿。旧两参fetchSchema仍是内部方法,不作为新管理链的无版本入口。

FC / common/FormSchemaValidator#validateField:

rejectUnknownProps(field, ALLOWED_PROPS, "字段属性(" + key + ")");

FC / common/FormValueValidator#validate先处理required再分派类型;当前没有显隐计算。FC / common/FormValueSchemaBuilder#withValueSchemas只生成读侧机读描述;前端 types/formSchema.ts / ALLOWED_FIELD_PROPS及 components/fields/index.ts#fieldWidget限定当前控件。根未知属性未统一拒绝,不构成安全规则兼容机制。

2. 当前边界与未来兼容矩阵

FC值/候选类型 当前schema/快照事实 未来FL路由要求(未实施)
number JSON number;FC校验边界/precision;FL快照只保留type等少量字段 显式数值域及空值语义;不能从缺失边界推定任意数值合法
select/radio 稳定value字符串;FL有enum 用value比较,不能按label;value缺失不能静默用展示文案给新契约兜底
multiselect/checkbox string[];快照有type及enum,但无完整array约束 禁止把整个数组当标量eq/gt操作数;若需contains等运算,必须另立版本化运算符及集合语义
upload/image [{id,fileName,key}];机读形状未完整进入FL快照 禁止对象/数组转字符串或比较附件URL作为路由;文件访问权限仍在FC
display metadata 当前无通用跨端透传保证 获批后可在专用命名空间保留,不能执行或改变审批判据
visible_when FC字段属性白名单拒绝,FL无执行器 必需规则不受支持则拒绝发布/发起;不得只在编辑器隐藏后继续按旧快照执行
matrix/scale 未冻结/未放行 拒绝复合值标量路由,或只消费显式版本化投影;两种策略实施前定稿

当前表达式校验与运行仍按现有引擎行为;上表右列是下一批要求,不冒充已存在的“复杂值安全闸”。不得为了通过候选schema而先修改PHASE1_TYPES、ALLOWED_PROPS或表达式白名单。

3. 能力协商与投影候选

下一版formContract应明确schemaContractVersion、requiredCapabilities以及字段完整值形状;具体字段名尚为候选。unsupported required capability必须阻断发布,不能丢掉字段后继续成功。已发布流程继续使用其原快照,不被FC新能力升级暗中改变。

若选择投影,应明确:

  • 稳定命名空间及命名冲突规则(候选如projection.satisfaction_score,当前表达式是否支持点号必须先核实,不能直接采用)。
  • 投影算法版本、输入表单版本、rowKey/枚举值域及顺序,禁止label参与算法。
  • 全部可见、部分空值、整题隐藏、不适用、非法复合结构的输出分别定义;hidden不能自动映射为0,null不能自动映射为空字符串。
  • 谁计算并校验投影、在哪个可信边界附带它、如何进入revision/hash;不能信任浏览器额外上报的分数。
  • 对象键顺序与数组顺序遵循已有规范化;如改变快照成员或哈希规则必须升协议,不原地改fc.canon.v1。
场景 候选输出/行为
已知row、有效值、题目可见 按已冻结投影算法产出标量/枚举
题目隐藏 输出显式不适用标记或拒绝该路由;不得假装0分,具体方案待定
必答row缺失 FC拒绝答卷,不向FL构造“补零”结果
重复row/未知row/非法枚举 拒绝复合值,错误可定位,不执行路由
旧schema无该题/旧流程无该能力 保持旧快照行为;需要新能力则升流程版本

4. 下一批任务书草案(均未授权实施)

这些文件已分别属于Task1/2或历史功能,实施前必须重新分配写权限;不能在Task3分支顺手追加。以下为成对功能包,不是可同时执行的互不相交白名单。正式拆分时要核对真实路径、确定独占文件集和按序依赖。

E1:公共扩展版本及静态规则校验

背景:先建立能力协商及拒绝边界,避免静默丢规则。

改动候选:FC common/FormSchemaValidator#validateSchema/#validateField/#validateOptions、common/FormValueSchemaBuilder#withValueSchemas;FC前端 types/formSchema.ts、设计器序列化路径;拟新增独立规则AST/能力清单类(名称待实施时确定)。必须同时处理根/group/field/options各层保留与拒绝规则,不能只放宽字段白名单。

行为:先校验契约版本与必需能力,再核对引用/类型/循环/资源预算;未知安全规则拒绝,允许的display metadata仅保留不执行。valueSchema仍由服务端派生。

依赖/约束:重新分配Task1 schema/目录契约相关文件;不改AppRegistry或部门模型,不引入eval。

验收计划:未知根/字段/选项、循环依赖、类型不符、超预算、保留metadata但不执行、旧schema保持原行为。此处仅列计划,本轮不写、不跑测试。

E2:可见性规则的全写入通道与普通题型回归

背景:显隐不是纯前端效果,必须覆盖自填、匿名、hosted、本人/管理员编辑和导入。

改动候选:FC service/AnswerService#doSubmit、service/AnswerReadService#editBySubmitter、service/AnswerAdminService#edit、service/AnswerImportService、公共FormValueValidator;FC前端 views/Fill.vue、字段渲染/校验及编辑入口。具体编辑组件路径在正式任务前用rg重新定位,不虚构已存在文件名。

行为:取钉版schema,执行同一规则服务,先visible再required;隐藏值A/B策略必须先获定稿。导入预检和执行使用同一版本;本人/匿名身份边界和hosted本人边界保持;索引/outbox基于实际存储结果更新。

依赖/约束:E1完成且隐藏值策略定稿;Answer/投递/Fill属于Task2,需重新分配;OPEN-T19b原有代填不是此任务取消对象。

验收计划:number=0、false、select value、空数组、多选顺序、upload归属;切换上游使下游隐藏;旧答卷按原版编辑;匿名与hosted隔离;导入同规则、原子回滚与hash一致。

E3:统计导出与历史解释

改动候选:FC service/AnswerStatsService、AnswerExportService、AnswerIndexService和已有统计/导出前端(路径须正式定位);矩阵渲染与行列编辑组件仅在题型获批后新增。

行为:区分N/E/V/A四类分母;逐答卷版本解释字段/规则,导出不适用与空值不同;历史读取不修改答卷。不跨版本同key暗合并,不把多选计次当人数。

依赖/约束:E2后才有稳定写入语义;不得用当前schema重解释历史数据。矩阵object/array结构、rowKey、算法上限先定稿。

验收计划:版本间增删题、隐藏/可见未答、V=0、多选计数、矩阵每行/整题分母、字典label变动、历史附件及业务扩展保留。

E4:FC—FL成对快照、复杂值拒绝或投影

改动候选:FC service/OapiFormService/机读schema契约;FL service/FormCenterSchemaClient#toSnapshot、FlowDefAdminService#publish、FlowInstanceService输入校验及engine/FlowDefModel/相关表达式验证入口;FL前端定义编辑器及表达式提示。调用端与服务端在一个任务中交付,不硬拆端点和调用。

行为:先识别required capabilities,再保存完整契约快照;不支持的安全能力拒绝发布。complex值不走标量比较,或仅使用显式受信投影。新绑定保存/发布均核验确切formUuid/version;旧快照只读,改动走新流程版本。

依赖/约束:E1能力格式稳定,E2/E3值与统计口径稳定;Task1版本绑定、Task2流程发起文件需重新分配;不改部门节点策略,不把矩阵处理塞进回调恢复。

验收计划:array/object标量路由拒绝、投影边界与null、返回坐标不符、撤权、跨版本不可变快照、普通表单仍可发布/发起。资源失败必须有稳定码,不把“网络不可达”误当“不支持能力”。

5. 本轮交付检查

  • 当前白名单、11类控件、根/group/field/options边界、FC验证与FL快照搬运已逐项对照源码。
  • 样例均明确标注候选;隐藏值A/B未被私自定稿,matrix/scale未被写成已实现。
  • 数值/单选/多选/附件及所有写入、编辑、导入、统计、导出的版本来源详见FC伴随草案。
  • L1状态:文档检查完成,功能测试未执行。按用户本轮指令只做编译/跳过测试打包;构建结果记录在根目录docs/tasks/evidence/refinement-20261022,不构成候选功能验收。
  • 后续具体测试与生产联调方案另出;本轮不连接真实库/MQ、不执行DDL、不启动对账、不做前端视觉验收。