# Rust 后端 - 改进计划

## 一、代码质量与架构改进

### 1.1 代码组织问题
- [ ] **所有路由处理器都在 main.rs 中**
  - 现状：`main.rs` 包含所有路由处理器，文件过大（800+ 行）
  - 改进：按功能模块拆分到独立文件
    - `handlers/auth.rs` - 登录相关
    - `handlers/weather.rs` - 天气数据相关
    - `handlers/user.rs` - 用户相关
    - `handlers/admin.rs` - 管理员相关
  - 影响：提高代码可维护性

- [ ] **config.rs 是死代码**
  - 现状：AGENTS.md 中提到 config.rs 未被使用
  - 改进：要么启用配置管理，要么删除该文件
  - 影响：减少代码混淆

### 1.2 数据库操作优化
- [ ] **重复查询问题**
  - 位置：`insert_weather_data` 中多次查询用户信息
  - 改进：合并查询或使用缓存
  - 影响：减少数据库负载

- [ ] **缺少数据库索引**
  - 现状：未见索引定义
  - 改进：添加常用查询字段索引
    ```sql
    CREATE INDEX idx_weather_data_user_id ON weather_data(user_id);
    CREATE INDEX idx_weather_data_date ON weather_data(date);
    CREATE INDEX idx_users_openid ON users(openid);
    ```

### 1.3 错误处理改进
- [x] **错误响应格式不统一** ✅
  - 现状：部分返回 `ErrorResponse`，部分返回 JSON 字符串
  - 改进：统一使用 `ErrorResponse` 结构体
  - 彰响：前端解析更一致
  - 完成时间：2026-04-15

- [x] **错误信息暴露过多** ✅
  - 现状：部分错误直接返回数据库错误信息
  - 改进：区分用户友好错误和开发者错误
  - 影响：安全性提升
  - 完成时间：2026-04-15
  - 修改：移除所有 `errmsg: Some(e.to_string())`，错误详情只记录到日志

## 二、安全性改进

### 2.1 认证安全
- [ ] **缺少请求频率限制**
  - 风险：API 可能被滥用或遭受暴力攻击
  - 改进：添加 Rate Limiting 中间件
  - 实现：使用 `actix-limitation` 或自定义中间件
  - 配置：
    - 登录接口：5 次/分钟
    - 数据上传：30 次/分钟
    - 查询接口：100 次/分钟

- [ ] **缺少 CSRF 防护**
  - 风险：跨站请求伪造攻击
  - 改进：添加 CSRF Token 验证
  - 实现：对于状态变更操作验证 Token

- [ ] **JWT Secret 管理**
  - 现状：明文存储在环境变量
  - 改进：使用密钥管理服务（如 AWS Secrets Manager）
  - 影响：提高密钥安全性

### 2.2 数据安全
- [ ] **数据库连接字符串明文存储**
  - 位置：`.env` 文件
  - 改进：使用连接字符串加密或密钥管理
  - 影响：防止凭证泄露

- [ ] **缺少敏感数据加密**
  - 现状：用户信息明文存储
  - 改进：对敏感字段加密存储
  - 字段：手机号、姓名等

- [ ] **缺少审计日志**
  - 需求：记录关键操作日志
  - 实现：添加审计日志表和中间件
  - 记录：登录、数据修改、管理员操作

### 2.3 输入验证
- [ ] **后端输入验证不完整**
  - 现状：部分依赖前端验证
  - 改进：添加完整的请求验证
  - 实现：使用 `validator` crate

## 三、性能优化

### 3.1 数据库性能
- [ ] **缺少连接池监控**
  - 现状：连接池配置固定
  - 改进：添加连接池监控和动态调整
  - 指标：连接数、等待时间、超时次数

- [ ] **缺少查询缓存**
  - 场景：用户信息、配置数据
  - 改进：添加 Redis 缓存层
  - 策略：用户信息缓存 5 分钟，配置数据缓存 1 小时

- [ ] **无读写分离支持**
  - 需求：高并发场景下的性能优化
  - 改进：支持主从数据库配置
  - 实现：使用 sqlx 的多数据源支持

### 3.2 API 性能
- [ ] **无响应压缩**
  - 现状：响应未压缩
  - 改进：添加 gzip 压缩中间件
  - 实现：使用 `actix-web` 的压缩功能

- [ ] **缺少 API 缓存**
  - 场景：天气数据列表查询
  - 改进：添加 HTTP 缓存头
  - 实现：`Cache-Control`、`ETag` 等

