feat(ssa): Complete Phase V-A editable analysis plan variables
Features: - Add editable variable selection in workflow plan (SingleVarSelect + MultiVarTags) - Implement 3-layer flexible interception (warning bar + icon + blocking dialog) - Add tool_param_constraints.json for 12 statistical tools parameter validation - Add PATCH /workflow/:id/params API with Zod structural validation - Implement synchronous parameter sync before execution (Promise chaining) - Fix LLM hallucination by strict system prompt constraints - Fix DynamicReport object-based rows compatibility (R baseline_table) - Fix Word export row.map error with same normalization logic - Restore inferGroupingVar for smart default variable selection - Add ReactMarkdown rendering in SSAChatPane - Update SSA module status document to v3.5 Modified files: - backend: workflow.routes, ChatHandlerService, SystemPromptService, FlowTemplateService - frontend: WorkflowTimeline, SSAWorkspacePane, DynamicReport, SSAChatPane, ssaStore, ssa.css - config: tool_param_constraints.json (new) - docs: SSA status doc, team review reports Tested: Cohort study end-to-end execution + report export verified Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# **架构与统计双重视角审查报告:分析方案变量可编辑化**
|
||||
|
||||
**审查对象:** plan\_editable\_variables\_27d3a9fd.plan.md
|
||||
|
||||
**审查时间:** 2026-02-23
|
||||
|
||||
**总体评级:** 🌟 **A 级 (方向极其正确,但存在隐性逻辑冲突需补强)**
|
||||
|
||||
**核心裁决:** 批准开发。但在前端变量过滤逻辑和后端校验机制上,必须引入“基于方法 Schema 的强约束”,否则极易导致下游 R 引擎大面积崩溃。
|
||||
|
||||
## **一、 视角一:资深统计学专家的评估**
|
||||
|
||||
**“不要给用户犯错的自由。医学统计的容错率是 0。”**
|
||||
|
||||
### **1\. 极度认可的改进**
|
||||
|
||||
* **尊重临床逻辑**:AI 经常会把“住院天数”和“年龄”搞混,或者漏掉医生特别关心的某个协变量。允许医生在执行前把遗漏的变量(Tag)加回来,这才是真正懂临床的工具。
|
||||
* **按类型分组展示**:下拉面板将连续变量和分类变量分开展示,极大地降低了医生寻找变量的认知负荷。
|
||||
|
||||
### **2\. 统计学视角的致命盲区 (The Statistical Blind Spot)**
|
||||
|
||||
正如您在提问中敏锐指出的,仅仅区分“分类 (Categorical)”和“连续 (Continuous)”是远远不够的。
|
||||
|
||||
* **二元 Logistic 回归陷阱**:该方法要求结局指标(Y)**必须且只能**是二分类变量(如:死/活,0/1)。如果用户的下拉列表里显示了所有“分类变量”(包含了 3 分类的“血型”),一旦用户手抖选了“血型”,后端的 R 代码执行时将 100% 报错崩溃。
|
||||
* **T 检验陷阱**:独立样本 T 检验的分组变量(X)**必须**是二分类变量。如果是 3 分类变量,必须用 ANOVA。
|
||||
* **生存分析陷阱**:它需要两个 Y(Time 是连续,Status 是二分类 0/1)。
|
||||
|
||||
### **🛠️ 统计专家的修正建议:引入“细粒度统计类型过滤”**
|
||||
|
||||
前端的下拉框候选项(Options),不能仅仅根据 type \=== 'categorical' 来过滤,必须**与当前 Step 绑定的统计方法强关联**。
|
||||
|
||||
* **建议实现**:前端在渲染下拉框时,必须读取该统计工具的 params\_schema(在 Phase III / IV 中已定义)。
|
||||
* **UI 约束逻辑**:
|
||||
* 如果当前是 ST\_LOGISTIC,结局变量的下拉框**只能**展示 DataProfile 中推断为 categorical\_2 (唯一值为2) 的变量。
|
||||
* 对于不符合当前统计方法要求的变量,在下拉框中将其 disabled (置灰),并 hover 提示:“该变量为多分类,二元逻辑回归仅支持二分类变量”。
|
||||
|
||||
## **二、 视角二:资深架构师的评估**
|
||||
|
||||
**“用户的每一次修改,都可能打破系统原本自洽的状态机。”**
|
||||
|
||||
### **1\. 架构师高度赞赏的决策 (Brilliant Architectural Choices)**
|
||||
|
||||
* **后端 PATCH API 的设计 (方案 A)**:
|
||||
这是非常正统的 RESTful 设计。用户修改参数后,先 PATCH /params 更新数据库实体,然后再触发 executeWorkflow。这保证了数据库中的 Plan 永远是 Single Source of Truth(单一事实来源),避免了前端传来“幽灵参数”导致历史记录无法复现的灾难。
|
||||
|
||||
### **2\. 工程视角的潜在风险 (Engineering Risks)**
|
||||
|
||||
#### **🚨 风险 1:UI 状态与执行动作的竞态条件 (Race Condition)**
|
||||
|
||||
* **场景**:用户在前端刚从下拉框里切换了变量,还没等组件把 state 同步完毕,或者还没等 PATCH 接口返回 200 OK,用户就光速点击了“开始执行分析”按钮。
|
||||
* **后果**:executeWorkflow 可能会拿着数据库里**旧的参数**去执行。
|
||||
* **修正建议**:
|
||||
“开始执行分析”按钮必须绑定一个复合动作(Promise Chaining):
|
||||
async function handleExecute() {
|
||||
setExecuting(true);
|
||||
// 1\. 必须先 await 等待 PATCH 成功
|
||||
if (hasUnsavedChanges) {
|
||||
await api.patchWorkflowParams(workflowId, modifiedSteps);
|
||||
}
|
||||
// 2\. 然后再触发执行
|
||||
startSseExecution(workflowId);
|
||||
}
|
||||
|
||||
#### **🚨 风险 2:级联失效与重新规划的边界 (Cascading Invalidation)**
|
||||
|
||||
* **场景**:AI 原本规划了 \[描述统计 \-\> T检验 \-\> Mann-Whitney\]。此时,用户在“描述统计”那一步,把 analyze\_vars 里的变量全删了,换成了一批全新的变量。
|
||||
* **架构思考**:此时,下游的 T检验 步骤的参数是否还有效?
|
||||
* **修正建议 (MVP 阶段的防御性降维)**:
|
||||
在当前计划中,请严格限制:**参数的可编辑性仅限于“同类替换”**。
|
||||
如果用户想要推翻整个研究假设(比如把 Y 变量从“血压”改成了“有效/无效”),系统不应该允许他们通过修改参数来完成,因为这会触发统计方法的变更(T检验 变 卡方)。
|
||||
* **前端提示**:在卡片顶部加一行提示:“如需更改核心分析目标(如改变数据类型),请在对话框告诉 AI 重新生成方案。”
|
||||
|
||||
#### **🚨 风险 3:Zod Schema 的后端防御 (Backend Defense)**
|
||||
|
||||
* **场景**:前端即便做了限制,但网络请求是可以被篡改的,或者存在前端 Bug 漏传了非法参数。
|
||||
* **修正建议**:
|
||||
新增的 PATCH /api/v1/ssa/workflow/:workflowId/params 接口,**绝对不能盲目接收数据**。它必须使用对应 R 工具的 Zod Schema 进行强校验。如果在 T 检验的 group\_var 里接收到了一个在 DataContext 中被标记为连续数值的变量,后端必须拦截并返回 400 Bad Request。
|
||||
|
||||
## **三、 终极结论与实施调整指南 (Actionable Summary)**
|
||||
|
||||
您的计划大体方向非常优秀,不仅提升了可用性,还大幅缓解了 AI 的幻觉焦虑。为了让它完美落地,请在您的开发计划中追加以下 **3 个微小但致命的补丁**:
|
||||
|
||||
1. **细化前端过滤条件 (UI Filter Patch)**:
|
||||
* 在 WorkflowTimeline.tsx 渲染下拉框时,利用 VariableDictionary 中更精细的属性(如 unique\_values\_count)来约束选项。
|
||||
* 例如:如果是分组变量下拉框,仅高亮展示 type \=== 'categorical' && levels \<= 5 的变量。
|
||||
2. **同步阻塞执行 (Sync Block Patch)**:
|
||||
* 确保“执行按钮”的 onClick 事件中,严格包含 await patchApi(),并在进行网络请求时将按钮置为 loading 状态,防止连点。
|
||||
3. **后端的参数防火墙 (Backend Firewall Patch)**:
|
||||
* 在开发 PATCH API 时,务必对传入的 params 进行统计学常识级别的 Zod 校验,防止将脏参数写入数据库,导致后续 R 引擎因 Fatal Error 宕机。
|
||||
|
||||
**批示:完全批准按照此计划及上述修正建议执行开发!这会让 SSA-Pro 的专业度再上一个大台阶。**
|
||||
Reference in New Issue
Block a user