docs(admin-service): 添加完整的技术文档体系

文档结构:
- docs/ARCHITECTURE.md: DDD+Hexagonal 架构设计详解
- docs/API.md: RESTful API 完整接口文档
- docs/DEVELOPMENT.md: 开发环境设置和代码规范
- docs/TESTING.md: 三层测试架构 (Unit/Integration/E2E)
- docs/DEPLOYMENT.md: 本地/Docker/生产环境部署指南
- docs/README.md: 文档中心导航和快速入门

架构文档 (ARCHITECTURE.md):
- 服务职责和核心功能说明
- DDD 领域模型 (聚合根、值对象、领域服务)
- 六边形架构分层设计
- 数据流和依赖方向详解
- SOLID 原则应用示例
- 性能优化和安全性考量

API 文档 (API.md):
- 6 个核心 API 端点完整说明
- 请求/响应格式和数据模型
- 错误处理和状态码规范
- cURL/Postman 使用示例
- 版本控制和更新策略
- 最佳实践和常见问题

开发文档 (DEVELOPMENT.md):
- VSCode 配置和推荐插件
- 本地环境初始化步骤
- Git 工作流和 Commit 规范
- 完整开发迭代流程示例
- TypeScript/DDD/NestJS/Prisma 代码规范
- 调试技巧和常见开发任务

测试文档 (TESTING.md):
- 测试金字塔三层架构 (53+21+15=89 测试用例)
- 本地/WSL2/Docker 测试环境设置
- 单元/集成/E2E 测试详细示例
- Make/npm 脚本快速执行
- 覆盖率目标和 CI/CD 集成
- GitHub Actions 配置示例

部署文档 (DEPLOYMENT.md):
- 部署架构和系统要求
- Ubuntu 服务器环境准备
- PM2 本地部署流程
- Docker Compose 容器化部署
- Nginx 反向代理和 SSL 配置
- 数据库备份和日志管理
- 监控告警和故障排查

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Developer 2025-12-02 19:01:12 -08:00
parent f8c9c579f2
commit 79e2b9bfdd
6 changed files with 5235 additions and 0 deletions

View File