- [ ] **无 CDN 支持**
  - 场景：静态资源分发
  - 改进：配置 CDN 加速
  - 资源：CSS、JS、图片、字体

## 四、功能完整性改进

### 4.1 API 功能扩展
- [ ] **缺少批量操作接口**
  - 需求：批量删除、批量查询
  - 实现：添加批量操作端点
  - 接口：`POST /weather/batch-delete`、`POST /weather/batch-query`

- [ ] **无数据导出格式支持**
  - 需求：支持 CSV、Excel 导出
  - 实现：添加导出端点
  - 接口：`GET /weather/export?format=csv`

- [ ] **缺少搜索和过滤功能**
  - 需求：按日期、标题、地点搜索
  - 实现：添加搜索参数
  - 参数：`?keyword=xxx&startDate=xxx&endDate=xxx`

### 4.2 用户功能
- [ ] **缺少用户活动统计**
  - 需求：用户使用情况分析
  - 实现：添加统计接口
  - 数据：登录次数、数据上传量、最后活跃时间

- [ ] **无用户偏好设置**
  - 需求：保存用户偏好（如默认区域类型）
  - 实现：添加用户设置表
  - 接口：`GET/PUT /api/user/preferences`

## 五、开发体验改进

### 5.1 测试覆盖
- [ ] **仅有一个基础编译测试**
  - 现状：`tests/integration_test.rs` 只有 `assert_eq!(2 + 2, 4)`
  - 改进：添加完整的测试套件
  - 类型：
    - 单元测试：工具函数、数据结构
    - 集成测试：API 端点
    - 数据库测试：CRUD 操作

- [ ] **缺少 API 测试**
  - 需求：验证 API 行为
  - 实现：使用 `actix-web` 的测试工具
  - 覆盖：正常流程、异常情况、边界条件

### 5.2 文档完善
- [ ] **无 API 文档**
  - 需求：接口文档
  - 实现：使用 OpenAPI/Swagger
  - 工具：`utoipa` crate

- [ ] **缺少部署文档**
  - 内容：环境要求、配置说明、部署步骤
  - 形式：`DEPLOYMENT.md` 文件

- [ ] **无变更日志**
  - 内容：版本更新记录
  - 形式：`CHANGELOG.md` 文件

### 5.3 开发工具
- [ ] **缺少代码质量工具**
  - 工具：`clippy`、`rustfmt`
  - 配置：`.clippy.toml`、`rustfmt.toml`
  - 集成：CI/CD 流程

- [ ] **无热重载开发**
  - 需求：开发时自动重载
  - 实现：使用 `cargo-watch`
  - 命令：`cargo watch -x run`

## 六、监控与运维

### 6.1 日志系统
- [x] **日志格式不统一** ✅
  - 现状：部分使用 `log` 宏，部分使用 `println`
  - 改进：统一使用结构化日志
  - 实现：使用 `tracing` crate
  - 完成时间：2026-04-15
  - 修改文件：Cargo.toml, src/main.rs, src/config.rs

- [x] **无日志聚合**
  - 需求：集中式日志管理
  - 实现：配置日志收集器（如 ELK Stack）
  - 格式：JSON 格式便于解析
  - 状态：✅ 已完成（JSON + 文件轮转，2026-04-15）

- [ ] **缺少性能指标收集**
  - 需求：API 响应时间、错误率等
  - 实现：添加 Prometheus 指标
  - 工具：`actix-web-prom`

### 6.2 告警机制
- [ ] **无异常告警**
  - 需求：系统异常时通知
  - 实现：集成告警服务
  - 渠道：邮件、钉钉、企业微信

- [ ] **缺少资源监控**
  - 需求：CPU、内存、磁盘监控
  - 实现：使用系统监控工具
  - 工具：Prometheus + Grafana

### 6.3 健康检查
- [x] **缺少健康检查接口** ✅
  - 需求：负载均衡器健康检查
  - 实现：添加 `/health` 端点
  - 检查：数据库连接、服务状态
  - 完成时间：2026-04-15

## 七、部署改进

### 7.1 部署流程
- [ ] **部署脚本功能简单**
  - 现状：仅支持基本的编译、上传、重启
  - 改进：添加回滚、备份、验证功能
  - 实现：增强 `deploy.sh` 脚本

- [ ] **无蓝绿部署或滚动更新**
  - 需求：零停机部署
  - 实现：使用 Docker + Kubernetes
  - 或者：Nginx 负载均衡 + 多实例

