# 系统生命周期与异常处理分析 (System Lifecycle Analysis)

## 1. 核心问题 (Core Issue)
目前系统的业务逻辑缺乏**确定性 (Determinism)** 和 **闭环 (Closed-loop Lifecycle)**。
虽然各个微服务独立运行，但缺乏统一的状态协调机制。当“快乐路径” (Happy Path) 被打断（如DB报错）时，下游服务无法感知上游的失败，导致系统处于“僵尸状态” (Zombie State)。

> **用户反馈**：“有始必有终...你接了这个任务你就要负责把它结束掉...我们既然是微服务,那这个有始有终,可以说是跟生命性一样重要的一个基本原则。”

## 2. 现状分析 (Current State Analysis)

### 2.1 当前的数据流与控制流
```mermaid
sequenceDiagram
    User->>API Gateway: 1. POST /data-requests
    API Gateway->>NATS: 2. Pub "data_fetch_commands"
    
    par Provider Execution
        NATS->>Provider: 3. Receive Command
        Provider->>Provider: 4. Fetch External Data
        Provider-->>DB: 5. Persist Data (Upsert)
    end

    rect rgb(20, 0, 0)
        Note right of DB: [CRITICAL FAILURE POINT]
        DB-->>Provider: 500 Error (Panic)
    end

    alt Happy Path
        Provider->>NATS: 6. Pub "events.financials_persisted"
        NATS->>Report Gen: 7. Trigger Analysis
    else Failure Path (Current)
        Provider->>Log: Log Error
        Provider->>TaskStore: Update Task = Failed
        Note right of Provider: 链条在此断裂 (Chain Breaks Here)
    end
    
    User->>API Gateway: 8. Poll Task Status
    API Gateway-->>User: All Failed
    
    User->>User: 9. Frontend Logic: "All Done" -> Switch to Analysis UI
    User->>API Gateway: 10. Connect SSE (Analysis Stream)
    Note right of User: Hangs forever (Waiting for Report Gen that never started)
```

### 2.2 存在的具体缺陷

1.  **隐式依赖链 (Implicit Dependency Chain)**:
    *   Report Generator 被动等待 `FinancialsPersistedEvent`。如果 Provider 挂了，事件永远不发，Report Generator 就像一个不知道此时该上班的工人，一直在睡觉。
    
2.  **缺乏全局协调者 (Lack of Orchestration)**:
    *   API Gateway 把命令发出去就不管了（除了被动提供查询）。
    *   没有人负责说：“嘿，数据获取全部失败了，取消本次分析任务。”

3.  **前端的状态误判**:
    *   前端认为 `Failed` 也是一种 `Completed`（终止态），这是对的。但前端错误地假设“只要终止了就可以进行下一步”。
    *   **修正原则**：只有 `Success` 才能驱动下一步。`Failed` 应该导致整个工作流的**熔断 (Circuit Break)**。

## 3. 改进方案 (Improvement Plan)

我们需要引入**Rustic**的确定性原则：**如果不能保证成功，就明确地失败。**

### 3.1 方案一：引入显式的工作流状态 (Explicit Workflow State) - 推荐
我们不需要引入沉重的 Workflow Engine (如 Temporal)，但在逻辑上必须闭环。

**后端改进：**
1.  **修复数据库错误**：这是首要任务。`unexpected null` 必须被修复。
2.  **事件驱动的失败传播 (Failure Propagation)**：
    *   如果 Provider 失败，发送 `events.data_fetch_failed`。
    *   Report Generator 或者 API Gateway 监听这个失败事件？
    *   **更好方案**：Report Generator 不需要监听失败。API Gateway 需要聚合状态。

**前端/交互改进：**
1.  **熔断机制**：
    *   在 `useReportEngine` 中，如果所有 Task 都是 `Failed`，**绝对不要**进入 Analysis 阶段。
    *   直接在界面显示：“数据获取失败，无法生成最新报告。是否查看历史数据？”

### 3.2 具体的实施步骤 (Action Items)

#### Phase 1: 修复根本错误 (Fix the Root Cause)
*   **Task**: 调试并修复 `data-persistence-service` 中的 `500 Internal Server Error`。
    *   原因推测：数据库 schema 中某列允许 NULL，但 Rust 代码中定义为非 Option 类型；或者反之。
    *   错误日志：`unexpected null; try decoding as an Option`。

#### Phase 2: 完善生命周期逻辑 (Lifecycle Logic)
*   **Task (Frontend)**: 修改 `useReportEngine`。
    *   逻辑变更：`if (allTasksFailed) { stop(); show_error(); }`
    *   逻辑变更：`if (partialSuccess) { proceed_with_warning(); }`
*   **Task (Backend - ReportGen)**: 增加超时机制。
    *   如果用户连接了 SSE 但长时间没有数据（因为没收到事件），应该发送一个 Timeout 消息给前端，结束连接，而不是无限挂起。

## 4. 结论
目前的“卡在 Analyzing”是因为**上游失败导致下游触发器丢失**，叠加**前端盲目推进流程**导致的。
我们必须：
1.  修好 DB 错误（让快乐路径通畅）。
2.  在前端增加“失败熔断”，不要在没有新数据的情况下假装去分析。

---
*Created: 2025-11-20*

