Files
mcphub/docs/dao-layer.md
2025-08-27 15:21:30 +08:00

255 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MCPHub DAO Layer 设计文档
## 概述
MCPHub的数据访问对象(DAO)层为项目中`mcp_settings.json`文件中的不同数据类型提供了统一的增删改查操作接口。这个设计使得未来从JSON文件存储切换到数据库存储变得更加容易。
## 架构设计
### 核心组件
```
src/dao/
├── base/
│ ├── BaseDao.ts # 基础DAO接口和抽象实现
│ └── JsonFileBaseDao.ts # JSON文件操作的基础类
├── UserDao.ts # 用户数据访问对象
├── ServerDao.ts # 服务器配置数据访问对象
├── GroupDao.ts # 群组数据访问对象
├── SystemConfigDao.ts # 系统配置数据访问对象
├── UserConfigDao.ts # 用户配置数据访问对象
├── DaoFactory.ts # DAO工厂类
├── examples.ts # 使用示例
└── index.ts # 统一导出
```
### 数据类型映射
| 数据类型 | 原始位置 | DAO类 | 主要功能 |
|---------|---------|-------|---------|
| IUser | `settings.users[]` | UserDao | 用户管理、密码验证、权限控制 |
| ServerConfig | `settings.mcpServers{}` | ServerDao | 服务器配置、启用/禁用、工具管理 |
| IGroup | `settings.groups[]` | GroupDao | 群组管理、服务器分组、成员管理 |
| SystemConfig | `settings.systemConfig` | SystemConfigDao | 系统级配置、路由设置、安装配置 |
| UserConfig | `settings.userConfigs{}` | UserConfigDao | 用户个人配置 |
## 主要特性
### 1. 统一的CRUD接口
所有DAO都实现了基础的CRUD操作
```typescript
interface BaseDao<T, K = string> {
findAll(): Promise<T[]>;
findById(id: K): Promise<T | null>;
create(entity: Omit<T, 'id'>): Promise<T>;
update(id: K, entity: Partial<T>): Promise<T | null>;
delete(id: K): Promise<boolean>;
exists(id: K): Promise<boolean>;
count(): Promise<number>;
}
```
### 2. 特定业务操作
每个DAO还提供了针对其数据类型的特定操作
#### UserDao 特殊功能
- `createWithHashedPassword()` - 创建用户时自动哈希密码
- `validateCredentials()` - 验证用户凭据
- `updatePassword()` - 更新用户密码
- `findAdmins()` - 查找管理员用户
#### ServerDao 特殊功能
- `findByOwner()` - 按所有者查找服务器
- `findEnabled()` - 查找启用的服务器
- `findByType()` - 按类型查找服务器
- `setEnabled()` - 启用/禁用服务器
- `updateTools()` - 更新服务器工具配置
#### GroupDao 特殊功能
- `findByOwner()` - 按所有者查找群组
- `findByServer()` - 查找包含特定服务器的群组
- `addServerToGroup()` - 向群组添加服务器
- `removeServerFromGroup()` - 从群组移除服务器
- `findByName()` - 按名称查找群组
### 3. 配置管理特殊功能
#### SystemConfigDao
- `getSection()` - 获取特定配置段
- `updateSection()` - 更新特定配置段
- `reset()` - 重置为默认配置
#### UserConfigDao
- `getSection()` - 获取用户特定配置段
- `updateSection()` - 更新用户特定配置段
- `getAll()` - 获取所有用户配置
## 使用方法
### 1. 基本使用
```typescript
import { getUserDao, getServerDao, getGroupDao } from './dao/index.js';
// 用户操作
const userDao = getUserDao();
const newUser = await userDao.createWithHashedPassword('username', 'password', false);
const user = await userDao.findByUsername('username');
const isValid = await userDao.validateCredentials('username', 'password');
// 服务器操作
const serverDao = getServerDao();
const server = await serverDao.create({
name: 'my-server',
command: 'node',
args: ['server.js'],
enabled: true
});
// 群组操作
const groupDao = getGroupDao();
const group = await groupDao.create({
name: 'my-group',
description: 'Test group',
servers: ['my-server']
});
```
### 2. 配置服务集成
```typescript
import { DaoConfigService, createDaoConfigService } from './config/DaoConfigService.js';
const daoService = createDaoConfigService();
// 加载完整配置
const settings = await daoService.loadSettings();
// 保存配置
await daoService.saveSettings(updatedSettings);
```
### 3. 迁移管理
```typescript
import { migrateToDao, switchToDao, switchToLegacy } from './config/configManager.js';
// 迁移到DAO层
const success = await migrateToDao();
// 运行时切换
switchToDao(); // 切换到DAO层
switchToLegacy(); // 切换回传统方式
```
## 配置选项
可以通过环境变量控制使用哪种数据访问方式:
```bash
# 使用DAO层 (推荐)
USE_DAO_LAYER=true
# 使用传统文件方式 (默认,向后兼容)
USE_DAO_LAYER=false
```
## 未来扩展
### 数据库支持
DAO层的设计使得切换到数据库变得容易只需要
1. 实现新的DAO实现类如DatabaseUserDao
2. 创建新的DaoFactory
3. 更新配置以使用新的工厂
```typescript
// 未来的数据库实现示例
class DatabaseUserDao implements UserDao {
constructor(private db: Database) {}
async findAll(): Promise<IUser[]> {
return this.db.query('SELECT * FROM users');
}
// ... 其他方法
}
```
### 新数据类型
添加新数据类型只需要:
1. 定义数据接口
2. 创建对应的DAO接口和实现
3. 更新DaoFactory
4. 更新配置服务
## 迁移指南
### 从传统方式迁移到DAO层
1. **备份数据**
```bash
cp mcp_settings.json mcp_settings.json.backup
```
2. **运行迁移**
```typescript
import { performMigration } from './config/migrationUtils.js';
await performMigration();
```
3. **验证迁移**
```typescript
import { validateMigration } from './config/migrationUtils.js';
const isValid = await validateMigration();
```
4. **切换到DAO层**
```bash
export USE_DAO_LAYER=true
```
### 性能对比
可以使用内置工具对比性能:
```typescript
import { performanceComparison } from './config/migrationUtils.js';
await performanceComparison();
```
## 最佳实践
1. **类型安全**: 始终使用TypeScript接口确保类型安全
2. **错误处理**: 在DAO操作周围实现适当的错误处理
3. **事务**: 对于复杂操作,考虑使用事务(未来数据库实现)
4. **缓存**: DAO层包含内置缓存机制
5. **测试**: 使用DAO接口进行单元测试的模拟
## 示例代码
查看以下文件获取完整示例:
- `src/dao/examples.ts` - 基本DAO操作示例
- `src/config/migrationUtils.ts` - 迁移和验证工具
- `src/scripts/dao-demo.ts` - 交互式演示脚本
## 总结
DAO层为MCPHub提供了
- 🏗️ **模块化设计**: 每种数据类型都有专门的访问层
- 🔄 **易于迁移**: 为未来切换到数据库做好准备
- 🧪 **可测试性**: 接口可以轻松模拟和测试
- 🔒 **类型安全**: 完整的TypeScript类型支持
-**性能优化**: 内置缓存和批量操作支持
- 🛡️ **数据完整性**: 强制数据验证和约束
通过引入DAO层MCPHub的数据管理变得更加结构化、可维护和可扩展。