# 收藏管理

<cite>
**本文引用的文件**
- [favorites.controller.ts](file://server/src/modules/favorites/favorites.controller.ts)
- [favorites.service.ts](file://server/src/modules/favorites/favorites.service.ts)
- [auth.ts](file://server/src/middleware/auth.ts)
- [errorHandler.ts](file://server/src/middleware/errorHandler.ts)
- [cache.ts](file://server/src/middleware/cache.ts)
- [schema.prisma](file://server/prisma/schema.prisma)
- [seed-test-user.js](file://server/prisma/seed-test-user.js)
- [API.md](file://docs/API.md)
</cite>

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

## 简介
本文件为收藏管理功能的详细技术文档，覆盖以下方面：
- 收藏列表获取、添加收藏、取消收藏、收藏状态检查等核心功能实现
- 收藏数据模型设计、数据库表结构与索引、关联查询优化
- 用户认证中间件集成、可选认证与开发环境测试用户ID处理
- 收藏状态检查算法、重复收藏处理、异常错误处理策略
- 完整RESTful API接口文档（HTTP方法、URL模式、请求参数、响应格式）
- 性能优化建议、缓存策略、并发控制机制
- 收藏数据的生命周期管理、清理策略、数据一致性保证

## 项目结构
收藏管理功能位于后端服务的模块化目录中，采用控制器-服务分层架构，并通过Prisma ORM访问MySQL数据库。认证中间件支持可选认证，开发环境下自动注入测试用户。

```mermaid
graph TB
subgraph "收藏模块"
C["favorites.controller.ts<br/>路由与请求处理"]
S["favorites.service.ts<br/>业务逻辑与数据库操作"]
end
subgraph "认证中间件"
A["auth.ts<br/>optionalAuth 可选认证"]
EH["errorHandler.ts<br/>全局错误处理"]
end
subgraph "缓存中间件"
CA["cache.ts<br/>Redis 缓存中间件"]
end
subgraph "数据层"
P["schema.prisma<br/>Prisma 模型与索引"]
DB["MySQL 数据库"]
end
C --> A
C --> S
S --> P
P --> DB
C --> EH
C --> CA
```

**图表来源**
- [favorites.controller.ts:1-76](file://server/src/modules/favorites/favorites.controller.ts#L1-L76)
- [favorites.service.ts:1-104](file://server/src/modules/favorites/favorites.service.ts#L1-L104)
- [auth.ts:51-80](file://server/src/middleware/auth.ts#L51-L80)
- [errorHandler.ts:1-67](file://server/src/middleware/errorHandler.ts#L1-L67)
- [cache.ts:1-98](file://server/src/middleware/cache.ts#L1-L98)
- [schema.prisma:94-105](file://server/prisma/schema.prisma#L94-L105)

**章节来源**
- [favorites.controller.ts:1-76](file://server/src/modules/favorites/favorites.controller.ts#L1-L76)
- [favorites.service.ts:1-104](file://server/src/modules/favorites/favorites.service.ts#L1-L104)
- [auth.ts:1-81](file://server/src/middleware/auth.ts#L1-L81)
- [errorHandler.ts:1-67](file://server/src/middleware/errorHandler.ts#L1-L67)
- [cache.ts:1-98](file://server/src/middleware/cache.ts#L1-L98)
- [schema.prisma:94-105](file://server/prisma/schema.prisma#L94-L105)

## 核心组件
- 控制器层：负责HTTP路由、参数解析、调用服务层、统一响应格式与可选认证中间件集成
- 服务层：封装Prisma查询，实现收藏列表、添加、删除、状态检查等业务逻辑
- 认证中间件：提供可选认证，开发环境下自动注入测试用户ID
- 错误处理：统一捕获异常并返回标准化错误响应
- 缓存中间件：提供通用Redis缓存能力，可按需对收藏相关接口进行缓存

**章节来源**
- [favorites.controller.ts:1-76](file://server/src/modules/favorites/favorites.controller.ts#L1-L76)
- [favorites.service.ts:1-104](file://server/src/modules/favorites/favorites.service.ts#L1-L104)
- [auth.ts:51-80](file://server/src/middleware/auth.ts#L51-L80)
- [errorHandler.ts:1-67](file://server/src/middleware/errorHandler.ts#L1-L67)
- [cache.ts:1-98](file://server/src/middleware/cache.ts#L1-L98)

## 架构总览
收藏管理的请求处理流程如下：

```mermaid
sequenceDiagram
participant Client as "客户端"
participant Router as "Koa 路由"
participant Auth as "optionalAuth 中间件"
participant Ctrl as "收藏控制器"
participant Svc as "收藏服务"
participant Prisma as "Prisma ORM"
participant DB as "MySQL"
Client->>Router : HTTP 请求
Router->>Auth : 可选认证
Auth-->>Router : 注入用户上下文或测试用户
Router->>Ctrl : 调用对应控制器方法
Ctrl->>Svc : 调用业务逻辑
Svc->>Prisma : 执行数据库查询/写入
Prisma->>DB : SQL 查询/写入
DB-->>Prisma : 结果集
Prisma-->>Svc : 结果
Svc-->>Ctrl : 业务结果
Ctrl-->>Client : 统一响应体
```

**图表来源**
- [favorites.controller.ts:13-73](file://server/src/modules/favorites/favorites.controller.ts#L13-L73)
- [auth.ts:51-80](file://server/src/middleware/auth.ts#L51-L80)
- [favorites.service.ts:8-103](file://server/src/modules/favorites/favorites.service.ts#L8-L103)
- [schema.prisma:94-105](file://server/prisma/schema.prisma#L94-L105)

## 详细组件分析

### 控制器层（路由与请求处理）
- GET /favorites：获取当前用户的收藏列表；开发环境使用测试用户ID
- POST /favorites：添加收藏；校验音频ID参数
- DELETE /favorites/:audioId：取消收藏
- GET /favorites/check/:audioId：检查是否已收藏

控制器统一使用可选认证中间件，若未携带有效Token则自动注入测试用户ID，便于开发联调。

**章节来源**
- [favorites.controller.ts:13-73](file://server/src/modules/favorites/favorites.controller.ts#L13-L73)
- [auth.ts:51-80](file://server/src/middleware/auth.ts#L51-L80)

### 服务层（业务逻辑与数据库操作）
- getFavorites：按用户ID查询收藏记录，并预加载书籍信息，按创建时间倒序
- addFavorite：先检查重复收藏，若不存在则创建收藏记录并返回包含书籍信息的结果
- removeFavorite：根据用户ID与书籍ID删除收藏
- isFavorited：根据唯一索引判断是否已收藏

服务层通过Prisma Client执行数据库操作，确保类型安全与SQL注入防护。

**章节来源**
- [favorites.service.ts:8-103](file://server/src/modules/favorites/favorites.service.ts#L8-L103)
- [schema.prisma:94-105](file://server/prisma/schema.prisma#L94-L105)

### 认证中间件与开发环境测试用户
- optionalAuth：若存在有效的Authorization Bearer Token，则解析并注入用户上下文；否则注入测试用户（ID=1，超级VIP）
- 开发环境可通过环境变量控制是否启用严格认证，默认跳过认证并注入测试用户
- 测试用户脚本会创建ID=1的超级VIP用户，便于本地调试

**章节来源**
- [auth.ts:51-80](file://server/src/middleware/auth.ts#L51-L80)
- [seed-test-user.js:10-71](file://server/prisma/seed-test-user.js#L10-L71)

### 错误处理策略
- 全局错误中间件捕获异常，统一返回code/message/data结构
- 自定义错误类型：Unauthorized、Forbidden、NotFound、BadRequest、QuotaExceeded等
- 开发环境额外返回堆栈信息，便于定位问题

**章节来源**
- [errorHandler.ts:1-67](file://server/src/middleware/errorHandler.ts#L1-L67)

### 缓存策略
- 提供通用缓存中间件，支持自定义TTL、键前缀与键生成器
- 支持清除指定前缀的缓存键
- 当前收藏模块未直接使用缓存中间件，但可按需扩展

**章节来源**
- [cache.ts:1-98](file://server/src/middleware/cache.ts#L1-L98)

### 数据模型与数据库结构
收藏模型（Favorite）包含：
- 唯一键：(userId, bookId)
- 索引：userId、bookId
- 关系：与User、Book的多对一关系，删除时级联处理

书籍模型（Book）与收藏模型存在一对多关系，服务层在查询收藏时会预加载书籍关键字段。

**章节来源**
- [schema.prisma:94-105](file://server/prisma/schema.prisma#L94-L105)
- [schema.prisma:130-160](file://server/prisma/schema.prisma#L130-L160)

### 收藏状态检查算法与重复收藏处理
- 状态检查：通过唯一索引查找是否存在对应记录，存在即认为已收藏
- 重复收藏：在插入前先查询唯一索引，若存在则直接返回现有记录，避免重复插入
- 并发场景：数据库唯一约束保证幂等性；应用层在高并发下仍需依赖数据库约束

```mermaid
flowchart TD
Start(["开始"]) --> Parse["解析用户ID与目标ID"]
Parse --> CheckDup{"检查重复收藏"}
CheckDup --> |存在| ReturnExist["返回现有记录"]
CheckDup --> |不存在| Insert["插入新收藏记录"]
Insert --> LoadBook["加载书籍信息"]
LoadBook --> Done(["结束"])
ReturnExist --> Done
```

**图表来源**
- [favorites.service.ts:34-68](file://server/src/modules/favorites/favorites.service.ts#L34-L68)
- [schema.prisma:94-105](file://server/prisma/schema.prisma#L94-L105)

## 依赖关系分析
收藏模块的依赖关系如下：

```mermaid
graph LR
Ctrl["favorites.controller.ts"] --> Auth["auth.ts"]
Ctrl --> Svc["favorites.service.ts"]
Svc --> Prisma["Prisma Client"]
Prisma --> Model["schema.prisma 模型"]
Model --> DB["MySQL"]
Ctrl --> Err["errorHandler.ts"]
Ctrl --> Cache["cache.ts"]
```

**图表来源**
- [favorites.controller.ts:1-76](file://server/src/modules/favorites/favorites.controller.ts#L1-L76)
- [favorites.service.ts:1-104](file://server/src/modules/favorites/favorites.service.ts#L1-L104)
- [auth.ts:1-81](file://server/src/middleware/auth.ts#L1-L81)
- [errorHandler.ts:1-67](file://server/src/middleware/errorHandler.ts#L1-L67)
- [cache.ts:1-98](file://server/src/middleware/cache.ts#L1-L98)
- [schema.prisma:94-105](file://server/prisma/schema.prisma#L94-L105)

**章节来源**
- [favorites.controller.ts:1-76](file://server/src/modules/favorites/favorites.controller.ts#L1-L76)
- [favorites.service.ts:1-104](file://server/src/modules/favorites/favorites.service.ts#L1-L104)
- [auth.ts:1-81](file://server/src/middleware/auth.ts#L1-L81)
- [errorHandler.ts:1-67](file://server/src/middleware/errorHandler.ts#L1-L67)
- [cache.ts:1-98](file://server/src/middleware/cache.ts#L1-L98)
- [schema.prisma:94-105](file://server/prisma/schema.prisma#L94-L105)

## 性能考虑
- 数据库索引
  - 收藏表：唯一索引(userId, bookId)，以及userId、bookId单列索引，满足查询与去重需求
  - 书籍表：常用查询字段建立索引，减少JOIN开销
- 关联查询优化
  - 服务层使用include预加载书籍关键字段，避免N+1查询
  - 排序按创建时间倒序，必要时可增加复合索引以优化排序
- 缓存策略
  - 可对收藏列表接口增加缓存（如按用户ID生成键），设置合理TTL
  - 对频繁读取的状态检查接口可考虑短期缓存
- 并发控制
  - 重复收藏通过数据库唯一约束保证幂等
  - 高并发下建议结合数据库事务与重试机制
- 查询优化建议
  - 在高频查询场景下，可考虑物化视图或读写分离
  - 对收藏列表分页查询时，确保索引命中与LIMIT限制

[本节为通用性能指导，不直接分析具体文件]

## 故障排查指南
- 认证相关
  - 若出现未授权错误，确认是否启用了严格认证（AUTH_ENABLED=true）
  - 可选认证下，若Token无效或过期，将回退到测试用户
- 参数校验
  - 添加收藏时若缺少音频ID，将抛出请求参数错误
- 数据库一致性
  - 重复收藏不会产生重复记录，检查唯一索引是否生效
- 错误响应
  - 全局错误中间件会统一返回code/message/data结构，开发环境额外返回堆栈信息

**章节来源**
- [auth.ts:51-80](file://server/src/middleware/auth.ts#L51-L80)
- [errorHandler.ts:1-67](file://server/src/middleware/errorHandler.ts#L1-L67)
- [favorites.controller.ts:33-35](file://server/src/modules/favorites/favorites.controller.ts#L33-L35)

## 结论
收藏管理功能通过清晰的控制器-服务分层、完善的认证与错误处理、以及基于Prisma的数据库模型设计，实现了稳定可靠的收藏能力。开发环境下的可选认证与测试用户脚本提升了联调效率。后续可在收藏列表与状态检查接口上引入缓存策略，并持续优化数据库索引与查询路径，以应对更高的并发与数据规模。

[本节为总结性内容，不直接分析具体文件]

## 附录

### RESTful API 接口文档
- 获取收藏列表
  - 方法：GET
  - 路径：/api/favorites
  - 认证：可选
  - 响应：包含收藏列表，每项包含书籍关键信息
- 添加收藏
  - 方法：POST
  - 路径：/api/favorites
  - 认证：可选
  - 请求体：{ audioId: number }
  - 响应：包含新增收藏及书籍信息
- 取消收藏
  - 方法：DELETE
  - 路径：/api/favorites/:audioId
  - 认证：可选
  - 响应：成功消息
- 检查是否已收藏
  - 方法：GET
  - 路径：/api/favorites/check/:audioId
  - 认证：可选
  - 响应：布尔值表示收藏状态

注：以上接口与实际实现保持一致，开发环境可自动注入测试用户ID，便于本地联调。

**章节来源**
- [favorites.controller.ts:13-73](file://server/src/modules/favorites/favorites.controller.ts#L13-L73)
- [auth.ts:51-80](file://server/src/middleware/auth.ts#L51-L80)

### 数据模型与索引
- 收藏模型（Favorite）
  - 唯一键：(userId, bookId)
  - 索引：userId、bookId
  - 关系：与User、Book的多对一
- 书籍模型（Book）
  - 与收藏模型存在一对多关系
  - 服务层查询收藏时预加载书籍关键字段

**章节来源**
- [schema.prisma:94-105](file://server/prisma/schema.prisma#L94-L105)
- [schema.prisma:130-160](file://server/prisma/schema.prisma#L130-L160)

### 开发环境测试用户
- 测试用户ID：1
- 脚本会创建或更新该用户为超级VIP，便于本地调试
- optionalAuth中间件在无Token时自动注入该用户

**章节来源**
- [seed-test-user.js:10-71](file://server/prisma/seed-test-user.js#L10-L71)
- [auth.ts:51-80](file://server/src/middleware/auth.ts#L51-L80)