- 新增评审版:projectionKey≡schemaKey、列表=work targetType 匹配多 schema(人类第四轮+评审走查决策)、RealContentMetaFacade 置 content-server 调 meta-api+回填本域 planning value、可见性起步版本级;含 design-docs SSOT 约束、关键决策表、边界数据流、blast/风险/验收/open items。 - execution 总账回写 B5c 前端完成 + projection 缺环发现(ContentMetaFacade 真后端 unavailable,e2e 实为真后端活体)+ 第四轮决策。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9.2 KiB
9.2 KiB
Meta-Projection 投影实现(补 B 缺环)—— 评审版
版本:v0.1(评审版) · 日期:2026-06-21 · 目标读者:架构 review + 实现 agent · 类型:评审版(结论先行,无代码细节) 上游:用量投影执行版第四轮决策(补 Meta owner projection 实现 + 完整投影分组建模)。 触发:B5 前端 PlanningEditor 依赖的 meta-projection 端口真后端 unavailable(
ContentMetaFacade仅 stub),B 落地链漏列了「Meta owner 投影实现」这一跨 BC 环。
一、结论先行
- 目标:让
GET /works/{workId}/meta-projections[/{projectionKey}]从 stub-unavailable 变为真实返回字段定义 + 字段级可见性 + 已存值回填,使 B5 PlanningEditor 端到端真跑(用户按 schema 字段填值→usedFieldKeys→快照→字段级计数)。 - 推荐方案(一句话):projectionKey ≡ schemaKey(对齐 design-docs);
RealContentMetaFacade置 content-server,调新增 meta-api 端口拿「字段定义+字段级可见性」,读本域 planning 回填 value,组装投影;起步以 work 当前绑定的单 schema 为投影列表,预留多 schema 演进。 - 关键依据(design-docs SSOT 已定义,实现须遵守):
- 投影是 read model(MetaSchema+权限+来源状态+dataRevision 动态计算),owner = MetaSchema BC,绝非事实源(后端-05 §4.3、架构-02 §4.2)。
- projectionKey 倾向 = schema_key(domain/scope/target_type 下唯一稳定业务键,后端-04 §4.7)。
- 5 可见性(uiVisible/aiContext/userEditable/userSearchable/exportable)= 策略级,由
muse_meta_visibility_policy管,语义不可合并(架构-02 §9)。 - 三版本 schemaVersion/projectionVersion/dataRevision 语义与递增条件已定(前端-03 §5.3、后端-05 §4.3)。
- 字段写入走 writeOwner/ownerCommand(如 planning:
PUT /works/{workId}/planning/{sectionKey}),无跨 owner 通用写口。
- 架构空白(design-docs 未明确,本评审拍板点见 §四/§九):① work↔多 schema 关联规则;② 字段↔投影分组存储映射;③ 多分组返回契约;④ 可见性字段级 vs 版本级粒度。
二、背景与缺环
- B5 前端(已完成):
usePlanninghooks +PlanningEditor(按 fieldType 渲染) +PlanningEditorPanel(列 projection→选→编辑,unavailable 优雅降级) + WorkspacePage 右侧 Tab 集成。vitest 全量 66/66。 - 缺环(自验反假绿):
ContentMetaProjectionServiceImpl转调ContentMetaFacade,但全仓仅UnavailableContentMetaFacade(@ConditionalOnMissingBean)→ 真后端返CONTENT_EXTERNAL_OWNER_UNAVAILABLE。playwright e2e 是真后端活体(VITE_API_MOCK=false),故 UI 全链路真跑必须先让 projection 真实可用。 - meta-api 现状:
MetaSchemaQueryApi仅listActiveSchemasByTargetType/getActiveSchemaById(返 brief:id/schemaKey/displayName/targetType),无字段定义、无可见性、无投影分组查询。
三、范围与非目标
范围
- 新增 meta-api 投影查询端口(字段定义 + 字段级可见性聚合)。
- meta-server 实现该端口(只读 active schema 的
MetaFieldDO+MetaVisibilityPolicyDO)。 - content-server
RealContentMetaFacade(替换 Unavailable):调 meta-api + 读本域 planning 回填 value + 组装MetaProjectionSummary/Detail/FieldRespVO。 - DynamicFieldValidation 真实化(校验字段类型/必填/枚举,返路由建议;不写事实)。
非目标(本轮)
- 不引入 schema 内字段分组子表(projectionKey≡schemaKey,schema 即投影单元;多 projection = 多 schema)。
- 不解决 work↔多 schema 的完整关联建模(起步用 work 单绑定;演进见 §九)。
- 不改 3 版本递增的既有产出点(沿用现有 schema/projection version 字段)。
四、关键决策(拍板点)
| # | 决策 | 选项 | 推荐 | 理由 |
|---|---|---|---|---|
| D-A | projectionKey 语义 | (a) =schemaKey;(b) schema 内分组键(需新表) | (a) | design-docs 后端-04 §4.7 schema_key 为唯一业务键;前端-02 的「作品设定/世界设定/角色关系…」对应不同 domain/scope 的 schema,非单 schema 内分组→无须新分组表 |
| D-B | work 的 projection 列表来源 | (a) work 单绑定 schema(1 个);(b) 按 targetType 匹配多 active schema;(c) work↔schema 多对多新表 | (a) 起步,预留 (b) | D1 已落 workSchemaId 单绑定,最小一致、零新建;(b)/(c) 涉 design-docs 空白(work 适用哪些 schema),留演进 |
| D-C | 字段级可见性粒度 | (a) 解析 policySnapshot JSON 取字段级;(b) 版本级统一应用到所有字段 | (a) 若快照含字段级,否则 (b) | 执行版 §四.3 实证字段级可见性在 policySnapshot/fieldContractSnapshot JSON;须实现期验证快照结构,不满足则降级 (b) 并声明 |
| D-D | RealContentMetaFacade 放置 | (a) content-server;(b) meta-server | (a) | value 回填须读 content 本域 planning;content 调 meta-api 拿定义合边界(参照 RealContentFileFacade 先例);meta 读 content 反向违边界 |
| D-E | meta-api 端口形态 | (a) 扩 MetaSchemaQueryApi;(b) 新增 MetaProjectionQueryApi |
(b) | 投影查询(字段+可见性)与 schema 发现职责不同,独立端口更清晰、不污染现有契约 |
五、推荐方案数据流
flowchart TD
FE[muse-studio PlanningEditorPanel] -->|GET /works/workId/meta-projections| C1[AppContentMetaProjectionController]
C1 --> C2[ContentMetaProjectionServiceImpl\nrequireOwnedWork 权限校验]
C2 --> F[RealContentMetaFacade\ncontent-server, @Component @Primary]
F -->|work.workSchemaId| W[(本域 WorkDO)]
F -->|projectionKey=schemaKey 拿字段+可见性| API[MetaProjectionQueryApi\nmeta-api 端口 新增]
API --> M[meta-server 实现\n读 MetaFieldDO+MetaVisibilityPolicyDO active]
F -->|按 fieldKey 回填 value| P[(本域 PlanningSectionDO.contentPayload)]
F --> R[组装 MetaProjectionDetailRespVO\n字段定义+可见性+value+sourceSnapshot]
R --> C2
C2 -->|available=false 即 fail-closed| X[CONTENT_EXTERNAL_OWNER_UNAVAILABLE]
subgraph 边界门 BcBoundaryArchTest 0 违例
API
end
F -. 仅依赖 meta-api 端口,不直连 meta.dal .-> API
职责切分(合边界):Meta 出「字段定义+可见性」(自域只读);Content 出「权限校验 + value 回填 + 投影组装」(本域只读 + 调 meta-api 端口)。
六、Blast Radius / 兼容 / 回滚
- meta-api:新增
MetaProjectionQueryApi+ DTO(只增,无既有契约改动)。 - meta-server:新增端口实现(只读 schema/可见性,不写)。
- content-server:新增
RealContentMetaFacade@Component @Primary替换 stub;ContentMetaProjectionServiceImpl/Controller 不改(已转调 facade)。 - 边界门:content 仅依赖 meta-api 端口 + 本域 DAL;
BcBoundaryArchTest须保持 0 违例(验收硬条件)。 - 兼容:projection 端点对外契约不变(VO 不动);仅从「恒 unavailable」变「真实返回」。
- 回滚:移除
RealContentMetaFacade的@Primary即回到 Unavailable stub(平滑)。
七、风险与缓解
| 风险 | 说明 | 缓解 |
|---|---|---|
| projectionKey=schemaKey 系推断 | design-docs 未逐字明说「projectionKey==schema_key」 | §九 列为人类确认点;若否,改 D-A(b) 需新分组表(范围扩大) |
| work↔多 schema 未定 | 前端-02 列 5 入口但 work 单绑定 | 起步单 schema(D-B a);多 schema 留演进,不阻塞 B5 |
| 可见性粒度不定 | policySnapshot 结构待实现期验证 | D-C:验证后字段级,否则版本级降级并声明 |
| 真后端无 active schema | 本地 fixture 可能无 governance 配置的 schema | meta-projections 空列表→前端已有优雅降级(不崩);e2e 需 fixture 含 active schema(globalSetup) |
| fail-closed 语义 | 任一 meta-api 失败/数据缺失 | facade 一律返 unavailable,绝不伪造部分投影(anti-false-green) |
八、验收标准
- meta-api
MetaProjectionQueryApi端口 + meta-server 实现:种 active schema → 返回字段定义 + 可见性(单测/IT)。 RealContentMetaFacade:work 绑 schema → meta-projections 真实返回字段(非 unavailable);value 从 planning 回填正确(单测)。- 边界:
BcBoundaryArchTest0 违例;恰一个ContentMetaFacadeBean。 - 端到端(真后端活体):B5 e2e——进作品规划 Tab → 字段渲染 → 填值保存 → usedFieldKeys 落快照 → 值回填(playwright,需 fixture 含 active schema)。
- 反假绿:无 active schema/数据缺失一律 unavailable+前端降级,绝不伪造字段。
九、Open Items(须人类确认)
- (拍板)projectionKey ≡ schemaKey? 若确认→无须新分组表(推荐);若 projectionKey 是 schema 内分组→须新建字段↔分组映射(范围显著扩大)。
- (拍板)work 的 projection 列表起步用单绑定 schema? 还是本轮即做 targetType 匹配多 schema(需定「work 适用哪些 schema」规则)?
- 可见性字段级 vs 版本级:实现期验证 policySnapshot 结构后定(D-C 已含降级)。
- DynamicFieldValidation 真实校验范围:本轮做类型/必填/枚举 + 路由建议是否足够?
下一步:本评审走查确认 §九.1/§九.2 两个拍板点后,出执行版 spec(端口契约 + 数据流 + 边界验收 + 分步)并实现。