Document aggregation for AI analysis
Configure and maintain the logic that gathers documents from the Document Management System (DMS) so the SAE can analyze them during assessments.
| Field | Description |
|---|---|
| Inputs | |
assessmentId |
Unique identifier for the assessment instance to analyze. This value is required. The logic stops with an error if it is not provided. |
| Processing context | |
| Assessment scope items |
Resolves scoped records for the assessment from
sn_smart_asmt_m2m_instance_scope_item and derives the source tables and records.
|
| Third‑party records | From each scoped record, collects related third‑party identifiers and uses them to locate associated documents. |
| DMS references |
Queries ds_document_references where table_name matches the third‑party table
and target_record is in the collected third‑party identifiers, then resolves the default document version.
|
| Document versions and files |
For each default version in ds_document_version, retrieves the stored file from
sys_attachment where table_name is ds_document_version
and table_sys_id is the version sys_id.
|
| Outputs | |
result.documents |
An array of document entries. Each entry includes:
|
result.errorStatus |
A boolean set only when an exception is detected. |
result.errorMessage |
Error description when result.errorStatus is true. On error, result.documents is empty.
|
| Usage and behavior | |
| When to run | Run when you need to assemble all DMS documents related to the third‑parties in scope of an assessment instance so those documents can be included in downstream analysis or AI‑assisted drafting. |
| Expected visibility | Ensure users have permission to the DMS document and its versions. Verify document sharing permissions before testing. |
| Safeguards |
Validates input and returns an error result when assessmentId is missing. Test changes in a sub‑production instance.
|
| Developer registration | |
| Where to register | Register as a Script Include callable from Flow Designer, a Subflow invoked by assessment automations, or an Action within an existing Subflow. Choose the option consistent with your automation pattern. |
| Invocation |
Pass the assessment instance sys_id to the entry point. Expect a result object with
documents, errorStatus, and errorMessage.
|
| Permissions | Confirm read access to scoped records, DMS references, document versions, and attachments for the execution context. |
| Performance |
The logic batches queries per table and uses indexed fields such as sys_id.
Maintain this approach to reduce query overhead in production.
|
Code listing
// Document aggregation for AI analysis
// PURPOSE: Gather all documents attached to an assessment for AI analysis
//
// HOW IT WORKS:
// 1. Get all the third-parties related to the assessment instance
// 2. Find documents in the Document Management repository for those third-parties
// 3. Get the actual file attachments for all documents
//
// INPUT: assessmentId - The unique identifier of the assessment instance being processed
// OUTPUT: result.documents - A list of documents found for this assessment
//
// RESULT SHAPE:
// result = {
// documents: [
// { sysAttachmentId: <sys_id>, sourceRecordTableName: <table>, sourceRecordId: <sys_id> },
// ...
// ],
// errorStatus: <boolean>,
// errorMessage: <string> | undefined
// }
(function executeAggregation() {
result.documents = [];
try {
if (!assessmentId) {
throw 'Assessment ID is required but was not provided';
}
// STEP 1: Resolve scoped records for the assessment instance
var vendorIds = [];
var recordTableMap = {};
var scopeItemRecords = new GlideRecord('sn_smart_asmt_m2m_instance_scope_item');
scopeItemRecords.addQuery('assessment_instance', assessmentId);
scopeItemRecords.query();
while (scopeItemRecords.next()) {
var tableName = String(scopeItemRecords.scope_item.table);
var recordId = String(scopeItemRecords.scope_item.record);
if (tableName && recordId) {
recordTableMap[recordId] = tableName;
}
}
// Group record sys_ids by table name for batched reads
var tableGroups = {};
for (var id in recordTableMap) {
var tbl = recordTableMap[id];
if (!tableGroups[tbl]) tableGroups[tbl] = [];
tableGroups[tbl].push(id);
}
// Resolve third-party ids from each table group
for (var tblName in tableGroups) {
var tblGr = new GlideRecord(tblName);
tblGr.addQuery('sys_id', 'IN', tableGroups[tblName].join(','));
tblGr.query();
while (tblGr.next()) {
if (tblGr.vendor) {
vendorIds.push(String(tblGr.vendor));
}
}
}
// STEP 2: Find DMS documents that reference those third-parties
var documentVersionIds = [];
var documentLookup = {};
if (vendorIds.length > 0) {
var docRef = new GlideRecord('ds_document_references');
docRef.addQuery('table_name', 'core_company'); // third-party table
docRef.addQuery('target_record', 'IN', vendorIds.join(','));
docRef.query();
while (docRef.next()) {
var versionId = String(docRef.document.default_version);
var targetRecord = docRef.getValue('target_record');
if (versionId) {
documentVersionIds.push(versionId);
documentLookup[versionId] = {
sourceTable: 'core_company',
sourceRecord: targetRecord
};
}
}
}
// STEP 3: Get the files stored for each document version
if (documentVersionIds.length > 0) {
var at = new GlideRecord('sys_attachment');
at.addQuery('table_name', 'ds_document_version');
at.addQuery('table_sys_id', 'IN', documentVersionIds.join(','));
at.query();
while (at.next()) {
var versionSysId = at.getValue('table_sys_id');
var sourceInfo = documentLookup[versionSysId];
if (sourceInfo) {
result.documents.push({
sysAttachmentId: at.getUniqueValue(),
sourceRecordTableName: sourceInfo.sourceTable,
sourceRecordId: sourceInfo.sourceRecord
});
}
}
}
} catch (ex) {
result.errorStatus = true;
result.errorMessage = String(ex);
result.documents = [];
}
})();
| Field | Description |
|---|---|
| Testing and rollout | |
| Unit tests |
Test with an assessment that has multiple scoped records and at least one third‑party with DMS documents.
Validate that result.documents contains expected attachments.
|
| Permissions checks | Impersonate assessor and manager personas to confirm access to the returned documents. Adjust document sharing permissions if the files are not visible. |
| Error paths |
Validate missing input, absent DMS references, and missing attachments.
Ensure downstream consumers handle an empty result.documents list.
|
| Observability | |
| Logging | Add scoped logs at entry and exit points. Capture the assessment sys_id, counts of scoped records and returned documents. Avoid logging attachment identifiers in production unless required by policy. |