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:
parent
f8c9c579f2
commit
79e2b9bfdd
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue