# 规则:BC 边界 —— 禁跨域 DAL 直连(ArchUnit 机械门禁) > **类型**:硬约束(rules) · **状态**:生效 2026-06-14 · **门禁**:ArchUnit(机械阻断,非自觉) > **上位**:[`verification-and-anti-false-green.md`](verification-and-anti-false-green.md) §二.6 > **由来**:对抗复盘 A4——软约束下 AI 模块 `ContentMuseWorkOwnerFacade` 直连 content 的 `WorkMapper/ChapterMapper/BlockMapper` + `WorkDO/ChapterDO/BlockDO`,实质破了"模块化单体 + 清晰 BC 边界"(ADR)的根基,且会随时间蔓延、拆服务时代价爆炸。 --- ## 一、规则 - 一个业务域(BC)模块**不得 import / 依赖他域的 DAL**(`.dal..`,含 dataobject 与 mysql Mapper)。 - 跨 BC 读写**只能走对外 API 或 facade-api 契约**(本域定义端口,他域提供适配器;或经对外 API)。 - 本域读自己的 DAL 不受限。 > 正面范例:P1 增量 2 的 `AiSuggestionMergeProjectionFacade` —— AI 实现 content 的 `ContentAiSuggestionFacade` 端口、只读 **AI 自有** suggestion 库,**不碰 content DAL**,即合规的跨 BC 接缝。 --- ## 二、机械门禁(不是自觉) - 测试:`muse-server/src/test/java/cn/iocoder/muse/server/framework/arch/BcBoundaryArchTest.java`(ArchUnit 1.3.0)。 - CI:随 `muse-cloud/.github/workflows/maven.yml`(P0 已打开测试门、JDK21)在 PR/push 阻断。 - 任何**新增**跨域 DAL 依赖 → 测试红 → 阻断合入。 --- ## 三、违例登记与整改 **当前无任何豁免**——`BcBoundaryArchTest` 已不含 `haveNameNotMatching`,任何 AI→他域 DAL 依赖一律红。 ### 已整改(历史) | 违例类 | 曾经内容 | 整改 | 验收(2026-06-14) | |---|---|---|---| | `module.ai.application.muse.facade.ContentMuseWorkOwnerFacade` | 直连 content `WorkMapper/ChapterMapper/BlockMapper` + `WorkDO/ChapterDO/BlockDO`(字节码 31 处依赖) | content 暴露对外只读端口 `MuseContentWorkOwnerApi`(content-api 定义、content-server 实现读自有 DAL);AI 适配器改消费该端口,移除全部 content.dal 依赖,AI 业务规则不变 | 反向:删豁免+旧码 → 门禁红、精确报 31 例;正向:整改+删豁免 → 门禁**绿**(收紧),适配器单测 13/0F、端口实现单测 7/0F | > 豁免一律视为**临时**:违例消除后必须从 `haveNameNotMatching` 删除该类,使门禁收紧——**收紧即整改验收**(本条已完成,豁免已清零)。新违例不在任何豁免内,一律红。 --- ## 四、扩展方式 - 新增 BC 间约束(如禁 content→ai.dal、禁前端契约外的耦合)按同样方式在 `BcBoundaryArchTest` 加 `@Test` 规则。 - 违例消除后,从对应 `haveNameNotMatching` 豁免里删掉该类,门禁随即收紧——**收紧动作本身就是整改完成的验收**。