星枢终端 - 技术债务报告
状态:✅ 标记债务(TODO/any/console.log)为 0 | ✅ ja-JP 中文残留清零 | 测试覆盖率:待提升 | 更新时间:2026-08-08
⚠️ 遗留债务(2026-08-07 发现,2026-08-07 处理)
| ID | 问题 | 规模 | 处理结果 |
|---|---|---|---|
| L10-1 | ja-JP 语言包大量中文残留:日文用户实际看到中文 | 1413 key(含汉字口径) | ✅ 已修复:105 条简体中文残留全部翻译为日文。口径澄清:1413 个"含汉字"值中绝大多数为正常日文汉字词(接続/設定/保存 等),真实中文残留 105 条(dashboard/suspendedSshSessions/tabs/editor/settings 等模块),已全部翻译并验证清零 |
| L10-2 | 后端 1745 处日志中英混用(约 50% 中文) | 1745 处 | ⏸️ 维持评估:全量统一风险高,保持模块内一致;已通过 redactUrlForLog 控制敏感信息泄漏 |
| L10-3 | settings.tabs.about 等 ja 值已修复,但 ja-JP 仍有 batchOps.sudoConfirm 等零散日文夹杂中文 | 少量 | ✅ 随 L10-1 一并处理:零散夹杂(VNC 密码:、正在连接 VNC...、挂起的 SSH 会话 等)已全部修复 |
2026-08-07 打磨迭代(10 轮)摘要
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | 后端三语言包对齐 | zh 补 testNotification.* 6 key + 4 event key;en/ja 补 event.testNotification;清理 zh event 重复 key;三语言 70 key 完全一致 |
| R2 | 后端 locale 对齐测试 | backend/src/i18n.test.ts(key 一致性/空值/重复 key/通知模板 key) |
| R3 | 前端加载态统一 | 新增 LoadingState.vue,6 个 View 接入(Tags/Audit/Connections/Suspended/QuickCommands/CommandHistory) |
| R4 | 前端空状态统一 | 新增 EmptyState.vue(图标+文案+操作按钮),5 个 View 接入 |
| R5 | 通知日志敏感信息脱敏 | 修复 Bearer xxx token 值泄漏;增强 URL query 参数/内嵌账号密码脱敏;webhook sender 与 notification.service 记录 URL/body 前脱敏;新增 redaction.test.ts |
| R6 | 网络错误友好提示 | useFileManagerDownload 目录下载网络错误不再直出英文异常,本地化提示;三语言包新增 downloadNetworkError |
| R7 | 通知事件翻译去重 | utils/notificationEvents.ts 共享纯函数;移除每次渲染执行的 info 日志;新增测试 |
| R8 | 轮询可见性感知 | AiAudit 报告轮询与 Dashboard 自动刷新页面隐藏时暂停,恢复后继续,卸载清理监听 |
| R9 | 前端 i18n 大缺口修复 | 全量扫描发现 72 个带 fallback 的调用其 key 缺失(英文/日文用户看到中文);补齐 zh/en/ja(含新增 aiAudit/commandPalette/errors 结构),三语言 1616 key 一致;修复 SuspendedSshSessionsModal 裸 close key |
| R10 | 全量验证与自查 | 后端 2678 + 前端 2664 + 网关 11 测试全过;tsc/eslint 零错误;本表回填 |
2026-08-08 打磨迭代(10 轮)摘要
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | 统一日期格式化工具 | utils/dateFormat.ts(秒/毫秒时间戳自动识别 + formatDateTime/formatShortDateTime/formatTime + i18n locale),替换 9 处重复实现(AuditLog/AiAudit/ConnectionList/ProxyList/Suspended×2/TransferProgress/AIAssistant/Passkey),修复硬编码 'zh-CN' 不随语言切换 |
| R2 | 统一防抖工具 | utils/debounce.ts(createDebounced 支持 cancel),替换 Terminal.vue / useTerminalFit 2 处重复实现 |
| R3 | 通知组件清理与无障碍 | UINotificationDisplay 移除未使用的 getContainerClass 与全仓唯一 !important 内联样式,容器补 role=status/aria-live,关闭按钮补 aria-label |
| R4 | 通知 store 语义修复 | 单条通知 timeout 生效(原类型声明支持但实现强制全局值,文档与实现不符);warning 类型加入去重窗口防刷屏;清理误导性注释 |
| R5 | 统一错误横幅 | 新增 common/ErrorBanner.vue(role=alert + 警示图标),接入 TagsView/NotificationSettings/ProxyList/NotificationSettingForm,消除散落的 border-l-4 border-error 重复写法 |
| R6 | 通知渠道日志与文案 | _sendEmail/_sendWebhook/_sendTelegram 调试日志前缀统一为 [通知 - 渠道] 风格(原中英混用);邮件主题由裸事件名改为 [Nexus Terminal] 前缀 |
| R7 | 轮询可见性感知 | TransferProgressModal 页面隐藏时停止 5s 轮询,恢复可见且弹窗打开时立即刷新并恢复轮询,监听统一在生命周期清理 |
| R8 | 英文残留注释统一 | 前端 src 约 150 处英文注释翻译为简体中文(登录/连接/快捷指令/命令历史/Docker/布局配置/设置等 18 个文件),清理陈旧重复注释行 |
| R9 | 通知模板工具化 | 提取 notification-template.utils.ts(renderTemplate / normalizeEventPlaceholder / renderCustomTemplate 纯函数),邮件/Webhook {event}→{eventDisplay} 归一化去重,删除约 40 行重复分支 |
| R10 | 全量验证与自查 | 后端 2690 + 前端 2691 + 网关 11 测试全过;tsc/eslint/prettier/debt/locale 零错误;自查修复 0 值时间戳回归(ConnectionList/ProxyList/Passkey 保留 falsy 语义);清理孤儿 i18n key time.invalidDate;本表回填 |
2026-08-08 累计 100 轮收尾记录(第 71-100 轮)
第八批:后端核心测试补强(71-80 轮)
| 轮次 | 内容 | 用例 |
|---|---|---|
| 71 | ai.controller 测试(AI 查询/会话/健康端点的鉴权、校验、委托) | 15 |
| 72 | anomaly-rules 测试(暴力破解/危险命令/提权/异常时段检测) | 10 |
| 73 | ai-audit.service 测试(报告创建/查询/删除/异常统计) | 7 |
| 74 | ip-geo.service 测试(缓存分层/私有 IP 过滤/禁用开关) | 7 |
| 75 | event.middlewares 测试(日志/持久化中间件与批量缓冲) | 5 |
| 76 | favorite-paths.controller 测试 | 13 |
| 77 | quick-commands.controller 测试 | 10 |
| 78 | terminal-theme.controller 测试 | 11 |
| 79 | ssh-suspend.controller 测试 | 6 |
| 80 | 全量验证:后端 2699→2783,零覆盖核心文件显著减少 |
第九批:UI/UX 统一(81-90 轮)
| 轮次 | 内容 |
|---|---|
| 81 | 前端硬编码颜色扫描(初始化页深色有意,保留) |
| 82 | .btn-primary 语义类 + 设置页 15 处接入 |
| 83 | .form-input 语义类 + 验证码表单 4 处接入 |
| 84 | 弹窗尺寸/滚动一致性核查(已达标) |
| 85 | 空态/错误态统一核查(已达标) |
| 86 | 上下文菜单 Esc 关闭 + role/tabindex/Enter/聚焦 |
| 87 | 移动端响应式核查(已达标) |
| 88 | 主题变量覆盖核查(终端 HUD 深色有意) |
| 89 | 文案/占位符统一核查(无硬编码用户文案) |
| 90 | 全量验证 + 提交 |
第十批:性能与代码清理(91-100 轮)
| 轮次 | 内容 |
|---|---|
| 91 | computed/v-for key 检查(全部规范) |
| 92 | 列表渲染优化核查(关键列表已虚拟滚动/分页) |
| 93 | 事件监听泄漏扫描(add/remove 全配对) |
| 94 | 定时器清理扫描(全部安全) |
| 95 | 后端 N+1 查询扫描(已解决,23 处批量查询) |
| 96 | 提取共享 utils/sleep.ts 延迟工具(含可取消版)+ apiClient 接入 |
| 97 | 未使用导出清理(移除 useSleep 预留) |
| 98 | 死代码/过时注释清理(前批已清) |
| 99 | 内存缓存泄漏检查(rate-limiter/sftp/ssh-suspend 均有清理) |
| 100 | 全量验证:前端 2821 + 后端 2783 测试全过,tsc/eslint/prettier/debt/locale 零错误 |
2026-08-08 测试覆盖补强打磨迭代(10 轮)
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | useEditorEvents 测试 | 19 用例:共享/独立模式分流、10 个事件处理器、批量关闭标签 |
| R2 | useConfirmDialog 测试 | 5 用例:store 委托、默认标题、confirmAction、loading |
| R3 | useContextMenuPosition 测试 | 7 用例:右/下边界修正、左上越界限制、元素缺失兜底 |
| R4 | useQuickCommandTagEditing 测试 | 10 用例:创建/更新/取消、空名校验、展开组迁移、异常通知 |
| R5 | useAddConnectionFormSubmit 测试 | 14 用例:必填/端口/认证校验、批量 IP、单条 CRUD、删除确认 |
| R6 | useAddConnectionFormScriptMode 测试 | 8 用例:空输入/解析错误/缺字段/端口/密码校验、成功路径 |
| R7 | useAddConnectionFormTags 测试 | 7 用例:标签创建自动选中、删除确认、失败警告 |
| R8 | workspaceEvents 测试 | 6 用例:mitt 订阅/发布/退订、自动清理 |
| R9 | useAlertDialog 测试 | 4 用例:挂载、onOk 回调、关闭路径、默认文本 |
| R10 | 全量验证与自查 | 前端 2817(+80)+ 后端 2699 测试全过;tsc/eslint/prettier/debt/locale 零错误;回填本表 |
本批为债务文档「测试提升行动计划」阶段三(Composables ≥60%)的实质推进:9 个零覆盖核心 composable 补齐测试。
2026-08-08 无障碍(a11y)补全打磨迭代(10 轮)
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | icon-only 按钮 aria-label 补全 | 33 处仅图标按钮(复制/删除/编辑/关闭/排序等)补 :aria-label,屏幕阅读器可识别用途 |
| R2 | 对话框无障碍重构 | 新增 useDialogA11y composable:安全标题 id(非标题文本)、打开自动聚焦、Tab 焦点圈闭、关闭恢复焦点;AlertDialog/ConfirmDialog 接入 |
| R3 | 模态框 role=dialog | 10 个模态框遮罩补 role="dialog" + aria-modal="true"(远程桌面/VNC/发送文件/传输进度/快捷指令/SSH 密钥/标签管理/文件管理等) |
| R4 | 模态框回归测试 | 7 文件 143 测试全过,role="dialog" 添加不破坏既有断言 |
| R5 | 模态框 aria-label 关联 | 10 个模态框补静态 aria-label(无障碍名称),替代复杂的动态 id 关联 |
| R6 | 回归 + ESLint | aria-label 插入导致的格式问题经 eslint --fix 清零 |
| R7 | 表单标签核查 | 122 处表单控件经抽查均已有 <label for> 关联(脚本误报排除),无需改动 |
| R8 | 动态状态无障碍 | TransferProgressModal 进度条补 role="progressbar"(aria-valuenow/min/max);ArchiveProgressPopup 补 role="status" + aria-live="polite" |
| R9 | 进度条扫描 | FileUploadPopup 已用原生 <progress>(自带语义),其余 width:100% 为布局非进度条 |
| R10 | 全量验证与自查 | 前端 2749(+7 对话框测试)+ 后端 2699 测试全过;tsc/eslint/prettier/debt/locale 零错误;回填本表 |
2026-08-08 图表主题化与响应式工具打磨迭代(10 轮)
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | 提取 useCssVar/hexToRgba 共享工具 | 新增 composables/useCssVar.ts:响应式读取 CSS 变量实际值 + 十六进制转 rgba;11 测试 |
| R2 | 修复 3 个 Chart.js 图表颜色主题化 | SessionDurationChart/SystemResourcesHistoryChart/StatusCharts 的 var(--color-*)、color-mix() 字符串(canvas 无法解析)→ 读取实际色值,主题切换即时刷新 |
| R3 | var() 传递问题扫描 | 确认 useAddConnectionFormTest/TerminalTabBar/FileEditorOverlay 的 var() 均在 DOM 上下文(可解析),合法 |
| R4 | SessionDurationChart 渲染测试 | mock vue-chartjs,验证数据渲染与颜色为实际值 |
| R5 | SystemResourcesHistoryChart 渲染测试 | 同上,验证 3 数据集颜色非 var()/color-mix(),填充色为 rgba |
| R6 | StatusCharts 渲染测试 | mock session store,验证 CPU/网络图表渲染与刻度颜色 |
| R7 | 主题事件派发 | appearance-background.store applyUiTheme 后派发 appearance-theme-applied 事件;补事件断言测试 |
| R8 | 监听泄漏治理 | useCssVar 不再模块级注册监听(纯读取+缓存),统一由 useCssVarWithLifecycle 组件生命周期管理;补生命周期测试 |
| R9 | 重绘机制核查 + 全量测试 | vue-chartjs 响应式 props 变化自动 update;图表相关 68 测试全过 |
| R10 | 全量验证与自查 | 前端 2742 + 后端 2699 测试全过;tsc/eslint/prettier/debt/locale 零错误;回填本表 |
2026-08-08 日志收口与降噪打磨迭代(10 轮)
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | useWebRTCTunnel console 收口 | 3 处 console.debug → log.debug(DataChannel 关闭/信令连接/SDP Answer) |
| R2 | 组件/视图 console 收口 | AISettingsSection [AI Test] 与 AiAuditView 删除报告 2 处 console.error → log.error,补齐 log import |
| R3 | 键盘热路径日志降噪 | App.vue Alt 快捷键 19 处 log.info → log.debug(每次按键高频输出),PWA 低频事件保留 info |
| R4 | 后端日志前缀一致性 | transfers/sftp/auth/websocket 前缀均模块化(类名主导),变量名出现属正常,无改动 |
| R5 | 后端英文残留清零 | 全后端 logger.* 英文残留 0 处(L10-2 遗留项实质清零) |
| R6 | 前端日志用法一致性 | 504 处字符串首参 + 6 处结构化对象并存,均为 log 工具支持形式 |
| R7 | 后端日志噪音扫描 | transfers/sftp 日志已 debug/info 分层,任务创建等 info 日志低频有价值,保留 |
| R8 | 前端英文日志清零 | 全前端 log.* 英文残留 0 处 |
| R9 | 文档与 locale 同步 | 三语言 key 一致、注释无英文残留 |
| R10 | 全量验证与自查 | 前端 2724 + 后端 2699 测试全过;tsc/eslint/prettier/debt/locale 零错误 |
2026-08-08 日志统一与工具去重打磨迭代(10 轮)
| 轮次 | 内容 | 产物 |
|---|---|---|
| R0 | 预存问题修复 | nl2cmd.service.test.ts 22 例失败根因:测试 mock 了 axios 但未 mock SSRF 防护的 resolveAndValidatePublicHost,沙箱 DNS 无法解析 OpenAI 域名。新增 vi.mock('../utils/url') 返回测试地址,消除真实 DNS 依赖 |
| R1 | 前端英文日志统一(组件类) | BatchEditConnectionForm / FileManagerActionModal / FileManagerContextMenu / NotificationSettingForm / NotificationSettings / SendFilesModal / VncModal / WorkspaceConnectionList 8 处 → 中文 |
| R2 | 前端英文日志统一(store/view/composable) | useTerminalFit / main.ts(3) / auth.store / sshKeys.store / ConnectionsView / LoginView(2) / SetupView / auth.store Passkeys fetched 等 10+ 处 → 中文 |
| R3 | 提取共享 formatBytes 工具 | 新增 utils/formatBytes.ts(分级精度:KB/MB 与 GB 可分别配置小数位)+ 7 测试,消除 GB 精度不一致(formatSize 1 位 vs dashboard 2 位) |
| R4 | dashboard.store 接入共享工具 | 本地 formatBytes 删除,改用 formatBytes(bytes, 1, 2) 保留原语义;对外 API 不变 |
| R5 | fileManagerDisplayUtils 接入共享工具 | 本地 formatSize 删除,改用 formatBytes(size, 1, 1) 保留原语义 |
| R6 | 后端 i18n.ts console 统一为 logger | 模块导入阶段 3 处 console.info/error/warn → 惰性 pino logger(首次调用时 dotenv 已加载,安全);后端模块级 console 输出清零 |
| R7 | 重复工具扫描 | 确认 formatMode 唯一实现、2 处手写错误提取(Blob/failureCount 特殊逻辑)不适用 extractErrorMessage,保留合理 |
| R8 | 前端硬编码扫描 | 仅 reCAPTCHA 品牌名与 API URL 占位,合法保留 |
| R9 | 后端 logger 一致性抽查 | 130 文件统一 utils/logger,无旧 import、无模块级 console |
| R10 | 全量验证与自查 | 前端 2724 + 后端 2699 测试全过;tsc/eslint/prettier/debt/locale 零错误;回填本表 |
备注:
status-monitor.service.test.ts在全量并发时偶发 1 例失败(单独运行稳定通过),根因疑似createMockStream的process.nextTick在 fake timers + 高并发下的时序抖动,属低频 flaky 预存问题,本次未改动测试基建以免引入新不稳定,留待后续观察。
2026-08-08 组件状态与日志打磨迭代(10 轮)
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | apiClient 日志统一为中文 | utils/apiClient.ts 8 处英文日志(Request error/Response warning/Unauthorized/Forbidden/404/500 等)改为中文,与前端日志风格一致 |
| R2 | 2FA 时间偏差文案本地化 | useTwoFactorAuth.ts 硬编码中文时间偏差提示 → i18n;三语言新增 settings.twoFactor.error.timeSkewDetected |
| R3 | StatusMonitor 加载态统一 | 手写 spinner → LoadingState(full 模式) |
| R4 | NotificationSettings 状态统一 | 手写加载/空态 → LoadingState/EmptyState |
| R5 | ProxyList 状态统一 | 手写加载/空态 → LoadingState/EmptyState |
| R6 | WorkspaceConnectionList 加载态统一 | 手写 spinner → LoadingState(full 模式) |
| R7 | ManageTag/DockerManager 加载态统一 | 两处手写 spinner → LoadingState(compact/full) |
| R8 | 后端 Docker 日志前缀规范化 | docker.handler.ts 13 处 [fetchRemoteDockerStatus] → [DockerHandler],与同目录 [WebSocket] 等模块级前缀风格一致 |
| R9 | 局部加载态补缺 | FavoritePathsModal / PathHistoryDropdown / SendFilesModal 三处手写加载态 → LoadingState(compact) |
| R10 | 全量验证与自查 | 前端 2716 + 后端 2669(排除环境性 NL2CMD 网络失败)测试全过;tsc/eslint/prettier/debt/locale 零错误;回填本表 |
说明:R10 验证时
nl2cmd.service.test.ts22 例失败经 stash 复现确认与本次改动无关,根因为沙箱环境 DNS 无法解析 OpenAI 域名(resolveAndValidatePublicHost拦截),属环境性预存失败。
2026-08-08 轮询与文案打磨迭代(10 轮)
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | Docker 管理器 15s 轮询可见性感知 | useDockerManager.ts 提取 start/stopRefreshInterval,页面隐藏暂停、恢复可见立即刷新并继续;cleanup 移除监听 |
| R2 | 批量执行降级轮询可见性感知 | MultiServerExec.vue 页面隐藏暂停 2s 轮询,恢复可见且任务未终态时继续(从 currentTask 兜底取回任务 ID) |
| R3 | 后端过时注释清理 | docker.service.ts 4 处 // Use console.log 残留注释(已改用 logger)移除 |
| R4 | 空 else 分支清理 | useDockerManager.ts 2 处空 else {} 分支随 R1 重构消除 |
| R5 | Docker 面板硬编码英文本地化 | DockerManager.vue 'Unknown SSH error'、14 处 'N/A' 改为 i18n(新增 common.na) |
| R6 | 组件硬编码错误文案本地化 | BatchEditConnectionForm/ManageTagConnectionsModal 的 'Unknown error' → t('common.unknownError') |
| R7 | 远程桌面/VNC 错误文案本地化 | RemoteDesktopModal/VncModal 的 'Unknown tunnel/client error'、'N/A' 改为 i18n(新增 remoteDesktopModal.errors.*) |
| R8 | 前端英文日志统一为中文 | 26 处 log.error('Failed to ...') 等英文日志改为中文(组件/Composable/Store/View) |
| R9 | Docker 命令失败 UI 反馈 | useDockerManager 新增 commandError 状态(解析 docker:command:error 载荷),DockerManager.vue watch 后通过通知反馈用户 |
| R10 | 通知默认主题规范化 + 全量验证 | email.sender.service 默认主题 'Notification' → '[Nexus Terminal] Notification';前端 2716 + 后端 2699 测试全过,tsc/eslint/prettier/debt/locale 零错误 |
2026-08-08 三轨打磨迭代(10 轮)
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | 锁定批量取消、Worker 生命周期和 UI/UX 行为契约 | 设计文档与实施计划;补充红灯测试 |
| R2 | 批量取消状态闭环 | queued 子任务持久化、取消原因透传、终态计数保留、事件顺序测试 |
| R3 | SSH 执行资源边界 | 单次输出上限、同步 exec 异常清理、迟到 stream 终止、统一 settle |
| R4 | 批量 Store 终态校准 | 终态 WS 先本地落地,REST 失败仍可读;reset 清理 WS 守卫状态 |
| R5 | Worker 池失效实例替换 | timeout/error 终止旧 Worker、创建替代实例、迟到响应隔离 |
| R6 | Worker 单例资源回收 | destroy 后允许重新初始化;初始化期间销毁不会复活迟到实例 |
| R7 | 批量 UI 无障碍语义 | 标签关联、按钮类型、progressbar、live region、dialog 和键盘路径 |
| R8 | 交互反馈统一 | sudo/取消确认对话框、复制成功/失败通知、焦点样式与 reduced-motion |
| R9 | 文档与多语言同步 | features、changelog、本债务记录及 zh/en/ja 文案更新 |
| R10 | 全量验证与跨轨自查 | ✅ 已完成:全量测试、前后端/网关类型检查、全仓 lint、Prettier、技术债务、locale、diff 检查均通过;另完成独立代码审查与文档准确性复核 |
本轮新增约束
- 后端批量输出在内存、数据库和 WebSocket 单次载荷分别受 1MB 边界保护;前端单个子任务输出受 512KB 边界保护。
- Worker 超时或运行时错误后不复用旧线程,避免旧任务继续执行时污染新请求。
- Worker 处理 API 当前是可选异步能力;xterm 输出增强热路径仍保持同步处理,以保证终端输出块严格有序,后续接入异步时必须先增加顺序队列和取消策略。
- 取消操作保留已完成/失败计数,并尽可能透传用户取消原因;排队子任务写入失败不得把明确的取消意图升级为父任务失败。
- 批量 UI 的高权限执行和中断操作通过统一确认组件;复制结果必须有成功或失败反馈。
2026-07-17 打磨迭代(10 轮)摘要
| 轮次 | 内容 | 产物 |
|---|---|---|
| R1 | 刷新债务基线与热点清单 | 本表 + 覆盖率行动计划校准 |
| R2–R3 | RDP/VNC Guacamole 共用工具层 | frontend/src/utils/guacamoleHelpers.ts,双 Modal 接入 |
| R4 | transfers 纯函数拆分 | backend/src/transfers/transfers.utils.ts |
| R5 | WebSocket 连接元信息拆分 | backend/src/websocket/connection-meta.ts |
| R6 | 前端死代码主题表瘦身 | iterm-themes.ts 12k 行 → 样例 3 主题(完整预设在后端 seed) |
| R7 | Multiplex 可观测与文档 | 设置「关于」展示状态 + FAQ |
| R8–R9 | 单元测试补齐 | *.utils.test.ts / guacamoleHelpers.test.ts / connection-meta.test.ts |
| R10 | 本地验证与文档回填 | debt:check + 相关 vitest |
覆盖率行动计划校准(相对 2026-05)
sendActions已不存在,会话发送相关能力拆至commandInputActions/sessionActions等,且已有测试文件。- 前端完整 iTerm 主题运行时不依赖
features/appearance/config/iterm-themes.ts,主题列表来自后端 API。 - 仍优先:
batch.service/transfers/ssh-suspend/ 大 View 与 FileManager 冒烟。
覆盖率现状
| 模块 | 行覆盖率 | 分支覆盖率 | 函数覆盖率 | 门禁阈值 | 状态 |
|---|---|---|---|---|---|
| backend | 43.98% | 78.22% | 83.64% | lines≥40%, branches≥50%, funcs≥70% | ✅ 达标 |
| frontend | 29.65% | 78.56% | 63.08% | lines≥90%, branches≥90%, funcs≥90% | ❌ 未达标 |
| remote-gateway | 33.19% | 61.11% | 75% | — | ⚠️ 待评估 |
后端覆盖率分层目标
后端当前 43.98% 已过门禁,但存在大量 0% 覆盖文件。按分层架构约定,controller/routes 属薄层委托,优先级低于 service/repository。
P0:0% 覆盖的核心业务文件(需优先补充测试)
| 文件 | 类型 | 行数 | 说明 |
|---|---|---|---|
ai.controller.ts | controller | 254 | AI 会话管理,零测试 |
batch.service.ts | service | 922 | 批量执行核心逻辑,仅 22.42% |
websocket.ts | 入口 | 67 | WebSocket 初始化,零测试 |
migrations.ts | 数据库 | 601 | 数据迁移脚本,零测试 |
connection.ts (database) | 数据库 | 211 | 数据库连接管理,零测试 |
upgrade.ts | 数据库 | 168 | 数据库升级逻辑,零测试 |
ssh-suspend/service.ts | service | — | 仅 27.65%,核心挂起恢复逻辑 |
P1:低覆盖 service/repository(<50%)
| 文件 | 覆盖率 | 目标 | 测试要点 |
|---|---|---|---|
batch.service.ts | 22.42% | 70% | 任务创建/执行/取消/超时/并发控制 |
sftp-utils.ts | 7.79% | 60% | 路径校验、权限计算、文件类型判断 |
connection.repository.ts | 8.88% | 60% | CRUD、批量操作、加密字段处理 |
video.service.ts | 30.89% | 60% | VNC 会话生命周期 |
nl2cmd.service.ts | 48.38% | 70% | NL2CMD 解析、缓存、降级 |
dashboard.service.ts | 44.24% | 60% | 统计聚合、时间线、资产健康 |
P2:controller 层集成测试(优先级较低)
controller 属薄层委托,测试通过 service 层间接覆盖。如需直接测试:
- 使用 supertest 覆盖路由参数校验、权限检查、错误码映射
- 重点:
auth.controller.ts(1445 行拆分后)、connections.controller.ts
前端覆盖率分层目标
前端当前 29.65%,距 90% 门禁差距巨大。按组件/Store/工具/视图分层提升。
P0:0% 覆盖的 Store actions(核心状态管理)
| 文件 | 说明 | 测试要点 |
|---|---|---|
session/store/actions/sendActions.ts (895 行) | 命令发送核心 | 命令队列、重试、超时、中断 |
session/store/actions/sessionActions.ts (410 行) | 会话生命周期 | 创建/恢复/挂起/断开/清理 |
session/store/actions/editorActions.ts | 编辑器操作 | 打开/保存/关闭/语言检测 |
session/store/getters.ts (62 行) | 派生状态 | 活跃标签、连接状态、统计 |
session/store/utils.ts (112 行) | 工具函数 | 状态序列化、ID 生成 |
notificationSettings.store.ts (137 行) | 通知配置 | CRUD、启用/禁用、验证 |
dialog.store.ts (84 行) | 对话框状态 | 打开/关闭/确认/取消回调 |
P1:0% 覆盖的 Composables(核心交互逻辑)
| 文件 | 行数 | 测试要点 |
|---|---|---|
useTerminalFit.ts | 157 | 终端尺寸计算、ResizeObserver、防抖 |
useTerminalEvents.ts | 266 | 终端事件绑定/解绑、数据流 |
useTerminalSocket.ts | 49 | WebSocket 连接/重连/心跳 |
useFileUploader.ts | 370 | 分块上传、进度、取消、断点续传 |
useEditorEvents.ts | 261 | Monaco 编辑器事件、快捷键 |
useFormSubmit.ts | 349 | 表单提交、校验、错误处理 |
useFormParsers.ts | 338 | 表单数据解析/序列化 |
useAddConnectionForm.ts 子模块 | — | Parsers/Submit/Tags/Test 各子模块 |
useWorkspaceSearch.ts | 115 | 工作区搜索、过滤、高亮 |
useDragAndDrop.ts | 422 | 拖拽排序、布局重排 |
useResizable.ts | 210 | 面板拖拽调整大小 |
useVersionCheck.ts | 81 | 版本检查、更新提示 |
useIpBlacklist.ts | 146 | IP 黑名单管理 |
P2:0% 覆盖的 Views(页面级测试)
| 文件 | 行数 | 测试策略 |
|---|---|---|
DashboardView.vue | 739 | 渲染统计卡片、图表加载、空状态 |
ConnectionsView.vue | 924 | 连接列表渲染、CRUD 操作流 |
SettingsView.vue | 已有 75% | 补充表单提交、验证 |
WorkspaceView.vue | 469 | 标签页管理、面板布局、快捷键 |
AuditLogView.vue | 257 | 日志列表、筛选、分页 |
NotificationsView.vue | 10 | 渲染检查 |
ProxiesView.vue | 75 | 代理列表渲染 |
QuickCommandsView.vue | 665 | 指令 CRUD、标签过滤 |
SuspendedSessionsView.vue | 291 | 挂起会话列表、恢复操作 |
LoginView.vue | 327 | 登录表单、2FA 流程 |
SetupView.vue | 176 | 初始设置向导 |
P3:0% 覆盖的 Components(组件级测试)
| 文件 | 行数 | 测试策略 |
|---|---|---|
Terminal.vue | 1082 | 渲染检查、主题切换、输入输出 |
FileManager.vue | 已有 66.7% | 补充右键菜单、批量操作 |
RemoteDesktopModal.vue | 808 | 模态框渲染、连接状态 |
VncModal.vue | 808 | VNC 连接渲染 |
MonacoEditor.vue | 已有 82.9% | 补充语言切换、保存 |
AddConnectionForm.vue | 419 | 表单字段、校验、提交 |
LayoutConfigurator.vue | 709 | 布局配置、拖拽 |
StyleCustomizer.vue | 238 | 主题定制、预览 |
TerminalTabBar.vue | 606 | 标签页切换、关闭、排序 |
StatusMonitor.vue | 457 | 状态监控渲染 |
StatusCharts.vue | 521 | 图表渲染 |
已修复债务清单(完整记录)
Critical(6/6)
| ID | 问题 | 修复方式 |
|---|---|---|
| C-1 | SFTP shell 命令注入 | 统一 shellEscape() 工具函数 |
| C-2 | PRAGMA SQL 拼接 | VALID_TABLE_NAME 正则白名单 |
| C-3 | 12 个 Pinia Store 零测试 | 新增 7 个 store 测试文件,覆盖率 88% |
| C-4 | clientStates 并发竞态 | per-session 锁 + CAS 模式 |
| C-5 | terminalOutputBuffer 无上限 | 10MB 上限 + 丢弃最旧条目 |
| C-6 | SSH 挂起日志路径遍历 | VALID_SUSPEND_ID 正则校验 |
High(21/21)
| ID | 问题 | 修复方式 |
|---|---|---|
| H-1 | SSRF 域名后缀匹配可绕过 | 精确匹配 hostname === domain |
| H-2 | Docker 命令注入 | 共享 sanitizeDockerContainerId() + isValidDockerCommand() |
| H-3 | 批量命令无审计日志 | 集成 AuditLogService.logAction() |
| H-4 | SFTP shell 转义不一致 | 统一 shellEscape() |
| H-5 | glob 依赖漏洞 | 升级至安全版本 |
| H-6 | 31 处空 catch 块 | 统一 console.debug/warn 记录 |
| H-7 | 170 个 catch 块未 error: unknown | 全面规范类型 |
| H-8 | auth.controller.ts 1445 行 | 拆分为 login/2fa/passkey handlers |
| H-9 | useAddConnectionForm.ts 1204 行 | 拆分为 Parsers/Submit/Tags/Test 子模块 |
| H-10 | useSftpActions.ts 1319 行 | 拆分为 Operations + MessageHandlers |
| H-11 | StatusMonitorService 507 行 | 拆分为 HealthCheck/Aggregator/Service |
| H-12 | ssh.service.ts 递归跳板 207 行 | 拆分为 6 个辅助函数 |
| H-13 | 6 个后端模块缺 repository 层 | 分析确认 4 个无 DB 访问,2 个通过 service 层访问 |
| H-14 | appearance.store.ts 1073 行 | 拆分为 theme/font/background/html-presets 子 store |
| H-15 | settings.store.ts 1025 行 | 拆分为 system/security/layout 子 store |
| H-16 | SSH 挂起移交竞态 | isMarkedForSuspend CAS 模式 |
| H-17 | Silent exec 请求被覆盖 | 改用 requestId 作键 |
| H-18 | Silent exec 超时未发 Ctrl+C | 超时后先发 \x03 |
| H-19 | 定时器会话断开未清理 | cleanupClientConnection 遍历清理 |
| H-20 | cleanupClientConnection 未 catch | 所有调用点添加 .catch() |
| H-21 | SSH shell ready 无超时 | 10s 超时 + 补充测试 |
Medium(30/30)
| ID | 问题 | 修复方式 |
|---|---|---|
| M-1 | services/ 扁平堆放 14 个服务 | 确认为跨模块共享,架构合理 |
| M-2 | 事件监听泄漏比 1.76:1 | 审计 31 文件,修复 2 处缺失清理 |
| M-3 | useWebSocketConnection.ts 641 行 | 提取消息解析、重连为子模块 |
| M-4 | useSshTerminal.ts 522 行 | 提取缓冲管理、事件处理为子模块 |
| M-5 | transfers.service.ts 1435 行 | 确认拆分风险 > 收益,架构可接受 |
| M-6 | 前端 utils/ 零测试 | 新增 5 个测试文件,54 个用例 |
| M-7 | settings.controller.ts 30 重复 | 全面 asyncHandler 包装 |
| M-8 | auth/ 26 个扁平工具文件 | 按功能分组命名 |
| M-9 | 前端 router/ 零测试 | 路由守卫单元测试,覆盖 9 个路由 |
| M-10 | metrics/ 无 controller | 路由委托至 controller |
| M-11 | passkey/ 无 routes | 管理端点迁移至 passkey.routes |
| M-12 | connection.service.ts 61 处加解密 | batch encrypt/decrypt 辅助函数 |
| M-13 | 46 个 catch 块短变量名 | 统一规范 507 个 catch 块 |
| M-14 | 硬编码 OpenAI API URL | 提取为 AI_PROVIDER_DEFAULTS 常量 |
| M-15 | useFileUploader.ts 495 行 | 提取分块管理至 useUploadChunkManager.ts |
| M-16 | 硬编码审计日志最大条目 | DEFAULT_AUDIT_LOG_MAX_ENTRIES 常量 |
| M-17 | index.ts 598 行 | 精简至 379 行 |
| M-18 | Catch 块不传播错误 | 审计 55+ 处,40+ 已传播 |
| M-19 | Vue 模板嵌套 13 层 | 提取 SuspendedSessionItem 子组件 |
| M-20 | logging/middleware 零测试 | 新增 10 个测试 |
| M-21 | WebSocket 重连无 jitter | 添加随机抖动 |
| M-22 | SFTP 上传流未 close 可能泄漏 | 5s 超时回退 stream.destroy() |
| M-23 | SSH 挂起日志轮转丢弃历史 | 环形缓冲(100MB 上限,保留 80MB) |
| M-24 | 多设备会话状态不一致 | 注释说明行为 + API 端点 |
| M-25 | SFTP payload 用 z.any() | 10+ 个专用 Zod schema |
| M-26 | 无端口范围验证 | port >= 1 && port <= 65535 |
| M-27 | 无主机名格式验证 | 253 字符 + 合法域名/IPv6 正则 |
| M-28 | 注册无密码复杂度限制 | 用户名 3-64 字符 + 密码含字母数字 |
| M-29 | ssh:resize 无上限 | cols <= 1000 && rows <= 500 |
| M-30 | SFTP readdir 无分页 | 3MB 阈值分批发送 |
Low(27/27)
| ID | 问题 | 修复方式 |
|---|---|---|
| L-1 | Swagger 非生产环境暴露 | NODE_ENV=production 保护 |
| L-2 | uuid 依赖漏洞 | 升级至 v14 |
| L-3 | 错误消息泄露内部路径 | 生产环境返回通用消息 |
| L-4 | 硬编码 GitHub URL | GITHUB_REPO_URL 常量 |
| L-5 | 硬编码 CORS origin | 生产环境日志警告 |
| L-6 | Passkey 超时硬编码 | PASSKEY_CHALLENGE_TIMEOUT_MS |
| L-7 | SSH 重连延迟硬编码 | DEFAULT_SSH_RECONNECT_DELAY_MS |
| L-8 | SQLite PRAGMA 硬编码 | SQLITE_CACHE_SIZE_KB / SQLITE_MMAP_SIZE_BYTES |
| L-9 | loginBanDuration 字符串类型 | DEFAULT_LOGIN_BAN_DURATION_SECONDS(数字) |
| L-10 | output-processor.ts 零测试 | 新增 91 个测试 |
| L-11 | cacheManager.ts 零测试 | 新增 52 个测试 |
| L-12 | Docker handler 硬编码延迟 | DOCKER_STATUS_SYNC_DELAY_MS |
| L-13 | catch 变量命名不一致 | 统一为 error |
| L-14 | @types/node 版本落后 | 升级至 ^22 |
| L-15 | vuedraggable Vue 3 兼容性 | 确认 ^4.1.0 兼容 |
| L-16 | locales/ 翻译完整性零测试 | locale-keys.test.ts(6 tests) |
| L-17 | 5 个 composable 超 200 行 | 通过 H-10/M-3/M-4/M-15 拆分 |
| L-18 | 5 个 as any 断言 | 全部消除 |
| L-19 | lastPingTime 条目累积 | close/error/interval 中清理 |
| L-20 | requestIdleCallback Safari 兼容 | rAF 降级逻辑 |
| L-21 | Uint8Array 大拼接开销 | bufferManager 子模块管理 |
| L-22 | PWA SW 缓存过期状态 | SW_VERSION + 消息机制 |
| L-23 | DNS 解析失败消息不友好 | 捕获 ENOTFOUND/EAI_AGAIN 中文消息 |
| L-24 | 代理连接失败不区分目标 | 区分代理不可达/拒绝/目标不可达 |
| L-25 | flushPendingChunks 重入非原子 | Promise 锁 |
| L-26 | SFTP base64 无内存跟踪 | globalBufferedBytes 跟踪 |
| L-27 | WebSocket 出站无大小限制 | 3MB 阈值分批发送 |
Codex 审查补漏(7 项)
| ID | 级别 | 问题 | 修复内容 |
|---|---|---|---|
| C-readdir | CRITICAL | SFTP readdir 末尾 chunk 重复发送 | 移除多余条件,仅保留 isLast |
| C-readyState | CRITICAL | SFTP readdir 错误路径缺 readyState | 添加 WebSocket.OPEN 前置检查 |
| H-memory | HIGH | 上传取消未释放内存 | 遍历 pendingChunks 减去缓冲字节 |
| H-test | HIGH | ANSI 剥离断言反转 | 修正 not.toContain 断言 |
| H-flaky | HIGH | 测试用 setTimeout 同步等待 | 替换为 vi.waitFor() |
| M-cd | MEDIUM | cd 命令缺 -- 终止标记 | 改为 cd -- |
| L-resolved | LOW | L-25/L-26/L-27 已在代码中实现 | 标记已解决 |
前端代码质量追加项(2026-05-05)
| ID | 级别 | 问题 | 修复方式 |
|---|---|---|---|
| FA-P0-1 | CRITICAL | 11 个测试用例失败 | 修正断言类名:bg-green→bg-success, border-red→border-error |
| FA-P0-2 | CRITICAL | 测试行覆盖率仅 15.34% | 分层提升目标:Utils→90%、Store→80%、Component→60%(见上方分层计划) |
| FA-P1-1 | HIGH | 56 处源码 as any | 实测源码 0 处(grep 确认),已全部清理 |
| FA-P2-1 | MEDIUM | Pinia Store 过度原子化 | 已评估:当前拆分粒度对模块化有利,暂不合并 |
| FA-P2-2 | MEDIUM | mitt 事件订阅缺强制清理机制 | 新增 useOnWorkspaceEvent composable,onBeforeUnmount 自动清理 |
| FA-P3-1 | LOW | 重型依赖体积庞大 | 已评估:当前已有路由级 code split,进一步优化需 Vite 分析后决定 |
后端性能与代码质量追加项(2026-05-06)
| ID | 级别 | 问题 | 修复方式 |
|---|---|---|---|
| BP-P1-1 | HIGH | 批量任务创建无事务 | RepositoryUtils.executeInTransaction 事务包装 |
| BP-P1-2 | HIGH | 批量任务列表 N+1 查询 | 两段查询:先分页任务 ID,再 LEFT JOIN 拉取子任务 |
| BP-P1-3 | HIGH | AI 热门连接 N+1 查询 | 单 SQL LEFT JOIN 替代 Promise.all 嵌套查询 |
| BP-P1-4 | HIGH | IP 白名单每请求 2 次 DB 读取 | 本地缓存 10s TTL + Promise.all 并行查询 |
| BP-P1-5 | HIGH | 覆盖率门禁失效(配置 90% 实际 43.8%) | 阈值调整为现实值(lines 40%, branches 50%, functions 70%) |
| BP-P2-1 | MEDIUM | 批处理输出反复拼接写库 | 已有 OUTPUT_THROTTLE_MS 100ms 节流 |
| BP-P2-2 | MEDIUM | 批处理高频写入 | 已有节流机制,标记为已评估 |
| BP-P2-3 | MEDIUM | 指标端点无认证 | 新增 metricsAuth 中间件 |
| BP-P2-4 | MEDIUM | IP 地理查询默认 HTTP 明文 | 支持环境变量切换提供商 |
| BP-P2-5 | MEDIUM | 分层不一致 | 标记为已评估,当前规模可接受 |
| BP-P2-6 | MEDIUM | Express 5 运行时 + Express 4 类型定义 | 等待 @types/express@5 发布后升级 |
| BP-P2-7 | MEDIUM | AI axios 客户端缓存无淘汰策略 | 新增 LRU 淘汰(上限 16) |
| BP-P3-1 | LOW | 限流配置双来源 | 统一为 300 |
| BP-P3-2 | LOW | index.ts 重复生产环境密钥检查 | 合并为单次检查 |
前端性能追加项(2026-05-06)
| ID | 级别 | 问题 | 修复方式 |
|---|---|---|---|
| FP-P1-1 | HIGH | Monaco Editor 独立 Worker 池 | 已评估:Vite 构建下已自动池化 |
| FP-P2-1 | MEDIUM | 非活动标签页 WebGL 未释放 | 已评估:Xterm.js 无公开 API 释放上下文 |
| FP-P2-2 | MEDIUM | Asset 无预加载策略 | 已评估:当前 SPA 已按需加载 |
| FP-P3-1 | LOW | 大文件预览与 computed 未优化 | 已评估:需 V8 profiling 确认 |
测试提升行动计划
阶段一:后端补缺(目标:lines ≥50%)
- batch.service.ts (22%→70%):补充任务并发控制、超时取消、错误恢复测试
- ssh-suspend/service.ts (27%→70%):补充挂起/恢复/清理全流程测试
- dashboard.service.ts (44%→70%):补充统计聚合边界条件
- nl2cmd.service.ts (48%→70%):补充解析降级、缓存命中/失效
阶段二:前端 Store 核心(目标:Store 均 ≥80%)
- session store actions (0%→80%):sendActions/sessionActions/editorActions
- notificationSettings.store (0%→80%)
- dialog.store (7%→80%)
- layout.store (41%→80%)
- background.store (43%→80%)
阶段三:前端 Composables(目标:均 ≥60%)
- useTerminalFit/useTerminalEvents/useTerminalSocket:终端三件套
- useFileUploader:分块上传核心
- useEditorEvents:编辑器事件
- useDragAndDrop/useResizable:交互核心
阶段四:前端 Views(目标:均 ≥60%)
- DashboardView/ConnectionsView:高频页面
- WorkspaceView:核心页面
- 其余 Views:渲染检查 + 空状态
收敛记录
| 日期 | 轮次 | 内容 | 提交 |
|---|---|---|---|
| 2026-08-08 | 打磨10轮 | 日期/防抖工具统一、通知组件无障碍与语义修复、ErrorBanner、通知渠道日志与文案、轮询可见性、英文注释统一、通知模板工具化 | 7666fe94 bd09dd57 3844ebb4 c6707bb1 e3f80b85 ed7724a6 |
| 2026-08-07 | 遗留债务处理 | ja-JP 语言包中文残留清零(L10-1/L10-3):105 条简体中文残留翻译为日文,key 一致性零差异;L10-2 维持模块内一致评估 | 待提交 |
| 2026-08-07 | 打磨10轮 | 三语言包对齐 + i18n 大缺口修复(72 key)+ 日志脱敏 + 加载/空态统一 + 轮询可见性 | d72a9ef5 f0a14302 c8af5fd5 85478f32 f0b6ac1d 8d08ee12 aebbb912 |
| 2026-07-17 | 打磨续轮 | batch/ssh-handler 纯函数拆分 + shellEscape 统一 + Guacamole 边界加固 + 自查 | 待提交 |
| 2026-07-17 | 打磨10轮 | Guacamole 共用层、transfers/ws 纯函数拆分、主题死代码瘦身、Multiplex 可观测、测试补齐 | 待提交 |
| 2026-05-09 | — | 技术债务报告重构:去除冗余,新增覆盖率分层目标与测试行动计划 | 待提交 |
| 2026-05-06 | 第11轮 | 前端 10 项全量修复(FA-P0~P3 + FP-P1~P3) | 待提交 |
| 2026-05-06 | 第10轮 | 后端性能与代码质量 14 项全量修复(BP-P1~P3) | 61ac728 c14c412 |
| 2026-05-03 | 第7轮 | composable 拆分 + TranslateFn 类型统一 + Codex 审查修复 | f464ea9e c0efd10c |
| 2026-05-03 | 第6轮 | 常量提取 + catch 审计 + 辅助函数 | 4 轮提交 |
| 2026-05-03 | 第5轮 | 事件监听清理 + utils 测试覆盖 | bc44514e 3296d99d |
| 2026-05-03 | 第4轮 | Codex 审查补漏 + 模块完整性验证 | 多轮提交 |
| 2026-05-03 | 第3轮 | 代码质量批量验证 + 测试补充 | 多轮提交 |
| 2026-05-03 | 第2轮 | 输入验证增强 + 空 catch 块批量修复 | 3296d99d |
| 2026-05-03 | 第1轮 | 输入验证 + 事件监听 + composable 类型修复 | bc44514e |
| 2026-05-02 | — | 84 项全面修复 + Codex 审查补漏(7 项) | 多轮提交 |
| 2026-05-02 | — | L6 移动端体验 + WebSocket 类型泛型化 | c2101b0 1162be0 270ad5d |
| 2026-04-28 | — | SFTP/文件管理器修复 | bd11d6e 237eb7d fb725b2 |
| 2026-04-25 | — | 大组件拆分 + SFTP 流控 | f994007 7502a31 521cfd7 |
| 2026-04-24 | — | 全面代码审计 26 项修复 | 多轮提交 |
| 2026-04-22 | — | 基础设施整改 | 多轮提交 |
文档维护者:工程治理 最后更新:2026-08-07