# 全栈一致性与历史回放增强设计 (Unified Architecture Design)

## 1. 背景与目标

当前系统存在三个主要割裂点：
1.  **节点行为不一致**: Analysis 节点输出报告，而部分 Data Provider (YFinance/Mock) 仅抓取数据无可视化输出（虽已部分修复，但缺乏强制规范）。
2.  **实时与历史割裂**: 实时页面依赖 SSE 推送，历史页面缺乏状态恢复机制，导致无法查看 DAG 结构和执行日志。
3.  **日志展示分散**: 实时日志是全局流，难以对应到具体任务；历史日志未与 UI 深度集成。

**本设计旨在将上述问题合并为一个系统性工程，实现以下目标：**
*   **后端标准化**: 所有节点必须通过统一 Trait 实现，强制产出 Markdown 报告和流式更新。
*   **前端统一化**: 使用同一套 `ReportPage` 逻辑处理“实时监控”和“历史回放”。
*   **上下文完整性**: 无论是实时还是历史，都能查看 DAG 状态、节点报告、以及执行日志 (`_execution.md`)。

---

## 2. 后端架构升级 (Backend Architecture)

### 2.1. 统一节点运行时 (`WorkflowNode` Trait)

引入强制性接口，确保所有 Worker 行为一致。

*   **Trait 定义**:
    ```rust
    #[async_trait]
    pub trait WorkflowNode {
        async fn execute(&self, ctx: &NodeContext, config: &Value) -> Result<NodeExecutionResult>;
        fn render_report(&self, result: &NodeExecutionResult) -> Result<String>;
    }
    ```
*   **`WorkflowNodeRunner` (Harness)**:
    *   **职责**: 负责 NATS 订阅、VGCS 读写、Git Commit、错误处理。
    *   **增强**: 
        *   自动将 `execute` 产生的日志写入 `_execution.md`。
        *   自动推送 `TaskStreamUpdate` (包含 Report Markdown)。
        *   自动推送 `TaskLog` (带 `task_id` 的结构化日志，用于前端分流)。

### 2.2. 工作流快照持久化 (Snapshot Persistence)

为了支持历史回放，Orchestrator 必须在工作流结束时保存“案发现场”。

*   **触发时机**: `handle_task_completed` 检测到 Workflow 结束 (Completed/Failed)。
*   **保存内容**: `WorkflowStateSnapshot` (DAG 结构、每个 Task 的最终 Status、Output Commit Hash)。
*   **存储位置**: `data-persistence-service` -> `session_data` 表。
    *   `data_type`: "workflow_snapshot"
    *   `request_id`: workflow_id
*   **API**: `GET /api/v1/workflow/snapshot/{request_id}` (API Gateway 转发)。

---

## 3. 前端架构升级 (Frontend Architecture)

### 3.1. 统一状态管理 (`useWorkflowStore`)

改造 Store 以支持“双模式”加载。

*   **State**: 增加 `mode: 'realtime' | 'historical'`。
*   **Action `initialize(id)`**:
    1.  重置 Store。
    2.  **尝试 SSE 连接** (`/api/v1/workflow/events/{id}`)。
        *   如果连接成功且收到 `WorkflowStarted` / `TaskStateChanged`，进入 **Realtime Mode**。
    3.  **并行/Fallback 调用 Snapshot API** (`/api/v1/workflow/snapshot/{id}`)。
        *   如果 SSE 连接失败（404/Closed，说明任务已结束），或者 Snapshot 返回了数据：
        *   调用 `loadFromSnapshot(snapshot)` 填充 DAG 和 Task 状态。
        *   进入 **Historical Mode**。

### 3.2. 统一页面逻辑 (`ReportPage.tsx`)

不再区分 `HistoricalReportPage`，统一使用 `ReportPage`。

*   **DAG 可视化**: 复用 `WorkflowVisualizer`，数据源由 Store 提供（无论是 SSE 来的还是 Snapshot 来的）。
*   **状态指示**:
    *   实时模式：显示 Spinner 和实时进度。
    *   历史模式：显示最终结果 Badge，并提示“Viewing History”。

