# 数据契约 **本文档中引用的文件** - [render-props-types.ts](file://frontend/src/render-props-types.ts) - [data_builder.py](file://backend/data_builder.py) - [mock-data.json](file://src/mock-data.json) - [mock-cashflow.json](file://src/mock-cashflow.json) - [Root.tsx](file://src/Root.tsx) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构概述](#架构概述) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排除指南](#故障排除指南) 9. [结论](#结论) ## 简介 本文件详细描述了视频渲染系统的数据契约,重点是 `render-props-types.ts` 中定义的 `RenderProps` 接口及其 Zod 验证模式。该数据契约作为 Python 后端(数据生成器)与 Remotion 前端(视频渲染器)之间的通信桥梁,确保了 `render_props.json` 文件在运行时的类型安全。文档还结合 `backend/data_builder.py` 的输出结构,说明了如何同步维护前后端的数据模型。 ## 项目结构 该项目采用前后端分离架构,前端使用 Remotion 框架进行视频渲染,后端使用 Python 生成渲染所需的数据。核心数据契约定义在 `frontend/src/render-props-types.ts` 中,而后端数据生成逻辑位于 `backend/data_builder.py`。 ```mermaid graph TB subgraph "前端 (Remotion)" A[render-props-types.ts] --> B[Root.tsx] B --> C[CashFlowChart] B --> D[LifePlanChart] B --> E[DualChartView] end subgraph "后端 (Python)" F[data_builder.py] --> G[FinancialSimulator] G --> H[build_chart_data] end F --> |生成 render_props.json| A ``` **图表来源** - [render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L250) - [data_builder.py](file://backend/data_builder.py#L1-L200) **章节来源** - [render-props-types.ts](file://frontend/src/render-props-types.ts#L1-L250) - [data_builder.py](file://backend/data_builder.py#L1-L200) ## 核心组件 `RenderProps` 接口是整个系统的核心数据模型,它定义了渲染视频所需的所有数据结构,包括元信息、图表数据、脚本和资产引用。`YearlySnapshot` 和 `CashFlowData` 是构成财务模拟数据的基础类型,而 `ScriptSegment` 和 `AssetCollection` 则用于控制视频的叙事和媒体资源。 **章节来源** - [render-props-types.ts](file://frontend/src/render-props-types.ts#L18-L230) ## 架构概述 系统的数据流始于后端的 `data_builder.py`。`FinancialSimulator` 类根据用户输入的财务参数(如当前年龄、退休年龄、资产、收入和支出)模拟未来每年的财务状况,生成 `YearlySnapshot` 数据。然后,`build_cashflow_data` 函数将这些数据转换为更详细的 `CashFlowData` 格式。最终,`build_chart_data` 函数将这些数据组织成 `render_props.json` 的标准格式,供前端使用。 ```mermaid sequenceDiagram participant Backend as "后端 (data_builder.py)" participant Frontend as "前端 (Remotion)" participant Data as "render_props.json" Backend->>Backend : FinancialSimulator.simulate_timeline() Backend->>Backend : build_cashflow_data() Backend->>Backend : build_chart_data() Backend->>Data : 生成 render_props.json Data->>Frontend : 加载数据 Frontend->>Frontend : validateRenderProps() 验证 Frontend->>Frontend : 渲染视频 ``` **图表来源** - [data_builder.py](file://backend/data_builder.py#L15-L200) - [render-props-types.ts](file://frontend/src/render-props-types.ts#L237-L250) ## 详细组件分析 ### RenderProps 接口分析 `RenderProps` 接口是数据契约的顶层结构,它包含四个主要部分:`meta`、`charts`、`script` 和 `assets`。 ```mermaid classDiagram class RenderProps { +meta : Meta +charts : Charts +script : ScriptSegment[] +assets : AssetCollection } class Meta { +title : string +currencyUnit : string +duration : number +clientName? : string +generatedAt? : string } class Charts { +assetDepletion : AssetDepletionChartData +cashFlow : CashFlowChartData } class AssetDepletionChartData { +timeline : YearlySnapshot[] } class CashFlowChartData { +timeline : CashFlowData[] } class YearlySnapshot { +currencyUnit : string +startYear : number } class CashFlowData { +currencyUnit : string } RenderProps --> Meta RenderProps --> Charts Charts --> AssetDepletionChartData Charts --> CashFlowChartData AssetDepletionChartData --> YearlySnapshot CashFlowChartData --> CashFlowData ``` **图表来源** - [render-props-types.ts](file://frontend/src/render-props-types.ts#L117-L134) ### 核心数据类型分析 `YearlySnapshot` 和 `CashFlowData` 是系统中最核心的两个数据类型,它们分别代表了资产消耗和现金流的年度数据。 ```mermaid classDiagram class YearlySnapshot { +year : number +ages_rep : number +ages_spouse? : number +financials_income : number +financials_expenditure : number +financials_assetBalance : number +events? : string[] +isCritical? : boolean } class CashFlowData { +year : number +age : number +income_total : number +expenses_living : number +expenses_housing : number +expenses_education : number +expenses_tax : number +expenses_event : number +totalExpense? : number +netCashFlow? : number +assetBalance? : number } YearlySnapshot --> "1" AssetDepletionChartData : "包含" CashFlowData --> "1" CashFlowChartData : "包含" ``` **图表来源** - [render-props-types.ts](file://frontend/src/render-props-types.ts#L18-L49) ### 脚本与资产分析 `ScriptSegment` 定义了视频的叙事结构,而 `AssetCollection` 则管理了视频中使用的所有媒体资源。 ```mermaid classDiagram class ScriptSegment { +id : number +text : string +duration : number +type : ScriptSegmentType +assetUrl? : string +chartSync? : ChartSync } class ChartSync { +chartId : "assetDepletion" | "cashFlow" +highlightYear? : number +animationStart? : number } class AssetCollection { +broll : Record +videoClips : VideoClipReference[] +ttsAudio? : string } class VideoClipReference { +id : string +sourcePath : string +startTime : number +duration : number +outputPath? : string } ScriptSegment --> ChartSync AssetCollection --> VideoClipReference ``` **图表来源** - [render-props-types.ts](file://frontend/src/render-props-types.ts#L81-L111) ## 依赖分析 该系统的关键依赖是 `zod` 库,它用于在运行时验证 `render_props.json` 的数据结构。`render-props-types.ts` 中的 `RenderPropsSchema` 确保了从后端传来的数据符合预期的格式,防止了因数据错误导致的渲染失败。 ```mermaid graph TD A[render-props-types.ts] --> B[zod] B --> C[RenderPropsSchema] C --> D[validateRenderProps] C --> E[isRenderProps] F[data_builder.py] --> A A --> G[Root.tsx] ``` **图表来源** - [render-props-types.ts](file://frontend/src/render-props-types.ts#L12-L250) **章节来源** - [render-props-types.ts](file://frontend/src/render-props-types.ts#L12-L250) ## 性能考虑 Zod 的运行时验证虽然增加了少量开销,但极大地提高了系统的健壮性。对于大型数据集,可以考虑在开发环境中进行严格验证,在生产环境中使用 `isRenderProps` 进行轻量级检查,以平衡安全性和性能。 ## 故障排除指南 当视频渲染失败时,最常见的原因是 `render_props.json` 数据格式错误。应首先使用 `validateRenderProps` 函数检查数据的有效性。如果验证失败,Zod 会提供详细的错误信息,指出具体是哪个字段不符合预期。 **章节来源** - [render-props-types.ts](file://frontend/src/render-props-types.ts#L241-L250) ## 结论 该视频渲染系统的数据契约设计清晰,通过 TypeScript 接口和 Zod 模式实现了前后端之间的强类型通信。`RenderProps` 接口及其子类型构成了一个完整、可扩展的数据模型,能够支持复杂的财务模拟和视频叙事。通过 `validateRenderProps` 和 `isRenderProps` 辅助函数,系统在运行时具备了强大的数据验证能力,确保了渲染过程的稳定性和可靠性。