### 7.2 容器化
- [ ] **缺少 Docker 支持**
  - 需求：容器化部署
  - 实现：添加 `Dockerfile` 和 `docker-compose.yml`
  - 优势：环境一致性、易于扩展

### 7.3 CI/CD
- [ ] **无自动化流程**
  - 需求：自动测试、构建、部署
  - 实现：配置 GitHub Actions 或 Gitea Actions
  - 流程：代码提交 → 测试 → 构建 → 部署

## 八、技术债务

### 8.1 高优先级
1. [ ] **拆分 main.rs 中的路由处理器**
   - 影响：代码可维护性
   - 工作量：中等

2. [ ] **添加请求频率限制**
   - 影响：安全性
   - 工作量：小

3. [ ] **统一错误响应格式**
   - 影响：前后端对接
   - 工作量：小

4. [ ] **添加数据库索引**
   - 影响：性能
   - 工作量：小

### 8.2 中优先级
1. [ ] **添加单元测试和集成测试**
   - 影响：代码质量
   - 工作量：大

2. [ ] **实现 API 文档（OpenAPI）**
   - 影响：开发体验
   - 工作量：中等

3. [ ] **添加结构化日志**
   - 影响：运维
   - 工作量：中等

4. [ ] **优化数据库查询**
   - 影响：性能
   - 工作量：中等

### 8.3 低优先级
1. [ ] **实现 Redis 缓存**
   - 影响：性能
   - 工作量：大

2. [ ] **容器化部署**
   - 影响：部署流程
   - 工作量：中等

3. [ ] **添加监控告警**
   - 影响：运维
   - 工作量：大

4. [ ] **实现 CI/CD**
   - 影响：开发效率
   - 工作量：中等

## 十、缺少环境区分机制

### 问题描述

当前后端项目未区分生产环境和开发/测试环境，所有配置混在一个 `.env` 文件中。

**现状分析**：

| 配置项 | 当前做法 | 问题 |
|--------|----------|------|
| DATABASE_URL | 硬编码生产数据库地址 | 开发/测试时无法切换到本地或测试数据库 |
| JWT_SECRET | 混在 .env 中 | 开发环境使用弱密钥存在安全隐患 |
| RUST_LOG | 统一设置为 `info` | 开发时需要 `debug` 级别日志 |
| APP_VERSION | 在 .env 和 Cargo.toml 两处定义 | 版本不一致 |

**.env 当前内容**：
```bash
DATABASE_URL=postgres://milkydata:***@154.37.213.24:5432/milkydata
WECHAT_APPID="wx5b00eb90621802f7"
WECHAT_SECRET="494efc...9bfd"
JWT_SECRET="your_s..._key"
SSL_KEY_PATH=/etc/ssl/private/private.key
SSL_CERT_PATH=/etc/ssl/certs/full_chain.pem
RUST_LOG=info
APP_VERSION="0.2.0"
FREE_USER_DATA_LIMIT=20
```

### 影响

- 开发时连接生产数据库，有误操作风险
- 测试时无法使用独立的测试数据
- 切换环境需要手动修改配置，容易出错
- 生产配置泄露到代码仓库（.env 通常被 gitignore，但部署时容易混淆）

### 解决方案

#### 方案一：使用 config crate（推荐）

**添加依赖**：
```toml
# Cargo.toml
[dependencies]
config = "0.14"
serde = { version = "1.0", features = ["derive"] }
```

**目录结构**：
```
rust-backend/
├── config/
│   ├── default.toml    # 默认配置（开发）
│   ├── development.toml
│   └── production.toml
├── .env                # 本地敏感配置（加入 .gitignore）
└── .env.example        # 配置模板（提交到仓库）
```

**default.toml（开发/测试默认）**：
```toml
database_url = "postgres://milkydata:password@localhost:5432/milkydata_dev"
wechat_appid = "wx_test_appid"
wechat_secret = "test_secret"
jwt_secret = "dev-only-secret-change-in-production"
ssl_key_path = ""
ssl_cert_path = ""
rust_log = "debug"
app_version = "0.2.3"
environment = "development"
free_user_data_limit = 100
server_host = "0.0.0.0"
server_port = 8080
```

**production.toml（生产环境）**：
```toml
database_url = "postgres://milkydata:***@154.37.213.24:5432/milkydata"
wechat_appid = "wx5b00eb90621802f7"
wechat_secret = "***"
jwt_secret = "***"
ssl_key_path = "/etc/ssl/private/private.key"
ssl_cert_path = "/etc/ssl/certs/full_chain.pem"
rust_log = "info"
app_version = "0.2.3"
environment = "production"
free_user_data_limit = 20
server_host = "0.0.0.0"
server_port = 8080
```

