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:
moyin
2026-01-15 13:53:56 +08:00
parent 223ba2abb8
commit 519394645a
2 changed files with 168 additions and 51 deletions

View File

@@ -87,6 +87,25 @@ Zulip Core 是应用的核心聊天集成模块提供完整的Zulip聊天服
### getAllAccountLinks()
获取所有活跃的账号关联信息,用于系统管理和监控。
## 用户注册功能
### registerUser()
在Zulip服务器上注册新用户账号包含邮箱验证、密码生成和API Key获取。
## 用户管理功能
### checkUserExists()
检查指定邮箱的用户是否存在于Zulip服务器。
### getUserInfo()
根据邮箱获取用户的详细信息包含用户ID、状态和权限信息。
### validateUserCredentials()
验证用户的API Key是否有效用于登录认证。
### getAllUsers()
从Zulip服务器获取所有用户列表用于管理和统计。
## 配置管理功能
### getAllMapConfigs()
@@ -101,6 +120,67 @@ Zulip Core 是应用的核心聊天集成模块提供完整的Zulip聊天服
### 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()
@@ -129,6 +209,32 @@ Zulip Core 是应用的核心聊天集成模块提供完整的Zulip聊天服
### getPerformanceMetrics()
获取系统性能指标,包含响应时间和吞吐量统计。
## 监控日志功能
### logConnection()
记录WebSocket连接事件日志包含连接、断开和错误事件。
### logApiCall()
记录Zulip API调用日志包含响应时间和结果状态。
### logMessageForward()
记录消息转发日志,包含成功率和延迟统计。
### confirmOperation()
记录操作确认信息,用于审计和追踪。
### sendAlert()
发送系统告警通知,支持不同严重级别。
### getStats()
获取监控统计信息包含连接、API调用和消息统计。
### getRecentAlerts()
获取最近的告警列表,用于问题排查。
### resetStats()
重置监控统计数据,用于周期性统计。
## 使用的项目内部依赖
### RedisModule (来自 ../redis/redis.module)
@@ -354,7 +460,7 @@ const newKey = await apiKeySecurityService.rotateApiKey('user123');
```
## 版本信息
- **版本**: 1.1.1
- **版本**: 1.2.0
- **作者**: moyin
- **创建时间**: 2025-12-25
- **最后修改**: 2026-01-07
- **最后修改**: 2026-01-15

View File

@@ -69,6 +69,7 @@ export interface CreateZulipAccountResult {
export interface GenerateApiKeyResult {
success: boolean;
apiKey?: string;
userId?: number; // 添加 userId从 profile 中获取
error?: string;
}
@@ -301,40 +302,44 @@ export class ZulipAccountService {
// 尝试获取已有用户的信息
const userInfo = await this.getExistingUserInfo(request.email);
if (userInfo.success) {
// 尝试为已有用户生成API Key
const apiKeyResult = await this.generateApiKeyForUser(request.email, request.password || '');
this.logger.log('Zulip账号绑定成功已存在', {
operation: 'handleExistingUser',
email: request.email,
userId: userInfo.userId,
hasApiKey: apiKeyResult.success,
apiKeyError: apiKeyResult.success ? undefined : apiKeyResult.error,
});
// 尝试为已有用户生成API Key同时可以获取 userId
const apiKeyResult = await this.generateApiKeyForUser(request.email, request.password || '');
return {
success: true,
userId: userInfo.userId,
email: request.email,
apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
isExistingUser: true,
};
} else {
this.logger.warn('用户已存在但无法获取详细信息,仍返回绑定成功', {
// 优先使用 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: true,
userId: undefined,
email: request.email,
apiKey: undefined,
success: false,
error: `用户已存在但无法获取用户ID`,
errorCode: 'USER_ID_NOT_FOUND',
isExistingUser: true,
};
}
this.logger.log('Zulip账号绑定成功已存在', {
operation: 'handleExistingUser',
email: request.email,
userId: finalUserId,
hasApiKey: apiKeyResult.success,
apiKeyError: apiKeyResult.success ? undefined : apiKeyResult.error,
});
return {
success: true,
userId: finalUserId,
email: request.email,
apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
isExistingUser: true,
};
}
/**
@@ -421,39 +426,43 @@ export class ZulipAccountService {
// 尝试获取已有用户信息
const userInfo = await this.getExistingUserInfo(request.email);
if (userInfo.success) {
// 尝试为已有用户生成API Key
const apiKeyResult = await this.generateApiKeyForUser(request.email, password);
this.logger.log('Zulip账号绑定成功API创建时发现已存在', {
operation: 'handleCreateUserError',
email: request.email,
userId: userInfo.userId,
hasApiKey: apiKeyResult.success,
});
// 尝试为已有用户生成API Key同时可以获取 userId
const apiKeyResult = await this.generateApiKeyForUser(request.email, password);
return {
success: true,
userId: userInfo.userId,
email: request.email,
apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
isExistingUser: true,
};
} else {
this.logger.warn('用户已存在但无法获取详细信息', {
// 优先使用 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: true,
userId: undefined,
email: request.email,
apiKey: undefined,
success: false,
error: `用户已存在但无法获取用户ID`,
errorCode: 'USER_ID_NOT_FOUND',
isExistingUser: true,
};
}
this.logger.log('Zulip账号绑定成功API创建时发现已存在', {
operation: 'handleCreateUserError',
email: request.email,
userId: finalUserId,
hasApiKey: apiKeyResult.success,
});
return {
success: true,
userId: finalUserId,
email: request.email,
apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
isExistingUser: true,
};
}
// 其他类型的错误
@@ -515,12 +524,14 @@ export class ZulipAccountService {
this.logger.log('API Key生成成功', {
operation: 'generateApiKeyForUser',
email,
userId: profile.user_id,
timestamp: new Date().toISOString(),
});
return {
success: true,
apiKey: apiKey,
userId: profile.user_id, // 返回从 profile 获取的 user_id
};
} catch (error) {