@ -0,0 +1,910 @@
# Admin Service API 文档
## 目录
- [1. API 概述](#1-api-概述)
- [2. 认证](#2-认证)
- [3. 通用响应格式](#3-通用响应格式)
- [4. 错误处理](#4-错误处理)
- [5. API 端点](#5-api-端点)
- [6. 数据模型](#6-数据模型)
- [7. 使用示例](#7-使用示例)
---
## 1. API 概述
### 1.1 基本信息
| 项目 | 值 |
|-----|---|
| **Base URL** | `http://localhost:3005/api/v1` |
| **协议** | HTTP/HTTPS |
| **数据格式** | JSON |
| **字符编码** | UTF-8 |
| **API 版本** | v1 |
### 1.2 API 分类
| 分类 | 端点数 | 说明 |
|-----|-------|------|
| 版本管理 | 5 | 创建、启用、禁用、查询版本 |
| 版本检查 | 1 | 移动端检查更新 |
---
## 2. 认证
### 2.1 认证方式 (待实现)
当前版本 API **未实现认证机制**,生产环境需要添加 JWT 认证。
**计划认证方案**:
```http
Authorization: Bearer <JWT_TOKEN>
```
**获取 Token** (待实现):
```http
POST /api/v1/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "password123"
}
```
**响应**:
```json
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 7200
}
```
### 2.2 权限级别 (待实现)
| 角色 | 权限 |
|-----|------|
| **admin** | 完全权限:创建、启用、禁用、删除版本 |
| **developer** | 创建、查询版本 |
| **public** | 仅检查更新 (无需认证) |
---
## 3. 通用响应格式
### 3.1 成功响应
**200 OK** - 查询成功:
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://cdn.example.com/app-v1.0.0.apk",
"fileSize": 52428800,
"fileSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"changelog": "Initial release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin",
"createdAt": "2025-01-02T10:00:00.000Z",
"updatedBy": "admin",
"updatedAt": "2025-01-02T10:00:00.000Z"
}
```
**201 Created** - 创建成功:
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 101,
...
}
```
**204 No Content** - 操作成功无返回内容
### 3.2 分页响应 (待实现)
```json
{
"data": [...],
"meta": {
"total": 50,
"page": 1,
"pageSize": 10,
"totalPages": 5
}
}
```
---
## 4. 错误处理
### 4.1 错误响应格式
```json
{
"statusCode": 400,
"message": "Invalid version code",
"error": "Bad Request",
"timestamp": "2025-01-02T10:00:00.000Z",
"path": "/api/v1/version"
}
```
### 4.2 HTTP 状态码
| 状态码 | 说明 | 常见场景 |
|-------|------|---------|
| **200** | 成功 | 查询成功 |
| **201** | 已创建 | 创建版本成功 |
| **204** | 无内容 | 启用/禁用成功 |
| **400** | 请求错误 | 参数验证失败 |
| **401** | 未认证 | Token 缺失或无效 |
| **403** | 禁止访问 | 权限不足 |
| **404** | 未找到 | 版本不存在 |
| **409** | 冲突 | 版本号重复 |
| **500** | 服务器错误 | 内部异常 |
### 4.3 业务错误码 (待实现)
| 错误码 | 说明 |
|-------|------|
| `VERSION_ALREADY_EXISTS` | 版本已存在 |
| `INVALID_VERSION_CODE` | 版本号格式错误 |
| `INVALID_VERSION_NAME` | 版本名称格式错误 |
| `INVALID_SHA256` | SHA256 格式错误 |
| `VERSION_NOT_FOUND` | 版本不存在 |
| `FILE_SIZE_INVALID` | 文件大小无效 |
---
## 5. API 端点
### 5.1 创建版本
**端点**: `POST /api/v1/version`
**权限**: 需要认证 (待实现)
**请求体**:
```json
{
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://cdn.example.com/app-v1.0.0.apk",
"fileSize": 52428800,
"fileSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"changelog": "Initial release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin"
}
```
**字段说明**:
| 字段 | 类型 | 必填 | 说明 | 验证规则 |
|-----|------|-----|------|---------|
| `platform` | string | ✅ | 平台 | `android``ios` |
| `versionCode` | number | ✅ | 版本号 | 正整数 |
| `versionName` | string | ✅ | 版本名称 | 语义化版本 (x.y.z) |
| `buildNumber` | string | ✅ | 构建号 | 非空字符串 |
| `downloadUrl` | string | ✅ | 下载链接 | 有效 URL |
| `fileSize` | number | ✅ | 文件大小 (字节) | > 0 |
| `fileSha256` | string | ✅ | SHA256 哈希 | 64 位十六进制 |
| `changelog` | string | ✅ | 更新日志 | 非空字符串 |
| `isEnabled` | boolean | ❌ | 是否启用 | 默认 `true` |
| `isForceUpdate` | boolean | ❌ | 是否强制更新 | 默认 `false` |
| `createdBy` | string | ✅ | 创建者 | 非空字符串 |
**响应**: `201 Created`
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://cdn.example.com/app-v1.0.0.apk",
"fileSize": 52428800,
"fileSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"changelog": "Initial release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin",
"createdAt": "2025-01-02T10:00:00.000Z",
"updatedBy": "admin",
"updatedAt": "2025-01-02T10:00:00.000Z"
}
```
**错误响应**:
```json
// 400 Bad Request - 版本号无效
{
"statusCode": 400,
"message": "Version code must be a positive integer",
"error": "Bad Request"
}
// 409 Conflict - 版本已存在
{
"statusCode": 409,
"message": "Version already exists for this platform",
"error": "Conflict"
}
```
**cURL 示例**:
```bash
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://cdn.example.com/app-v1.0.0.apk",
"fileSize": 52428800,
"fileSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"changelog": "Initial release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin"
}'
```
---
### 5.2 查询所有版本
**端点**: `GET /api/v1/version`
**权限**: 需要认证 (待实现)
**查询参数**:
| 参数 | 类型 | 必填 | 说明 | 示例 |
|-----|------|-----|------|------|
| `platform` | string | ❌ | 过滤平台 | `android` |
| `isEnabled` | boolean | ❌ | 过滤启用状态 | `true` |
| `page` | number | ❌ | 页码 (待实现) | `1` |
| `pageSize` | number | ❌ | 每页数量 (待实现) | `10` |
**请求示例**:
```http
GET /api/v1/version?platform=android&isEnabled=true
```
**响应**: `200 OK`
```json
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 101,
"versionName": "1.0.1",
...
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
...
}
]
```
**cURL 示例**:
```bash
curl -X GET "http://localhost:3005/api/v1/version?platform=android&isEnabled=true"
```
---
### 5.3 查询单个版本
**端点**: `GET /api/v1/version/:id`
**权限**: 需要认证 (待实现)
**路径参数**:
| 参数 | 类型 | 说明 |
|-----|------|------|
| `id` | string (UUID) | 版本 ID |
**请求示例**:
```http
GET /api/v1/version/550e8400-e29b-41d4-a716-446655440000
```
**响应**: `200 OK`
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"platform": "android",
"versionCode": 100,
"versionName": "1.0.0",
...
}
```
**错误响应**:
```json
// 404 Not Found
{
"statusCode": 404,
"message": "Version not found",
"error": "Not Found"
}
```
**cURL 示例**:
```bash
curl -X GET http://localhost:3005/api/v1/version/550e8400-e29b-41d4-a716-446655440000
```
---
### 5.4 启用版本
**端点**: `PATCH /api/v1/version/:id/enable`
**权限**: 需要认证 (待实现)
**路径参数**:
| 参数 | 类型 | 说明 |
|-----|------|------|
| `id` | string (UUID) | 版本 ID |
**请求体**:
```json
{
"updatedBy": "admin"
}
```
**请求示例**:
```http
PATCH /api/v1/version/550e8400-e29b-41d4-a716-446655440000/enable
Content-Type: application/json
{
"updatedBy": "admin"
}
```
**响应**: `204 No Content`
**错误响应**:
```json
// 404 Not Found
{
"statusCode": 404,
"message": "Version not found",
"error": "Not Found"
}
```
**cURL 示例**:
```bash
curl -X PATCH http://localhost:3005/api/v1/version/550e8400-e29b-41d4-a716-446655440000/enable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
```
---
### 5.5 禁用版本
**端点**: `PATCH /api/v1/version/:id/disable`
**权限**: 需要认证 (待实现)
**路径参数**:
| 参数 | 类型 | 说明 |
|-----|------|------|
| `id` | string (UUID) | 版本 ID |
**请求体**:
```json
{
"updatedBy": "admin"
}
```
**请求示例**:
```http
PATCH /api/v1/version/550e8400-e29b-41d4-a716-446655440000/disable
Content-Type: application/json
{
"updatedBy": "admin"
}
```
**响应**: `204 No Content`
**业务逻辑**:
- 禁用版本时,会自动将 `isForceUpdate` 设置为 `false`
- 禁用后的版本不会出现在 "检查更新" 结果中
**cURL 示例**:
```bash
curl -X PATCH http://localhost:3005/api/v1/version/550e8400-e29b-41d4-a716-446655440000/disable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
```
---
### 5.6 检查更新 (移动端)
**端点**: `GET /api/v1/version/check`
**权限**: 公开 (无需认证)
**查询参数**:
| 参数 | 类型 | 必填 | 说明 | 示例 |
|-----|------|-----|------|------|
| `platform` | string | ✅ | 平台 | `android` |
| `versionCode` | number | ✅ | 当前版本号 | `100` |
**请求示例**:
```http
GET /api/v1/version/check?platform=android&versionCode=100
```
**响应 1**: `200 OK` - 有更新
```json
{
"hasUpdate": true,
"latestVersion": "1.0.1",
"downloadUrl": "https://cdn.example.com/app-v1.0.1.apk",
"isForceUpdate": false,
"changelog": "Bug fixes and performance improvements"
}
```
**响应 2**: `200 OK` - 无更新
```json
{
"hasUpdate": false
}
```
**响应 3**: `200 OK` - 强制更新
```json
{
"hasUpdate": true,
"latestVersion": "2.0.0",
"downloadUrl": "https://cdn.example.com/app-v2.0.0.apk",
"isForceUpdate": true,
"changelog": "Major security update. Please update immediately!"
}
```
**错误响应**:
```json
// 400 Bad Request - 参数缺失
{
"statusCode": 400,
"message": ["platform should not be empty", "versionCode must be a number"],
"error": "Bad Request"
}
```
**业务逻辑**:
1. 查询指定平台的所有启用版本 (`isEnabled = true`)
2. 按 `versionCode` 降序排序,取第一个作为最新版本
3. 如果最新版本的 `versionCode` > 当前版本号,返回更新信息
4. 否则返回 `hasUpdate: false`
**移动端处理逻辑**:
```typescript
// Flutter 示例
async function checkForUpdate() {
const response = await fetch(
`${API_BASE}/version/check?platform=android&versionCode=100`
);
const data = await response.json();
if (data.hasUpdate) {
if (data.isForceUpdate) {
// 显示强制更新对话框(无法关闭)
showForceUpdateDialog({
version: data.latestVersion,
downloadUrl: data.downloadUrl,
changelog: data.changelog,
});
} else {
// 显示普通更新对话框(可以关闭)
showUpdateDialog({
version: data.latestVersion,
downloadUrl: data.downloadUrl,
changelog: data.changelog,
});
}
}
}
```
**cURL 示例**:
```bash
curl -X GET "http://localhost:3005/api/v1/version/check?platform=android&versionCode=100"
```
---
## 6. 数据模型
### 6.1 AppVersion (应用版本)
```typescript
interface AppVersion {
id: string; // UUID
platform: 'android' | 'ios';// 平台
versionCode: number; // 版本号(整数)
versionName: string; // 版本名称x.y.z
buildNumber: string; // 构建号
downloadUrl: string; // 下载链接
fileSize: number; // 文件大小(字节)
fileSha256: string; // SHA256 哈希
changelog: string; // 更新日志
isEnabled: boolean; // 是否启用
isForceUpdate: boolean; // 是否强制更新
createdBy: string; // 创建者
createdAt: string; // 创建时间ISO 8601
updatedBy: string; // 更新者
updatedAt: string; // 更新时间ISO 8601
}
```
### 6.2 Platform (平台枚举)
```typescript
enum Platform {
ANDROID = 'android',
IOS = 'ios',
}
```
### 6.3 VersionCheckResult (版本检查结果)
```typescript
interface VersionCheckResult {
hasUpdate: boolean; // 是否有更新
latestVersion?: string; // 最新版本名称
downloadUrl?: string; // 下载链接
isForceUpdate?: boolean; // 是否强制更新
changelog?: string; // 更新日志
}
```
---
## 7. 使用示例
### 7.1 完整发版流程
#### 步骤 1: 创建 Android 新版本
```bash
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "android",
"versionCode": 101,
"versionName": "1.0.1",
"buildNumber": "20250102001",
"downloadUrl": "https://cdn.rwadurian.com/android/app-v1.0.1.apk",
"fileSize": 54525952,
"fileSha256": "a3c5d7e9f1b2c4d6e8f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2",
"changelog": "1. Fixed mining reward calculation bug\n2. Improved UI performance\n3. Added dark mode support",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin"
}'
```
#### 步骤 2: 验证版本已创建
```bash
curl -X GET "http://localhost:3005/api/v1/version?platform=android&isEnabled=true"
```
#### 步骤 3: 移动端检查更新
```bash
# 用户当前版本号 100
curl -X GET "http://localhost:3005/api/v1/version/check?platform=android&versionCode=100"
# 响应:
{
"hasUpdate": true,
"latestVersion": "1.0.1",
"downloadUrl": "https://cdn.rwadurian.com/android/app-v1.0.1.apk",
"isForceUpdate": false,
"changelog": "1. Fixed mining reward calculation bug\n2. Improved UI performance\n3. Added dark mode support"
}
```
#### 步骤 4: 发现问题,紧急禁用版本
```bash
curl -X PATCH http://localhost:3005/api/v1/version/550e8400-e29b-41d4-a716-446655440001/disable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
```
#### 步骤 5: 创建修复版本
```bash
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "android",
"versionCode": 102,
"versionName": "1.0.2",
"buildNumber": "20250102002",
"downloadUrl": "https://cdn.rwadurian.com/android/app-v1.0.2.apk",
"fileSize": 54530048,
"fileSha256": "b4d6e8f0a2c3d5e7f9a1b3c4d6e8f0a2b3c5d7e9f1a2b4c6d8e0f1a3b5c7d9e1",
"changelog": "Hotfix: Fixed critical security vulnerability",
"isEnabled": true,
"isForceUpdate": true,
"createdBy": "admin"
}'
```
### 7.2 iOS 版本发布
```bash
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "ios",
"versionCode": 1,
"versionName": "1.0.0",
"buildNumber": "1",
"downloadUrl": "https://apps.apple.com/app/rwa-durian/id123456789",
"fileSize": 67108864,
"fileSha256": "c5e7f9a1b3c4d6e8f0a2b3c5d7e9f1a2b4c6d8e0f1a3b5c7d9e1f2a4b6c8d0e2",
"changelog": "Initial iOS release",
"isEnabled": true,
"isForceUpdate": false,
"createdBy": "admin"
}'
```
### 7.3 Postman Collection (部分示例)
```json
{
"info": {
"name": "Admin Service API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Create Android Version",
"request": {
"method": "POST",
"header": [{"key": "Content-Type", "value": "application/json"}],
"body": {
"mode": "raw",
"raw": "{\n \"platform\": \"android\",\n \"versionCode\": 100,\n \"versionName\": \"1.0.0\",\n \"buildNumber\": \"1\",\n \"downloadUrl\": \"https://cdn.example.com/app-v1.0.0.apk\",\n \"fileSize\": 52428800,\n \"fileSha256\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n \"changelog\": \"Initial release\",\n \"isEnabled\": true,\n \"isForceUpdate\": false,\n \"createdBy\": \"admin\"\n}"
},
"url": {
"raw": "http://localhost:3005/api/v1/version",
"protocol": "http",
"host": ["localhost"],
"port": "3005",
"path": ["api", "v1", "version"]
}
}
},
{
"name": "Check For Update",
"request": {
"method": "GET",
"url": {
"raw": "http://localhost:3005/api/v1/version/check?platform=android&versionCode=100",
"protocol": "http",
"host": ["localhost"],
"port": "3005",
"path": ["api", "v1", "version", "check"],
"query": [
{"key": "platform", "value": "android"},
{"key": "versionCode", "value": "100"}
]
}
}
}
]
}
```
---
## 8. 版本控制策略
### 8.1 版本号规则
**VersionCode** (数字版本号):
- 每次发布递增 1
- Android: 从 1 开始
- iOS: 从 1 开始
- 用于版本比较 (机器识别)
**VersionName** (语义化版本):
- 格式: `MAJOR.MINOR.PATCH` (例如: `1.2.3`)
- 用于用户展示 (人类可读)
**BuildNumber** (构建号):
- 格式: 自定义 (建议: `YYYYMMDDXXX`)
- 例如: `20250102001` = 2025年1月2日第1次构建
### 8.2 更新策略
| 场景 | isForceUpdate | 说明 |
|-----|---------------|------|
| 功能更新 | `false` | 用户可选择更新时机 |
| Bug 修复 | `false` | 建议更新,但不强制 |
| 安全漏洞 | `true` | 必须更新才能继续使用 |
| API 破坏性变更 | `true` | 旧版本无法正常工作 |
---
## 9. 最佳实践
### 9.1 文件托管建议
1. **使用 CDN**: 加速全球用户下载
2. **HTTPS**: 确保传输安全
3. **文件命名**: `app-{platform}-v{versionName}.{ext}`
- Android: `app-android-v1.0.0.apk`
- iOS: `app-ios-v1.0.0.ipa`
### 9.2 SHA256 校验流程
**服务端计算** (发版时):
```bash
# Linux/macOS
sha256sum app-android-v1.0.0.apk
# Windows
certutil -hashfile app-android-v1.0.0.apk SHA256
```
**移动端校验** (下载后):
```dart
// Flutter 示例
import 'package:crypto/crypto.dart';
import 'dart:io';
Future<bool> verifyApkIntegrity(String filePath, String expectedSha256) async {
final file = File(filePath);
final bytes = await file.readAsBytes();
final digest = sha256.convert(bytes);
return digest.toString() == expectedSha256.toLowerCase();
}
// 使用
final isValid = await verifyApkIntegrity(
'/storage/emulated/0/Download/app.apk',
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
);
if (!isValid) {
throw Exception('File integrity check failed! Possible tampering detected.');
}
```
### 9.3 更新日志编写规范
**推荐格式**:
```
1. 新功能:添加暗黑模式支持
2. 优化:挖矿页面性能提升 30%
3. 修复:交易历史加载失败问题
4. 安全:修复账户导入漏洞
```
**避免**:
- ❌ "Bug fixes and improvements" (太笼统)
- ❌ 技术术语 (普通用户不理解)
- ✅ 简洁明了,面向用户
---
## 10. 常见问题
### Q1: 如何回滚版本?
**方案 1**: 禁用问题版本,启用旧版本
```bash
# 禁用 v1.0.1
curl -X PATCH http://localhost:3005/api/v1/version/{v1.0.1-id}/disable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
# 启用 v1.0.0
curl -X PATCH http://localhost:3005/api/v1/version/{v1.0.0-id}/enable \
-H "Content-Type: application/json" \
-d '{"updatedBy": "admin"}'
```
**方案 2**: 创建新版本,使用更高的 versionCode
```bash
# 创建 v1.0.0-hotfix (versionCode = 103)
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{
"platform": "android",
"versionCode": 103,
"versionName": "1.0.0",
"buildNumber": "20250102003",
...
}'
```
### Q2: 如何处理多渠道包 (Google Play, 自建服务器)?
当前版本不支持,建议通过 `buildNumber` 区分:
```bash
# Google Play 渠道
{
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "100-gplay",
"downloadUrl": "https://play.google.com/store/apps/details?id=com.rwa.durian",
...
}
# 自建渠道
{
"versionCode": 100,
"versionName": "1.0.0",
"buildNumber": "100-self",
"downloadUrl": "https://cdn.rwadurian.com/android/app-v1.0.0.apk",
...
}
```
### Q3: 如何实现灰度发布?
当前版本不支持,未来可扩展:
```typescript
// 计划实现
interface AppVersion {
...
releaseType: 'full' | 'gray'; // 发布类型
grayRatio?: number; // 灰度比例 (0-100)
grayUserIds?: string[]; // 灰度用户列表
}
```
---
**最后更新**: 2025-12-03
**版本**: 1.0.0
**维护者**: RWA Durian Team

View File

@ -0,0 +1,685 @@
# Admin Service 架构文档
## 目录
- [1. 服务概述](#1-服务概述)
- [2. 架构设计](#2-架构设计)
- [3. 领域设计](#3-领域设计)
- [4. 技术栈](#4-技术栈)
- [5. 目录结构](#5-目录结构)
- [6. 数据流](#6-数据流)
---
## 1. 服务概述
### 1.1 服务职责
Admin Service 是 RWA Durian 项目的**应用版本管理服务**,负责:
- 📱 **版本发布管理**: 管理 Android/iOS 应用版本的创建、更新、启用/禁用
- 🔄 **版本检查**: 为移动端提供版本检查 API支持强制更新和普通更新
- 📊 **版本查询**: 支持按平台、版本号、启用状态等条件查询版本信息
- 🔐 **SHA256 校验**: 确保 APK/IPA 文件完整性和安全性
### 1.2 核心功能
| 功能 | 说明 | API 端点 |
|-----|------|---------|
| 创建版本 | 发布新版本Android/iOS | POST /api/v1/version |
| 检查更新 | 移动端检查是否有新版本 | GET /api/v1/version/check |
| 查询版本 | 查询所有版本或特定版本 | GET /api/v1/version |
| 启用/禁用版本 | 控制版本可用性 | PATCH /api/v1/version/:id/enable<br>PATCH /api/v1/version/:id/disable |
---
## 2. 架构设计
### 2.1 架构模式
Admin Service 采用 **DDD (领域驱动设计) + Hexagonal Architecture (六边形架构)** 的混合架构模式。
```
┌─────────────────────────────────────────────────────────┐
│ API Layer (NestJS) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Controllers │ │ DTOs │ │ Guards │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Application Layer (Handlers) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Commands │ │ Queries │ │ Events │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Domain Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Entities │ │ Value Objects│ │ Services │ │
│ │ │ │ │ │ │ │
│ │ AppVersion │ │VersionCode │ │VersionCheck │ │
│ │ │ │VersionName │ │ Service │ │
│ │ │ │ FileSize │ │ │ │
│ │ │ │ FileSha256 │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Repository Interfaces (Port) │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Infrastructure Layer (Adapters) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Repositories │ │ Mappers │ │ Prisma │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
┌──────────┐
│PostgreSQL│
└──────────┘
```
### 2.2 分层职责
#### API Layer (接口层)
- **Controllers**: 处理 HTTP 请求,路由分发
- **DTOs**: 定义请求/响应数据传输对象
- **Guards**: 身份验证、权限控制 (暂未实现)
- **依赖方向**: → Application Layer
#### Application Layer (应用层)
- **Command Handlers**: 处理写操作命令 (Create, Update, Delete)
- **Query Handlers**: 处理读操作查询 (Get, List, Find)
- **Event Handlers**: 处理领域事件 (暂未实现)
- **依赖方向**: → Domain Layer
#### Domain Layer (领域层)
- **Entities**: 聚合根,包含业务逻辑 (`AppVersion`)
- **Value Objects**: 不可变值对象 (`VersionCode`, `VersionName`, `FileSize`, `FileSha256`)
- **Domain Services**: 跨实体的业务逻辑 (`VersionCheckService`)
- **Repository Interfaces**: 持久化端口定义
- **依赖方向**: 无外部依赖 (核心层)
#### Infrastructure Layer (基础设施层)
- **Repositories**: Repository 接口的 Prisma 实现
- **Mappers**: 领域对象 ↔ 持久化对象转换
- **Prisma Client**: 数据库 ORM
- **依赖方向**: → Domain Layer (依赖倒置)
---
## 3. 领域设计
### 3.1 领域模型
#### 聚合根: AppVersion
```typescript
class AppVersion {
// 标识
private readonly _id: string;
private readonly _platform: Platform;
// 版本信息
private readonly _versionCode: VersionCode;
private readonly _versionName: VersionName;
private readonly _buildNumber: string;
// 文件信息
private _downloadUrl: string;
private readonly _fileSize: FileSize;
private readonly _fileSha256: FileSha256;
// 更新信息
private _changelog: string;
private _isEnabled: boolean;
private _isForceUpdate: boolean;
// 审计信息
private readonly _createdBy: string;
private readonly _createdAt: Date;
private _updatedBy: string;
private _updatedAt: Date;
}
```
**业务不变式**:
1. `versionCode` 必须是正整数
2. `versionName` 必须符合语义化版本格式 (x.y.z)
3. `fileSize` 必须大于 0
4. `fileSha256` 必须是有效的 64 位十六进制字符串
5. 同一平台同一版本号的版本只能有一个启用
#### 值对象
**VersionCode (版本号)**
```typescript
class VersionCode {
constructor(private readonly value: number) {
if (!Number.isInteger(value) || value < 1) {
throw new DomainException('Version code must be a positive integer');
}
}
isGreaterThan(other: VersionCode): boolean
isLessThan(other: VersionCode): boolean
equals(other: VersionCode): boolean
}
```
**VersionName (版本名称)**
```typescript
class VersionName {
private readonly SEMVER_REGEX = /^\d+\.\d+\.\d+$/;
constructor(private readonly value: string) {
if (!this.SEMVER_REGEX.test(value)) {
throw new DomainException('Invalid semantic version format');
}
}
get major(): number
get minor(): number
get patch(): number
}
```
**FileSize (文件大小)**
```typescript
class FileSize {
constructor(private readonly bytes: bigint) {
if (bytes < 0n) {
throw new DomainException('File size cannot be negative');
}
}
toHumanReadable(): string // "1.50 MB"
toMegabytes(): string // "1.50"
}
```
**FileSha256 (SHA256 哈希)**
```typescript
class FileSha256 {
private readonly SHA256_REGEX = /^[a-f0-9]{64}$/;
constructor(private readonly hash: string) {
if (!this.SHA256_REGEX.test(hash.toLowerCase())) {
throw new DomainException('Invalid SHA256 hash format');
}
}
}
```
### 3.2 领域服务
**VersionCheckService**
```typescript
class VersionCheckService {
async checkForUpdate(
platform: Platform,
currentVersionCode: number,
): Promise<VersionCheckResult> {
// 1. 查找最新启用的版本
const latestVersion = await this.repository.findLatestEnabledVersion(platform);
// 2. 比较版本号
if (!latestVersion || latestVersion.versionCode.value <= currentVersionCode) {
return VersionCheckResult.noUpdate();
}
// 3. 返回更新信息
return VersionCheckResult.hasUpdate({
latestVersion: latestVersion.versionName.value,
downloadUrl: latestVersion.downloadUrl,
isForceUpdate: latestVersion.isForceUpdate,
changelog: latestVersion.changelog,
});
}
}
```
### 3.3 业务规则
| 规则 | 实现位置 | 验证时机 |
|-----|---------|---------|
| 版本号必须唯一 | `AppVersionRepository` | 创建版本时 |
| 禁用版本不能强制更新 | `AppVersion.disable()` | 禁用操作时 |
| 文件大小必须 > 0 | `FileSize` VO | 值对象创建时 |
| SHA256 必须 64 位十六进制 | `FileSha256` VO | 值对象创建时 |
| 版本名称必须符合 semver | `VersionName` VO | 值对象创建时 |
---
## 4. 技术栈
### 4.1 核心框架
| 技术 | 版本 | 用途 |
|-----|------|------|
| NestJS | 10.0.0 | Web 框架 |
| TypeScript | 5.1.3 | 编程语言 |
| Node.js | 20.x | 运行时 |
| Prisma | 5.7.0 | ORM |
| PostgreSQL | 16 | 数据库 |
### 4.2 开发工具
| 工具 | 版本 | 用途 |
|-----|------|------|
| Jest | 29.5.0 | 测试框架 |
| ts-jest | 29.1.0 | TypeScript + Jest |
| Supertest | 6.3.3 | HTTP 测试 |
| ESLint | 8.42.0 | 代码检查 |
| Prettier | 3.0.0 | 代码格式化 |
### 4.3 部署工具
| 工具 | 用途 |
|-----|------|
| Docker | 容器化 |
| Docker Compose | 多容器编排 |
| Makefile | 自动化脚本 |
---
## 5. 目录结构
```
admin-service/
├── src/
│ ├── api/ # API 层
│ │ ├── controllers/ # 控制器
│ │ │ └── version.controller.ts
│ │ └── dtos/ # 数据传输对象
│ │ ├── create-version.dto.ts
│ │ ├── update-version.dto.ts
│ │ ├── check-version.dto.ts
│ │ └── version-response.dto.ts
│ │
│ ├── application/ # 应用层
│ │ ├── commands/ # 命令
│ │ │ ├── create-version.command.ts
│ │ │ ├── enable-version.command.ts
│ │ │ └── disable-version.command.ts
│ │ ├── handlers/ # 处理器
│ │ │ ├── create-version.handler.ts
│ │ │ ├── enable-version.handler.ts
│ │ │ └── disable-version.handler.ts
│ │ └── queries/ # 查询
│ │ ├── find-version-by-id.query.ts
│ │ └── find-all-versions.query.ts
│ │
│ ├── domain/ # 领域层
│ │ ├── entities/ # 实体
│ │ │ └── app-version.entity.ts
│ │ ├── value-objects/ # 值对象
│ │ │ ├── version-code.vo.ts
│ │ │ ├── version-name.vo.ts
│ │ │ ├── file-size.vo.ts
│ │ │ └── file-sha256.vo.ts
│ │ ├── repositories/ # 仓储接口
│ │ │ └── app-version.repository.ts
│ │ ├── services/ # 领域服务
│ │ │ └── version-check.service.ts
│ │ └── enums/ # 枚举
│ │ └── platform.enum.ts
│ │
│ ├── infrastructure/ # 基础设施层
│ │ ├── persistence/ # 持久化
│ │ │ ├── repositories/ # 仓储实现
│ │ │ │ └── app-version.repository.impl.ts
│ │ │ └── mappers/ # 映射器
│ │ │ └── app-version.mapper.ts
│ │ └── prisma/ # Prisma
│ │ └── prisma.service.ts
│ │
│ ├── shared/ # 共享模块
│ │ ├── exceptions/ # 异常
│ │ │ ├── domain.exception.ts
│ │ │ └── application.exception.ts
│ │ └── utils/ # 工具
│ │
│ ├── app.module.ts # 根模块
│ └── main.ts # 入口文件
├── prisma/
│ ├── schema.prisma # Prisma Schema
│ └── migrations/ # 数据库迁移
├── test/ # 测试
│ ├── unit/ # 单元测试
│ ├── integration/ # 集成测试
│ └── e2e/ # E2E 测试
├── database/ # 数据库初始化
│ ├── init.sql # 初始化脚本
│ └── README.md
├── docs/ # 文档
│ ├── ARCHITECTURE.md # 本文档
│ ├── API.md # API 文档
│ ├── DEVELOPMENT.md # 开发指南
│ ├── TESTING.md # 测试文档
│ └── DEPLOYMENT.md # 部署文档
├── scripts/ # 脚本
│ ├── test-in-wsl.sh
│ ├── run-wsl-tests.ps1
│ └── test-with-docker-db.sh
├── docker-compose.yml # Docker Compose
├── Dockerfile # Dockerfile
├── Makefile # Make 命令
├── package.json # NPM 配置
├── tsconfig.json # TypeScript 配置
└── README.md # 项目说明
```
---
## 6. 数据流
### 6.1 创建版本流程
```
Client Request (POST /api/v1/version)
┌─────────────────────────────────────┐
│ VersionController.createVersion() │ ← API Layer
└─────────────────────────────────────┘
│ CreateVersionDto
┌─────────────────────────────────────┐
│ CreateVersionHandler.execute() │ ← Application Layer
│ 1. Create Command │
│ 2. Validate Business Rules │
│ 3. Call Repository │
└─────────────────────────────────────┘
│ CreateVersionCommand
┌─────────────────────────────────────┐
│ AppVersion.create() │ ← Domain Layer
│ 1. Create Value Objects │
│ - VersionCode │
│ - VersionName │
│ - FileSize │
│ - FileSha256 │
│ 2. Create Entity │
│ 3. Apply Business Rules │
└─────────────────────────────────────┘
│ AppVersion Entity
┌─────────────────────────────────────┐
│ AppVersionRepositoryImpl.save() │ ← Infrastructure Layer
│ 1. Map Entity → Prisma Model │
│ 2. Save to Database │
│ 3. Return Persisted Entity │
└─────────────────────────────────────┘
PostgreSQL
```
### 6.2 检查更新流程
```
Mobile Client (GET /api/v1/version/check?platform=android&versionCode=100)
┌─────────────────────────────────────┐
│ VersionController.checkForUpdate() │ ← API Layer
└─────────────────────────────────────┘
│ CheckVersionDto
┌─────────────────────────────────────┐
│ VersionCheckService.checkForUpdate()│ ← Domain Service
│ 1. Query Latest Enabled Version │
│ 2. Compare Version Codes │
│ 3. Build Update Result │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ AppVersionRepository │ ← Repository
│ .findLatestEnabledVersion() │
└─────────────────────────────────────┘
PostgreSQL
┌─────────────────────────────────────┐
│ VersionCheckResult │ ← Response
│ - hasUpdate: boolean │
│ - latestVersion: string │
│ - downloadUrl: string │
│ - isForceUpdate: boolean │
│ - changelog: string │
└─────────────────────────────────────┘
```
### 6.3 依赖方向
```
API Layer
↓ depends on
Application Layer
↓ depends on
Domain Layer (Core)
↑ implemented by
Infrastructure Layer
```
**核心原则**:
- Domain Layer 不依赖任何外部层
- Infrastructure Layer 通过接口依赖 Domain Layer (依赖倒置原则)
- Application Layer 协调 Domain 和 Infrastructure
- API Layer 仅依赖 Application Layer
---
## 7. 设计原则
### 7.1 SOLID 原则应用
| 原则 | 应用实例 |
|-----|---------|
| **S** (单一职责) | 每个值对象只负责一个验证逻辑<br>每个 Handler 只处理一个命令/查询 |
| **O** (开闭原则) | 新增平台类型无需修改现有代码<br>通过 enum 扩展实现 |
| **L** (里氏替换) | Repository 接口可被不同实现替换<br>Prisma, TypeORM, InMemory |
| **I** (接口隔离) | Repository 接口仅定义必要方法<br>不强制实现不需要的功能 |
| **D** (依赖倒置) | Domain Layer 定义 Repository 接口<br>Infrastructure Layer 实现接口 |
### 7.2 DDD 战术模式
| 模式 | 应用 |
|-----|------|
| **Entity** | `AppVersion` 聚合根 |
| **Value Object** | `VersionCode`, `VersionName`, `FileSize`, `FileSha256` |
| **Aggregate** | `AppVersion` 作为聚合边界 |
| **Repository** | `AppVersionRepository` 接口及实现 |
| **Domain Service** | `VersionCheckService` 处理跨实体逻辑 |
| **Factory Method** | `AppVersion.create()` 静态工厂方法 |
---
## 8. 扩展性设计
### 8.1 新增平台支持
当需要支持新平台(如 HarmonyOS
1. **枚举扩展** (`domain/enums/platform.enum.ts`):
```typescript
export enum Platform {
ANDROID = 'android',
IOS = 'ios',
HARMONYOS = 'harmonyos', // 新增
}
```
2. **无需修改**:
- Entity 逻辑
- Repository 实现
- Controller/Handler
### 8.2 新增版本检查策略
当需要支持灰度发布、A/B 测试时:
1. **新增领域服务**:
```typescript
class GrayReleaseService {
async checkEligibility(userId: string, version: AppVersion): Promise<boolean>
}
```
2. **修改 VersionCheckService**:
```typescript
async checkForUpdate(
platform: Platform,
currentVersionCode: number,
userId?: string, // 新增参数
): Promise<VersionCheckResult>
```
---
## 9. 性能考量
### 9.1 数据库索引
```sql
-- 平台 + 版本号唯一索引
CREATE UNIQUE INDEX idx_platform_versioncode
ON "AppVersion" (platform, "versionCode");
-- 启用状态 + 平台 + 版本号索引(查询最新版本)
CREATE INDEX idx_enabled_platform_versioncode
ON "AppVersion" ("isEnabled", platform, "versionCode" DESC);
```
### 9.2 缓存策略
**建议实现** (当前未实现):
```typescript
@Injectable()
export class CachedVersionCheckService {
constructor(
private readonly versionCheckService: VersionCheckService,
private readonly cacheManager: Cache,
) {}
async checkForUpdate(platform: Platform, versionCode: number) {
const cacheKey = `version:${platform}:${versionCode}`;
const cached = await this.cacheManager.get(cacheKey);
if (cached) return cached;
const result = await this.versionCheckService.checkForUpdate(platform, versionCode);
await this.cacheManager.set(cacheKey, result, { ttl: 300 }); // 5分钟
return result;
}
}
```
---
## 10. 安全性
### 10.1 文件校验
- **SHA256 验证**: 确保下载文件未被篡改
- **下载 URL**: 建议使用 HTTPS + CDN
- **文件大小**: 防止异常大文件攻击
### 10.2 API 安全 (待实现)
```typescript
@Controller('api/v1/version')
@UseGuards(JwtAuthGuard) // 管理端需要认证
export class VersionController {
@Post()
@UseGuards(RolesGuard)
@Roles('admin', 'developer') // 仅管理员和开发者可创建版本
async createVersion(@Body() dto: CreateVersionDto) {}
@Get('check')
// 公开端点,无需认证
async checkForUpdate(@Query() dto: CheckVersionDto) {}
}
```
---
## 11. 监控和日志
### 11.1 关键指标
| 指标 | 说明 | 监控方式 |
|-----|------|---------|
| 版本检查 QPS | 每秒查询次数 | Prometheus + Grafana |
| 创建版本成功率 | 创建操作成功/失败比例 | Application Logs |
| 数据库查询延迟 | 查询耗时 | Prisma Metrics |
| 强制更新触发率 | 强制更新用户占比 | Business Metrics |
### 11.2 日志记录
```typescript
@Injectable()
export class CreateVersionHandler {
private readonly logger = new Logger(CreateVersionHandler.name);
async execute(command: CreateVersionCommand): Promise<AppVersion> {
this.logger.log(`Creating version: ${command.platform} v${command.versionName}`);
try {
const version = await this.repository.save(appVersion);
this.logger.log(`Version created successfully: ${version.id}`);
return version;
} catch (error) {
this.logger.error(`Failed to create version: ${error.message}`, error.stack);
throw error;
}
}
}
```
---
## 12. 未来改进
### 12.1 短期 (1-3 个月)
- [ ] 实现 JWT 认证和 RBAC 权限控制
- [ ] 添加版本删除功能(软删除)
- [ ] 实现分页查询
- [ ] 添加 Redis 缓存层
### 12.2 中期 (3-6 个月)
- [ ] 实现灰度发布功能
- [ ] 添加版本回滚机制
- [ ] 实现版本发布审批流程
- [ ] 集成 CDN 文件上传
### 12.3 长期 (6-12 个月)
- [ ] 实现多渠道版本管理Google Play, App Store, 自建服务器)
- [ ] 添加 A/B 测试支持
- [ ] 实现版本使用统计和分析
- [ ] 集成 Sentry 错误监控
---
**最后更新**: 2025-12-03
**版本**: 1.0.0
**维护者**: RWA Durian Team

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,305 @@
# Admin Service 文档中心
欢迎来到 Admin Service 文档中心!本目录包含了服务的完整技术文档。
## 📚 文档列表
### [1. ARCHITECTURE.md](ARCHITECTURE.md) - 架构设计文档
**内容概览**:
- 服务职责和核心功能
- DDD + Hexagonal 架构设计
- 领域模型详解 (聚合根、值对象、领域服务)
- 技术栈和目录结构
- 数据流和依赖方向
- SOLID 原则应用
- 性能和安全性考量
**适合人群**: 架构师、技术负责人、新加入开发者
**关键章节**:
- §2 架构设计 - 了解系统整体架构
- §3 领域设计 - 深入理解业务模型
- §6 数据流 - 掌握请求处理流程
---
### [2. API.md](API.md) - API 接口文档
**内容概览**:
- API 端点完整说明
- 请求/响应格式和示例
- 错误处理和状态码
- 认证授权机制 (待实现)
- 使用示例和最佳实践
**适合人群**: 前端开发者、API 集成开发者、测试工程师
**核心端点**:
- `POST /api/v1/version` - 创建版本
- `GET /api/v1/version/check` - 检查更新 (移动端)
- `PATCH /api/v1/version/:id/enable` - 启用版本
- `PATCH /api/v1/version/:id/disable` - 禁用版本
**快速开始**:
```bash
# 检查更新
curl "http://localhost:3005/api/v1/version/check?platform=android&versionCode=100"
# 创建版本
curl -X POST http://localhost:3005/api/v1/version \
-H "Content-Type: application/json" \
-d '{"platform": "android", "versionCode": 101, ...}'
```
---
### [3. DEVELOPMENT.md](DEVELOPMENT.md) - 开发指南
**内容概览**:
- 开发环境设置
- 项目初始化步骤
- 完整开发迭代流程
- 代码规范 (TypeScript, DDD, NestJS, Prisma)
- 调试技巧和常见开发任务
**适合人群**: 开发者、贡献者
**推荐阅读顺序**:
1. §1 开发环境设置 - 配置本地环境
2. §2 项目初始化 - 快速启动项目
3. §3 开发流程 - 学习标准开发流程
4. §4 代码规范 - 遵循团队规范
**Git 工作流**:
```bash
git checkout develop
git checkout -b feature/add-version-delete
# 开发...
git commit -m "feat(version): add delete version functionality"
git push origin feature/add-version-delete
```
---
### [4. TESTING.md](TESTING.md) - 测试文档
**内容概览**:
- 三层测试架构 (单元/集成/E2E)
- 测试环境设置 (本地/WSL2/Docker)
- 测试用例详细示例
- 测试执行方法
- 覆盖率要求和 CI/CD 集成
**适合人群**: 开发者、测试工程师、CI/CD 工程师
**测试统计**:
- **单元测试**: 53 个用例, 6 个文件
- **集成测试**: 21 个用例, 2 个文件
- **E2E 测试**: 15 个用例, 1 个文件
- **总计**: ~89 个测试用例
**快速运行测试**:
```bash
# 单元测试 (无需数据库)
npm run test:unit
# 集成测试 (需要数据库)
DATABASE_URL="postgresql://..." npm run test:integration
# E2E 测试 (需要数据库)
DATABASE_URL="postgresql://..." npm run test:e2e
# 所有测试 + 覆盖率
npm run test:cov
```
---
### [5. DEPLOYMENT.md](DEPLOYMENT.md) - 部署文档
**内容概览**:
- 部署架构和环境准备
- 本地部署 (PM2)
- Docker 容器化部署
- 生产环境最佳实践
- 监控、日志、备份策略
- 故障排查和回滚方案
**适合人群**: 运维工程师、DevOps 工程师、系统管理员
**部署方式**:
| 方式 | 适用场景 | 复杂度 |
|-----|---------|-------|
| 本地部署 (PM2) | 开发/测试环境 | ⭐⭐ |
| Docker Compose | 本地/小规模生产 | ⭐⭐⭐ |
| Kubernetes | 大规模生产 | ⭐⭐⭐⭐⭐ |
**快速部署**:
```bash
# Docker 方式
docker-compose up -d
docker-compose exec admin-service npx prisma migrate deploy
# PM2 方式
npm run build
pm2 start ecosystem.config.js
```
---
## 🚀 快速导航
### 我是新开发者
1. 阅读 [ARCHITECTURE.md](ARCHITECTURE.md) §1-§2 了解服务职责和架构
2. 按照 [DEVELOPMENT.md](DEVELOPMENT.md) §1-§2 设置开发环境
3. 查看 [API.md](API.md) §5-§6 熟悉 API 端点
4. 阅读 [DEVELOPMENT.md](DEVELOPMENT.md) §3 学习开发流程
### 我要集成 API
1. 阅读 [API.md](API.md) §1 了解基本信息
2. 查看 [API.md](API.md) §5 学习具体端点用法
3. 参考 [API.md](API.md) §7 查看使用示例
4. 查阅 [API.md](API.md) §4 处理错误情况
### 我要编写测试
1. 阅读 [TESTING.md](TESTING.md) §1 了解测试架构
2. 按照 [TESTING.md](TESTING.md) §2 设置测试环境
3. 参考 [TESTING.md](TESTING.md) §3-§5 编写测试用例
4. 查看 [TESTING.md](TESTING.md) §7 检查覆盖率
### 我要部署服务
1. 阅读 [DEPLOYMENT.md](DEPLOYMENT.md) §1 了解部署架构
2. 按照 [DEPLOYMENT.md](DEPLOYMENT.md) §2 准备环境
3. 选择合适的部署方式:
- 开发: [DEPLOYMENT.md](DEPLOYMENT.md) §3 本地部署
- 测试: [DEPLOYMENT.md](DEPLOYMENT.md) §4 Docker 部署
- 生产: [DEPLOYMENT.md](DEPLOYMENT.md) §5 生产环境部署
4. 配置监控: [DEPLOYMENT.md](DEPLOYMENT.md) §6
### 我遇到问题
1. 查看 [DEVELOPMENT.md](DEVELOPMENT.md) §7 开发常见问题
2. 查看 [TESTING.md](TESTING.md) §9 测试最佳实践
3. 查看 [DEPLOYMENT.md](DEPLOYMENT.md) §7 故障排查
---
## 📖 文档约定
### 版本标记
- ✅ **已实现**: 功能已完成并经过测试
- ⚠️ **部分实现**: 功能部分完成或待优化
- ❌ **未实现**: 计划功能但尚未开发
- 🎯 **目标**: 性能或覆盖率目标
### 优先级标记
- **P0**: 核心功能,必须实现
- **P1**: 重要功能,高优先级
- **P2**: 常用功能,中优先级
- **P3**: 辅助功能,低优先级
- **P4**: 增强功能,可选实现
### 代码示例标记
```typescript
// ✅ 推荐: 说明推荐的做法
const goodExample = () => {};
// ❌ 避免: 说明不推荐的做法
const badExample = () => {};
```
---
## 🔄 文档更新日志
### 2025-12-03 - v1.0.0 (初始版本)
- ✅ 创建完整文档体系
- ✅ ARCHITECTURE.md - 架构设计文档
- ✅ API.md - API 接口文档
- ✅ DEVELOPMENT.md - 开发指南
- ✅ TESTING.md - 测试文档
- ✅ DEPLOYMENT.md - 部署文档
---
## 📋 待办事项
### 短期 (1-3 个月)
- [ ] 添加 Swagger/OpenAPI 规范文档
- [ ] 完善 JWT 认证文档
- [ ] 添加性能测试文档
- [ ] 补充故障案例库
### 中期 (3-6 个月)
- [ ] 添加 Kubernetes 部署指南
- [ ] 完善监控告警文档
- [ ] 添加安全审计文档
- [ ] 补充数据迁移指南
### 长期 (6-12 个月)
- [ ] 添加多语言 API 客户端示例
- [ ] 完善灰度发布文档
- [ ] 添加 A/B 测试指南
- [ ] 补充性能调优案例
---
## 🤝 贡献指南
### 文档更新流程
1. **创建分支**:
```bash
git checkout -b docs/update-api-examples
```
2. **修改文档**:
- 遵循现有格式和风格
- 添加清晰的示例代码
- 更新版本日期
3. **提交变更**:
```bash
git add docs/
git commit -m "docs: add API usage examples for version check"
```
4. **创建 Pull Request**:
- 描述文档变更内容
- 标注相关 Issue
- 请求 Review
### 文档规范
1. **Markdown 格式**:
- 使用标题层级 (H1-H6)
- 代码块指定语言
- 表格对齐美观
2. **命名规范**:
- 文件名大写: `ARCHITECTURE.md`
- 章节使用数字编号: `§1`, `§2`
- 代码示例清晰标注
3. **内容要求**:
- 简洁明了
- 示例完整可运行
- 及时更新版本信息
---
## 📞 联系方式
- **项目**: RWA Durian
- **服务**: Admin Service
- **维护团队**: RWA Durian Backend Team
- **技术支持**: backend-team@rwadurian.com
- **问题反馈**: [GitHub Issues](https://github.com/your-org/rwa-durian/issues)
---
## 📄 许可证
本文档遵循项目许可证。
---
**最后更新**: 2025-12-03
**文档版本**: 1.0.0
**维护者**: RWA Durian Team

File diff suppressed because it is too large Load Diff