business-rule-patterns

Business Rule Best Practices for ServiceNow

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "business-rule-patterns" with this command: npx skills add groeimetai/snow-flow/groeimetai-snow-flow-business-rule-patterns

Business Rule Best Practices for ServiceNow

Business Rules are server-side scripts that execute when records are displayed, inserted, updated, or deleted.

When to Use Each Type

Type Timing Use Case Performance Impact

Before Before database write Validate, modify current record Low

After After database write Create related records, notifications Medium

Async Background (after commit) Heavy processing, integrations None (background)

Display When form loads Modify form display, set defaults Low

Available Objects

// 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 Business Rules

Use for validation and field manipulation:

// 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)

Never do in Before rules:

  • Call current.update() (causes recursion!)

  • Query other tables (keep it fast)

  • External API calls

After Business Rules

Use for related record operations:

// 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 Business Rules

Use for heavy processing that shouldn't block the transaction:

// 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)

Useful Methods

current Methods

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

Field Change Detection

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 Comparisons

// 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") }

Condition Examples

Use conditions to limit when the rule runs:

Condition Meaning

current.active == true

Only active records

current.isNewRecord()

Only on insert

current.priority.changes()

Only when priority changes

gs.hasRole('admin')

Only for admins

current.assignment_group.nil()

Only when unassigned

Performance Best Practices

  • Use conditions - Limit when the rule runs

  • Keep Before rules fast - No queries if possible

  • Use Async for integrations - Don't block transactions

  • Avoid Display rules - Slows form load

  • Set Order - Lower numbers run first (100-500 range)

  • Check "when to run" - insert, update, delete, query

Common Patterns

Auto-Assignment

// Before Insert/Update if (current.assignment_group.changes() && !current.assignment_group.nil()) { var members = new GroupMembers(current.assignment_group) current.assigned_to = members.getNextAvailable() }

Cascade Updates

// 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() } }

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

predictive-intelligence

No summary provided by upstream source.

Repository SourceNeeds Review
General

scheduled-jobs

No summary provided by upstream source.

Repository SourceNeeds Review
General

document-management

No summary provided by upstream source.

Repository SourceNeeds Review
General

reporting-dashboards

No summary provided by upstream source.

Repository SourceNeeds Review