You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
11 KiB
11 KiB
RFC 139: 编辑器数据层统一与分镜看板可扩展重构
状态: 🟡 提议
创建日期: 2026-02-25
目标启动日期: 2026-02-26
目标完成日期: 2026-03-20
作者: Codex(基于现网代码分析)
1. 摘要
当前 ProjectPage 及其子面板存在明显的数据域割裂问题:
- 同一业务域被多套 Hook/接口重复拉取。
- 分镜看板仍以全量数据为中心,分页能力未真正落地。
- 资源面板、预览面板、右侧编辑器对资源信息的来源不统一。
200+分镜场景下,当前链路会出现数据截断和性能退化风险。
本 RFC 提出“统一编辑器数据层 + 分镜看板窗口化加载 + 增量写接口”的完整重构方案,目标是在不牺牲功能的前提下显著降低重复请求、提升可维护性与规模上限。
2. 现状与问题
2.1 现状(关键调用链)
- 页面顶层:
ProjectPage.tsx同时拉useProject/useStoryboards/useScreenplays。 - 分镜看板:
useStoryboardBoardLogic同时拉useStoryboardBoardSkeleton/useStoryboardBoard/useStoryboardsWithDialogues/useResourceLibraryResources(4次)。 - 预览面板:
usePreviewData再次拉useStoryboardsWithDialogues、useProjectElementsForPicker、useResourceLibraryResources、多类详情接口。 - 分镜列表:
StoryboardList独立拉useStoryboards、useScreenplays。 - 资源相关:
useResources(resourceApi)与useResourceLibraryResources并存。 - 左/中/右布局区域对同一资源详情有重复读取(
CenterArea与RightSidebar都调用useResource)。
2.2 已识别的高优先级问题
P0
- 分镜列表请求存在上限风险:
storyboards当前固定pageSize=100。 - 分镜看板主链仍是全量读取,未使用窗口化分页。
storyboardBoardApi.update仍是占位实现,不具备真实持久化语义。useScreenplaysquery key 未包含参数,存在缓存串用风险。
P1
- 同一数据在多个面板重复聚合与重复转换。
useStoryboardsWithDialogues通过“分镜 + 看板字幕轨”二次拼接,导致数据依赖方向反转。- 资源域存在两套模型与两套入口,增加维护复杂度与认知成本。
3. 重构目标
- 统一编辑器数据入口,避免同域重复请求。
- 支持
200~500分镜可用(滚动、拖拽、选择、预览稳定)。 - 分镜看板实现窗口化读取与增量更新。
- 资源域统一数据模型与缓存策略。
- 将“面板逻辑”与“数据获取逻辑”分离,提升可测试性与可演进性。
4. 非目标(本轮不做)
- 不重做 UI/视觉设计。
- 不更改核心业务语义(分镜、资源、标签、对白定义)。
- 不在本 RFC 内覆盖移动端专门优化。
- 不引入新的状态管理库(继续使用 Zustand + TanStack Query)。
5. 设计原则
- 单一事实源:每个业务域只有一个 canonical source。
- 读写分离:读取窗口化、写入增量化。
- 参数即身份:Query Key 必须完整表达查询语义。
- 渐进迁移:允许旧组件短期并存,但由统一 facade 对外。
- 可回滚:每个阶段可独立开关,出现回归可快速切回。
6. 目标架构(推荐)
6.1 编辑器工作区数据层
新增聚合 Hook(前端 facade):
useEditorWorkspaceData(projectId)
对外统一提供:
projectMeta:项目/父项目/剧本目录摘要。storyboardSkeleton:分镜顺序与时长骨架。storyboardWindow:当前可视窗口轨道元素。storyboardDetailMap:按需加载的分镜详情。resourceIndex:统一资源索引(character/location/prop/footage)。selectionContext:当前选中分镜/轨道元素/资源的规范化上下文。
面板(资源、预览、右侧编辑器、分镜看板)只消费 selector,不直接各自拼装跨域数据。
6.2 分镜域数据分层
Skeleton(轻量):id/orderIndex/duration/totalDuration。Window(中量):按startIndex/endIndex + overscan返回轨道元素。Detail(重):点击或编辑时按需拉单分镜详情(含 items、资源映射)。
6.3 资源域统一
以 resource-library 为主模型,废弃编辑器主链对 useResources 的依赖。
统一输出 ResourceViewModel,避免各处重复转换。
7. API 设计调整
7.1 读接口(建议)
- 保留并强化
GET /projects/{id}/storyboard-board/skeleton
- 新增或替换(窗口化)
GET /projects/{id}/storyboard-board/window?startIndex=...&endIndex=...&trackTypes=...
- 详情按需
GET /storyboards/{id}?includeItems=true
- 资源统一索引(可选聚合接口)
GET /projects/{id}/resource-library/index?types=character,location,prop,footage&search=...
7.2 写接口(建议)
严格禁止“整板全量回写”,仅保留增量语义:
POST /projects/{id}/storyboard-board/reorderPATCH /storyboards/{id}(时长/标题/描述)POST /storyboards/{id}/itemsPATCH /storyboard-items/{itemId}(位置/可见性/层级等)DELETE /storyboard-items/{itemId}
8. 前端重构方案
8.1 Query Key 规范化
示例:
screenplayKeys.list(projectId, params)
storyboardBoardKeys.window(projectId, startIndex, endIndex, trackTypes)
resourceKeys.index(projectId, { types, search, page, pageSize })
要求:
- Key 必须包含所有影响结果的参数。
- 禁止同 key 复用不同分页条件。
- selector 层禁止直接
any映射,统一 ViewModel。
8.2 组件职责重分配
ProjectPage:只做路由与工作区生命周期,不直接驱动业务判断请求。StoryboardBoardPanel:只关心渲染与交互,数据通过useEditorWorkspaceData注入。PreviewPanel与RightSidebar:统一消费selectionContext + resourceIndex/detail。ProjectResourcePanel:基于统一资源索引与筛选参数,不再二次拼装。
8.3 逐步淘汰
- 逐步移除
useStoryboardsWithDialogues。 - 逐步将
useResources/useResource迁移到资源库统一域。 - 将
updateStoryboardBoard全量写路径替换为增量 mutation。
9. 分阶段实施计划
阶段 0(2026-02-26 ~ 2026-02-27):止血修复
- 修复
useScreenplayskey 参数缺失。 - 修复
storyboards固定pageSize=100。 - 标注
storyboardBoardApi.update为受控禁用路径(仅本地乐观用途,不作为持久化)。
退出标准:
- 不再出现
screenplays缓存串用。 - 分镜列表可读取
>100数据。
阶段 1(2026-02-28 ~ 2026-03-04):统一读模型
- 新建
useEditorWorkspaceDatafacade。 - 接入 skeleton + window 读取。
- 预览、看板、资源面板切换到 facade selector。
退出标准:
- 同一 project 在一次进入流程中,不再出现同域重复网络请求。
- 面板间切换无额外全量刷新。
阶段 2(2026-03-05 ~ 2026-03-10):增量写模型
- 引入 item 级更新 mutation。
- 分镜重排与时长更新仅走增量接口。
- 移除全量 tracks 回写依赖。
退出标准:
- 拖拽/改时长/增删资源条目均可持久化。
- 无全量 payload 写回。
阶段 3(2026-03-11 ~ 2026-03-15):资源域收敛
- 将编辑器资源读取统一到
resource-library。 - 清理
useResources在编辑器主链的使用点。 - 统一
ResourceViewModel。
退出标准:
- 资源面板、预览、右侧属性使用同一资源缓存域。
- 资源点击联动不再触发跨模型补丁代码。
阶段 4(2026-03-16 ~ 2026-03-20):收尾与观测
- 性能回归测试与错误率监控。
- 移除临时兼容分支与无效 Hook。
- 完成文档与开发指南更新。
10. 验收标准(DoD)
10.1 功能验收
- 资源面板点击资源后,预览与右侧编辑器联动一致。
- 分镜看板点击分镜/元素后,选择态与内容态一致。
- 分镜列表排序与看板顺序无错位。
- 剧本目录、分镜稿列表、看板入口数据源一致。
10.2 性能验收(200 分镜基线)
- 首屏仅拉 skeleton + 首窗口数据。
- 水平滚动仅触发窗口增量请求。
- 看板操作不触发全量列表重拉。
200分镜下交互无明显卡顿(主观可用 + 性能面板无持续长任务尖峰)。
10.3 工程验收
- Query key 全量参数化通过 code review。
- 不再存在整板全量持久化调用。
- 关键链路具备最少集成测试覆盖(看板排序、资源联动、分镜详情按需拉取)。
11. 风险与回滚
11.1 主要风险
- 旧组件依赖隐式字段,迁移期间出现联动回归。
- 增量写接口上线顺序不当,导致乐观更新与服务端状态不一致。
- 资源模型统一时出现类型映射缺漏(尤其标签字段)。
11.2 回滚策略
- 阶段开关:
workspaceDataFacadeEnabled、storyboardWindowEnabled、incrementalBoardMutationEnabled。 - 每阶段保留一条旧链路兜底,发布后观察 24 小时再清理。
- 出现 P0 回归时,按开关回退到前一稳定阶段,不回退数据库结构。
12. 影响范围(预估)
12.1 前端
client/src/pages/ProjectPage.tsxclient/src/hooks/useStoryboardBoardLogic.tsclient/src/hooks/useStoryboardsWithDialogues.ts(逐步废弃)client/src/components/features/preview/hooks/usePreviewData.tsclient/src/components/features/project/ProjectResourcePanel.tsxclient/src/hooks/api/useScreenplays.tsclient/src/hooks/api/useStoryboardBoard.tsclient/src/hooks/api/useResources.ts(编辑器主链移除)
12.2 后端(如配套实施)
storyboard-board读取窗口化接口。storyboard-items增量更新接口能力完善。- 资源库聚合索引接口(可选)。
13. 任务清单(执行版)
- Phase 0: 修复
useScreenplayskey 参数化 - Phase 0: 取消
storyboards固定pageSize=100 - Phase 1: 新建
useEditorWorkspaceData - Phase 1: 接入 skeleton + window 读链路
- Phase 1: 迁移
PreviewPanel/StoryboardBoardPanel/ProjectResourcePanel到 facade selector - Phase 2: 替换全量看板写入为增量 mutation
- Phase 2: 加入看板拖拽/排序/时长变更集成测试
- Phase 3: 统一资源域并移除编辑器主链
useResources - Phase 4: 清理遗留 Hook 与兼容分支
- Phase 4: 更新开发文档与故障排查手册
14. 参考
docs/client/changelogs/2026-02-08-storyboard-board-optimization.mddocs/client/changelogs/2026-01-31-storyboard-performance-optimization.mddocs/client/rfcs/132-screenplay-resources-refactor.mddocs/architecture/adrs/003-storyboard-board-orderindex-optimization.md