Skip to content

Conversation

@vhudlikar
Copy link
Contributor

This is a Action that returns a record’s full hierarchy path (parents and/or children) which is part of the feature #100

Inputs needed for this action.

Input Label Name (Internal) Type Description Required
Table Name table_name String The table containing the hierarchy (e.g., sys_user_group). Yes
Record Sys ID record_sys_id String The Sys ID of the starting record for traversal (e.g., G0005). Yes
Parent Field Name parent_field String The reference field on the table that defines the hierarchy (e.g., parent). Yes
Direction direction Choice Traversal direction: Ancestors (up) or Descendants (down). Yes
Maximum Depth u_max_depth Integer Maximum level of recursion to prevent excessive runtime (e.g., 10). No

Logic

  1. Validate All Inputs (Pre-Check): Before initiating any database traversal, the action rigorously checks that the Table Name, Record Sys ID, and Parent Field are valid and exist in the system dictionary. If any mandatory input is invalid (e.g., misspelled table or non-existent record), the action immediately sets the status to FAILURE and terminates execution, providing a detailed error message.
  2. Initialize Traversal & Cycle Prevention: The script initializes the hierarchy array (to collect all found records) and the visitedSysIds hash map. The hash map is critical for recording every sys_id encountered during a path to ensure that circular references (infinite loops) are instantly detected and prevented.
  3. Execute Directional Recursive Search: Based on the Direction input (Ancestors or Descendants), the script executes the appropriate recursive search function. This function uses the Maximum Depth limit to prevent runaway operations:
    • Ancestors: Starts at the parent of the input record and recursively traverses up by following the parent field until it reaches the root (no parent).
    • Descendants: Starts at the input record and recursively traverses down by executing a GlideRecord query to find all child records that reference the current record's sys_id in their parent field.
  4. Post-Process & Path Construction: Once the recursive traversal completes, the collected hierarchy array is post-processed:
    • The records are ordered (e.g., Root ➡️ Leaf for ancestors).
    • The full path string (Root ➡️ Node ➡️ Record) is calculated and added to each record's data object, correctly handling branching paths found in descendants.
  5. Deliver Results & Status: The final, structured hierarchy array is converted to a JSON text string for the u_hierarchy_array output. The action reports the final status (SUCCESS or FAILURE), and the u_breadcrumb_string output is populated with a clean, newline-separated list of all unique traversal paths found.

Output

  • This Action provides a complete hierarchy traversal report, detailing the lineage of the requested record:
    • Hierarchy Array String: Delivers the full record lineage (Ancestors or Descendants) as a JSON String, ready for the JSON Parser. Each record includes its sys_id, name, calculated depth, and the full path string from the starting node.
    • Full Breadcrumb String: Provides a clean, newline-separated string listing all unique traversal paths found, clearly illustrating any branching hierarchy. This string will contain the VALIDATION FAILURE or RUNTIME ERROR message if the traversal was unsuccessful.
    • Success Status: Reports the final Action Status (SUCCESS or FAILURE) based on the input validation and script execution integrity.

Testing Result
For testing I have utilized Groups [sys_user_group].

Group Name sys_id Parent Field (sys_id it references) Description
Global IT Leadership G0001 (blank) Root of the hierarchy.
IT Infrastructure G0002 G0001 Parent for all technical operations.
Server & Cloud Team G0003 G0002 Manages core infrastructure.
DB Administration G0004 G0002 Sibling branch to G0003.
Linux Sub-Group G0005 G0003 Deepest node in the primary branch.
CIRCULAR TEST GROUP G0006 G0005 Child of G0005, used for circular test.
Hypothetical G0007 G0006 Child of G0006 (Forms a loop with G0005 for testing).
Test ID Test Scenario (Type) Input Condition Expected Result (Full Breadcrumb String) Expected Result (Success Status) Expected Hierarchy Array String
POS-01 Success: Descendants Traversal table_name: sys_user_group, record_sys_id: G0001, direction: Descendants, parent_field: parent This is a newline-separated string listing all distinct paths found true JSON String of 5 Objects (Descendants)
POS-02 Success: Ancestors Traversal table_name: sys_user_group, record_sys_id: G0005, direction: Ancestors, parent_field: parent Single full path listed: G0001→G0002→G0003→G0005. true JSON string containing 4 objects ordered Root → Start Node.
POS-03 Success: Max Depth Limit table_name: sys_user_group, record_sys_id: G0001, direction: Descendants, Max Depth: 1 Paths for direct children only (e.g., G0001 -> G0002; G0001 -> G0004). true JSON string containing only objects at depth=1.
POS-04 Success: Circular Reference Check table_name: sys_user_group, record_sys_id: G0003, direction: Descendants (Cycle Check) The traversal path stops immediately before repeating a Sys ID (loop detection). true JSON string showing records up to the point of loop detection.
NEG-01 Failure: Invalid Table table_name: sy_use_grou, record_sys_id: G0001, direction: Descendants, parent_field: parent VALIDATION FAILED: Table 'sy_use_grou' does not exist or is not accessible. false [ ]
NEG-02 Failure: Invalid Record Sys ID table_name: sys_user_group, record_sys_id: wrong, direction: Descendants, parent_field: parent VALIDATION FAILED: Record with sys_id 'wrong' not found in table 'sys_user_group'. false [ ]
NEG-03 Failure: Invalid Parent Field table_name: sys_user_group, record_sys_id: G0001, direction: Descendants, parent_field: u_non_existent_field VALIDATION FAILED: Parent field 'u_non_existent_field' does not exist on table 'sys_user_group'. false [ ]

NOTE
This Action, "Get Record Hierarchy Path," was created within the scoped application "Action Pack."
If this action is used on tables that reside outside of this scope (e.g., Global tables like incident, sys_user_group, or tables in another custom scope), it will fail due to cross-scope security restrictions unless a policy is explicitly defined.

@github-actions
Copy link

github-actions bot commented Oct 8, 2025

Valid PR for ActionPack

Thank you for your contribution. This PR complies with the CONTRIBUTING.md.
A maintainer will review this shortly. In the meantime, Happy Hacking!

@rohi-v rohi-v self-assigned this Oct 8, 2025
@rohi-v
Copy link
Contributor

rohi-v commented Oct 8, 2025

Hii @vhudlikar

Approved, Thank you for your contribution.

Enhancment - We can enhance this more by changing Table name to type 'Table Name' instead of string so that way we can skip the table validation.

@rohi-v rohi-v merged commit d21b981 into ServiceNowDevProgram:main Oct 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants