spec.md 33 KB

编码规则配置优化

status: reviewed_passed created: 2026-07-16 complexity: 🔴复杂

1. 背景与目标

Forge 当前编码规则使用 ai_code_rule.template 保存 ${...} 模板,能够覆盖简单日期和十进制流水号,但无法用结构化方式表达固定段、变量段、系统变量、进制、分组和周期重置。配置页要求管理员直接理解模板语法,也无法可靠校验溢出、分组碰撞和段级联动。

本变更把编码规则升级为“规则主表 + 稳定分段明细 + 统一生成引擎”,并保持低代码字段自动编号及旧 /ai/code-rule 调用兼容。完成后应达到以下可验证结果:

  • 管理员通过分段编辑器配置 DATE、FIXED、SEQ、VARIABLE、SYS_VAR 五种段类型。
  • 每条规则首期允许零个或一个 SEQ 段;存在 SEQ 时支持 DECIMAL、HEX、ALPHA_UPPER、ALPHA_LOWER、ALPHANUMERIC。
  • SEQ 支持固定宽度转换、起始值、按年/月/日/时切换计数 key,以及按一个或多个“参与分组”段独立计数。
  • 预览不消耗真实流水号,并返回逐段解析结果、总长度、警告和错误。
  • 低代码新增记录继续通过 CodeRuleService 自动生成编号,旧模板规则迁移后无需重新绑定。
  • 编码管理具备独立菜单与 system:codeRule:* 权限,业务字段不能伪造租户、用户或组织系统变量。

2. 代码现状(Research Findings)

2.1 相关入口与链路

  • forge-admin-ui/src/views/app-center/code-rules.vue 使用 AiCrudPage 维护模板字符串、重置周期和流水长度,没有分段编辑器。
  • forge-admin-ui/src/views/app-center/components/designer/forge-form-designer/ForgePropertyPanel.vue#loadCodeRuleOptions 调用 /ai/code-rule/list,字段生成配置保存 generation.ruleCode
  • forge-server/.../generator/controller/CodeRuleController.java 暴露 /ai/code-rule CRUD、预览和生成接口,所有操作共用 ai:businessObject:design
  • forge-server/.../generator/service/businessapp/CodeRuleService.java 解析 ${yyyyMMdd}${seq:4}${field:xxx} 等 Token,并调用 ISequenceService.nextId
  • forge-server/.../generator/service/DynamicCrudService.java#applyAutoGeneratedFields 在低代码新增前调用 CodeRuleService.generate,已是统一自动编号主链路。

2.2 现有实现

  • AiCodeRule 只包含 scene/template/resetPolicy/seqLength/status/builtin/options 等主表字段。
  • CodeRuleMapper.xml 已显式过滤 tenant_iddel_flag='0',规则编码按租户唯一。
  • SegmentSequenceGenerator 使用数据库号段和进程内缓存生成序列,默认每次分配 1000 个号。
  • 历史建表与内置数据脚本位于 forge-server/db/backup/V1.0.86__add_code_rule_generator.sql,正式迁移目录没有结构化编码规则脚本。
  • 当前正式 Flyway 最高版本为 V1.0.35,本变更新脚本使用下一可用版本;执行前仍需重新检查版本占用。

2.3 发现与风险

  • SegmentSequenceGenerator#tryPrefetch 在当前段余量低于阈值后会重复分配并覆盖 next 段,可能造成巨量跳号;结构化规则不能直接复用该行为。
  • 当前 CodeRuleService#resolveToken 优先读取请求 context 中的 tenantId/userId/username,调用方可以覆盖系统变量。
  • 当前 resolveTenantId 在上下文缺失时回退租户 1,不适合作为业务取号的安全边界。
  • 当前序列 key 使用对象和字段作为 sequenceScope;新规则需要由规则分段明确决定分组,迁移时必须保留原规则绑定而不能改写 generation.ruleCode
  • 旧规则编码为 lower snake case,新需求文档又要求大写编码;强制转换会破坏低代码引用。本变更保留现有编码大小写,只校验安全标识符。