### 3.3. 沉浸式报告与调试面板 (Immersive Report & Debugging Panel)

为了提升用户体验，我们将摒弃原本“三等分标签页”的设计，采用 **"主视图 + 侧边栏"** 的布局策略，实现“隐形调试”。

*   **主视图 (Main View - The Report)**:
    *   **定位**: 面向最终用户，强调阅读体验。
    *   **布局**: 占据屏幕中央核心区域，无干扰展示 Markdown 渲染结果。
    *   **状态栏**: 顶部仅保留最关键信息（任务状态 Badge、耗时）。
*   **调试面板 (Debug Panel - The Inspector)**:
    *   **定位**: 面向开发者和排查问题，默认隐藏。
    *   **入口**: 顶部导航栏右侧的 "Terminal/Code" 图标按钮。
    *   **交互**: 点击从屏幕右侧滑出 (Sheet/Drawer)，支持拖拽调整宽度。
    *   **内容结构**: 面板内采用 Tabs 组织调试信息：
        1.  **Logs**: 聚合实时流日志与 `_execution.md` 回放。
        2.  **Context**: 文件系统快照 (Context Explorer)，展示 Input/Output 文件及 Diff。
        3.  **Raw**: 任务原始配置 (Config) 与元数据 (Metadata)。

这样的设计实现了“一步到位”：普通用户完全感知不到调试页面的存在，而开发者只需一次点击即可获得所有深层上下文。

### 3.4. 历史记录入口 (`RecentReports`)

*   **组件**: `RecentReportsDropdown` (Header 区域)。
*   **逻辑**: 调用 `GET /api/v1/analysis-results?limit=10`。
*   **跳转**: 点击跳转到 `/report/{id}` (复用统一页面)。

---

## 4. 实施计划 (Implementation Plan)

### Phase 1: 后端 - 统一运行时 (Backend Standardization)
1.  在 `common-contracts` 实现 `WorkflowNode` Trait 和 `WorkflowNodeRunner`。
2.  重构 `yfinance`, `tushare`, `mock` Provider 使用新架构。
    *   确保它们都生成 `report.md` 和 `_execution.md`。
3.  验证实时流推送是否包含正确的 `task_id` 日志。

### Phase 2: 后端 - 快照持久化 (Snapshot Persistence)
1.  `workflow-orchestrator`: 结束时保存 `WorkflowStateSnapshot` 到 Session Data。
2.  `api-gateway`: 暴露 Snapshot 查询接口。
3.  `data-persistence`: 优化 `get_analysis_results` 支持全局最近 10 条查询。

### Phase 3: 前端 - 统一页面与日志 (Frontend Unification)
1.  改造 `useWorkflowStore` 支持 Snapshot Hydration。
2.  改造 `ReportPage` 实现 SSE + Snapshot 双重加载策略。
3.  改造 `TaskDetailView` 为“沉浸式”布局：
    *   默认仅展示 Markdown Viewer。
    *   添加 Right Sheet 组件承载 Logs/Context。
4.  实现 `RecentReportsDropdown`。

### Phase 4: 清理与验证
1.  删除旧的 `HistoricalReportPage` 路由和组件。
2.  验证全流程：
    *   **实时**: 启动新任务 -> 看到 DAG 生长 -> 看到节点实时 Log -> 看到 Report 生成。
    *   **历史**: 点击下拉框 -> 加载旧任务 -> 看到完整 DAG -> 点击节点看到 Report -> 打开 Inspector 看到 Logs。

---

## 5. 废弃文档

本设计取代以下文档：
- `docs/3_project_management/tasks/pending/20251128_backend_unified_worker_trait.md`
- `tasks/pending/20251128_historical_playback_design.md`
- `docs/3_project_management/tasks/pending/20251128_historical_reports_design.md`
