pulsemcp-cms-admin-mcp-server 0.7.2 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/shared/src/pulsemcp-admin-client/lib/save-results-for-mirror.js +1 -1
- package/build/shared/src/tools/save-results-for-mirror.js +30 -15
- package/package.json +1 -1
- package/shared/pulsemcp-admin-client/lib/save-results-for-mirror.js +1 -1
- package/shared/tools/save-results-for-mirror.js +30 -15
|
@@ -95,26 +95,41 @@ Typical workflow:
|
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
// Extract exam_result lines from stored data.
|
|
98
|
-
// The exam_id may live at the top level of the stream line OR inside
|
|
99
|
-
// line.data (the actual result payload). Prefer the data payload to
|
|
100
|
-
// avoid reading from potentially incomplete display metadata.
|
|
101
98
|
//
|
|
102
|
-
// The real proctor API returns
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
99
|
+
// The real proctor API returns a deeply nested structure:
|
|
100
|
+
// line.data = {
|
|
101
|
+
// mirror_id, server_slug, exam_id, ...,
|
|
102
|
+
// result: { ← envelope
|
|
103
|
+
// exam_id, machine_id, status,
|
|
104
|
+
// result: { ← actual payload
|
|
105
|
+
// input: {...}, output: {...}, processedBy: {...}
|
|
106
|
+
// },
|
|
107
|
+
// error, logs
|
|
108
|
+
// }
|
|
109
|
+
// }
|
|
110
|
+
//
|
|
111
|
+
// The PulseMCP API expects the actual payload { input, output,
|
|
112
|
+
// processedBy } at the top level of the saved results column.
|
|
113
|
+
// We must unwrap through data.result.result to reach it.
|
|
109
114
|
results = stored.lines
|
|
110
115
|
.filter((line) => line.type === 'exam_result')
|
|
111
116
|
.map((line) => {
|
|
112
117
|
const data = line.data;
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
// Unwrap nested result objects to find the exam payload
|
|
119
|
+
// containing { input, output, processedBy }.
|
|
120
|
+
let resultData = data;
|
|
121
|
+
// Level 1: data.result (envelope with exam_id, machine_id, logs, etc.)
|
|
122
|
+
if (resultData?.result &&
|
|
123
|
+
typeof resultData.result === 'object' &&
|
|
124
|
+
!Array.isArray(resultData.result)) {
|
|
125
|
+
resultData = resultData.result;
|
|
126
|
+
// Level 2: data.result.result (actual payload with input, output, processedBy)
|
|
127
|
+
if (resultData.result &&
|
|
128
|
+
typeof resultData.result === 'object' &&
|
|
129
|
+
!Array.isArray(resultData.result)) {
|
|
130
|
+
resultData = resultData.result;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
118
133
|
return {
|
|
119
134
|
exam_id: extractExamId(line),
|
|
120
135
|
status: extractStatus(line),
|
package/package.json
CHANGED
|
@@ -95,26 +95,41 @@ Typical workflow:
|
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
// Extract exam_result lines from stored data.
|
|
98
|
-
// The exam_id may live at the top level of the stream line OR inside
|
|
99
|
-
// line.data (the actual result payload). Prefer the data payload to
|
|
100
|
-
// avoid reading from potentially incomplete display metadata.
|
|
101
98
|
//
|
|
102
|
-
// The real proctor API returns
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
99
|
+
// The real proctor API returns a deeply nested structure:
|
|
100
|
+
// line.data = {
|
|
101
|
+
// mirror_id, server_slug, exam_id, ...,
|
|
102
|
+
// result: { ← envelope
|
|
103
|
+
// exam_id, machine_id, status,
|
|
104
|
+
// result: { ← actual payload
|
|
105
|
+
// input: {...}, output: {...}, processedBy: {...}
|
|
106
|
+
// },
|
|
107
|
+
// error, logs
|
|
108
|
+
// }
|
|
109
|
+
// }
|
|
110
|
+
//
|
|
111
|
+
// The PulseMCP API expects the actual payload { input, output,
|
|
112
|
+
// processedBy } at the top level of the saved results column.
|
|
113
|
+
// We must unwrap through data.result.result to reach it.
|
|
109
114
|
results = stored.lines
|
|
110
115
|
.filter((line) => line.type === 'exam_result')
|
|
111
116
|
.map((line) => {
|
|
112
117
|
const data = line.data;
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
// Unwrap nested result objects to find the exam payload
|
|
119
|
+
// containing { input, output, processedBy }.
|
|
120
|
+
let resultData = data;
|
|
121
|
+
// Level 1: data.result (envelope with exam_id, machine_id, logs, etc.)
|
|
122
|
+
if (resultData?.result &&
|
|
123
|
+
typeof resultData.result === 'object' &&
|
|
124
|
+
!Array.isArray(resultData.result)) {
|
|
125
|
+
resultData = resultData.result;
|
|
126
|
+
// Level 2: data.result.result (actual payload with input, output, processedBy)
|
|
127
|
+
if (resultData.result &&
|
|
128
|
+
typeof resultData.result === 'object' &&
|
|
129
|
+
!Array.isArray(resultData.result)) {
|
|
130
|
+
resultData = resultData.result;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
118
133
|
return {
|
|
119
134
|
exam_id: extractExamId(line),
|
|
120
135
|
status: extractStatus(line),
|