mcpField
R
rails-audit-thoughtbot

rails-audit-thoughtbot

github.com/thoughtbot测试与质量26253 次安装10 周前更新
代码仓库

关于 rails-audit-thoughtbot

面向 Claude Code 的 Ruby on Rails 审计 Skill,依据 thoughtbot 的 Ruby Science 和测试实践检查应用。支持全项目或指定路径审查,可选收集 SimpleCov、RubyCritic 指标并生成 Markdown 报告。

主要功能

  1. 01全项目或定向 Rails 审计
  2. 02可选 SimpleCov 覆盖率指标
  3. 03可选 RubyCritic 质量指标
  4. 04检查测试、安全、设计与数据库
  5. 05生成 RAILS_AUDIT_REPORT.md

适用场景

  1. 01审查整个 Rails 应用
  2. 02审计指定文件或目录
  3. 03梳理安全与测试问题的优先级

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/thoughtbot/rails-audit-thoughtbot --skill rails-audit-thoughtbot

安装后在 Claude Code 中输入/rails-audit-thoughtbot确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
CODEOWNERS
README.md
agents/
simplecov_agent.md
rubycritic_agent.md
references/
rails_antipatterns.md
poro_patterns.md
report_template.md
security_checklist.md
code_smells.md
testing_guidelines.md

详细介绍

Rails 审计技能(thoughtbot 最佳实践)

根据 thoughtbot 的 Ruby Science 和 Testing Rails 最佳实践,对 Ruby on Rails 应用进行全面审计,重点关注优先使用普通 Ruby 对象(PORO),而非 Service Object。

审计范围

审计可以通过两种模式运行:

  1. 完整应用审计:分析整个 Rails 应用
  2. 定向审计:分析指定文件或目录

执行流程

步骤 1:确定审计范围

询问用户,或根据请求推断:

  • 完整审计:分析整个 app/、spec/ 或 test/、config/、db/、lib/
  • 定向审计:仅分析指定路径
步骤 2:收集可选指标(SimpleCov + RubyCritic)

通过一次 AskUserQuestion 提前同时询问用户这两个问题,让用户可以一次性做出选择:

  • 问题:“开始审计前,是否要收集自动化指标?\n\n1. SimpleCov — 运行测试套件以获取实际代码覆盖率百分比\n2. RubyCritic — 分析代码复杂度、重复和异味(不运行测试)\n\n建议同时使用两者,以进行最全面的审计。”
  • 选项:“两者都要(推荐)” / “仅 SimpleCov” / “仅 RubyCritic” / “两者都跳过”

根据用户的选择,使用 Task 工具并行启动已获准的子 Agent。两者可以同时运行,因为 SimpleCov 会修改测试辅助文件,而 RubyCritic 只读取源文件,两者不会冲突。

SimpleCov 子 Agent(如获准):

阅读文件 agents/simplecov_agent.md 并遵循其中描述的所有步骤。审计范围为:{{SCOPE from Step 1}}。按照该文件指定的输出格式返回覆盖率数据。

RubyCritic 子 Agent(如获准):

阅读文件 agents/rubycritic_agent.md 并遵循其中描述的所有步骤。审计范围为:{{SCOPE from Step 1}}。按照该文件指定的输出格式返回代码质量数据。

两个 Agent 完成后,进行清理:

  • 如果运行了 SimpleCov:rm -rf coverage/
  • 如果运行了 RubyCritic:rm -rf tmp/rubycritic/

解读响应:

  • COVERAGE_FAILED / RUBYCRITIC_FAILED:该工具没有数据 — SimpleCov 使用估算模式,或省略 RubyCritic 部分。请在报告中注明失败原因。
  • COVERAGE_DATA:解析并保留在上下文中,供步骤 4 和 5 使用(总体覆盖率、各目录明细、覆盖率最低的文件、覆盖率为零的文件)。
  • RUBYCRITIC_DATA:解析并保留在上下文中,供步骤 4 和 5 使用(总评分、各目录评级、评级最低的文件、主要异味、复杂度最高的文件)。
步骤 3:加载参考资料

开始分析前,阅读相关参考文件:

  • references/code_smells.md - 需要识别的代码异味模式
  • references/testing_guidelines.md - 测试最佳实践
  • references/poro_patterns.md - PORO 和 ActiveModel 模式
  • references/security_checklist.md - 安全漏洞模式
  • references/rails_antipatterns.md - Rails 专属反模式(外部服务、迁移、性能)
第 4 步:按类别分析代码

所有分析都必须限制在项目根目录和 bundle 路径内。要检查 gem 源码,请使用 bundle show <gem> 定位(参见 Analysis Commands 下的“Locate gem source”)——切勿运行 find / 等全文件系统搜索。如果将以下任何类别委派给子 Agent,请在每个子 Agent 的提示词中注明此限制。

