mcpField
C
code-review

code-review

github.com/serac-labs测试与质量7758 次安装9 周前更新
代码仓库

关于 code-review

面向 ServiceNow 开发者的服务端代码审查技能,适用于 Business Rules、Script Includes 和 Scheduled Jobs。它按严重级别检查 JavaScript 兼容性、安全、性能与代码质量问题。

主要功能

  1. 01检查 ES5 兼容性
  2. 02识别注入、XSS 与访问控制风险
  3. 03审查查询和 GlideRecord 性能
  4. 04检查错误处理与日志
  5. 05检查 Business Rule 递归和规则类型

适用场景

  1. 01部署前审查 Business Rule
  2. 02检查 Script Include 的注入风险
  3. 03查找无界或重复的数据库查询

安装

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

$npx skills add https://github.com/serac-labs/serac --skill code-review

安装后在 Claude Code 中输入/code-review确认已加载。

详细介绍

ServiceNow 代码审查清单

使用此清单审查 ServiceNow 服务端代码(业务规则、脚本包含项、计划作业等)。

1. ES5 合规性(严重)

// CHECK FOR THESE ES6+ VIOLATIONS:
const x = 5;           // ❌ Use var
let items = [];        // ❌ Use var
() => {}               // ❌ Use function()
`template ${var}`      // ❌ Use 'string ' + var
for (x of arr)         // ❌ Use traditional for loop
{a, b} = obj           // ❌ Use obj.a, obj.b

操作: 将所有 ES6+ 语法标记为严重错误。

2. 安全问题

2.1 SQL/GlideRecord 注入
// ❌ DANGEROUS - User input directly in query
gr.addEncodedQuery(userInput)
gr.addQuery("field", userInput) // OK if validated

// ✅ SAFE - Validate and sanitize
var safeInput = new GlideSysAttachment().cleanFileName(userInput)
gr.addQuery("field", safeInput)
2.2 跨站脚本(XSS)
// ❌ DANGEROUS - Unescaped output
gs.addInfoMessage(userInput)

// ✅ SAFE - Escape HTML
gs.addInfoMessage(GlideStringUtil.escapeHTML(userInput))
2.3 访问控制
// ❌ MISSING - No ACL check
var gr = new GlideRecord("sys_user")
gr.get(userProvidedSysId)

// ✅ SAFE - Check permissions
var gr = new GlideRecord("sys_user")
if (gr.get(userProvidedSysId) && gr.canRead()) {
  // Process record
}
2.4 敏感数据泄露
// ❌ DANGEROUS - Logging sensitive data
gs.info("Password: " + password)
gs.info("API Key: " + apiKey)

// ✅ SAFE - Never log credentials
gs.info("Authentication attempt for user: " + username)

3. 性能问题

3.1 循环中的查询
// ❌ SLOW - N+1 query problem
for (var i = 0; i < userIds.length; i++) {
  var gr = new GlideRecord("sys_user")
  gr.get(userIds[i]) // Query for each user!
}

// ✅ FAST - Single query
var gr = new GlideRecord("sys_user")
gr.addQuery("sys_id", "IN", userIds.join(","))
gr.query()
while (gr.next()) {}
3.2 缺少 setLimit()
// ❌ SLOW - Could return millions of records
var gr = new GlideRecord("incident")
gr.query()

// ✅ FAST - Limit results
var gr = new GlideRecord("incident")
gr.setLimit(1000)
gr.query()
3.3 不必要的查询
// ❌ WASTEFUL - Query just to check existence
var gr = new GlideRecord("incident")
gr.addQuery("number", incNumber)
gr.query()
if (gr.getRowCount() > 0) {
}

// ✅ EFFICIENT - Use get() for single record
var gr = new GlideRecord("incident")
if (gr.get("number", incNumber)) {
}
3.4 GlideRecord 与 GlideAggregate
// ❌ SLOW - Counting with loop
var count = 0
var gr = new GlideRecord("incident")
gr.addQuery("active", true)
gr.query()
while (gr.next()) count++

// ✅ FAST - Use GlideAggregate
var ga = new GlideAggregate("incident")
ga.addQuery("active", true)
ga.addAggregate("COUNT")
ga.query()
var count = ga.next() ? ga.getAggregate("COUNT") : 0

4. 代码质量问题

4.1 硬编码的 sys_id
// ❌ BAD - Hard-coded sys_id (breaks across instances)
var assignmentGroup = "681ccaf9c0a8016400b98a06818d57c7"

// ✅ GOOD - Use property or lookup
var assignmentGroup = gs.getProperty("my.default.assignment.group")
// OR
var gr = new GlideRecord("sys_user_group")
if (gr.get("name", "Service Desk")) {
  var assignmentGroup = gr.getUniqueValue()
}
4.2 魔法数字/字符串
// ❌ BAD - Magic numbers
if (current.state == 6) {
}
if (current.priority == 1) {
}

// ✅ GOOD - Named constants or comments
var STATE_RESOLVED = 6
var PRIORITY_CRITICAL = 1
if (current.state == STATE_RESOLVED) {
}
4.3 缺少错误处理
// ❌ BAD - No error handling
var response = request.execute()
var data = JSON.parse(response.getBody())

// ✅ GOOD - Proper error handling
try {
  var response = request.execute()
  var status = response.getStatusCode()
  if (status != 200) {
    gs.error("API call failed: " + status)
    return null
  }
  var data = JSON.parse(response.getBody())
} catch (e) {
  gs.error("Exception: " + e.message)
  return null
}
4.4 正确的日志记录
// ❌ BAD - No context in logs
gs.info("Error occurred")

// ✅ GOOD - Contextual logging
gs.info("[MyScriptInclude.process] Processing incident: " + current.number + ", user: " + gs.getUserName())

5. 业务规则专项

5.1 防止递归
// ❌ DANGEROUS - Can cause infinite loop
current.update() // In a Before rule

// ✅ SAFE - Use workflow control
current.setWorkflow(false)
current.update()
current.setWorkflow(true)
5.2 选择恰当的规则类型
// ❌ WRONG - Heavy processing in Before rule
// Before rules should be fast!

// ✅ RIGHT - Use Async for heavy operations
// Move integrations and heavy processing to Async rules

6. 审查输出格式

审查代码时,请按以下格式组织反馈:

## Code Review Summary

### Critical Issues (Must Fix)

1. [SECURITY] Description...
2. [ES5] Description...

### Performance Issues (Should Fix)

1. [PERF] Description...

### Code Quality (Nice to Have)

1. [QUALITY] Description...

### Positive Observations

- Good use of...
- Well-structured...

7. 严重级别

级别操作示例
CRITICAL部署前必须修复安全漏洞、ES6 语法
HIGH应当修复性能问题、缺少错误处理
MEDIUM建议修复代码质量、硬编码值
LOW可考虑修复风格、细微改进

评论

支持 Markdown