Files
AIclinicalresearch/docs/03-业务模块/SSA-智能统计分析/06-开发记录/J技术报告审核评估与建议/SSA-Pro R 服务代码深度审查报告.md
HaHafeng 371e1c069c feat(ssa): Complete QPER architecture - Query, Planner, Execute, Reflection layers
Implement the full QPER intelligent analysis pipeline:

- Phase E+: Block-based standardization for all 7 R tools, DynamicReport renderer, Word export enhancement

- Phase Q: LLM intent parsing with dynamic Zod validation against real column names, ClarificationCard component, DataProfile is_id_like tagging

- Phase P: ConfigLoader with Zod schema validation and hot-reload API, DecisionTableService (4-dimension matching), FlowTemplateService with EPV protection, PlannedTrace audit output

- Phase R: ReflectionService with statistical slot injection, sensitivity analysis conflict rules, ConclusionReport with section reveal animation, conclusion caching API, graceful R error classification

End-to-end test: 40/40 passed across two complete analysis scenarios.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-21 18:15:53 +08:00

4.9 KiB
Raw Blame History

SSA-Pro R 服务代码深度审查报告

审查对象: SSA-Pro R Service Source Code (v1.0)

审查文件: Dockerfile, plumber.R, data_loader.R, guardrails.R, etc.

审查时间: 2026-02-18

审查结论: 🟡 总体优秀,但存在阻断性缺失 (Blocker)

1. 🚨 阻断性问题 (Critical Issues)

这些问题会导致服务无法启动或无法下载数据,必须在联调前修复。

1.1 data_loader.R 中缺失 OSS 签名函数

  • 问题描述:在 data_loader.R 第 63 行调用了 generate_oss_signature(config, "GET", oss_key),但我翻遍了上传的所有文件,没有找到这个函数的定义
  • 风险:代码运行到下载 OSS 步骤时会直接报错 Error: could not find function "generate_oss_signature"。
  • 修复建议
    1. 方案 A (推荐):在 utils/ 下新建 oss_signer.R实现阿里云 OSS 的 HMAC-SHA1 签名逻辑(需要引入 digest 和 base64enc 包)。
    2. 方案 B (替代):如果不想手写签名,可以使用系统调用 awscli (配置阿里云 endpoint) 或寻找现成的 R 包(如 aliyunr但需验证维护状态

1.2 plumber.R 的动态加载性能隐患

  • 问题描述:在 plumber.R 的 POST /api/v1/skills/<tool_code> 接口中,第 38 行使用了 source(tool_file)。这意味着每次请求都会重新从磁盘读取并解析 R 脚本
  • 风险
    • 开发环境:这是好事,支持热重载。
    • 生产环境:这是性能杀手。在高并发下,频繁的磁盘 I/O 和语法解析会显著增加延迟。
  • 修复建议
    • 引入 DEV_MODE 变量判断。
    • 生产环境:在服务启动时(第 13 行左右)预先加载所有 tools/ 下的脚本,或者使用 environment 缓存已加载的函数。
    • 开发环境:保持现有的动态 source 逻辑。

2. 工程与安全隐患 (Engineering & Security Risks)

2.1 Docker 容器的 Root 权限风险

  • 问题描述Dockerfile 未指定用户,默认使用 root 运行 R 服务。
  • 风险:如果 R 代码中存在漏洞(如允许执行系统命令 system()),攻击者将获得容器的 Root 权限,可能逃逸或破坏文件系统。
  • 修复建议:在 Dockerfile 末尾添加非特权用户切换:
    RUN useradd -m appuser
    USER appuser

2.2 路径遍历攻击 (Path Traversal)

  • 问题描述plumber.R 第 33 行:
    tool_file <- file.path("tools", paste0(tolower(gsub("ST_", "", tool_code)), ".R"))
    虽然做了 gsub但如果 tool_code 包含 ../ 等字符,仍可能尝试访问上层目录。
  • 修复建议:增加严格的白名单校验,或者校验 tool_code 只能包含字母、数字和下划线。
    if (!grepl("^[A-Z0-9_]+$", tool_code)) {
    return(list(status="error", message="Invalid tool code format"))
    }

3. 最佳实践点赞 (Highlights)

  1. 依赖锁定 (renv.lock):使用了 renv 进行包管理,这是 R 工程化的基石,做得非常棒。
  2. 护栏设计 (guardrails.R)
    • 包含了 LARGE_SAMPLE_THRESHOLD (5000) 的抽样逻辑,避免了大样本下 Shapiro 检验过敏的问题,非常专业的统计学处理。
    • 接口设计清晰 (passed, action, reason)。
  3. 结果格式化 (result_formatter.R):统一处理了 P 值 < 0.001 的显示,符合 APA 规范。
  4. 环境隔离 (docker-compose.yml):正确使用了环境变量注入 OSS 配置,且区分了开发/生产环境。

4. 优化代码清单 (Code Improvement Snippets)

补全 OSS 签名逻辑 (utils/oss_signer.R)

这部分逻辑比较复杂,我直接提供一个简版实现供参考:

library(digest)
library(base64enc)

generate_oss_signature <- function(config, verb, resource) {
date <- format(Sys.time(), "%a, %d %b %Y %H:%M:%S GMT", tz="GMT")
content_type <- ""
content_md5 <- ""

canonicalized_resource <- paste0("/", config$bucket, "/", resource)
string_to_sign <- paste(verb, content_md5, content_type, date, "", canonicalized_resource, sep="\n")

signature <- base64encode(hmac(config$access_key_secret, string_to_sign, algo="sha1", raw=TRUE))
auth_header <- paste0("OSS ", config$access_key_id, ":", signature)

return(c("Authorization" = auth_header, "Date" = date))
}

注意:需要在 renv.lock 中补充 digest 包。

5. 总结

这份代码作为 MVP 已经达到了 85分 的水平。

接下来的行动指南:

  1. 必须做:补全 generate_oss_signature 函数(或相关文件)。
  2. 必须做:在 renv 中添加 digest 依赖。
  3. 建议做:优化 plumber.R 的生产环境加载逻辑。

请将这份报告发给 R 开发工程师,让他们快速修正,然后就可以开始构建镜像了。