审计整改说明.md
7.43 KB
审计整改说明(对应 审计报告-2026-07-20.md)
本轮按"全面改造"口径整改。核心思路:把散落在 Java/TS 里的业务字面量上移为可机器读的本体元数据, 让引擎真正通用地解释执行。所有改动均加法、向后兼容。
一、模型层新增的结构化元数据(加法)
| 模型 | 新增字段 | 用途 |
|---|---|---|
| M1 | 属性 constraints(min/max/pattern/patternMessage) |
通用校验(取代中文子串匹配 + 硬编码字段) |
| M2 | 命令 commandType(create/update/cancel) |
通用分派(取代"一律新建") |
| M2 | 命令 effect(op/targetField/keyParam/amountParam/guardField) |
跨聚合副作用通用执行(取代硬编码扣库存) |
| M2 | 命令 derivations(如 totalAmount=sum(quantity*itemPrice)) |
服务端重算(防 totalAmount 篡改) |
| M2 | 新增 StockReturn 命令 |
取消订单回补库存(修正 ME 与语义相反) |
| ME | 跨聚合规则 sourceItemEntity + paramMap
|
通用组装目标命令入参(取代硬编码 productId/quantity) |
| ME | 补齐 OrderItemAdded/OrderPaymentTermSet/OrderDeliveryAddressSet/ProductStockReturned
|
修复 M2 引用了 ME 未定义的事件 |
| M4 | 新增 SCENE_CREATE_CUSTOMER
|
修复 M8 悬空绑定;顺带证明"第二个聚合/场景零代码可跑" |
| M5 | 新增 customer_create 权限 |
配套客户场景 |
二、按发现的整改(A 级 32 条 / B 级 18 条)
铁律违背 → 全部改为模型驱动
-
A1/A13/A16/B8 跨聚合硬编码 StockDeduct/Product/stockNum/productId/OrderCreated:
EventEngine.applyCrossConsistency现遍历实际发出的事件,按 MEcrossAggConsistencyRules匹配,用 M2effect+paramMap通用执行任意增/减副作用;CommandEngine不再传字面量"OrderCreated"。 -
A2/A9/A10/A23 风控变量白名单 + customerLevel()/productStock() 专用方法:删除这两个方法;
runRules现把 master/detail 全字段注入规则 env,并按 M1refAggregate通用解析被引用聚合属性(customerLevel、stockNum 自动可用)。新增引用其他字段的规则即生效。 -
A11/A12/A25 中文子串匹配 + 硬编码实体/字段校验:删除;改由 M1
constraints(pattern/min/max)通用校验,遍历 master 与各子实体行。 -
A29 firstItemEntity/idPrefix "O for Order":删除
firstItemEntity字面量兜底(改由 MEsourceItemEntity指定);idPrefix取聚合根名首字母(通用)。 -
A31 seed 硬编码 Customer/Product:改为遍历
seed-data.yaml的聚合 key 通用落库。 -
A7/A8/A16/A17/A21/A22/A28 前端硬编码:
SceneForm用schema.sceneName+result.rootId(后端新增稳定键rootId/rootIdField);TracePanel/OrdersEventsPanel列改由/api/meta/aggregate/{id}的 M1 属性与引擎通用动作形状驱动。 -
A19/A20 /orders/list 硬编码 OrderAggregate:改为通用
/api/data/{aggregateId}/list;前端api.list(agg)。 -
A30 前端默认场景硬编码:改为取
/meta/scenes首个hasTemplate场景。 -
EventEngine Outbox 表名硬编码:改读 ME
outbox.table。
正确性 / 数据一致性
-
B1 超卖:create 语义下,跨聚合动作任一非 OK(库存不足/不存在)→
setRollbackOnly回滚整单,返回CONSISTENCY_FAILED(已加测试:P002 库存8 下单100 → 失败且库存仍为8)。 -
A5 并发扣减竞争:改为原子条件更新
... SET col=col+? WHERE pk=? AND col+?>=0,受影响 0 行即判不足。 -
A27 负数数量膨胀库存:
effect执行拒绝 amount≤0;且 M1constraints.min=1在校验阶段拦截。 -
A4/B15/B16 非数字入 int/decimal / dueDays 绕过 / NULL 库存崩溃:校验阶段按 M1 类型做数值可解析性校验(precheck 与 execute 同源);
readLong容错 NULL。 -
A6 reload 数据竞争:
ModelRepository改为不可变快照 + volatile 原子发布,读取方永远看到完整旧/新快照。 -
A24 修改/取消被误当新建插入:按
commandType分派 create/update/cancel,不再对非新建命令插入新根。 -
A14/A32 ME OrderCancelled→StockDeduct 语义相反且从不触发:新增
StockReturn(increment),ME 指向它;触发改为遍历实际事件,cancel 场景从库加载明细回补库存。 -
B18 事件 payload 仅取 master:
eventPayload现 master 优先、其次子实体行查找。 - B7 Map.of NPE:改用可空 Map 组装(现由 paramMap 通用组装,容忍空值并 SKIP)。
安全
-
A26 storageEncrypt 从未兑现:新增
EncryptService(AES-GCM),落库前加密、读出后解密(M5 声明的字段)。已加测试断言物理列为enc:密文。 -
A15 totalAmount 客户端篡改:M2
derivations服务端按明细重算,喂给风控与落库。 - B5 permitted 失败即放行:改为 fail-closed(无 permissionBind 的场景默认拒绝)。
-
A3 X-Principal 可伪造 / 无认证:坦诚标注为演示态 stub(
CommandControllerJavadoc + README);热重载改为仅管理员(M8 dragRolePermission)可触发。真正的 OAuth2/JWT 属生产接入项,见"仍为演示简化"。 -
B12 CORS 全放行:改为按 profile 配置
onto.cors.allowed-origins,生产收紧为具体域名。 - B11/B14 H2 控制台无鉴权 / 弱默认口令:生产 profile 已禁用 H2 控制台;加密密钥与 CORS 域名在 prod profile 要求经环境/密管注入(文档强调)。
模型完整性
- B3 M8 绑定未定义的 SCENE_CREATE_CUSTOMER:M4 补齐该场景 + M5 权限,客户模板变为可跑。
- B4 M2 引用 ME 未定义事件:ME 补齐三事件定义。
-
B9 控件不随 M1 type 变:
FieldControl在 compType 为通用文本时按 M1fieldType(int/decimal/boolean/datetime)升级控件,兑现"改 M1 type→控件变"。
三、仍为演示简化(诚实标注,未在本轮做成生产级)
-
真实认证(A3):未接入 Spring Security + OAuth2/JWT;
X-Principal仅演示 M5 权限分支。生产必须替换。 - 幂等(B2):未加请求幂等键;生产应加唯一约束去重表。
- M0 JSON-Schema 强校验(B10):M0 仍为规范文档,未在加载时对各层做 Schema 校验(各层命名 snake_case 与 M0 Identifier 模式的历史不一致亦未强改)。
- 生产重组件(MySQL/RocketMQ/SkyWalking/Prometheus)仍以
deploy/docker-compose + 文档形式交付。
更新(补全 M8 后):M8 已补齐
SCENE_CANCEL_ORDER(订单取消模板)与SCENE_MODIFY_ORDER_ADDR(收货地址修改模板)两套模板,四个场景全部可渲染。引擎相应把update命令做成含子实体更新(updateChildByParent,据 M3 定位子实体表按父外键更新),cancel走通用StockReturn回补库存。已加测试:改地址断言子实体行被更新、取消断言库存回补。故原"update/cancel 子实体级修改未接线"一项已闭合。
四、验证
- 后端 9 个 JUnit 全绿:schema 合成、有效下单(通用一致性)、大额 REJECT、约束校验、超卖回滚、负数数量拒绝、预检、客户权限、手机号密文落库。
-
tests/verify-model-change.sh:改 MetaRule 阈值 + 热重载 → 同单通过↔拦截。 - 浏览器端到端:订单与客户两个场景均由 M8 动态渲染;执行追踪显示 derive/通用跨聚合动作/正确 topic。