docs(zulip_core): 完善模块文档和优化账号服务逻辑
范围:src/core/zulip_core/ - 补充README.md缺失的服务文档(用户注册、用户管理、动态配置、错误处理、监控日志) - 优化zulip_account.service.ts中已存在用户的处理逻辑 - 增强userId获取的可靠性,优先使用userInfo,其次使用apiKeyResult - 版本更新:1.1.1 -> 1.2.0
This commit is contained in:
@@ -87,6 +87,25 @@ Zulip Core 是应用的核心聊天集成模块,提供完整的Zulip聊天服
|
|||||||
### getAllAccountLinks()
|
### getAllAccountLinks()
|
||||||
获取所有活跃的账号关联信息,用于系统管理和监控。
|
获取所有活跃的账号关联信息,用于系统管理和监控。
|
||||||
|
|
||||||
|
## 用户注册功能
|
||||||
|
|
||||||
|
### registerUser()
|
||||||
|
在Zulip服务器上注册新用户账号,包含邮箱验证、密码生成和API Key获取。
|
||||||
|
|
||||||
|
## 用户管理功能
|
||||||
|
|
||||||
|
### checkUserExists()
|
||||||
|
检查指定邮箱的用户是否存在于Zulip服务器。
|
||||||
|
|
||||||
|
### getUserInfo()
|
||||||
|
根据邮箱获取用户的详细信息,包含用户ID、状态和权限信息。
|
||||||
|
|
||||||
|
### validateUserCredentials()
|
||||||
|
验证用户的API Key是否有效,用于登录认证。
|
||||||
|
|
||||||
|
### getAllUsers()
|
||||||
|
从Zulip服务器获取所有用户列表,用于管理和统计。
|
||||||
|
|
||||||
## 配置管理功能
|
## 配置管理功能
|
||||||
|
|
||||||
### getAllMapConfigs()
|
### getAllMapConfigs()
|
||||||
@@ -101,6 +120,67 @@ Zulip Core 是应用的核心聊天集成模块,提供完整的Zulip聊天服
|
|||||||
### validateConfig()
|
### validateConfig()
|
||||||
验证配置文件的完整性和正确性,确保系统正常运行。
|
验证配置文件的完整性和正确性,确保系统正常运行。
|
||||||
|
|
||||||
|
## 动态配置管理功能
|
||||||
|
|
||||||
|
### testZulipConnection()
|
||||||
|
测试与Zulip服务器的连接状态,用于健康检查和故障诊断。
|
||||||
|
|
||||||
|
### getZulipStreams()
|
||||||
|
从Zulip服务器获取所有Stream列表,用于配置同步。
|
||||||
|
|
||||||
|
### getZulipTopics()
|
||||||
|
获取指定Stream的所有Topic列表,用于交互对象配置。
|
||||||
|
|
||||||
|
### getConfig()
|
||||||
|
获取当前缓存的配置信息,优先使用内存缓存。
|
||||||
|
|
||||||
|
### syncConfig()
|
||||||
|
手动触发配置同步,从Zulip服务器获取最新配置并更新本地文件。
|
||||||
|
|
||||||
|
### getConfigStatus()
|
||||||
|
获取配置管理器的状态信息,包含同步时间、配置来源等。
|
||||||
|
|
||||||
|
### getBackupFiles()
|
||||||
|
获取配置备份文件列表,用于配置恢复和版本管理。
|
||||||
|
|
||||||
|
### restoreFromBackup()
|
||||||
|
从指定的备份文件恢复配置,支持配置回滚。
|
||||||
|
|
||||||
|
## 错误处理功能
|
||||||
|
|
||||||
|
### handleZulipError()
|
||||||
|
处理Zulip API错误,分析错误类型并决定处理策略。
|
||||||
|
|
||||||
|
### enableDegradedMode()
|
||||||
|
启用服务降级模式,在Zulip服务不可用时提供基础功能。
|
||||||
|
|
||||||
|
### enableNormalMode()
|
||||||
|
恢复正常服务模式,从降级状态切换回正常状态。
|
||||||
|
|
||||||
|
### retryWithBackoff()
|
||||||
|
使用指数退避算法进行重试,避免对服务造成过大压力。
|
||||||
|
|
||||||
|
### handleConnectionError()
|
||||||
|
处理网络连接错误,决定是否重试和启用降级模式。
|
||||||
|
|
||||||
|
### executeWithTimeout()
|
||||||
|
带超时控制的操作执行,超时时自动取消并返回错误。
|
||||||
|
|
||||||
|
### scheduleReconnect()
|
||||||
|
调度自动重连,在连接断开时使用指数退避策略重连。
|
||||||
|
|
||||||
|
### cancelReconnect()
|
||||||
|
取消正在进行的重连尝试,清理重连状态。
|
||||||
|
|
||||||
|
### checkServiceHealth()
|
||||||
|
检查服务健康状态,返回综合健康报告。
|
||||||
|
|
||||||
|
### getServiceStatus()
|
||||||
|
获取当前服务状态(正常/降级/不可用)。
|
||||||
|
|
||||||
|
### getLoadStatus()
|
||||||
|
获取系统负载状态,用于连接限流决策。
|
||||||
|
|
||||||
## 安全管理功能
|
## 安全管理功能
|
||||||
|
|
||||||
### encryptApiKey()
|
### encryptApiKey()
|
||||||
@@ -129,6 +209,32 @@ Zulip Core 是应用的核心聊天集成模块,提供完整的Zulip聊天服
|
|||||||
### getPerformanceMetrics()
|
### getPerformanceMetrics()
|
||||||
获取系统性能指标,包含响应时间和吞吐量统计。
|
获取系统性能指标,包含响应时间和吞吐量统计。
|
||||||
|
|
||||||
|
## 监控日志功能
|
||||||
|
|
||||||
|
### logConnection()
|
||||||
|
记录WebSocket连接事件日志,包含连接、断开和错误事件。
|
||||||
|
|
||||||
|
### logApiCall()
|
||||||
|
记录Zulip API调用日志,包含响应时间和结果状态。
|
||||||
|
|
||||||
|
### logMessageForward()
|
||||||
|
记录消息转发日志,包含成功率和延迟统计。
|
||||||
|
|
||||||
|
### confirmOperation()
|
||||||
|
记录操作确认信息,用于审计和追踪。
|
||||||
|
|
||||||
|
### sendAlert()
|
||||||
|
发送系统告警通知,支持不同严重级别。
|
||||||
|
|
||||||
|
### getStats()
|
||||||
|
获取监控统计信息,包含连接、API调用和消息统计。
|
||||||
|
|
||||||
|
### getRecentAlerts()
|
||||||
|
获取最近的告警列表,用于问题排查。
|
||||||
|
|
||||||
|
### resetStats()
|
||||||
|
重置监控统计数据,用于周期性统计。
|
||||||
|
|
||||||
## 使用的项目内部依赖
|
## 使用的项目内部依赖
|
||||||
|
|
||||||
### RedisModule (来自 ../redis/redis.module)
|
### RedisModule (来自 ../redis/redis.module)
|
||||||
@@ -354,7 +460,7 @@ const newKey = await apiKeySecurityService.rotateApiKey('user123');
|
|||||||
```
|
```
|
||||||
|
|
||||||
## 版本信息
|
## 版本信息
|
||||||
- **版本**: 1.1.1
|
- **版本**: 1.2.0
|
||||||
- **作者**: moyin
|
- **作者**: moyin
|
||||||
- **创建时间**: 2025-12-25
|
- **创建时间**: 2025-12-25
|
||||||
- **最后修改**: 2026-01-07
|
- **最后修改**: 2026-01-15
|
||||||
@@ -69,6 +69,7 @@ export interface CreateZulipAccountResult {
|
|||||||
export interface GenerateApiKeyResult {
|
export interface GenerateApiKeyResult {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
apiKey?: string;
|
apiKey?: string;
|
||||||
|
userId?: number; // 添加 userId,从 profile 中获取
|
||||||
error?: string;
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,40 +302,44 @@ export class ZulipAccountService {
|
|||||||
|
|
||||||
// 尝试获取已有用户的信息
|
// 尝试获取已有用户的信息
|
||||||
const userInfo = await this.getExistingUserInfo(request.email);
|
const userInfo = await this.getExistingUserInfo(request.email);
|
||||||
if (userInfo.success) {
|
|
||||||
// 尝试为已有用户生成API Key
|
// 尝试为已有用户生成API Key(同时可以获取 userId)
|
||||||
const apiKeyResult = await this.generateApiKeyForUser(request.email, request.password || '');
|
const apiKeyResult = await this.generateApiKeyForUser(request.email, request.password || '');
|
||||||
|
|
||||||
|
// 优先使用 userInfo 中的 userId,其次使用 apiKeyResult 中的 userId
|
||||||
|
const finalUserId = userInfo.userId ?? apiKeyResult.userId;
|
||||||
|
|
||||||
|
if (finalUserId === undefined) {
|
||||||
|
this.logger.error('用户已存在但无法获取用户ID,绑定失败', {
|
||||||
|
operation: 'handleExistingUser',
|
||||||
|
email: request.email,
|
||||||
|
getUserInfoError: userInfo.error,
|
||||||
|
apiKeyError: apiKeyResult.error,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: `用户已存在但无法获取用户ID`,
|
||||||
|
errorCode: 'USER_ID_NOT_FOUND',
|
||||||
|
isExistingUser: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.log('Zulip账号绑定成功(已存在)', {
|
this.logger.log('Zulip账号绑定成功(已存在)', {
|
||||||
operation: 'handleExistingUser',
|
operation: 'handleExistingUser',
|
||||||
email: request.email,
|
email: request.email,
|
||||||
userId: userInfo.userId,
|
userId: finalUserId,
|
||||||
hasApiKey: apiKeyResult.success,
|
hasApiKey: apiKeyResult.success,
|
||||||
apiKeyError: apiKeyResult.success ? undefined : apiKeyResult.error,
|
apiKeyError: apiKeyResult.success ? undefined : apiKeyResult.error,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
userId: userInfo.userId,
|
userId: finalUserId,
|
||||||
email: request.email,
|
email: request.email,
|
||||||
apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
|
apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
|
||||||
isExistingUser: true,
|
isExistingUser: true,
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
this.logger.warn('用户已存在但无法获取详细信息,仍返回绑定成功', {
|
|
||||||
operation: 'handleExistingUser',
|
|
||||||
email: request.email,
|
|
||||||
getUserInfoError: userInfo.error,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
userId: undefined,
|
|
||||||
email: request.email,
|
|
||||||
apiKey: undefined,
|
|
||||||
isExistingUser: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -421,39 +426,43 @@ export class ZulipAccountService {
|
|||||||
|
|
||||||
// 尝试获取已有用户信息
|
// 尝试获取已有用户信息
|
||||||
const userInfo = await this.getExistingUserInfo(request.email);
|
const userInfo = await this.getExistingUserInfo(request.email);
|
||||||
if (userInfo.success) {
|
|
||||||
// 尝试为已有用户生成API Key
|
// 尝试为已有用户生成API Key(同时可以获取 userId)
|
||||||
const apiKeyResult = await this.generateApiKeyForUser(request.email, password);
|
const apiKeyResult = await this.generateApiKeyForUser(request.email, password);
|
||||||
|
|
||||||
|
// 优先使用 userInfo 中的 userId,其次使用 apiKeyResult 中的 userId
|
||||||
|
const finalUserId = userInfo.userId ?? apiKeyResult.userId;
|
||||||
|
|
||||||
|
if (finalUserId === undefined) {
|
||||||
|
this.logger.error('用户已存在但无法获取用户ID,绑定失败', {
|
||||||
|
operation: 'handleCreateUserError',
|
||||||
|
email: request.email,
|
||||||
|
getUserInfoError: userInfo.error,
|
||||||
|
apiKeyError: apiKeyResult.error,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: `用户已存在但无法获取用户ID`,
|
||||||
|
errorCode: 'USER_ID_NOT_FOUND',
|
||||||
|
isExistingUser: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.log('Zulip账号绑定成功(API创建时发现已存在)', {
|
this.logger.log('Zulip账号绑定成功(API创建时发现已存在)', {
|
||||||
operation: 'handleCreateUserError',
|
operation: 'handleCreateUserError',
|
||||||
email: request.email,
|
email: request.email,
|
||||||
userId: userInfo.userId,
|
userId: finalUserId,
|
||||||
hasApiKey: apiKeyResult.success,
|
hasApiKey: apiKeyResult.success,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
userId: userInfo.userId,
|
userId: finalUserId,
|
||||||
email: request.email,
|
email: request.email,
|
||||||
apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
|
apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
|
||||||
isExistingUser: true,
|
isExistingUser: true,
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
this.logger.warn('用户已存在但无法获取详细信息', {
|
|
||||||
operation: 'handleCreateUserError',
|
|
||||||
email: request.email,
|
|
||||||
getUserInfoError: userInfo.error,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
userId: undefined,
|
|
||||||
email: request.email,
|
|
||||||
apiKey: undefined,
|
|
||||||
isExistingUser: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 其他类型的错误
|
// 其他类型的错误
|
||||||
@@ -515,12 +524,14 @@ export class ZulipAccountService {
|
|||||||
this.logger.log('API Key生成成功', {
|
this.logger.log('API Key生成成功', {
|
||||||
operation: 'generateApiKeyForUser',
|
operation: 'generateApiKeyForUser',
|
||||||
email,
|
email,
|
||||||
|
userId: profile.user_id,
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
apiKey: apiKey,
|
apiKey: apiKey,
|
||||||
|
userId: profile.user_id, // 返回从 profile 获取的 user_id
|
||||||
};
|
};
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user