3. 功能点

  • 规则分页支持编码、名称、编码分类和状态查询,详情返回稳定排序的分段列表。
  • 新增/编辑使用专用 DTO,不直接接收数据库实体;内置规则只允许修改名称、说明和状态。
  • 分段支持添加、删除、拖拽排序和高级属性联动,保存使用稳定 segmentKey 标识计数器身份。
  • DATE 使用服务端白名单日期格式;FIXED 使用固定文本;VARIABLE 从 fields 取值;SYS_VAR 只从可信 Session 读取。
  • SEQ 使用固定宽度普通进制转换,默认起始值 1,固定左补;超过容量直接报错,不截断。
  • 分组 key 由全部 groupEnabled=true 分段的解析值按段顺序构建并摘要,避免分隔碰撞和数据库 key 超长。
  • 预览支持未保存规则直接携带 segments,使用示例序号和示例变量,不访问真实计数器。
  • 新增 /system/code-rule 管理接口和 capability 接口,保留旧 /ai/code-rule list/preview/generate 兼容协议。
  • ai_code_rule 全量迁移:已知模板由 SQL 回填,其它历史模板由 legacy parser 兼容物化并返回迁移提示。
  • 旧号段水位高于历史流水宽度时优先保证唯一续接,仅按旧水位所需的最小宽度兼容扩宽;没有旧水位的新规则仍严格按配置宽度溢出失败。
  • 低代码字段自动编号继续读取 generation.ruleCode,生成上下文中的业务字段映射为新请求的 fields
  • UI 继续使用 AiCrudPage 承载查询和列表,新增/编辑进入同路由下的全屏配置工作台和分段编辑器。
  • 适用场景改用 sys_code_rule_scene 字典;该字段保留旧调用方场景筛选语义,低代码精确范围改由业务对象绑定控制。
  • VARIABLE 支持 CUSTOM 自定义变量和 LOWCODE 低代码字段两种分段来源;只有 LOWCODE 分段需要保存 source_object_id/source_object_code 并校验字段归属,CUSTOM 由业务代码通过 fields 显式传值。
  • LOWCODE 变量映射由当前分段行触发弹窗,在弹窗内完成“业务对象 → 字段”两级选择;行内回显映射摘要,不再把来源对象放在分段表格顶部。
  • 规则编码在租户内永久唯一,逻辑删除后不得复用;已有 SEQ 必须保留原 segmentKey,禁止通过删除、改型或替换分段重置计数器。
  • 高基数分组/周期号段缓存有界且过期可淘汰,号段分配采用 REQUIRES_NEW + READ_COMMITTED 保证多实例重试可见性。
  • 新规则按进制容量选择号段步长并裁剪数据库水位,缓存淘汰或 JVM 重启后不会因固定预分配 1000 直接跳出固定宽度容量。
  • 原始 /sequence API 默认关闭;显式开启后仅允许 POST、要求 system:sequence:use,并限制 bizKey 长度和字符集。
  • 存量规则用 legacy_compat_enabled=1 安全续接旧水位,新建规则显式写 0,不再为每个新分组扫描 legacy key。
  • 真实生成按 tenantId/ruleId/versionNo 缓存不可变分段快照,不构造预览模板、表达式、分段预览或 warning VO。
  • 实时预览会取消上一条请求,两个预览接口不写操作日志;真实生成继续保留审计。

