# 拒绝跨领域通用条件写入 Module 状态:已采纳(2026-08-11) ## 背景 Campaign 与 Intelligent Evaluation 的 Repository 都使用条件更新,并都区分 `applied`、`not_found`、`conflict`。因此曾考虑抽取跨领域的 compare-and-set module,以复用 SQL 模板和结果分类。 ## 删除测试 假想 interface 至少需要调用方提供:数据库表与主键列、状态列、一个或多个期望状态、目标字段映射、时间戳策略、JSON 序列化、更新后模型映射,以及可选的同事务副作用。 两个领域真正需要隐藏的知识并不相同: | 维度 | Campaign | Intelligent Evaluation | |---|---|---| | 状态条件 | 可接受多个来源状态 | 单一期望状态与完整转换表 | | 时间语义 | 调用方传入时间;按目标状态写开始或完成时间 | Repository 取当前时间;始终更新 `updated_at`,首次执行用 `coalesce` | | 业务字段 | 主要写状态 | 同时写计划、反馈或报告,并负责 JSON 序列化 | | 事务副作用 | 完成/取消时同步结算 Exploration Session | 无跨聚合结算 | | 冲突结果 | 返回当前 Campaign 快照 | 返回冲突分类,由 lifecycle 重新表达领域错误 | 删除该假想 module 后,只会在两个 Repository 中恢复少量 SQL 更新与结果分类;状态规则、字段映射和事务副作用仍必须留在各自领域。它不能减少调用方需要掌握的知识,反而会把稳定的领域差异暴露为通用参数和回调,形成浅 interface。 ## 决策 不创建跨 Campaign 与 Intelligent Evaluation 的通用条件写入 module。两侧保留领域命名的结果类型和 Repository 私有 helper;生命周期 module 继续作为生产调用方的写入 interface。 只有出现第三个真实 adapter,且至少三个调用面共享相同的状态条件、时间策略、字段语义、事务副作用和冲突映射时,才重新评估该 seam。单纯重复 SQL 形状不足以建立新 module。 ## 影响 - 保持领域事务知识的 locality,Campaign 结算变化不会影响 Intelligent Evaluation。 - 接受少量 SQL 模板重复,避免通用字典、回调和类型擦除。 - 测试继续穿过各自 lifecycle interface,断言持久状态和领域副作用,而不是测试通用 SQL helper。