686 lines
25 KiB
Markdown
686 lines
25 KiB
Markdown
# 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
|