4. 业务规则

  1. ruleCode 在租户内历史永久唯一,逻辑删除后仍保留且不得复用;创建后不可修改,格式为字母开头,后续只允许字母、数字和下划线,保留历史大小写。
  2. 编码分类使用 sys_code_rule_category 字典;现有 scene 保留为兼容适用范围,不与分类混用。
  3. 规则至少包含一个 includeInCode=true 的分段,总声明长度不得超过 96。
  4. 首期每条规则最多一个 SEQ;无 SEQ 的规则允许生成确定性编码,但预览提示“不会自动递增”。
  5. SEQ 仅允许左补,补位字符由进制固定:DECIMAL/HEX/ALPHANUMERIC 为 0,ALPHA_UPPER 为 A,ALPHA_LOWER 为 a
  6. 固定宽度进制按零基数字位转换,但业务序号值由 startValue 决定;默认 startValue=1,因此所有进制首个值均对应数值 1。
  7. SEQ 容量为 radix^length;新规则序号值必须落在 [0, capacity-1],否则抛出溢出异常。历史规则因旧号段预分配水位已经超过原宽度时,为避免回退水位造成重复编号,真实生成允许按“旧安全起点”所需的最小宽度兼容扩宽;扩宽只覆盖旧水位所需位数,后续序号超过该有效宽度仍抛出溢出异常。
  8. excludeAmbiguous 只对 ALPHA_UPPER、ALPHA_LOWER、ALPHANUMERIC 生效,移除 I/O/Z 或 i/o/z。
  9. resetEnabled=false 时周期强制为 NONE;为 true 时只允许 YEAR/MONTH/DAY/HOUR。周期使用应用配置时区,本轮以注入 Clock 的服务端时区为基线。
  10. 多个参与分组段按 segmentOrder 解析,使用长度前缀规范化后做 SHA-256 摘要;原始分组值不进入日志和计数 key。
  11. 参与分组但不列入编码的段可能造成跨组重复,保存时返回警告;调用方必须按分组范围建立唯一性,或把分组段列入编码。
  12. 预览永不调用 ISequenceService,默认使用 startValue 作为示例序号。
  13. 真实生成只允许 VARIABLE 从业务 fields 取值;SYS_VAR 不读取同名业务字段。
  14. 缺少租户上下文、规则停用、变量缺失、格式非法或序列溢出时失败关闭。
  15. 编号允许因事务回滚、号段预分配和服务重启产生空洞,保证唯一递增但不承诺连续无缺口。
  16. 内置规则禁止删除;自定义规则和分段均采用逻辑删除。自定义规则删除只影响可见性,规则编码和已分配计数器身份永久保留。
  17. 分段拼接顺序由 segmentOrder 和拖拽排序表达,不新增重复的“顺序段”;SEQ 对用户显示为“流水号(顺序递增)”。
  18. VARIABLE 分段必须声明 variableSource=CUSTOM|LOWCODE;历史协议缺省和 legacy parser 物化均按 CUSTOM 处理。
  19. CUSTOM 变量名必须是安全标识符,不要求来源业务对象;真实生成时调用方必须通过 fields.<variableName> 提供值。
  20. LOWCODE 变量必须选择一个启用的来源业务对象,字段编码必须来自该对象当前启用的非系统字段目录。
  21. 纯 CUSTOM VARIABLE 规则是通用规则,保存时清空来源对象;只要存在任一 LOWCODE VARIABLE,规则就是对象专属规则,列表筛选和运行时继续校验当前 objectCode
  22. LOWCODE 映射弹窗打开和取消不修改规则草稿;只有点击“确认映射”后才原子更新当前分段、来源对象和字段。
  23. 一条规则的 LOWCODE 分段共用同一来源对象;在映射弹窗切换对象时,确认前必须提示影响,确认后清空其它 LOWCODE 分段的旧字段映射,禁止保留跨对象字段。
  24. 已存在 SEQ 的规则更新时必须保留同一 segmentKey 且该段仍为 SEQ;允许排序和属性调整,禁止删除、改型或用新 key 替换。原本没有 SEQ 的规则允许首次增加。
  25. VARIABLE 业务字段兼容 exact、snake_case 与 camelCase 别名;SYS_VAR 仍只按声明键读取可信系统上下文,禁止使用业务字段别名兜底。
  26. 新建规则的号段步长按 clamp(radix^length / 1000, 1, 1000) 计算,数据库 UPDATE 前按剩余容量裁剪;达到 capacity-1 后失败且不得推进水位。
  27. 升级前既有规则默认启用 legacy 兼容并允许按旧安全水位最小扩宽;新代码创建的规则关闭 legacy 兼容并严格遵守配置容量。
  28. /sequence 不是默认公共能力;只有配置 forge.id.sequence.enable-api=true 后才注册,且所有取号入口要求专用权限、POST 和安全 bizKey
  29. 一条规则最多 32 个分段,业务上下文字段最多 256 个;未声明长度的 VARIABLE/SYS_VAR 单值最多 96 个字符。
  30. 同一规则版本的分段定义最多加载一次,缓存值必须是不可变快照,每次调用返回独立 DTO,禁止引擎规范化污染后续请求。
  31. 真实生成必须在取号前拒绝已知非法字符和可预判的总长度超限;预览仍返回逐段错误,不消耗真实流水。
  32. 实时预览属于高频只读操作,不写操作日志;新预览发起、草稿失效或离开工作台时必须取消旧请求,并保留最新请求 Guard。

5. 数据变更

