Bug fixes: - Fix garbled error messages in chat (TypeWriter rendering issue) - Fix R engine NA crash in descriptive.R (defensive isTRUE/is.na checks) - Fix intent misclassification for statistical significance queries - Fix step 2 results not displayed (accept warning status alongside success) - Fix incomplete R code download (only step 1 included) - Fix multi-task state confusion (clicking old card shows new results) - Add R engine and backend parameter logging for debugging Refactor - Unified Record Architecture: - Replace 12 global singleton fields with AnalysisRecord as single source of truth - Remove isWorkflowMode branching across all components - One Analysis = One Record = N Steps paradigm - selectRecord only sets currentRecordId, all rendering derives from currentRecord - Fix cross-hook-instance issue: executeWorkflow fallback to store currentRecordId Updated files: ssaStore, useWorkflow, useAnalysis, SSAChatPane, SSAWorkspacePane, SSACodeModal, WorkflowTimeline, QueryService, WorkflowExecutorService, descriptive.R Tested: Manual integration test passed - multi-task switching, R code completeness Co-authored-by: Cursor <cursoragent@cursor.com>
7.0 KiB
7.0 KiB
SSA 前后端集成测试 Bug 修复与统一状态管理重构
日期: 2026-02-21
阶段: QPER 闭环后首次集成测试 + 架构重构
核心成果: 修复 7 个集成 Bug + 完成统一状态管理重构(消除双轨逻辑)
一、Bug 修复清单
Bug 1: 前端错误消息乱码(分分析行执行执失行败失…undefined重)
| 项目 | 内容 |
|---|---|
| 现象 | 执行失败时,对话区错误消息显示为乱码字符 |
| 根因 | 错误消息被 TypeWriter 组件逐字渲染导致字符交错;errText 提取有竞态导致 undefined |
| 修复 | useWorkflow.ts — 确保 errText 始终为 String(),错误消息添加 artifactType: 'execution' 跳过 TypeWriter |
| 文件 | frontend-v2/src/modules/ssa/hooks/useWorkflow.ts |
Bug 2: R 引擎 missing value where TRUE/FALSE needed 错误
| 项目 | 内容 |
|---|---|
| 现象 | 描述性统计执行时 R 崩溃,返回 500 错误 |
| 根因 | descriptive.R 中多处 if 条件(group_var 判断、var_types 比较、分组子集)接收到 NA 而非 TRUE/FALSE |
| 修复 | 全面防御性编程:isTRUE()、is.na() 检查、robust group_var 归一化、sapply 类型推断 tryCatch、可复现代码生成 tryCatch |
| 文件 | r-statistics-service/tools/descriptive.R |
Bug 3: 分析意图识别错误("统计学意义" → 描述性统计)
| 项目 | 内容 |
|---|---|
| 现象 | 用户问"Yqol和bmi是否有统计学意义",系统使用描述性统计而非 T 检验/相关分析 |
| 根因 | Q 层 LLM Prompt 和 Regex fallback 缺少"统计学意义""显著""检验""p值"等关键词到 correlation goal 的映射 |
| 修复 | QueryService.ts fallbackToRegex 增加统计学意义关键词;seed-ssa-intent-prompt.ts 新增 Few-Shot 示例 |
| 文件 | backend/src/modules/ssa/services/QueryService.ts, backend/scripts/seed-ssa-intent-prompt.ts |
Bug 4: 步骤 2(Logistic 回归)结果不显示
| 项目 | 内容 |
|---|---|
| 现象 | R 返回 status="warning"(ggplot2 废弃警告),前端仅过滤 status="success",导致步骤 2 结果丢失 |
| 根因 | 前端 SSAWorkspacePane、SSACodeModal 只识别 success,不识别 warning |
| 修复 | 引入 stepHasResult 辅助函数:(s.status === 'success' || s.status === 'warning') && s.result,替换所有 6 处过滤 |
| 文件 | frontend-v2/src/modules/ssa/components/SSAWorkspacePane.tsx, SSACodeModal.tsx |
Bug 5: R 代码下载不完整(仅步骤 1)
| 项目 | 内容 |
|---|---|
| 现象 | 多步骤分析完成后,下载的 R 代码只包含步骤 1(描述统计),缺少步骤 2(回归) |
| 根因 | 与 Bug 4 同源 — SSACodeModal 过滤条件只匹配 success |
| 修复 | 随 Bug 4 一并修复 |
Bug 6: 多任务状态混淆(点击旧卡片显示新任务结果)
| 项目 | 内容 |
|---|---|
| 现象 | 完成两次分析后,点击第 1 次的卡片显示的是第 2 次的结果 |
| 根因 | workflowPlan/workflowSteps/conclusionReport 等是全局单例,切换记录时未正确同步 |
| 修复 | 通过统一状态管理重构彻底解决(见下文第二节) |
Bug 7: 后端/R 引擎调试日志不足
| 项目 | 内容 |
|---|---|
| 现象 | R 执行失败时无法定位具体哪些变量传入导致错误 |
| 修复 | WorkflowExecutorService.ts 增加 R 调用前参数日志;plumber.R 增加参数接收日志和错误日志 |
| 文件 | backend/src/modules/ssa/services/WorkflowExecutorService.ts, r-statistics-service/plumber.R |
二、统一状态管理重构
问题描述
前端存在"双轨逻辑":
- Legacy 路径:
currentPlan/executionResult/traceSteps(全局单例) - Workflow 路径:
workflowPlan/workflowSteps/workflowProgress/conclusionReport(也是全局单例) isWorkflowMode分支在多个组件中分叉
多任务场景下,全局单例被最新任务覆盖,导致切换卡片时显示错误数据。
重构方案
核心思想:一次分析 = 一个 Record = N 个 Steps
AnalysisRecord {
id, query, createdAt,
status: 'planning' | 'executing' | 'completed' | 'error',
plan: WorkflowPlan | null,
steps: WorkflowStepResult[],
progress: number,
conclusionReport: ConclusionReport | null,
}
改动文件
| 文件 | 改动要点 |
|---|---|
ssaStore.ts |
删除 12 个全局单例字段及 setter;新增 addRecord/updateRecord/selectRecord;selectRecord 只设 currentRecordId,不复制数据 |
useWorkflow.ts |
SSE 事件处理只调用 updateRecord(rid, patch);删除对 setWorkflowSteps 等全局 setter 的调用 |
useAnalysis.ts |
generatePlan 改为调用 addRecord 创建 1-step Record |
SSAChatPane.tsx |
SAP/Result 卡片统一行为:selectRecord(recordId) + 打开工作区;已完成记录显示绿色"已完成"徽章 |
SSAWorkspacePane.tsx |
所有渲染基于 currentRecord;删除 isWorkflowMode 分支;phase 直接使用 record.status |
SSACodeModal.tsx |
从 currentRecord.steps 聚合代码;删除 Legacy fallback |
ssa-workspace.css |
新增 .sap-card-badge 样式 |
额外修复
- executeWorkflow 跨 hook 实例问题:
SSAChatPane和SSAWorkspacePane各自有独立的useWorkflow()实例,generateWorkflowPlan在 ChatPane 实例中设置了currentRecordIdRef,但executeWorkflow在 WorkspacePane 实例中执行时 ref 为 null。修复:fallback 到 store 的currentRecordId。
三、未完成工作与后续计划
QPER 透明化与可观测性
目前 QPER 四层的执行细节对用户不够透明,出错时用户难以了解具体原因,开发调试也依赖日志查看:
-
Q 层透明化
- 展示 LLM 意图解析的 ParsedQuery 结果(goal、变量、设计类型、置信度)
- 低置信度时展示降级原因("LLM 超时,使用关键词匹配")
-
P 层透明化
- 展示决策表匹配过程(匹配了哪条规则、得分)
- 展示流程模板填充参数
-
E 层透明化
- 实时展示每个步骤的输入参数和 R 返回结果摘要
- 错误时展示 R 原始错误信息(开发模式)
-
R 层透明化
- 展示 LLM 结论生成的槽位注入内容
- Zod 校验失败时展示具体字段错误
-
开发调试增强
- 持久化 trace_log 到数据库
- 前端"开发者面板"查看完整 QPER pipeline 日志
- LLM 调用的 prompt/response 可查看
其他待完成项
- Phase Deploy:补齐 ANOVA / Fisher / Wilcoxon / 线性回归等 R 工具
- Phase Q+:变量数据字典 + 变量选择确认面板
- 前端 UI 细节打磨:执行计划格式美化、错误状态视觉增强
测试状态: 手动集成测试通过(多任务切换、卡片状态、R 代码完整性)
影响范围: 纯前端重构 + R 脚本防御性修复 + 后端日志增强,后端 API 不变