按以下顺序分析:

  1. 测试覆盖率与质量

    • 如果在第 2 步收集了 SimpleCov 数据,请使用实际覆盖率百分比,而非估算值
    • 交叉核对每个文件的 SimpleCov 数据:覆盖率为 0% 的文件 =“缺少测试”
    • 检查是否缺少测试文件
    • 找出未经测试的公共方法
    • 检查测试结构(四阶段测试)
    • 检查测试反模式
  2. 安全漏洞

    • SQL 注入风险
    • 批量赋值漏洞
    • XSS 漏洞
    • 身份验证/授权问题
    • 敏感数据泄露
  3. 模型与数据库

    • 检测臃肿模型
    • 缺少验证
    • N+1 查询风险
    • 回调复杂度
    • 违反迪米特法则(窥视型模型)
    • 如果收集了 RubyCritic 数据,标记评级为 D/F 或复杂度较高的模型
  4. 控制器

    • 检测臃肿控制器
    • 控制器中的业务逻辑
    • 缺少强参数
    • 响应处理
    • 单体控制器(非 RESTful 操作、操作数 > 7)
    • 臃肿的会话(存储对象而非 ID)
    • 如果收集了 RubyCritic 数据,标记评级为 D/F 或复杂度较高的控制器
  5. 代码设计与架构

    • 服务对象 → 建议重构为 PORO
    • 类过大
    • 方法过长
    • 特性嫉妒
    • 违反迪米特法则
    • 违反单一职责原则
    • 如果收集了 RubyCritic 数据,将评级为 D/F 或复杂度较高的文件与人工代码审查结果交叉核对
  6. 视图与 Presenter

    • 视图中的逻辑(PHPitis)
    • 缺少用于 DRY 的局部视图
    • 助手复杂度
    • 视图中的查询逻辑
  7. 外部服务与错误处理

    • 发后不管(HTTP 调用缺少异常处理)
    • 响应迟缓的服务(缺少超时设置、应放到后台处理却仍同步执行的调用)
    • 裸 rescue 语句
    • 静默失败(保存时未检查返回值)
  8. 数据库与迁移

    • 混乱的迁移(引用模型、缺少 down 方法)
    • 外键、多态关联、唯一性验证缺少索引
    • 性能反模式(使用 Ruby 迭代而非 SQL 查询)
    • 未使用事务的批量操作
第 5 步:生成审计报告

在项目根目录创建 RAILS_AUDIT_REPORT.md,结构按照 references/report_template.md 中的定义。

如果在第 2 步收集了 SimpleCov 覆盖率数据,请在报告中使用测试部分的 SimpleCov 变体。如果没有覆盖率数据,请使用估算变体。

如果在第 2b 步收集了 RubyCritic 数据,请在报告中使用报告模板中的 RubyCritic 变体,并包含 代码质量指标部分。如果没有 RubyCritic 数据,请使用不可用变体。

严重程度定义

  • 严重:安全漏洞、数据丢失风险、会导致生产环境故障的问题
  • 高:性能问题、关键路径缺少测试、重大代码异味
  • 中:代码异味、违反约定、可维护性问题
  • 低:风格问题、细微改进、建议

关键检测模式

服务对象 → PORO 重构

当你在 app/services/ 中发现类时:

  • 名称为 *Service、*Manager、*Handler 的类
  • 仅有 .call 或 .perform 方法的类
  • 建议:重命名为领域名词,并包含 ActiveModel::Model
臃肿模型检测

符合以下情况的模型:

  • 超过 200 行
  • 超过 15 个公共方法
  • 承担多项互不相关的职责
  • 建议:使用组合方式提取为 PORO
臃肿控制器检测

控制器存在以下情况时:

  • 操作超过 15 行
  • 包含业务逻辑(而非请求/响应处理)
  • 多次赋值实例变量
  • 建议:提取为表单对象或领域模型
缺少测试检测

对于 app/ 中的每个 Ruby 文件:

  • 检查是否有对应的 _spec.rb 或 _test.rb
  • 检查公共方法是否经过测试
  • 报告未测试的文件和方法

分析命令

使用 Claude Code 的内置工具,而非 shell 命令——它们速度更快、能正确处理权限,并且输出效果更好:

  • 按类型查找 Ruby 文件:使用 Glob 工具和 app/models/**/*.rb、app/controllers/**/*.rb、app/services/**/*.rb 等模式
  • 查找测试文件:使用 Glob 工具和 spec/**/*_spec.rb 或 test/**/*_test.rb
  • 搜索代码中的模式:使用 Grep 工具(例如搜索 rescue\s*$、\.save\b、params\.permit!)
  • 读取文件并统计行数:使用 Read 工具检查文件;根据输出统计行数
  • 查找较长的文件:使用 Glob 列出所有 app/**/*.rb 文件,然后逐个使用 Read 检查行数
  • 定位 gem 源码:当分析需要读取 gem 提供的代码(例如来自 Devise、Administrate 或 Madmin 等引擎的基础控制器或 concern)时,使用 bundle show <gem>(或 bundle exec gem which <gem>/<path>)查找已安装 gem 的目录,然后在其中使用 Read/Grep。切勿在项目根目录和 bundle 路径之外搜索——不要使用 find / 或覆盖整个主目录的 glob。

报告输出

始终将审计报告保存到项目根目录下的 RAILS_AUDIT_REPORT.md,并提供给用户。

评论

支持 Markdown