操作 表名 字段/索引 说明
修改 ai_code_rule category, source_object_id, source_object_code, version_no, legacy_compat_enabled, in_code_list, del_flag, logic_delete_active 增加分类、低代码来源对象、乐观锁、legacy 兼容标记、可选择标记和逻辑删除;存量规则默认兼容,新规则显式关闭
调整唯一索引 ai_code_rule (tenant_id, rule_code) 规则编码跨逻辑删除记录永久唯一,禁止删除后重建导致新 ruleId 重置计数器
新增 ai_code_rule_segment variable_source、标准审计字段、del_flaglogic_delete_active 保存稳定分段定义;VARIABLE 来源为 CUSTOM/LOWCODE,默认 CUSTOM
调整索引 ai_code_rule_segment (tenant_id, rule_id, del_flag, segment_order, id) 先按租户、规则和活跃状态定位,再稳定按序读取
新增唯一索引 ai_code_rule_segment (tenant_id, rule_id, segment_key, logic_delete_active) 稳定分段键仅约束未删除记录
新增字典 sys_dict_type/sys_dict_data sys_code_rule_category 编码分类,tenant_id 固定 1
新增字典 sys_dict_type/sys_dict_data sys_code_rule_scene 兼容适用场景,tenant_id 固定 1
调整资源 sys_resource/sys_role_resource system:codeRule:* 迁移菜单权限并保留路由
数据回填 ai_code_rule_segment 现有全部规则 SQL 回填已知内置模板,Java legacy parser 兜底其它模板

ai_code_rule.template/reset_policy/seq_length/options 本轮不删除。结构化规则保存时同步生成兼容摘要;没有分段的旧规则继续由 legacy parser 解释,成功后可在编辑保存时物化为分段。

6. 接口变更

操作 接口 方法 变更内容
新增 /system/code-rule/page GET 规则分页
新增 /system/code-rule/list GET 启用且可选择规则
新增 /system/code-rule/getById POST 主表和分段详情
新增 /system/code-rule/add POST 新增规则及分段
新增 /system/code-rule/edit POST 乐观锁更新规则及全量分段
新增 /system/code-rule/remove/{id} POST 逻辑删除自定义规则
新增 /system/code-rule/status POST 启停规则
新增 /system/code-rule/preview POST 无副作用结构化预览
新增 /system/code-rule/generate POST 生成编码,返回 code/sequence/group/period
新增 /system/code-rule/capabilities?sourceObjectId=... GET 返回段类型、日期格式、系统变量、进制、业务对象及指定对象字段能力
兼容 `/ai/code-rule/list preview generate`
收口 /sequence/next* POST 默认不注册;显式开启后要求 system:sequence:use,限制 bizKey 且禁止 GET 取号

管理接口使用 POST-safe 配置协议,所有请求/响应继续使用 @ApiDecrypt/@ApiEncrypt。权限拆分为 system:codeRule:list/add/edit/remove/use

7. 影响范围

  • forge-plugin-generator:编码规则实体、Mapper、DTO/VO、生成引擎、Controller、低代码自动编号。
  • forge-starter-id:号段缓存切换、起始值、旧水位只读解析、有界缓存和 READ_COMMITTED 分配事务。
  • forge-admin-ui:编码规则列表、全屏编辑工作台、分段编辑器、API 和低代码字段预览摘要。
  • 低代码对象设计器:自动编号规则选项按当前 objectCode 过滤,通用规则与当前对象专属规则可见。
  • forge-server/db/migration:结构、字典、菜单权限和历史规则迁移。
  • 现有 generation.ruleCodeai_code_rule 数据和 /ai/code-rule 兼容调用。

8. 风险与关注点

  • ⚠️ 权限变更:菜单从 ai:businessObject:code-rules 迁移到 system:codeRule:*;Flyway 必须同步已有角色授权,避免升级后菜单丢失。
  • ⚠️ 多租户:超级管理员跨租户查询不在普通租户接口中隐式实现;所有生成动作必须有确定租户。
  • ⚠️ 编号唯一性:规则变更可能改变最终文本,但底层数值序列继续递增;不提供无审计的手工重置。
  • ⚠️ 迁移:任意用户模板无法完全用 SQL 解析;不可解析模板必须保留 legacy 执行路径并显示警告,禁止静默丢失。
  • ⚠️ 共享底座:修改 forge-starter-id 会影响其它序列调用者,必须用回归测试覆盖段耗尽和并发切换。
  • 工作区已有 .DS_Store 等无关差异;本变更不清理、不回滚这些文件。

