# 评论系统

<cite>
**本文引用的文件**
- [comments.controller.ts](file://server/src/modules/comments/comments.controller.ts)
- [comments.service.ts](file://server/src/modules/comments/comments.service.ts)
- [schema.prisma](file://server/prisma/schema.prisma)
- [app.ts](file://server/src/app.ts)
- [security.ts](file://server/src/middleware/security.ts)
- [rate-limiter.ts](file://server/src/middleware/rate-limiter.ts)
- [index.ts](file://server/src/models/index.ts)
- [API.md](file://docs/API.md)
</cite>

## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 引言
本文件为评论系统的开发文档，面向后端工程师与产品/测试同学，系统性阐述评论模块的架构设计、数据模型、业务流程、API 接口、安全机制与性能优化策略。当前仓库中评论模块已具备基础能力：按章节获取评论列表、发布评论；尚未包含子评论/回复、评论树结构、内容审核、举报处理等高级能力。本文在现有实现基础上，给出扩展建议与最佳实践，帮助团队在不破坏现有架构的前提下逐步完善评论系统。

## 项目结构
评论模块位于后端服务的模块化目录下，采用“控制器-服务-数据层”的分层设计，配合全局中间件实现安全与性能保障。

```mermaid
graph TB
subgraph "应用入口"
APP["app.ts<br/>注册路由/中间件"]
end
subgraph "评论模块"
CTRL["comments.controller.ts<br/>路由定义"]
SVC["comments.service.ts<br/>业务逻辑"]
PRISMA["prisma/schema.prisma<br/>数据模型"]
MODELS["models/index.ts<br/>Prisma 客户端"]
end
subgraph "安全与性能"
SEC["middleware/security.ts<br/>XSS/SQL注入防护"]
RL["middleware/rate-limiter.ts<br/>限流中间件"]
end
APP --> CTRL
CTRL --> SVC
SVC --> MODELS
MODELS --> PRISMA
APP --> SEC
APP --> RL
```

**图表来源**
- [app.ts:100-128](file://server/src/app.ts#L100-L128)
- [comments.controller.ts:1-59](file://server/src/modules/comments/comments.controller.ts#L1-L59)
- [comments.service.ts:1-33](file://server/src/modules/comments/comments.service.ts#L1-L33)
- [schema.prisma:107-119](file://server/prisma/schema.prisma#L107-L119)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)
- [security.ts:6-27](file://server/src/middleware/security.ts#L6-L27)
- [rate-limiter.ts:49-81](file://server/src/middleware/rate-limiter.ts#L49-L81)

**章节来源**
- [app.ts:100-128](file://server/src/app.ts#L100-L128)
- [comments.controller.ts:1-59](file://server/src/modules/comments/comments.controller.ts#L1-L59)
- [comments.service.ts:1-33](file://server/src/modules/comments/comments.service.ts#L1-L33)
- [schema.prisma:107-119](file://server/prisma/schema.prisma#L107-L119)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)
- [security.ts:6-27](file://server/src/middleware/security.ts#L6-L27)
- [rate-limiter.ts:49-81](file://server/src/middleware/rate-limiter.ts#L49-L81)

## 核心组件
- 控制器层：负责路由定义与请求响应包装，当前提供“按章节获取评论”和“发布评论”两个接口。
- 服务层：封装评论业务逻辑，直接调用 Prisma 数据访问层。
- 数据层：基于 Prisma 的数据模型，包含用户、章节与评论之间的关系。
- 安全中间件：提供 XSS 与 SQL 注入防护，响应头加固。
- 限流中间件：提供内存/Redis 双栈限流器，支持多场景限流策略。

**章节来源**
- [comments.controller.ts:13-29](file://server/src/modules/comments/comments.controller.ts#L13-L29)
- [comments.controller.ts:35-56](file://server/src/modules/comments/comments.controller.ts#L35-L56)
- [comments.service.ts:10-29](file://server/src/modules/comments/comments.service.ts#L10-L29)
- [schema.prisma:107-119](file://server/prisma/schema.prisma#L107-L119)
- [security.ts:6-27](file://server/src/middleware/security.ts#L6-L27)
- [rate-limiter.ts:49-81](file://server/src/middleware/rate-limiter.ts#L49-L81)

## 架构总览
评论系统采用典型的三层架构：HTTP 层（Koa 路由）、业务层（服务类）、数据层（Prisma）。请求从控制器进入，经服务层处理后访问数据库，返回统一格式的响应。

```mermaid
sequenceDiagram
participant C as "客户端"
participant R as "路由控制器<br/>comments.controller.ts"
participant S as "服务层<br/>comments.service.ts"
participant M as "Prisma 客户端<br/>models/index.ts"
participant D as "数据库"
C->>R : "GET /api/comments/ : chapterId"
R->>S : "getCommentsByChapterId(chapterId)"
S->>M : "comment.findMany(where, orderBy)"
M->>D : "执行查询"
D-->>M : "返回结果"
M-->>S : "评论列表"
S-->>R : "评论列表"
R-->>C : "统一响应"
Note over C,R : "POST /api/comments 发布评论流程类似"
```

**图表来源**
- [comments.controller.ts:13-29](file://server/src/modules/comments/comments.controller.ts#L13-L29)
- [comments.controller.ts:35-56](file://server/src/modules/comments/comments.controller.ts#L35-L56)
- [comments.service.ts:10-29](file://server/src/modules/comments/comments.service.ts#L10-L29)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)

## 详细组件分析

### 数据模型设计
评论模型与用户、章节存在明确的一对多关系，索引覆盖了常用查询维度，便于后续扩展。

```mermaid
erDiagram
USER {
int id PK
string phone
string openid
string nickname
string avatar
int memberLevel
datetime createdAt
datetime updatedAt
}
BOOKCHAPTER {
int id PK
int bookId
int parentId
int level
int number
string title
int estimatedWords
int audioDuration
boolean isPublic
string genStage
datetime createdAt
datetime updatedAt
}
COMMENT {
int id PK
int userId
int chapterId
text content
int rating
datetime createdAt
}
USER ||--o{ COMMENT : "发表"
BOOKCHAPTER ||--o{ COMMENT : "承载"
```

- 用户与评论：一对多，一个用户可有多条评论。
- 章节与评论：一对多，一个章节可有多条评论。
- 索引设计：评论表对 chapterId、userId 建有索引，有利于按章节查询与用户历史查询。

**图表来源**
- [schema.prisma:107-119](file://server/prisma/schema.prisma#L107-L119)
- [schema.prisma:161-192](file://server/prisma/schema.prisma#L161-L192)
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)

**章节来源**
- [schema.prisma:107-119](file://server/prisma/schema.prisma#L107-L119)
- [schema.prisma:161-192](file://server/prisma/schema.prisma#L161-L192)
- [schema.prisma:10-38](file://server/prisma/schema.prisma#L10-L38)

### 控制器与服务层
- 控制器：定义评论相关路由，负责参数解析与统一响应包装。
- 服务层：封装评论查询与新增逻辑，直接使用 Prisma 客户端。

```mermaid
classDiagram
class CommentsController {
+GET /api/comments/ : chapterId
+POST /api/comments
}
class CommentsService {
+getCommentsByChapterId(chapterId)
+addComment(userId, chapterId, content, rating)
}
class PrismaClient {
+comment.findMany()
+comment.create()
}
CommentsController --> CommentsService : "调用"
CommentsService --> PrismaClient : "使用"
```

**图表来源**
- [comments.controller.ts:13-29](file://server/src/modules/comments/comments.controller.ts#L13-L29)
- [comments.controller.ts:35-56](file://server/src/modules/comments/comments.controller.ts#L35-L56)
- [comments.service.ts:10-29](file://server/src/modules/comments/comments.service.ts#L10-L29)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)

**章节来源**
- [comments.controller.ts:13-29](file://server/src/modules/comments/comments.controller.ts#L13-L29)
- [comments.controller.ts:35-56](file://server/src/modules/comments/comments.controller.ts#L35-L56)
- [comments.service.ts:10-29](file://server/src/modules/comments/comments.service.ts#L10-L29)

### API 接口文档
- 获取章节评论
  - 方法与路径：GET /api/comments/:chapterId
  - 请求参数：chapterId（路径参数）
  - 响应字段：code、message、data（评论数组）
- 发布评论
  - 方法与路径：POST /api/comments
  - 请求体字段：chapterId、content、rating
  - 响应字段：code、message、data（新建评论）

注：当前实现中，发布评论使用固定测试用户 ID，实际部署需结合鉴权中间件替换为真实用户上下文。

**章节来源**
- [comments.controller.ts:13-29](file://server/src/modules/comments/comments.controller.ts#L13-L29)
- [comments.controller.ts:35-56](file://server/src/modules/comments/comments.controller.ts#L35-L56)

### 安全机制
- XSS 防护：对请求体与查询参数进行递归清洗，设置安全响应头。
- SQL 注入防护：对请求参数进行模式匹配检测，命中即拒绝请求。
- 限流策略：提供内存/Redis 双栈限流器，支持全局 API、登录、短信、TTS、上传等场景。

```mermaid
flowchart TD
Start(["请求进入"]) --> XSS["XSS 防护<br/>sanitizeObject()"]
XSS --> SQL["SQL 注入检测<br/>detectSQLInjection()"]
SQL --> OK{"是否通过校验"}
OK --> |否| Reject["返回 400 非法字符"]
OK --> |是| Rate["限流检查<br/>createRateLimiter()"]
Rate --> Pass["继续处理业务"]
Reject --> End(["结束"])
Pass --> End
```

**图表来源**
- [security.ts:6-27](file://server/src/middleware/security.ts#L6-L27)
- [security.ts:60-102](file://server/src/middleware/security.ts#L60-L102)
- [rate-limiter.ts:49-81](file://server/src/middleware/rate-limiter.ts#L49-L81)

**章节来源**
- [security.ts:6-27](file://server/src/middleware/security.ts#L6-L27)
- [security.ts:60-102](file://server/src/middleware/security.ts#L60-L102)
- [rate-limiter.ts:49-81](file://server/src/middleware/rate-limiter.ts#L49-L81)

### 业务逻辑与扩展建议
- 当前业务逻辑
  - 查询：按章节 ID 查询评论，按创建时间倒序。
  - 新增：创建评论记录，包含用户 ID、章节 ID、内容与评分。
- 扩展方向（建议）
  - 子评论/回复：在评论模型中增加 parentCommentId 字段，形成评论树；服务层实现层级查询与渲染。
  - 内容审核：接入敏感词库与第三方审核服务，在新增评论前进行过滤与标记。
  - 举报处理：新增举报记录表，关联评论与用户，支持人工复核与封禁。
  - 统计与排序：新增点赞/踩统计字段，支持按热度、时间、评分等多维排序。
  - 通知联动：评论触发章节作者/关注者通知。

**章节来源**
- [comments.service.ts:10-29](file://server/src/modules/comments/comments.service.ts#L10-L29)
- [schema.prisma:107-119](file://server/prisma/schema.prisma#L107-L119)

## 依赖分析
- 控制器依赖服务层，服务层依赖 Prisma 客户端，Prisma 客户端依赖数据库。
- 应用入口注册评论路由，并加载安全与限流中间件。
- 限流中间件可选择 Redis 或内存实现，自动降级。

```mermaid
graph LR
CTRL["comments.controller.ts"] --> SVC["comments.service.ts"]
SVC --> MODELS["models/index.ts"]
MODELS --> PRISMA["prisma/schema.prisma"]
APP["app.ts"] --> CTRL
APP --> SEC["middleware/security.ts"]
APP --> RL["middleware/rate-limiter.ts"]
```

**图表来源**
- [comments.controller.ts:1-59](file://server/src/modules/comments/comments.controller.ts#L1-L59)
- [comments.service.ts:1-33](file://server/src/modules/comments/comments.service.ts#L1-L33)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)
- [schema.prisma:107-119](file://server/prisma/schema.prisma#L107-L119)
- [app.ts:100-128](file://server/src/app.ts#L100-L128)
- [security.ts:6-27](file://server/src/middleware/security.ts#L6-L27)
- [rate-limiter.ts:49-81](file://server/src/middleware/rate-limiter.ts#L49-L81)

**章节来源**
- [app.ts:100-128](file://server/src/app.ts#L100-L128)
- [comments.controller.ts:1-59](file://server/src/modules/comments/comments.controller.ts#L1-L59)
- [comments.service.ts:1-33](file://server/src/modules/comments/comments.service.ts#L1-L33)
- [index.ts:1-15](file://server/src/models/index.ts#L1-L15)
- [schema.prisma:107-119](file://server/prisma/schema.prisma#L107-L119)
- [security.ts:6-27](file://server/src/middleware/security.ts#L6-L27)
- [rate-limiter.ts:49-81](file://server/src/middleware/rate-limiter.ts#L49-L81)

## 性能考虑
- 数据库层面
  - 为评论表的 chapterId、userId 建立索引，满足高频查询。
  - 对长文本字段（如评论内容）避免不必要的投影，减少网络传输。
- 服务层面
  - 使用分页查询，避免一次性返回大量数据。
  - 对热点章节评论可引入缓存（如 Redis），降低数据库压力。
- 中间件层面
  - 合理配置限流参数，防止突发流量冲击。
  - 在高并发场景启用 Redis 限流器，保证跨实例一致性。

[本节为通用性能建议，无需特定文件引用]

## 故障排查指南
- 常见问题
  - 获取评论失败：检查 chapterId 是否有效、数据库连接是否正常。
  - 发布评论失败：检查请求体字段、用户上下文（当前使用测试用户 ID）。
  - 安全拦截：若出现 400 非法字符，检查请求参数是否包含危险关键字。
  - 限流触发：若出现 429，请等待 Retry-After 秒后再试。
- 排查步骤
  - 查看应用日志与 Sentry 错误上报。
  - 核对 Prisma 数据库连接状态与索引情况。
  - 验证中间件顺序与配置（安全中间件应在限流之前）。

**章节来源**
- [comments.controller.ts:23-28](file://server/src/modules/comments/comments.controller.ts#L23-L28)
- [comments.controller.ts:50-55](file://server/src/modules/comments/comments.controller.ts#L50-L55)
- [security.ts:60-102](file://server/src/middleware/security.ts#L60-L102)
- [rate-limiter.ts:52-71](file://server/src/middleware/rate-limiter.ts#L52-L71)

## 结论
当前评论模块已完成基础能力：按章节获取评论与发布评论。建议在下一阶段引入子评论/回复、内容审核、举报处理与统计排序等功能，同时完善鉴权与限流策略，确保系统在高并发与复杂业务下的稳定性与安全性。

[本节为总结性内容，无需特定文件引用]

## 附录

### API 接口清单（基于现有实现）
- 获取章节评论
  - 方法与路径：GET /api/comments/:chapterId
  - 请求参数：chapterId（路径参数）
  - 响应：code、message、data（评论数组）
- 发布评论
  - 方法与路径：POST /api/comments
  - 请求体字段：chapterId、content、rating
  - 响应：code、message、data（新建评论）

**章节来源**
- [comments.controller.ts:13-29](file://server/src/modules/comments/comments.controller.ts#L13-L29)
- [comments.controller.ts:35-56](file://server/src/modules/comments/comments.controller.ts#L35-L56)

### 数据模型要点（基于 Prisma）
- 评论模型包含：用户 ID、章节 ID、内容、评分、创建时间。
- 用户与评论、章节与评论为一对多关系。
- 评论表对 chapterId、userId 建有索引。

**章节来源**
- [schema.prisma:107-119](file://server/prisma/schema.prisma#L107-L119)