Skip to content
data-policies logo

Data Policies & Dictionary for ServiceNow

data-policies

Manage ServiceNow dictionary (sys_dictionary), table/field creation, choice lists, dictionary overrides, and sys_data_policy2 rules that enforce mandatory/read-only/visible field behavior on the data layer.

groeimetai/snow-flow0installs78stars

SKILL.md

Full skill instructions

Data Policies & Dictionary for ServiceNow

Data Policies enforce data integrity rules. Dictionary controls schema and field behavior.

Architecture

Dictionary (sys_dictionary)
    ├── Field Definition
    │   ├── Type, Length, Default
    │   └── Dependent Field
    └── Dictionary Overrides (sys_dictionary_override)

Data Policy (sys_data_policy2)
    └── Data Policy Rules (sys_data_policy_rule)
        └── Condition-based field behaviors

Key Tables

TablePurpose
sys_dictionaryField definitions
sys_dictionary_overrideScoped overrides
sys_data_policy2Data policies
sys_data_policy_rulePolicy rules
sys_db_objectTable definitions

Dictionary Management (ES5)

Create Table

// Create custom table (ES5 ONLY!)
var table = new GlideRecord("sys_db_object")
table.initialize()

table.setValue("name", "u_custom_table")
table.setValue("label", "Custom Table")
table.setValue("super_class", "task") // Extends task
table.setValue("is_extendable", true)
table.setValue("create_access_controls", true)
table.setValue("live_feed_enabled", false)

table.insert()

Create Field

// Create field on table (ES5 ONLY!)
var field = new GlideRecord("sys_dictionary")
field.initialize()

// Table and element
field.setValue("name", "u_custom_table")
field.setValue("element", "u_customer_name")

// Field properties
field.setValue("column_label", "Customer Name")
field.setValue("internal_type", "string")
field.setValue("max_length", 100)
field.setValue("mandatory", false)
field.setValue("read_only", false)
field.setValue("display", false)
field.setValue("active", true)

// Default value
field.setValue("default_value", "")

// Reference field specific
// field.setValue('reference', 'customer_account');
// field.setValue('reference_qual', 'active=true');

field.insert()

Field Types

// Common field types
var FIELD_TYPES = {
  STRING: "string",
  INTEGER: "integer",
  DECIMAL: "decimal",
  BOOLEAN: "boolean",
  GLIDE_DATE: "glide_date",
  GLIDE_DATE_TIME: "glide_date_time",
  REFERENCE: "reference",
  CHOICE: "choice",
  JOURNAL: "journal",
  JOURNAL_INPUT: "journal_input",
  HTML: "html",
  URL: "url",
  EMAIL: "email",
  SCRIPT: "script",
  CONDITIONS: "conditions",
}

// Create different field types (ES5 ONLY!)
function createField(tableName, fieldDef) {
  var field = new GlideRecord("sys_dictionary")
  field.initialize()
  field.setValue("name", tableName)
  field.setValue("element", fieldDef.name)
  field.setValue("column_label", fieldDef.label)
  field.setValue("internal_type", fieldDef.type)

  if (fieldDef.maxLength) {
    field.setValue("max_length", fieldDef.maxLength)
  }

  if (fieldDef.reference) {
    field.setValue("reference", fieldDef.reference)
  }

  if (fieldDef.choices) {
    field.setValue("choice", 1) // Has choices
  }

  return field.insert()
}

Create Choices

// Create choice list values (ES5 ONLY!)
function createChoices(tableName, fieldName, choices) {
  for (var i = 0; i < choices.length; i++) {
    var choice = new GlideRecord("sys_choice")
    choice.initialize()
    choice.setValue("name", tableName)
    choice.setValue("element", fieldName)
    choice.setValue("value", choices[i].value)
    choice.setValue("label", choices[i].label)
    choice.setValue("sequence", (i + 1) * 10)
    choice.setValue("inactive", false)
    choice.insert()
  }
}

// Usage
createChoices("incident", "u_custom_status", [
  { value: "pending", label: "Pending Review" },
  { value: "approved", label: "Approved" },
  { value: "rejected", label: "Rejected" },
])

Dictionary Overrides (ES5)

Create Override

// Create dictionary override for scoped app (ES5 ONLY!)
var override = new GlideRecord("sys_dictionary_override")
override.initialize()

// Reference the base field
override.setValue("base_table", "task")
override.setValue("base_element", "short_description")

// Target table
override.setValue("name", "u_custom_table")

// Override properties
override.setValue("column_label", "Request Summary")
override.setValue("mandatory", true)
override.setValue("read_only", false)
override.setValue("max_length", 200)

