From ef13ea1e9029b02961d5a16ffdc7add59f2c56da Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Oct 2025 14:59:33 -0700 Subject: [PATCH] added VA topic coverage checker --- .../AI Search Usage Analytics/script.js | 0 .../MOCK_DATA.md | 89 +++++++++++++++ .../README.md | 27 +++++ .../script.js | 106 ++++++++++++++++++ 4 files changed, 222 insertions(+) create mode 100644 Server-Side Components/Background Scripts/AI Search Usage Analytics/script.js create mode 100644 Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/MOCK_DATA.md create mode 100644 Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/README.md create mode 100644 Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/script.js diff --git a/Server-Side Components/Background Scripts/AI Search Usage Analytics/script.js b/Server-Side Components/Background Scripts/AI Search Usage Analytics/script.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/MOCK_DATA.md b/Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/MOCK_DATA.md new file mode 100644 index 0000000000..8b4b44999e --- /dev/null +++ b/Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/MOCK_DATA.md @@ -0,0 +1,89 @@ +# Mock Data Seeder for VA Topic Coverage Report + +Use this script to create test data for the Virtual Agent Topic Coverage Report. + +## Mock Data Script + +Run this in **System Definition → Scripts - Background** to create test topics: + +```javascript +// Generate mock VA topics for testing Topic Coverage Report +// Creates topics with various states (active/inactive, published/unpublished) + +(function() { + var TEST_TOPICS = [ + {name: 'Password Reset Help', active: true, published: true, hasConversations: true, count: 15}, + {name: 'VPN Access Request', active: true, published: true, hasConversations: true, count: 8}, + {name: 'Laptop Request', active: true, published: true, hasConversations: false, count: 0}, + {name: 'Printer Support', active: true, published: false, hasConversations: false, count: 0}, + {name: 'Email Issues', active: false, published: true, hasConversations: false, count: 0}, + {name: 'Test Topic Draft', active: false, published: false, hasConversations: false, count: 0} + ]; + + var topicGr = new GlideRecord('sys_cs_topic'); + if (!topicGr.isValid()) { + gs.error('Table sys_cs_topic not found. Virtual Agent may not be installed.'); + return; + } + + // Auto-detect conversation field + var convGr = new GlideRecord('sys_cs_conversation'); + var topicField = null; + if (convGr.isValid()) { + topicField = convGr.isValidField('topic') ? 'topic' : + (convGr.isValidField('selected_topic') ? 'selected_topic' : null); + } + + gs.info('Creating ' + TEST_TOPICS.length + ' test VA topics...'); + + for (var i = 0; i < TEST_TOPICS.length; i++) { + var topic = TEST_TOPICS[i]; + + // Check if topic already exists + topicGr.initialize(); + topicGr.addQuery('name', topic.name); + topicGr.setLimit(1); + topicGr.query(); + + var topicId; + if (topicGr.next()) { + topicId = topicGr.getUniqueValue(); + gs.info('Topic already exists: ' + topic.name); + } else { + // Create new topic + topicGr.initialize(); + topicGr.setValue('name', topic.name); + if (topicGr.isValidField('short_description')) { + topicGr.setValue('short_description', 'Test topic for coverage report'); + } + topicGr.setValue('active', topic.active); + topicGr.setValue('published', topic.published); + topicId = topicGr.insert(); + gs.info('Created topic: ' + topic.name + ' (active: ' + topic.active + ', published: ' + topic.published + ')'); + } + + // Create conversations if needed + if (topic.hasConversations && topicField && topicId) { + for (var j = 0; j < topic.count; j++) { + convGr.initialize(); + convGr.setValue(topicField, topicId); + if (convGr.isValidField('state')) convGr.setValue('state', 2); // closed + convGr.insert(); + } + gs.info(' Created ' + topic.count + ' conversations for: ' + topic.name); + } + } + + gs.info('\n=== Mock Data Complete ==='); + gs.info('Run the Virtual Agent Topic Coverage Report to see results!'); +})(); +``` + +## Expected Output + +After running the mock data seeder, your coverage report should show: + +- **Total Topics**: 6 +- **Inactive Topics**: 2 (Email Issues, Test Topic Draft) +- **Unpublished Topics**: 2 (Printer Support, Test Topic Draft) +- **Topics with Zero Usage**: 1 (Laptop Request - active & published but no conversations) \ No newline at end of file diff --git a/Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/README.md b/Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/README.md new file mode 100644 index 0000000000..b81cc30eaa --- /dev/null +++ b/Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/README.md @@ -0,0 +1,27 @@ +# Virtual Agent Topic Coverage Report + +A background script that analyzes Virtual Agent topic configuration health by identifying inactive, unpublished, or unused topics. + +## Usage + +1. Navigate to **System Definition → Scripts - Background** +2. Copy and paste the script content +3. (Optional) Modify `daysBack` variable to set the usage analysis timeframe (default: 30 days) +4. Click "Run script" + +## What It Does + +The script: +1. Queries all Virtual Agent topics in the system +2. Checks each topic's active and published status +3. Counts conversations per topic over the past 30 days (configurable) +4. Displays inactive topics, unpublished topics, and zero-usage topics +5. Helps identify topics that need attention before go-live or during health checks + +## Report Categories + +**Inactive Topics**: Topics where the "Active" checkbox is unchecked. These topics are disabled and won't respond to user inputs even if published. + +**Unpublished Topics**: Topics where the "Published" checkbox is unchecked. These are draft topics not yet available to end users. + +**Topics with Zero Usage**: Topics that are both active and published but have had no conversations in the specified timeframe. May indicate topics that need better training phrases or are not discoverable by users. \ No newline at end of file diff --git a/Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/script.js b/Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/script.js new file mode 100644 index 0000000000..663b114139 --- /dev/null +++ b/Server-Side Components/Background Scripts/Virtual Agent Topic Coverage Report/script.js @@ -0,0 +1,106 @@ +// Virtual Agent Topic Coverage Report +// Analyzes VA topic configuration health and usage patterns + +var daysBack = 30; // Analyze topic usage from the past 30 days + +// Calculate date range for usage analysis +var startDate = new GlideDateTime(); +startDate.addDaysLocalTime(-daysBack); + +gs.info('=== Virtual Agent Topic Coverage Report ==='); +gs.info('Analyzing topics and usage from: ' + startDate.getDisplayValue()); + +// Get all VA topics +var topicGr = new GlideRecord('sys_cs_topic'); +if (!topicGr.isValid()) { + gs.warn('Table sys_cs_topic not found. Virtual Agent may not be installed.'); +} else { + topicGr.query(); + + var totalTopics = topicGr.getRowCount(); + gs.info('Total Topics: ' + totalTopics); + + var inactiveTopics = []; + var unpublishedTopics = []; + var zeroUsageTopics = []; + var topicUsage = {}; + + // Auto-detect conversation table field name + var convGr = new GlideRecord('sys_cs_conversation'); + var topicField = null; + if (convGr.isValid()) { + topicField = convGr.isValidField('topic') ? 'topic' : + (convGr.isValidField('selected_topic') ? 'selected_topic' : null); + } + + while (topicGr.next()) { + var topicId = topicGr.getUniqueValue(); + var topicName = topicGr.getValue('name'); + var isActive = topicGr.getValue('active') == 'true' || topicGr.getValue('active') == '1'; + var isPublished = topicGr.getValue('published') == 'true' || topicGr.getValue('published') == '1'; + + // Track inactive topics + if (!isActive) { + inactiveTopics.push(topicName); + } + + // Track unpublished topics + if (!isPublished) { + unpublishedTopics.push(topicName); + } + + // Count conversations for this topic (if conversation table exists) + var conversationCount = 0; + if (topicField) { + var convCountGr = new GlideAggregate('sys_cs_conversation'); + convCountGr.addQuery(topicField, topicId); + convCountGr.addQuery('sys_created_on', '>=', startDate); + convCountGr.addAggregate('COUNT'); + convCountGr.query(); + if (convCountGr.next()) { + conversationCount = parseInt(convCountGr.getAggregate('COUNT')) || 0; + } + } + + topicUsage[topicName] = conversationCount; + + // Track topics with zero usage + if (isActive && isPublished && conversationCount === 0) { + zeroUsageTopics.push(topicName); + } + } + + // Display results + gs.info('\n=== Inactive Topics ==='); + if (inactiveTopics.length > 0) { + for (var i = 0; i < inactiveTopics.length; i++) { + gs.info((i + 1) + '. ' + inactiveTopics[i]); + } + } else { + gs.info('No inactive topics found'); + } + + gs.info('\n=== Unpublished Topics ==='); + if (unpublishedTopics.length > 0) { + for (var j = 0; j < unpublishedTopics.length; j++) { + gs.info((j + 1) + '. ' + unpublishedTopics[j]); + } + } else { + gs.info('No unpublished topics found'); + } + + gs.info('\n=== Topics with Zero Usage (Active & Published) ==='); + if (zeroUsageTopics.length > 0) { + for (var k = 0; k < zeroUsageTopics.length; k++) { + gs.info((k + 1) + '. ' + zeroUsageTopics[k]); + } + } else { + if (topicField) { + gs.info('All active & published topics have been used'); + } else { + gs.info('Cannot analyze usage - conversation table not available'); + } + } +} + +gs.info('\n=== Analysis Complete ==='); \ No newline at end of file