8.5 测试策略

  • 测试范围:结构化规则校验、五种进制边界、日期与变量解析、分组摘要、周期 key、序列号段切换、旧模板解析、低代码上下文、Controller DTO、Mapper XML、Flyway 静态检查、前端纯函数和生产构建。
  • 覆盖率目标:编码生成引擎所有段类型和错误分支;序列分配跨段边界;关键权限与租户失败关闭路径均有测试证据。
  • 独立 Test Spec:是,见 test-spec.md

9. 待澄清

无。用户在上一轮分析后明确回复“按照你的方案实施 按照sdd开发流程”,本 Spec 采用上一轮推荐的兼容和安全取舍。

10. 技术决策

  • 保留 ai_code_rule 主表,新增 ai_code_rule_segment,避免重建规则 ID 和低代码绑定。
  • segmentKey 是计数器稳定身份,segmentOrder 只控制展示和拼接顺序。
  • ruleCode 和既有 SEQ segmentKey 都属于计数器永久身份:逻辑删除不释放 ruleCode,规则更新不允许替换已有 SEQ 的 key。
  • 生成引擎拆为无状态 Manager/Compiler,CodeRuleService 负责事务编排,避免 Service 互相注入。
  • 序列继续复用 ISequenceService 的数据库号段能力,不在 Generator 内另建 Redis 计数器;先修复缓存跨段问题并补起始值接口。
  • 号段缓存使用 Caffeine 限制最大 10000 项并在 60 分钟无访问后过期;淘汰只产生允许的号段空洞。分配事务使用 REQUIRES_NEW + READ_COMMITTED,避免 MySQL RR 快照让乐观重试持续读取旧版本。
  • 规则分类使用字典;段类型和进制属于可执行能力,由后端 capability 接口返回,不能仅靠插入字典扩展。
  • 适用场景属于兼容筛选维度,使用 sys_code_rule_scene 字典;VARIABLE 的精确字段边界使用低代码业务对象和字段元数据,不复用自由文本场景。
  • VARIABLE 来源是分段级属性:CUSTOM 保持引擎现有 fields 取值协议,LOWCODE 只在配置和运行时增加元数据边界;不为两种来源分叉生成引擎。
  • LOWCODE 映射使用工作台内的 Naive UI Modal,映射草稿与规则草稿隔离;字段目录仍按选中对象调用 capability 接口加载,不新增后端协议。
  • 对象专属规则在无 objectCode 的选择请求中不可见;精确匹配当前对象时优先于 COMMON 场景过滤,运行时仍再次校验对象编码。
  • 列表继续复用 AiCrudPage,复杂主从编辑使用同路由查询状态切换到全屏工作台,保持通用 CRUD 与业务编辑器边界,同时避免新增权限路由。
  • UI 采用克制的企业配置工作台风格,遵循现有主题变量,不引入渐变、重动画或新的设计体系。
  • 新规则使用容量感知号段;存量规则通过 legacy_compat_enabled 保留升级安全边界。该标记由 V1.0.37 默认置 1,新建服务代码显式写 0,兼容滚动升级。
  • legacy 水位查询由对 biz_key 做函数改为尾部通配的参数化前缀 LIKE,并使用 ! 显式转义 _/%,让主键可参与前缀范围过滤且不受反斜杠 SQL mode 影响。
  • 规则定义缓存只缓存同版本分段快照;每次仍保留一次规则主表查询,以及时感知跨实例的版本、状态和删除变化,避免用长 TTL 换取错误编号。
  • 数据库计数器行不自动 TTL 清理,因为删除仍可能使用的计数器会造成编号复用;本轮通过关闭原始 API、限制输入和缓存规模收口非业务膨胀,合法高基数留给容量监控和留存策略治理。

11. 执行日志