// Default value override
override.setValue("default_value", "")

override.insert()

Data Policies (ES5)

Create Data Policy

// Create data policy (ES5 ONLY!)
var policy = new GlideRecord("sys_data_policy2")
policy.initialize()

policy.setValue("model_table", "incident")
policy.setValue("short_description", "Resolution Fields Required on Resolve")
policy.setValue("active", true)

// Conditions - when policy applies
policy.setValue("conditions", "state=6") // Resolved state

// Apply to forms
policy.setValue("apply_to_client", true)
policy.setValue("apply_to_import_sets", true)
policy.setValue("apply_to_soap", true)

// Reverse
policy.setValue("reverse_if_false", true)

var policySysId = policy.insert()

// Add policy rules
addDataPolicyRule(policySysId, "resolution_code", true, false, false)
addDataPolicyRule(policySysId, "close_notes", true, false, false)

Add Policy Rules

// Add data policy rule (ES5 ONLY!)
function addDataPolicyRule(policySysId, fieldName, mandatory, readOnly, hidden) {
  var rule = new GlideRecord("sys_data_policy_rule")
  rule.initialize()
  rule.setValue("sys_data_policy", policySysId)
  rule.setValue("field", fieldName)
  rule.setValue("mandatory", mandatory)
  rule.setValue("read_only", readOnly)
  rule.setValue("visible", !hidden)
  return rule.insert()
}

Complex Data Policy

// Data policy with scripted condition (ES5 ONLY!)
var policy = new GlideRecord("sys_data_policy2")
policy.initialize()

policy.setValue("model_table", "change_request")
policy.setValue("short_description", "High Risk Change Requirements")
policy.setValue("active", true)

// Use scripted condition for complex logic
policy.setValue("use_as_condition", true)
policy.setValue(
  "script",
  "(function checkCondition(current) {\n" +
    "    // High risk changes require additional fields\n" +
    '    if (current.risk == "high") {\n' +
    "        return true;\n" +
    "    }\n" +
    "    \n" +
    "    // Also apply to changes affecting critical CIs\n" +
    "    if (current.cmdb_ci) {\n" +
    "        var ci = current.cmdb_ci.getRefRecord();\n" +
    '        if (ci.business_criticality == "1 - most critical") {\n' +
    "            return true;\n" +
    "        }\n" +
    "    }\n" +
    "    \n" +
    "    return false;\n" +
    "})(current);",
)

var policySysId = policy.insert()

// Require additional documentation for high risk
addDataPolicyRule(policySysId, "implementation_plan", true, false, false)
addDataPolicyRule(policySysId, "backout_plan", true, false, false)
addDataPolicyRule(policySysId, "test_plan", true, false, false)
addDataPolicyRule(policySysId, "justification", true, false, false)

Field Validation (ES5)

Dictionary Attribute Validation

// Add validation to dictionary field (ES5 ONLY!)
var field = new GlideRecord("sys_dictionary")
if (field.get("name", "incident").get("element", "u_email")) {
  // Add regex validation
  field.setValue("attributes", "validate=email")
  field.update()
}

// Common validation attributes
var VALIDATION_ATTRIBUTES = {
  EMAIL: "validate=email",
  PHONE: "validate=phone_number",
  URL: "validate=url",
  CUSTOM: "validate=script", // Uses script in Calculated Value
}

Script Validation

// Calculated field with validation (ES5 ONLY!)
// Set in Dictionary > Calculated Value

// Check phone format
;(function calculate() {
  var phone = current.getValue("u_phone")
  if (!phone) return ""

  // Format validation
  var phonePattern = /^\+?[1-9]\d{1,14}$/
  if (!phonePattern.test(phone.replace(/[\s\-\(\)]/​g, ""))) {
    gs.addErrorMessage("Invalid phone number format")
    return ""
  }

  return phone
})()

Schema Queries (ES5)

Get Table Fields

// Get all fields for a table (ES5 ONLY!)
function getTableFields(tableName) {
  var fields = []

  var dict = new GlideRecord("sys_dictionary")
  dict.addQuery("name", tableName)
  dict.addQuery("internal_type", "!=", "collection")
  dict.addQuery("active", true)
  dict.orderBy("element")
  dict.query()

  while (dict.next()) {
    fields.push({
      name: dict.getValue("element"),
      label: dict.getValue("column_label"),
      type: dict.getValue("internal_type"),
      mandatory: dict.getValue("mandatory") === "true",
      reference: dict.getValue("reference"),
      maxLength: dict.getValue("max_length"),
    })
  }

  return fields
}

Check Field Exists