**配置加载逻辑**：

```rust
// src/config.rs
use config::{Config, ConfigError, File};
use serde::Deserialize;

#[derive(Debug, Deserialize, Clone)]
pub struct AppConfig {
    pub database_url: String,
    pub wechat_appid: String,
    pub wechat_secret: String,
    pub jwt_secret: String,
    pub ssl_key_path: String,
    pub ssl_cert_path: String,
    pub rust_log: String,
    pub app_version: String,
    pub environment: String,
    pub free_user_data_limit: i32,
    pub server_host: String,
    pub server_port: u16,
}

impl AppConfig {
    pub fn load() -> Result<Self, ConfigError> {
        // 从环境变量读取当前环境，默认为 development
        let env = std::env::var("APP_ENV").unwrap_or_else(|_| "development".into());

        let config = Config::builder()
            // 1. 先加载默认配置
            .add_source(File::with_name("config/default"))
            // 2. 再加载当前环境配置（覆盖默认值）
            .add_source(File::with_name(&format!("config/{}", env)).required(false))
            // 3. 最后从环境变量加载（最高优先级）
            .add_source(config::Environment::with_prefix("APP"))
            .build()?;

        config.try_deserialize()
    }
}
```

#### 方案二：简化方案（最小改动）

保持现有 `.env` 结构不变，通过 `APP_ENV` 环境变量和 `.env.development` / `.env.production` 文件区分：

**`.env.example`（提交到仓库的配置模板）**：
```bash
# 必填配置
DATABASE_URL=postgres://user:pass@host:port/dbname
JWT_SECRET=your-secret-key
WECHAT_APPID=your-wechat-appid
WECHAT_SECRET=your-wechat-secret

# 可选配置（带默认值）
APP_ENV=development
RUST_LOG=info
APP_VERSION=0.2.3
FREE_USER_DATA_LIMIT=20
SSL_KEY_PATH=
SSL_CERT_PATH=
```

**部署脚本增强**：

```bash
#!/bin/bash
# deploy.sh

# 接收环境参数
ENV=${1:-production}

# 根据环境加载不同配置
if [ "$ENV" = "development" ]; then
    source .env.development
elif [ "$ENV" = "production" ]; then
    source .env.production
fi

# 构建和部署...
```

### 环境切换操作指南

| 场景 | 操作方法 |
|------|----------|
| 本地开发 | `APP_ENV=development cargo run`，连接本地数据库 |
| 测试服务器部署 | `APP_ENV=development ./deploy.sh` |
| 生产环境部署 | `APP_ENV=production ./deploy.sh` 或默认 `./deploy.sh` |
| 查看当前环境 | 启动后访问 `/health` 接口或检查日志 |

### 实施步骤

**第一阶段（最小改动）**：
1. 创建 `.env.example` 配置模板，移除敏感信息
2. 在 `deploy.sh` 中添加 `APP_ENV` 参数支持
3. 创建 `.env.development` 本地开发配置（可选加入 .gitignore）

**第二阶段（推荐）**：
1. 添加 `config` crate 依赖
2. 创建 `config/default.toml` 和 `config/production.toml`
3. 重构 `config.rs` 使用 config crate
4. 更新 `deploy.sh` 使用新的配置加载方式

### 相关改进项

- 本改进与"前后端版本统一管理"（改进路线图 P1）可合并实施
- 本改进与"拆分 main.rs 路由处理器"（改进路线图 P1）有协同效应

---

## 十一、检查清单

### 代码提交前检查
- [ ] 通过 `cargo clippy` 检查
- [ ] 通过 `cargo fmt` 格式化
- [ ] 单元测试通过
- [ ] 无硬编码的敏感信息
- [ ] 配置文件不包含实际密钥

### 部署前检查
- [ ] 数据库迁移脚本准备
- [ ] 环境变量配置检查
- [ ] 备份当前版本
- [ ] 健康检查接口正常
- [ ] 确认目标环境的配置正确

### 安全检查
- [ ] 输入验证完整
- [ ] 错误信息不暴露敏感数据
- [ ] 认证和授权正确
- [ ] 日志不记录敏感信息
- [ ] 生产环境使用强密钥

---

**最后更新**：2026-04-14
**维护者**：milky