Task 状态 实际改动文件 备注
Task 0 complete spec.md, tasks.md, test-spec.md, execution-log.md SDD 基线与 HARD-GATE
Task 1 complete forge-starter-id 序列接口、生成器及测试 3/3 测试通过;跨 1000 号段连续且并发唯一
Task 2 complete Flyway、实体、Mapper 存量主表逻辑删除升级与结构化分段模型完成
Task 3 complete 结构化引擎、DTO/VO、服务 五类分段、五种进制、分组、周期和 legacy 兼容完成
Task 4 complete Controller 与兼容接口 /system/code-rule、独立权限、API 资源和旧入口兼容完成
Task 5 complete 前端 API、分段编辑器和页面 AiCrudPage 列表、全屏编辑工作台、拖拽编辑和实时预览完成
Task 6 complete 低代码兼容与回归 generation.ruleCode 与业务 fields 分层完成
Task 7 complete 测试、构建和审查 定向测试、Admin 编译、前端构建和两阶段自审通过
Task 9 complete 场景字典、来源对象字段映射、低代码规则过滤与运行时校验 Generator 15/15、前端 Vitest 9/9、Admin 42/42 和生产构建通过
Task 10 complete VARIABLE 分段 CUSTOM/LOWCODE 双来源、按需对象映射与自定义 fields 调用 Generator 20/20、前端 11/11、ESLint、Admin 42/42 和生产构建通过
Task 11 complete LOWCODE 字段映射弹窗、行内摘要和对象切换原子应用 前端 Vitest 13/13、ESLint、生产构建和交互静态契约通过
Task 12 complete 旧号段水位与固定宽度组合兼容 归档前 Review 发现 P0 后完成 Red/Green;Starter ID 7/7、Generator 21/21、Admin 42/42 通过
Task 13 complete 归档前两阶段复审安全与质量修复 规则/SEQ 身份保护、缓存上限、事务隔离、legacy/字段别名兼容;Starter ID 9/9、Generator 25/25、Admin 42/42 通过
Task 14 complete SDD 归档与知识沉淀 状态统一为 done,四份 SDD 文档及需求/UI 原型归档到日期目录
Task 15 complete 容量感知号段、CAS 热路径及测试 有限容量按剩余值裁剪;当前段 CAS 消费;Starter ID 15/15 通过
Task 16 complete 原始 /sequence API 收口 默认关闭、POST、专用权限及 bizKey 边界完成
Task 17 complete V1.0.37、legacy 标记与索引友好查询 存量/新规则兼容边界分离;转义前缀 LIKE 和活跃分段索引完成
Task 18 complete 规则定义缓存、生成快路径与输入上限 Caffeine 不可变快照、版本重载、32/256/96 上限完成
Task 19 complete 预览降载、聚合验证与复审 AbortController、预览免审计、全量增量验证和两阶段复审完成

12. 审查结论

review-date: 2026-07-16 conclusion: NEEDS_FIX

阶段一:Spec Compliance — FAIL

  • 已实现:分页/详情、DTO 隔离、内置规则限制、稳定分段键、五类分段、五种进制、分组摘要、周期 key、无副作用预览、独立权限、legacy 解析和低代码自动编号主链路。
  • R1 / P0 — 存量计数器未续接。 旧实现使用 code-rule:{tenant}:{ruleCode}:{scope}:{period},新实现改为 cr:{tenant}:{ruleId}:{segmentHash}:{groupHash}:{period}V1.0.36 只物化分段且把 start_value 固定为 1,没有迁移或兼容读取 sys_id_sequence 旧 key。升级后的新 key 可从 1 重新取号,违反编号唯一递增和迁移连续性要求。
  • R2 / P0 — 多实例可能返回同一号段。 乐观锁 UPDATE 成功后再次查询当前 max_id 再计算区间;另一实例可在两条语句之间完成下一次分配,使两个实例都按较新的 max_id 返回同一后段。
  • R3 / P0 — 业务回滚后内存号段与数据库失配。 低代码新增在外层事务内取号,号段分配没有独立提交;业务事务回滚会回滚 sys_id_sequence,但 JVM 的 SegmentHolder 不会回滚,另一实例或进程重启后可再次分配同一区间。
  • R4 / P1 — 分类回填不完全可重跑。 分类 UPDATE 依赖本轮是否刚新增 category 字段;若 DDL 后、UPDATE 前失败,修复重跑时 @category_added=0,存量分类将永久跳过回填。

阶段二:Code Quality — SKIPPED

  • 阶段一存在阻塞 Spec 偏差,按两阶段 Review Gate 不启动正式 Code Quality Review。
  • 初步检查另发现前端详情/预览异步请求缺少过期响应保护,以及新增/编辑/启停/删除入口未按独立权限隐藏;在 P0 修复后复审时一并确认。