// Check if field exists on table (ES5 ONLY!)
function fieldExists(tableName, fieldName) {
  var dict = new GlideRecord("sys_dictionary")
  dict.addQuery("name", tableName)
  dict.addQuery("element", fieldName)
  dict.query()
  return dict.hasNext()
}

MCP Tool Integration

Available Tools

ToolPurpose
snow_query_tableQuery dictionary
snow_discover_table_fieldsGet field definitions
snow_execute_script_with_outputTest dictionary scripts
snow_find_artifactFind data policies

Example Workflow

// 1. Get table fields
await snow_discover_table_fields({
  table_name: "incident",
})

// 2. Query data policies
await snow_query_table({
  table: "sys_data_policy2",
  query: "model_table=incident^active=true",
  fields: "short_description,conditions,apply_to_client",
})

// 3. Check dictionary overrides
await snow_query_table({
  table: "sys_dictionary_override",
  query: "name=u_custom_table",
  fields: "base_element,column_label,mandatory,read_only",
})

Best Practices

  1. Schema Planning - Design before implementation
  2. Field Naming - u_ prefix for custom fields
  3. Data Types - Use appropriate types
  4. Mandatory Fields - Only when truly required
  5. Data Policies - Enforce business rules
  6. Performance - Avoid complex calculated fields
  7. Documentation - Document custom schema
  8. ES5 Only - No modern JavaScript syntax

More skills from groeimetai

reporting-dashboards logo
groeimetai/snow-flow

reporting-dashboards

Build ServiceNow reports (list/bar/pie/line/pivot/single-score) on sys_report, sys_dashboard layouts with widget placement, scheduled report delivery, and drill-down configuration.

78 0
View
rest-integration logo
groeimetai/snow-flow

rest-integration

Make outbound REST calls from ServiceNow with sn_ws.RESTMessageV2 — basic/bearer/OAuth/API-key auth, error handling by status code, response parsing, sys_rest_message records, and retry with exponential backoff.

78 0
View
mcp-tool-discovery logo
groeimetai/snow-flow

mcp-tool-discovery

Use tool_search to discover and enable lazy-loaded Serac MCP tools (snow_*, jira_*, github_*, etc). Explains naming conventions, search strategies, and always-available activity tools.

78 0
View
atf-testing logo
groeimetai/snow-flow

atf-testing

Build ServiceNow Automated Test Framework tests and suites — impersonation, form steps, assertions, server-side script steps, test parameters, and execution via snow_create_atf_test / snow_execute_atf_test.

78 0
View
import-export logo
groeimetai/snow-flow

import-export

Move data in and out of ServiceNow — CSV parsing into import sets, GlideImportSetTransformer runs, CSV/JSON/XML exports, scheduled data sources, bulk update and deleteMultiple safety patterns.

78 0
View
discovery-patterns logo
groeimetai/snow-flow

discovery-patterns

Configure ServiceNow Discovery — schedules, IP ranges, credential affinities, MID Server assignment, custom probes/sensors, identification rules, and run-status monitoring on discovery_* tables.

78 0
View
csm-patterns logo
groeimetai/snow-flow

csm-patterns

Build ServiceNow Customer Service Management — customer_account, customer_contact, sn_customerservice_case routing, service entitlements with usage decrement, and Customer Portal case submission widgets.

78 0
View
mobile-development logo
groeimetai/snow-flow

mobile-development

Configure ServiceNow Mobile (Now Mobile/Agent) — sys_sg_mobile_app screens, card builders, push notifications, offline sync rules, mobile actions for barcode/GPS, and offline-queue change processing.

78 0
View
email-notifications logo
groeimetai/snow-flow

email-notifications

Create ServiceNow sysevent_email_action notifications — templates with substitution variables, mail scripts for dynamic content/recipients/attachments, custom events, weights, and digest configuration.

78 0
View
es5-compliance logo
groeimetai/snow-flow

es5-compliance

Enforce ES5-only syntax for ServiceNow server-side scripts (Rhino engine) — convert const/let, arrow functions, template literals, destructuring, for-of, and async/await to ES5 equivalents.

78 0
View
asset-management logo
groeimetai/snow-flow

asset-management

Manage ServiceNow hardware assets, software licenses, and lifecycle states on alm_hardware/alm_license — license allocation, CMDB-to-asset linking, warranty tracking, inventory aggregation (HAM/SAM).

78 0
View
change-management logo
groeimetai/snow-flow

change-management

Create and transition ServiceNow change requests (normal/standard/emergency), change tasks, affected CIs, approval routing, CAB scheduling, and conflict detection across maintenance windows.

78 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View