mcpField
B
business-rule-patterns

business-rule-patterns

github.com/serac-labs开发7764 次安装9 周前更新
代码仓库

关于 business-rule-patterns

面向 ServiceNow 开发者的业务规则模式技能,讲解规则时机、记录操作和字段变更检测,并提供性能与常见模式建议。

主要功能

  1. 01区分 Before、After、Async 和 Display
  2. 02使用 current 与 previous 处理记录
  3. 03检测字段变化并设置运行条件
  4. 04提供自动分配和级联更新模式
  5. 05优化规则性能

适用场景

  1. 01验证记录并自动填写字段
  2. 02在记录更新后创建关联记录
  3. 03将耗时集成放到后台处理

安装

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

$npx skills add https://github.com/serac-labs/serac --skill business-rule-patterns

安装后在 Claude Code 中输入/business-rule-patterns确认已加载。

详细介绍

ServiceNow 业务规则最佳实践

业务规则是在显示、插入、更新或删除记录时执行的服务器端脚本。

各类型的适用场景

类型时机使用场景性能影响
Before写入数据库之前验证、修改当前记录低
After写入数据库之后创建相关记录、发送通知中
Async后台(提交后)耗时处理、集成无(在后台运行)
Display表单加载时修改表单显示、设置默认值低

可用对象

// In Business Rules, these are always available:
current // The record being operated on
previous // The record BEFORE changes (update/delete only)
gs // GlideSystem utilities

Before 业务规则

用于验证和字段操作:

// Prevent update if condition not met
;(function executeRule(current, previous) {
  if (current.state == 7 && previous.state != 6) {
    current.setAbortAction(true)
    gs.addErrorMessage("Must resolve before closing")
  }
})(current, previous)
// Auto-populate fields
;(function executeRule(current, previous) {
  if (current.isNewRecord()) {
    current.setValue("caller_id", gs.getUserID())
    current.setValue("opened_by", gs.getUserID())
  }
})(current, previous)

Before 规则中切勿执行以下操作:

  • 调用 current.update()(会导致递归!)
  • 查询其他表(保持执行快速)
  • 调用外部 API

After 业务规则

用于处理相关记录:

// Create child record when priority is P1
;(function executeRule(current, previous) {
  if (current.priority.changesTo(1)) {
    var task = new GlideRecord("task")
    task.initialize()
    task.setValue("short_description", "P1 Follow-up: " + current.number)
    task.setValue("parent", current.sys_id)
    task.insert()
  }
})(current, previous)
// Update parent record
;(function executeRule(current, previous) {
  var parent = new GlideRecord("problem")
  if (parent.get(current.problem_id)) {
    parent.setValue("related_incidents", parent.related_incidents + 1)
    parent.update()
  }
})(current, previous)

Async 业务规则

用于不应阻塞事务的耗时处理:

// External integration
;(function executeRule(current, previous) {
  var integrator = new ExternalSystemIntegration()
  integrator.syncIncident(current.sys_id)
})(current, previous)
// Send custom notification
;(function executeRule(current, previous) {
  gs.eventQueue("incident.priority.high", current, current.assigned_to, gs.getUserID())
})(current, previous)

实用方法

current 方法
current.isNewRecord() // True if insert
current.isValidRecord() // True if record exists
current.getValue("field") // Get field value
current.setValue("field", val) // Set field value
current.setAbortAction(true) // Cancel the operation
current.operation() // 'insert', 'update', 'delete'
current.isActionAborted() // Check if aborted
字段变更检测
current.priority.changes() // Field changed (any value)
current.priority.changesTo(1) // Changed TO this value
current.priority.changesFrom(3) // Changed FROM this value
current.priority.nil() // Field is empty
previous 比较
// Check if field was modified
if (current.state != previous.state) {
  gs.info("State changed from " + previous.state + " to " + current.state)
}

// Check specific change
if (current.assigned_to.changes() && !previous.assigned_to.nil()) {
  gs.info("Reassignment occurred")
}

条件示例

使用条件限制规则的运行时机:

条件含义
current.active == true仅处理活动记录
current.isNewRecord()仅在插入时运行
current.priority.changes()仅在优先级变更时运行
gs.hasRole('admin')仅对管理员运行
current.assignment_group.nil()仅在未分配时运行

性能最佳实践

  1. 使用条件 - 限制规则的运行时机
  2. 保持 Before 规则快速 - 尽可能不执行查询
  3. 集成使用 Async - 不要阻塞事务
  4. 避免使用 Display 规则 - 会减慢表单加载速度
  5. 设置 Order - 数值越小越先运行(范围为 100-500)
  6. 检查“何时运行” - 插入、更新、删除、查询

常见模式

自动分配
// Before Insert/Update
if (current.assignment_group.changes() && !current.assignment_group.nil()) {
  var members = new GroupMembers(current.assignment_group)
  current.assigned_to = members.getNextAvailable()
}
级联更新
// After Update
if (current.state.changesTo(7)) {
  // Closed
  var tasks = new GlideRecord("task")
  tasks.addQuery("parent", current.sys_id)
  tasks.addQuery("state", "!=", 7)
  tasks.query()
  while (tasks.next()) {
    tasks.setValue("state", 7)
    tasks.update()
  }
}

评论

支持 Markdown