Review Gate

  • 本次 Review 当时状态为 reviewed_with_findings,不得归档。
  • Review 后已执行 /fix 编码规则配置优化;修复结果见下节,仍需重新执行 /review 编码规则配置优化 后才能归档。

12.5 Fix 结果

fix-date: 2026-07-16 status: fixed_pending_review

Review 项 修复结果 实现摘要
R1 旧计数器续接 FIXED 新结构化 key 首次初始化时按租户、规则编码和周期精确查询旧 code-rule:* 最大水位,从 max(startValue, legacyMaxId + 1) 开始;HOUR 兼容旧小时/分钟/秒周期。
R2 多实例号段 FIXED 乐观锁 UPDATE 前保存本实例读取的 currentMaxId,成功后直接返回本次快照对应区间,不再重新查询最新水位。
R3 事务回滚 FIXED 号段分配使用 TransactionTemplate + PROPAGATION_REQUIRES_NEW,提交成功后才写入 JVM 缓存;外层业务回滚只产生空洞,不回退数据库号段。
R4 分类回填 FIXED Flyway 分类 UPDATE 改为按 category/scene/rule_code 当前数据状态幂等执行,移除 @category_added 会话条件。
前端复核项 FIXED 详情和预览采用最新请求 Guard,输入变化即作废在途预览;新增、编辑/启停、删除入口分别按权限显示。用户验收发现页面误用 Naive 组件内部颜色变量后,已复修为 Forge 全局背景、文字、边框和主色 Token。
  • Fix 定向回归:Starter ID 6/6,Generator 11/11,前端 Vitest 8/8。
  • 聚合验证:Admin reactor 42/42 编译成功,前端生产构建成功(8691 modules),三个 Mapper XML、Flyway 静态检查和 tracked/untracked 差异格式均通过。
  • 真实 Flyway、数据库状态和登录态 HTTP 未执行,继续由可用环境在复审/验收阶段补验。
  • 主题复修覆盖列表页、编辑工作台、基础信息、分段表格、展开区和实时预览;亮色/暗色均读取系统 Token,不再把 --n-color--n-action-color 当作页面背景。
  • 用户验收确认复杂分段配置不适合抽屉;现已改为列表与编辑工作台同路由切换,分段操作列固定在横向滚动区域右侧。

12.6 归档前复审补修

review-date: 2026-07-17 status: fixed_pending_review

  • 归档前阶段一复审发现:旧号段默认预分配 1000 个值,历史三位 material_code 只要使用过一次,旧数据库水位就可能为 1000;按 R1 从 1001 续接会与三位十进制容量冲突。
  • 修复保持新规则固定宽度语义:先严格按配置宽度编码,只有实际溢出时才只读解析旧安全起点;确有旧水位时按其所需的最小位数兼容扩宽,没有旧水位仍失败。
  • 兼容宽度不会随当前实际序号无限扩张;例如旧安全起点 1001 只允许四位,后续达到 10000 时仍按容量溢出失败。
  • Red:新增组合测试后,旧接口缺少 resolveLegacyStartValue,Generator 测试编译失败。
  • Green:Starter ID 7/7、Generator 编码规则 21/21、Admin reactor 42/42 编译通过;未启动服务、数据库或 Redis。

12.7 最终两阶段复审

review-date: 2026-07-17 conclusion: PASS_WITH_COMMENTS

  • 阶段一 Spec Compliance:PASS。R1-R4、旧水位容量、VARIABLE CUSTOM/LOWCODE、对象边界、LOWCODE Modal、主题与兼容接口均符合 Spec。
  • 阶段二 Code Quality:PASS_WITH_COMMENTS,P0/P1 为零。归档前新增修复包括:兼容宽度有界缓存、号段缓存上限/过期、READ_COMMITTED 乐观重试、HHmmss 旧 NONE/all 语义、VARIABLE snake/camel 别名、ruleCode 历史唯一和 SEQ identity 保护。
  • P2 保留:冷缓存并发首个溢出请求可能重复少量旧水位查询;旧水位 SQL 仅在首次/淘汰后执行;前端可后续提前禁用已有 SEQ 的删除/改型,当前后端已失败关闭。
  • 最终验证:Starter ID 9/9、Generator 编码规则 25/25、Admin reactor 42/42;前端复用最新 13/13、ESLint 0 errors 和 8691 modules 生产构建基线。
  • 真实 Flyway、MySQL/Redis、登录态 HTTP 和浏览器点击验收未执行,按既定分工保留为环境验收项。

