From 519394645a2f143e3054949e3a34cee881b8229f Mon Sep 17 00:00:00 2001 From: moyin <244344649@qq.com> Date: Thu, 15 Jan 2026 13:53:56 +0800 Subject: [PATCH] =?UTF-8?q?docs(zulip=5Fcore):=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=96=87=E6=A1=A3=E5=92=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E6=9C=8D=E5=8A=A1=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 范围:src/core/zulip_core/ - 补充README.md缺失的服务文档(用户注册、用户管理、动态配置、错误处理、监控日志) - 优化zulip_account.service.ts中已存在用户的处理逻辑 - 增强userId获取的可靠性,优先使用userInfo,其次使用apiKeyResult - 版本更新:1.1.1 -> 1.2.0 --- src/core/zulip_core/README.md | 110 +++++++++++++++++- .../services/zulip_account.service.ts | 109 +++++++++-------- 2 files changed, 168 insertions(+), 51 deletions(-) diff --git a/src/core/zulip_core/README.md b/src/core/zulip_core/README.md index 1a29f81..8dc2766 100644 --- a/src/core/zulip_core/README.md +++ b/src/core/zulip_core/README.md @@ -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 \ No newline at end of file +- **最后修改**: 2026-01-15 \ No newline at end of file diff --git a/src/core/zulip_core/services/zulip_account.service.ts b/src/core/zulip_core/services/zulip_account.service.ts index f8fff45..fe795b8 100644 --- a/src/core/zulip_core/services/zulip_account.service.ts +++ b/src/core/zulip_core/services/zulip_account.service.ts @@ -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, - }); - - return { - success: true, - userId: userInfo.userId, - email: request.email, - apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined, - isExistingUser: true, - }; - } else { - this.logger.warn('用户已存在但无法获取详细信息,仍返回绑定成功', { + + // 尝试为已有用户生成API Key(同时可以获取 userId) + 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: 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, - }); - - return { - success: true, - userId: userInfo.userId, - email: request.email, - apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined, - isExistingUser: true, - }; - } else { - this.logger.warn('用户已存在但无法获取详细信息', { + + // 尝试为已有用户生成API Key(同时可以获取 userId) + 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: 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) {