---
status: 'Active'
created: '2025-11-16'
last_updated: '2025-11-16'
owner: '@lv'
---

# 系统架构设计总览

## 1. 引言

### 1.1. 文档目的

本文档旨在为“基本面选股系统”的事件驱动微服务架构，提供一份统一的、作为“单一事实源”的核心技术蓝图。它整合并取代了多个历史设计文档，旨在清晰、准确地描述当前系统的核心架构理念、服务职责、关键设计以及数据模型。

### 1.2. 核心架构理念

本系统采用纯 Rust 构建的现代化微服务架构，其核心理念根植于“Rustic”风格的健壮性与确定性，遵循以下原则：

- **服务独立化**: 每个外部数据源、每个核心业务能力都被封装成独立的、可独立部署和运行的微服务。
- **事件驱动**: 引入消息总线（Message Bus）作为服务间通信的主干，实现服务的高度解耦和异步协作。
- **数据中心化**: 所有微服务将标准化的数据写入一个由 `data-persistence-service` 独占管理的中央数据库，实现“数据写入即共享”。
- **契约先行**: 所有服务间的通信与数据模型，均通过 `common-contracts` 共享库进行强类型约束，确保系统的一致性与稳定性。

## 2. 架构图与服务职责

### 2.1. 目标架构图

```
+-------------+      +------------------+      +---------------------------+
|             | HTTP |                  |      |                           |
|  前端        |----->|   API 网关        |----->|      消息总线 (NATS)      |
|  (Next.js)  |      |     (Rust)       |      |                           |
|             |      |                  |      |                           |
+-------------+      +-------+----------+      +-------------+-------------+
                             |                                |
        (读操作)             |                                | (发布/订阅 命令与事件)
                             |                                |
           +-----------------v------------------+      +------v------+  +----------------+
           |                                    |      | 数据提供商A |  | 数据提供商B |
           |   数据持久化服务 (Rust)              |<---->| (Tushare)   |  | (Finnhub)      |
           |                                    |      | 服务 (Rust) |  | 服务 (Rust)    |
           +-----------------+------------------+      +-------------+  +----------------+
                             |
                             v
+-----------------------------------------------------+
|                                                     |
|                PostgreSQL 数据库                  |
|                                                     |
+-----------------------------------------------------+
```

### 2.2. 服务职责划分

- **API 网关 (api-gateway)**:
    - 面向前端的唯一入口 (BFF)。
    - 负责用户请求、认证鉴权。
    - 将前端的查询请求，转化为对**数据持久化服务**的数据读取调用。
    - 将前端的操作请求（如“生成新报告”），转化为命令（Command）并发布到**消息总线**。

- **数据提供商服务 (`*_provider-service`)**:
    - 一组独立的微服务，每个服务对应一个外部数据 API。
    - 订阅消息总线上的相关命令（如 `FetchFinancialsRequest`）。
    - 独立调用外部 API，对返回数据进行清洗、标准化。
    - 调用**数据持久化服务**的接口，将标准化后的数据写入数据库。

- **数据持久化服务 (data-persistence-service)**:
    - 数据库的**唯一守门人**，是整个系统中唯一有权直接与数据库交互的服务。
    - 为所有其他内部微服务提供稳定、统一的数据库读写 HTTP 接口。

- **消息总线 (Message Bus)**:
    - 整个系统的神经中枢，负责所有服务间的异步通信。当前选用 **NATS** 作为具体实现。

## 3. `SystemModule` 核心规范

为确保所有微服务行为一致、可观测、易于管理，我们定义了一套名为 `SystemModule` 的设计规范。它并非真实的 Rust Trait，而是一个所有服务都必须遵守的**行为契约**。

**每个微服务都必须：**

1.  **容器化**: 提供一个 `Dockerfile` 用于部署。
2.  **配置驱动**: 从环境变量或配置服务中读取配置，缺少必要配置必须启动失败。
3.  **消息契约**: 严格按照 `common-contracts` 中定义的契约进行消息的订阅和发布。
4.  **暴露标准接口**: 实现一个内置的 HTTP 服务器，并暴露**两个强制性的 API 端点**：
    -   `GET /health`: 返回服务的健康状态。
    -   `GET /tasks`: 返回服务当前正在处理的所有任务列表及其进度。

## 4. 关键服务设计：数据持久化服务

- **核心定位**: 整个微服务架构中**唯一的数据持久化层**。
- **职责边界**: 严格限定在管理跨多个业务领域共享的**核心数据实体**上（如公司信息、财务数据、市场数据、AI分析结果）。
- **API 端点摘要**:
    | Method | Endpoint | 描述 |
    | :--- | :--- | :--- |
    | `PUT` | `/api/v1/companies` | 创建或更新公司基本信息 |
    | `GET` | `/api/v1/companies/{symbol}` | 获取公司基本信息 |
    | `POST` | `/api/v1/market-data/financials/batch` | 批量写入时间序列财务指标 |
    | `GET` | `/api/v1/market-data/financials/{symbol}` | 查询财务指标 |
    | `POST` | `/api/v1/analysis-results` | 保存一条新的 AI 分析结果 |
    | `GET` | `/api/v1/analysis-results` | 查询分析结果列表 |

## 5. 数据库 Schema 设计

### 5.1. 设计哲学

采用**“为不同形态的数据建立专属的、高度优化的持久化方案”**的核心哲学，统一使用 **PostgreSQL** 及其扩展生态。

- **时间序列数据**: 明确采用 **TimescaleDB** 扩展，通过 Hypertables 机制保障高性能的写入与查询。
- **其他数据**: 使用标准的关系表进行存储。

### 5.2. 核心表结构

#### `time_series_financials` (财务指标表 - TimescaleDB)
```sql
CREATE TABLE time_series_financials (
    symbol VARCHAR(32) NOT NULL,
    metric_name VARCHAR(64) NOT NULL,
    period_date DATE NOT NULL,
    value NUMERIC NOT NULL,
    source VARCHAR(64),
    PRIMARY KEY (symbol, metric_name, period_date)
);
SELECT create_hypertable('time_series_financials', 'period_date');
```

#### `daily_market_data` (每日市场数据表 - TimescaleDB)
```sql
CREATE TABLE daily_market_data (
    symbol VARCHAR(32) NOT NULL,
    trade_date DATE NOT NULL,
    open_price NUMERIC,
    close_price NUMERIC,
    volume BIGINT,
    total_mv NUMERIC,
    PRIMARY KEY (symbol, trade_date)
);
SELECT create_hypertable('daily_market_data', 'trade_date');
```

#### `analysis_results` (AI分析结果表)
```sql
CREATE TABLE analysis_results (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    symbol VARCHAR(32) NOT NULL,
    module_id VARCHAR(64) NOT NULL,
    generated_at TIMESTAMTz NOT NULL DEFAULT NOW(),
    content TEXT NOT NULL,
    meta_data JSONB
);
```

#### `company_profiles` (公司基本信息表)
```sql
CREATE TABLE company_profiles (
    symbol VARCHAR(32) PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    industry VARCHAR(255),
    list_date DATE
);
```