13. 确认记录(HARD-GATE)

  • 确认时间:2026-07-16
  • 确认人:用户
  • 确认内容:用户确认按上一轮分析方案实施,并要求遵循 SDD 开发流程;授权进入 /apply

14. 归档记录(HARD-GATE)

  • 状态:done
  • 归档时间:2026-07-17
  • 归档人:code-copilot(用户明确要求归档)
  • 归档路径code-copilot/changes/archive/2026-07-17-编码规则配置优化/
  • Review 结论:Spec Compliance PASS;Code Quality PASS_WITH_COMMENTS,P0/P1 为零。
  • 归档验收:Starter ID 9/9、Generator 编码规则 25/25、Admin reactor 42/42;前端复用 Vitest 13/13、ESLint 0 errors 和 8691 modules 生产构建基线;最终 git diff --check、三个 Mapper XML 和 Flyway placeholder 静态检查通过。
  • 环境验收保留项:未启动 Admin/MySQL/Redis,未实跑 Flyway、登录态 HTTP 或浏览器点击,按既定分工由可用环境补验。

15. 归档后性能与可用性复审(2026-07-17)

conclusion: NEEDS_FIX fix-authorized: true

  • P0 / 固定宽度提前耗尽:数据库号段固定预分配 1000,JVM 重启或 Caffeine 淘汰会丢弃未消费区间;三位十进制新规则生成一次后,下一次可能从 1001 继续并立即溢出。
  • P0 / 原始序列接口暴露/sequence 默认启用、使用 GET 执行取号、没有专用权限且接受任意 bizKey,登录用户可制造序列表膨胀和缓存淘汰,放大正常编码规则不可用风险。
  • P1 / 冷 key SQL 放大:每个新分组和新周期都会执行 legacy 水位查询,旧 SQL 对 biz_key 使用函数,无法稳定利用主键前缀范围。
  • P1 / 运行时重复加载:每次生成都查询规则主表和分段表,并构造只供预览使用的模板、表达式和分段 VO。
  • P1 / 高基数治理不足:缓存容量有界但数据库 key 永久增长;同一热门 key 的每次取号仍进入 synchronized
  • 用户明确回复“开始修复”,原归档状态作废,目录恢复到 code-copilot/changes/编码规则配置优化/,按 /fix 增量执行。

16. 性能 Fix 最终两阶段复审(2026-07-17)

conclusion: PASS_WITH_COMMENTS status: reviewed_passed

阶段一:Spec Compliance — PASS

  • Task 15-19 全部完成。有限容量号段、API 收口、legacy 标记与 V1.0.37、规则分段缓存、生成快路径、输入上限和预览降载均与本轮增量 Spec 一致。
  • 新规则严格容量、存量规则安全续接的边界已显式落库;低代码 generation.ruleCode、CUSTOM/LOWCODE 字段协议、主题和全屏工作台没有回退。
  • 验证结果:Starter ID 15/15,Generator 编码规则 31/31,前端 Vitest 14/14、定向 ESLint 0 errors,Admin reactor 42/42,前端生产构建 8691 modules。

阶段二:Code Quality — PASS_WITH_COMMENTS

  • P0/P1 为零。数据库分配在 UPDATE 前裁剪且容量耗尽不推进;热门 key 使用 CAS;新规则不扫 legacy;分段定义按版本缓存并返回深拷贝;真实生成不构造预览 VO。
  • SQL/XML/迁移静态检查通过:三个 Mapper XML 合法,legacy 查询不再对 biz_key 使用函数,V1.0.36/V1.0.37 无 Flyway placeholder,tracked/untracked 差异无空白错误。
  • P2 保留:合法的高基数“规则 × 分组 × 周期”仍会形成持久计数器行,不能在未证明业务停用时自动删除,否则会复用编号;建议生产监控 sys_id_sequence 增长率并另行制定可审计留存策略。
  • 为跨实例及时感知规则停用和版本变化,真实生成仍保留一次轻量规则主表查询;已消除更重的分段查询和预览对象构造。
  • 未启动 Admin/MySQL/Redis,未实跑 Flyway、登录态 HTTP 或浏览器点击;这些属于环境验收保留项,不改变静态实现与自动化审查结论。