# 重构任务：统一 Data Provider 工作流抽象

## 1. 背景 (Background)

目前的 Data Provider 服务（Tushare, YFinance, AlphaVantage 等）在架构上存在严重的重复代码和实现不一致问题。每个服务都独立实现了完整的工作流，包括：
- NATS 消息接收与反序列化
- 缓存检查与写入 (Cache-Aside Pattern)
- 任务状态管理 (Observability/Task Progress)
- Session Data 持久化
- NATS 事件发布 (Success/Failure events)

这种"散弹式"架构导致了以下问题：
1.  **Bug 易发且难以统一修复**：例如 Tushare 服务因未执行 NATS Flush 导致事件丢失，而 YFinance 却因为实现方式不同而没有此问题。修复一个 Bug 需要在每个服务中重复操作。
2.  **逻辑不一致**：不同 Provider 对缓存策略、错误处理、重试机制的实现可能存在细微差异，违背了系统的统一性。
3.  **维护成本高**：新增一个 Provider 需要复制粘贴大量基础设施代码（Boilerplate），容易出错。

## 2. 目标 (Objectives)

贯彻 "Rustic" 的设计理念（强类型、单一来源、早失败），通过控制反转（IoC）和模板方法模式，将**业务逻辑**与**基础设施逻辑**彻底分离。

- **单一来源 (Single Source of Truth)**：工作流的核心逻辑（缓存、持久化、通知）只在一个地方定义和维护。
- **降低耦合**：具体 Provider 只需关注 "如何从 API 获取数据"，而无需关心 "如何与系统交互"。
- **提升稳定性**：统一修复基础设施层面的问题（如 NATS Flush），所有 Provider 自动受益。

## 3. 技术方案 (Technical Design)

### 3.1 核心抽象 (The Trait)

在 `common-contracts` 中定义纯粹的业务逻辑接口：

```rust
#[async_trait]
pub trait DataProviderLogic: Send + Sync {
    /// Provider 的唯一标识符 (e.g., "tushare", "yfinance")
    fn provider_id(&self) -> &str;

    /// 检查是否支持该市场 (前置检查)
    fn supports_market(&self, market: &str) -> bool {
        true
    }

    /// 核心业务：从外部源获取原始数据并转换为标准 DTO
    /// 不涉及任何 DB 或 NATS 操作
    async fn fetch_data(&self, symbol: &str) -> Result<(CompanyProfileDto, Vec<TimeSeriesFinancialDto>), anyhow::Error>;
}
```

### 3.2 通用工作流引擎 (The Engine)

实现一个泛型结构体或函数 `StandardFetchWorkflow`，封装所有基础设施逻辑：

1.  **接收指令**：解析 `FetchCompanyDataCommand`。
2.  **前置检查**：调用 `supports_market`。
3.  **状态更新**：向 `AppState` 写入 "InProgress"。
4.  **缓存层**：
    *   检查 `persistence_client` 缓存。
    *   HIT -> 直接返回。
    *   MISS -> 调用 `fetch_data`，然后写入缓存。
5.  **持久化层**：将结果写入 `SessionData`。
6.  **事件通知**：
    *   构建 `FinancialsPersistedEvent`。
    *   发布 NATS 消息。
    *   **关键：执行 `flush().await`。**
7.  **错误处理**：统一捕获错误，发布 `DataFetchFailedEvent`，更新 Task 状态为 Failed。

## 4. 执行步骤 (Execution Plan)

1.  **基础设施准备**：
    *   在 `services/common-contracts` 中添加 `DataProviderLogic` trait。
    *   在 `services/common-contracts` (或新建 `service-kit` 模块) 中实现 `StandardFetchWorkflow`。

2.  **重构 Tushare Service**：
    *   创建 `TushareFetcher` 实现 `DataProviderLogic`。
    *   删除 `worker.rs` 中的冗余代码，替换为对 `StandardFetchWorkflow` 的调用。
    *   验证 NATS Flush 问题是否自然解决。

3.  **重构 YFinance Service**：
    *   同样方式重构，验证通用性。

4.  **验证**：
    *   运行 E2E 测试，确保数据获取流程依然通畅。

## 5. 验收标准 (Acceptance Criteria)

- `common-contracts` 中包含清晰的 Trait 定义。
- Tushare 和 YFinance 的 `worker.rs` 代码量显著减少（预计减少 60%+）。
- 所有 Provider 的行为（日志格式、状态更新频率、缓存行为）完全一致。
- 即使不手动写 `flush`，重构后的 Provider 也能可靠发送 NATS 消息。

