@resolveio/server-lib 22.3.234 → 22.3.236
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/package.json
CHANGED
|
@@ -2718,7 +2718,7 @@ function buildResolveIORunnerBugfixComparisonQaScript() {
|
|
|
2718
2718
|
].join('\n');
|
|
2719
2719
|
}
|
|
2720
2720
|
function buildResolveIOPartInventorySnapshotProofScriptLines() {
|
|
2721
|
-
return String.raw(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\nfunction activeMatrixRow() {\n\tconst matrix = readJson(matrixPath) || {};\n\tconst rows = matrixRows(matrix);\n\treturn rows.find((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\"))) || rows[0] || {};\n}\nfunction readSeedPartInventorySnapshotContext() {\n\tconst seed = readJson(path.join(artifactDir, \"qa-live-data-seed-result.json\")) || {};\n\tconst selected = seed && seed.selected || {};\n\tconst context = selected.part_inventory_snapshot_context || selected.partInventorySnapshotContext || null;\n\tif (!context || typeof context !== \"object\") return null;\n\tconst partIds = uniqueStrings(context.part_ids || context.partIds || []);\n\tconst dayKeys = uniqueStrings(context.day_keys || context.dayKeys || []);\n\tif (!partIds.length && !dayKeys.length && !Number(context.snapshot_count || context.snapshotCount || 0)) return null;\n\treturn { ...context, part_ids: partIds, day_keys: dayKeys };\n}\nfunction shouldRunPartInventorySnapshotProof() {\n\tconst context = readSeedPartInventorySnapshotContext();\n\tif (!context) return false;\n\tconst text = [activeRowText(), targetRoute].join(\"\n\");\n\treturn /\b(reportDailyInventorySnapshot|inventory-daily-snapshots|dailys+inventorys+snapshot|parts+inventorys+snapshot|warehouse_location|Parts)\b/i.test(text);\n}\nfunction normalizePartSnapshotDayKey(value) {\n\tconst text = String(value || \"\").trim();\n\tconst match = /d{4}-d{2}-d{2}/.exec(text);\n\tif (match) return match[0];\n\tconst date = new Date(text);\n\treturn Number.isFinite(date.getTime()) ? date.toISOString().slice(0, 10) : \"\";\n}\nfunction partSnapshotRowPartId(row) {\n\tconst metadata = row && typeof row.metadata === \"object\" ? row.metadata : {};\n\treturn String(metadata.id_part || row.id_part || row.id_item || row.id_source || \"\").trim();\n}\nfunction partSnapshotRowYardId(row) {\n\tconst metadata = row && typeof row.metadata === \"object\" ? row.metadata : {};\n\tconst explicit = String(metadata.id_yard || row.id_yard || row.id_warehouse_location || \"\").trim();\n\tif (explicit) return explicit;\n\tconst source = String(row && row.id_source || \"\");\n\tconst sourceMatch = /^yard:([A-Za-z0-9_-]+)/i.exec(source);\n\treturn sourceMatch ? sourceMatch[1] : \"\";\n}\nfunction normalizeWarehouseName(value) {\n\treturn String(value || \"\").trim().toLowerCase().replace(/s+/g, \" \");\n}\nfunction methodDateFromDayKey(dayKey) {\n\treturn new Date(dayKey + \"T12:00:00.000Z\");\n}\nfunction resolveWsUrl() {\n\tif (/^https:/i.test(serverUrl)) return serverUrl.replace(/^https:/i, \"wss:\");\n\tif (/^http:/i.test(serverUrl)) return serverUrl.replace(/^http:/i, \"ws:\");\n\treturn serverUrl;\n}\nfunction callResolveIOMethodViaWs(auth, route, methodName, args) {\n\treturn new Promise((resolve, reject) => {\n\t\tconst token = auth && auth.accessToken;\n\t\tif (!token) {\n\t\t\treject(new Error(\"Missing access token for websocket method proof.\"));\n\t\t\treturn;\n\t\t}\n\t\tconst WebSocket = requireQaModule(\"ws\");\n\t\tconst { unpack } = requireQaModule(\"msgpackr\");\n\t\tconst ws = new WebSocket(resolveWsUrl(), [token], { origin: clientUrl });\n\t\tconst messageId = Date.now() + Math.floor(Math.random() * 100000);\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttry { ws.close(); } catch (error) {}\n\t\t\treject(new Error(\"Timed out waiting for \" + methodName + \" websocket response.\"));\n\t\t}, Number(process.env.RESOLVEIO_SUPPORT_QA_METHOD_PROOF_TIMEOUT_MS || process.env.RESOLVEIO_RUNNER_QA_METHOD_PROOF_TIMEOUT_MS || 30000));\n\t\tlet settled = false;\n\t\tconst finish = (error, value) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timeout);\n\t\t\ttry { ws.close(); } catch (closeError) {}\n\t\t\tif (error) reject(error);\n\t\t\telse resolve(value);\n\t\t};\n\t\tws.on(\"open\", () => {\n\t\t\tconst payload = [[route || \"/\", new Date().toISOString(), messageId, \"method\", methodName, ...(args || [])]];\n\t\t\tws.send(JSON.stringify(payload));\n\t\t});\n\t\tws.on(\"message\", (raw) => {\n\t\t\tlet messages = [];\n\t\t\tconst text = Buffer.isBuffer(raw) ? raw.toString(\"utf8\") : String(raw || \"\");\n\t\t\tif (text === \"ping\") {\n\t\t\t\ttry { ws.send(\"pong\"); } catch (error) {}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst decoded = Buffer.isBuffer(raw) ? unpack(raw) : JSON.parse(text);\n\t\t\t\tmessages = Array.isArray(decoded) ? decoded : [decoded];\n\t\t\t}\n\t\t\tcatch (error) { return; }\n\t\t\tfor (const payload of messages) {\n\t\t\t\tif (!payload || payload.messageId !== messageId) continue;\n\t\t\t\tif (payload.data === \"ACK\" && payload.hasError === false) continue;\n\t\t\t\tif (payload.hasError) finish(new Error(typeof payload.data === \"string\" ? payload.data : JSON.stringify(payload.data || {})));\n\t\t\t\telse finish(null, payload.data);\n\t\t\t}\n\t\t});\n\t\tws.on(\"error\", (error) => finish(error));\n\t});\n}\nasync function readPartInventorySnapshotProofData(context, dayKey) {\n\tconst { MongoClient } = mongoRequire();\n\tconst client = new MongoClient(safeLocalMongoUrl());\n\tawait client.connect();\n\ttry {\n\t\tconst db = client.db();\n\t\tconst query = { section: \"Parts\" };\n\t\tif (dayKey) query.day_key = dayKey;\n\t\tconst partIds = uniqueStrings(context.part_ids || []);\n\t\tif (partIds.length) query.$or = [{ \"metadata.id_part\": { $in: partIds } }, { id_part: { $in: partIds } }];\n\t\tconst snapshots = await db.collection(\"inventory-daily-snapshots\").find(query).sort({ day_key: -1, item_name: 1, location: 1 }).limit(120).toArray();\n\t\tconst yardIds = uniqueStrings(snapshots.map(partSnapshotRowYardId));\n\t\tconst yards = yardIds.length ? await db.collection(\"yards\").find({ _id: { $in: yardIds } }).project({ _id: 1, name: 1 }).toArray() : [];\n\t\tconst yardById = new Map(yards.map((yard) => [String(yard._id), yard]));\n\t\treturn { snapshots, yards, yardById };\n\t} finally {\n\t\tawait client.close().catch(() => undefined);\n\t}\n}\nasync function renderPartInventorySnapshotProofScreenshot(page, payload, rowRoute, screenshotPath) {\n\tconst escapeHtml = (value) => String(value === undefined || value === null ? \"\" : value).replace(/[&<>\"']/g, (char) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", \"\"\": \""\", \"'\": \"'\" }[char]));\n\tconst comparisons = (payload.comparisons || []).slice(0, 12).map((entry) => \"<tr><td>\" + escapeHtml(entry.partId || entry.itemName || \"part\") + \"</td><td>\" + escapeHtml(entry.beforeWarehouse || \"\") + \"</td><td>\" + escapeHtml(entry.expectedYardName || \"\") + \"</td><td>\" + escapeHtml(entry.afterWarehouse || \"\") + \"</td><td>\" + (entry.pass ? \"<span class=\"ok\">PASS</span>\" : \"<span class=\"bad\">FAIL</span>\") + \"</td></tr>\").join(\"\");\n\tconst html = \"<!doctype html><html><head><meta charset=\"utf-8\"><style>body{margin:0;background:#f5f7fb;color:#111827;font-family:Arial,Helvetica,sans-serif}.wrap{padding:42px 52px}.eyebrow{font-size:16px;text-transform:uppercase;color:#475569;font-weight:700}.title{font-size:34px;font-weight:800;margin:10px 0}.caption{font-size:20px;line-height:1.35;color:#1f2937;margin:0 0 22px}.grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px;margin:22px 0}.card{background:white;border:2px solid #d7dde8;border-radius:8px;padding:18px}.label{font-size:14px;color:#64748b;font-weight:700;text-transform:uppercase}.value{font-size:28px;font-weight:800;margin-top:8px}.ok{color:#047857;font-weight:800}.bad{color:#b91c1c;font-weight:800}table{width:100%;border-collapse:collapse;background:white;border:2px solid #d7dde8;border-radius:8px;overflow:hidden;font-size:17px}th{background:#111827;color:white;text-align:left;padding:12px}td{border-top:1px solid #e5e7eb;padding:12px}.footer{margin-top:20px;font-size:16px;color:#475569}.path{font-family:Menlo,Consolas,monospace;font-size:14px;color:#334155}</style></head><body><main class=\"wrap\"><div class=\"eyebrow\">ResolveIO Support QA Business Proof</div><div class=\"title\">Part Inventory Snapshot Warehouse Attribution</div><p class=\"caption\">\" + escapeHtml(payload.caption || \"\") + \"</p><section class=\"grid\"><div class=\"card\"><div class=\"label\">Report Method</div><div class=\"value\">reportDailyInventorySnapshot</div></div><div class=\"card\"><div class=\"label\">Snapshot Date</div><div class=\"value\">\" + escapeHtml(payload.dayKey || \"\") + \"</div></div><div class=\"card\"><div class=\"label\">Stale Rows Corrected</div><div class=\"value \" + (payload.pass ? \"ok\" : \"bad\") + \"\">\" + Number(payload.correctedStaleRows || 0) + \"/\" + Number(payload.staleRows || 0) + \"</div></div></section><table><thead><tr><th>Part</th><th>Before Saved Warehouse</th><th>Expected Yard</th><th>Method Response Warehouse</th><th>Result</th></tr></thead><tbody>\" + comparisons + \"</tbody></table><div class=\"footer\">Before: saved historical Parts snapshot rows contained stale warehouse_location values. Action: called reportDailyInventorySnapshot(date, [\"Parts\"]) on the local QA server. After: the method response used the authoritative yard lineage for the affected part rows.</div><div class=\"footer path\">Route: \" + escapeHtml(rowRoute || targetRoute) + \" | Artifacts: qa-part-inventory-snapshot-proof.json, aiqa-business-assertion.json, qa-coverage-matrix.json</div></main></body></html>\";\n\tawait page.setViewport({ width: Math.max(viewportWidth, 1600), height: Math.max(viewportHeight, 900) }).catch(() => undefined);\n\tawait page.setContent(html, { waitUntil: \"domcontentloaded\", timeout: 30000 });\n\tawait page.screenshot({ path: screenshotPath, type: \"png\", fullPage: false });\n}\nasync function runPartInventorySnapshotMethodProof(page, routeSummary, auth) {\n\tif (!shouldRunPartInventorySnapshotProof()) return null;\n\tconst context = readSeedPartInventorySnapshotContext();\n\tconst row = activeMatrixRow();\n\tconst rowRoute = String(row.route || row.screen || \"/print\").trim() || \"/print\";\n\tconst rowWorkflow = String(row.workflow || row.action_under_test || \"Invoke reportDailyInventorySnapshot(date, [\"Parts\"]) and verify Part warehouse_location uses authoritative yard lineage.\").trim();\n\tconst proofPath = path.join(artifactDir, \"qa-part-inventory-snapshot-proof.json\");\n\tconst businessAssertionPath = path.join(artifactDir, \"aiqa-business-assertion.json\");\n\tconst beforeAfterScreenshotPath = path.join(artifactDir, \"support-business-proof-before-after.png\");\n\tconst requestedDayKeys = uniqueStrings(context.day_keys || []).map(normalizePartSnapshotDayKey).filter(Boolean);\n\tconst dayKey = requestedDayKeys[0] || normalizePartSnapshotDayKey(new Date(Date.now() - 86400000).toISOString());\n\tconst writeFailed = async (message, extra) => {\n\t\tconst payload = { status: \"failed\", targetRoute: rowRoute, dayKey, context, error: message, ...(extra || {}), updated_at: new Date().toISOString() };\n\t\twriteJson(proofPath, payload);\n\t\twriteJson(businessAssertionPath, { assertion: String(row.assertion || row.required_proof || \"Part inventory snapshot warehouse attribution proof\"), status: \"failed\", result: \"business_assertion_failed\", outcome: \"business_assertion_failed\", workflow: rowWorkflow, route: rowRoute, before: \"\", action: \"Attempted deterministic reportDailyInventorySnapshot websocket method proof.\", expected: \"Affected Part rows return the yard named by snapshot metadata.id_yard instead of stale saved warehouse_location.\", after: \"\", observed: message, dataProof: message, mongoDelta: {}, artifactPaths: [proofPath, matrixPath], metadata: { supportDiagnosisProof: false, proofType: \"part_inventory_snapshot_report_method\", generatedBy: \"resolveio_runner_part_inventory_snapshot_business_proof\", generatedAt: new Date().toISOString() } });\n\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };\n\t\tconst rows = matrixRows(matrix);\n\t\tconst activeIndex = Math.max(0, rows.indexOf(row));\n\t\tif (rows[activeIndex]) { rows[activeIndex].status = \"failed\"; rows[activeIndex].result = \"failed\"; rows[activeIndex].acceptance_blocked = true; rows[activeIndex].blocker = message; rows[activeIndex].artifact = proofPath; }\n\t\tmatrix.rows = rows;\n\t\tmatrix.status = \"failed\";\n\t\tmatrix.part_inventory_snapshot_proof = proofPath;\n\t\tmatrix.aiqa_business_assertion = businessAssertionPath;\n\t\tmatrix.updated_at = new Date().toISOString();\n\t\twriteJson(matrixPath, matrix);\n\t\treturn payload;\n\t};\n\ttry {\n\t\tconst data = await readPartInventorySnapshotProofData(context, dayKey);\n\t\tif (!data.snapshots.length) return await writeFailed(\"No seeded Part inventory daily snapshot rows were available for day_key \" + dayKey + \".\");\n\t\tconst methodResult = await callResolveIOMethodViaWs(auth, rowRoute, \"reportDailyInventorySnapshot\", [methodDateFromDayKey(dayKey), [\"Parts\"]]);\n\t\tconst responseRows = Array.isArray(methodResult && methodResult.rows) ? methodResult.rows : [];\n\t\tconst comparisons = data.snapshots.map((snapshot) => {\n\t\t\tconst partId = partSnapshotRowPartId(snapshot);\n\t\t\tconst yardId = partSnapshotRowYardId(snapshot);\n\t\t\tconst yard = yardId ? data.yardById.get(String(yardId)) : null;\n\t\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\t\tconst beforeWarehouse = String(snapshot.warehouse_location || snapshot.location || \"\").trim();\n\t\t\tconst responseCandidates = responseRows.filter((candidate) => !partId || partSnapshotRowPartId(candidate) === partId || String(candidate.item_name || candidate.name || \"\") === String(snapshot.item_name || snapshot.name || \"\"));\n\t\t\tconst afterRow = responseCandidates.find((candidate) => expectedYardName && normalizeWarehouseName(candidate.warehouse_location || candidate.location) === normalizeWarehouseName(expectedYardName)) || responseCandidates[0] || null;\n\t\t\tconst afterWarehouse = String(afterRow && (afterRow.warehouse_location || afterRow.location) || \"\").trim();\n\t\t\tconst staleBefore = !!expectedYardName && !!beforeWarehouse && normalizeWarehouseName(beforeWarehouse) !== normalizeWarehouseName(expectedYardName);\n\t\t\treturn { partId, itemName: String(snapshot.item_name || snapshot.name || \"\"), dayKey: String(snapshot.day_key || \"\"), beforeWarehouse, expectedYardName, afterWarehouse, staleBefore, pass: staleBefore && !!afterWarehouse && normalizeWarehouseName(afterWarehouse) === normalizeWarehouseName(expectedYardName) };\n\t\t}).filter((entry) => entry.expectedYardName);\n\t\tconst staleRows = comparisons.filter((entry) => entry.staleBefore);\n\t\tconst passedRows = staleRows.filter((entry) => entry.pass);\n\t\tconst pass = staleRows.length > 0 && passedRows.length === staleRows.length;\n\t\tconst caption = pass\n\t\t\t? \"Part inventory snapshot proof passed: \" + passedRows.length + \" stale saved row(s) returned the authoritative yard warehouse in reportDailyInventorySnapshot.\"\n\t\t\t: \"Part inventory snapshot proof failed: staleRows=\" + staleRows.length + \", corrected=\" + passedRows.length + \".\";\n\t\tconst payload = { status: pass ? \"pass\" : \"failed\", targetRoute: rowRoute, dayKey, methodName: \"reportDailyInventorySnapshot\", context, snapshotCount: data.snapshots.length, responseRowCount: responseRows.length, staleRows: staleRows.length, correctedStaleRows: passedRows.length, comparisons, caption, screenshot: beforeAfterScreenshotPath, page: routeSummary, updated_at: new Date().toISOString() };\n\t\tawait renderPartInventorySnapshotProofScreenshot(page, payload, rowRoute, beforeAfterScreenshotPath).catch(() => undefined);\n\t\twriteJson(proofPath, payload);\n\t\tconst businessAssertion = {\n\t\t\tassertion: String(row.assertion || row.required_proof || \"Affected Part warehouse_location maps to authoritative yard lineage in reportDailyInventorySnapshot response.\").trim(),\n\t\t\tstatus: pass ? \"pass\" : \"failed\",\n\t\t\tresult: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",\n\t\t\toutcome: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",\n\t\t\tworkflow: rowWorkflow,\n\t\t\troute: rowRoute,\n\t\t\tbefore: \"Saved non-today Parts snapshot rows for day_key \" + dayKey + \" included \" + staleRows.length + \" stale warehouse_location value(s): \" + staleRows.map((entry) => (entry.itemName || entry.partId) + \"=\" + entry.beforeWarehouse).join(\"; \"),\n\t\t\taction: \"Called reportDailyInventorySnapshot(\" + dayKey + \", [\"Parts\"]) through the local QA websocket method path.\",\n\t\t\texpected: \"Every affected stale Part row returns the yard named by metadata.id_yard in warehouse_location.\",\n\t\t\tafter: \"Method response corrected \" + passedRows.length + \" of \" + staleRows.length + \" stale row(s): \" + passedRows.map((entry) => (entry.itemName || entry.partId) + \"=\" + entry.afterWarehouse).join(\"; \"),\n\t\t\tobserved: caption,\n\t\t\tdataProof: comparisons.map((entry) => (entry.itemName || entry.partId || \"part\") + \": before=\" + entry.beforeWarehouse + \", expected=\" + entry.expectedYardName + \", after=\" + entry.afterWarehouse + \", pass=\" + entry.pass).join(\"\n\"),\n\t\t\tmongoDelta: { collection: \"inventory-daily-snapshots\", day_key: dayKey, staleRows: staleRows.length, correctedStaleRows: passedRows.length, responseRowCount: responseRows.length },\n\t\t\tartifactPaths: [proofPath, beforeAfterScreenshotPath, matrixPath],\n\t\t\tmetadata: { supportDiagnosisProof: pass, proofType: \"part_inventory_snapshot_report_method\", methodPath: \"server/src/methods/report.ts reportDailyInventorySnapshot\", generatedBy: \"resolveio_runner_part_inventory_snapshot_business_proof\", generatedAt: new Date().toISOString() }\n\t\t};\n\t\twriteJson(businessAssertionPath, businessAssertion);\n\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };\n\t\tconst rows = matrixRows(matrix);\n\t\tconst rowIndex = rows.findIndex((candidate) => String(candidate && candidate.workflow || \"\") === rowWorkflow) >= 0 ? rows.findIndex((candidate) => String(candidate && candidate.workflow || \"\") === rowWorkflow) : rows.findIndex((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\")));\n\t\tconst activeIndex = rowIndex >= 0 ? rowIndex : 0;\n\t\tif (rows[activeIndex]) {\n\t\t\trows[activeIndex].status = pass ? \"pass\" : \"failed\";\n\t\t\trows[activeIndex].result = pass ? \"pass\" : \"failed\";\n\t\t\trows[activeIndex].acceptance_blocked = !pass;\n\t\t\trows[activeIndex].screenshot = beforeAfterScreenshotPath;\n\t\t\trows[activeIndex].screenshots = [beforeAfterScreenshotPath, passScreenshotPath].filter(Boolean);\n\t\t\trows[activeIndex].caption = caption;\n\t\t\trows[activeIndex].artifact = proofPath;\n\t\t\trows[activeIndex].artifacts = [{ path: proofPath, caption: \"Part inventory snapshot method response proof.\" }, { screenshot: beforeAfterScreenshotPath, caption }, { path: businessAssertionPath, caption: \"AIQaBusinessAssertion for support diagnosis proof plan.\" }];\n\t\t\trows[activeIndex].persisted_assertion = businessAssertion.dataProof;\n\t\t\tif (!pass) rows[activeIndex].blocker = caption;\n\t\t}\n\t\tmatrix.rows = rows;\n\t\tmatrix.status = pass ? \"pass\" : \"failed\";\n\t\tmatrix.part_inventory_snapshot_proof = proofPath;\n\t\tmatrix.aiqa_business_assertion = businessAssertionPath;\n\t\tmatrix.updated_at = new Date().toISOString();\n\t\twriteJson(matrixPath, matrix);\n\t\treturn payload;\n\t} catch (error) {\n\t\treturn await writeFailed(error && (error.stack || error.message) || String(error));\n\t}\n}\n"], ["\nfunction activeMatrixRow() {\n\tconst matrix = readJson(matrixPath) || {};\n\tconst rows = matrixRows(matrix);\n\treturn rows.find((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\"))) || rows[0] || {};\n}\nfunction readSeedPartInventorySnapshotContext() {\n\tconst seed = readJson(path.join(artifactDir, \"qa-live-data-seed-result.json\")) || {};\n\tconst selected = seed && seed.selected || {};\n\tconst context = selected.part_inventory_snapshot_context || selected.partInventorySnapshotContext || null;\n\tif (!context || typeof context !== \"object\") return null;\n\tconst partIds = uniqueStrings(context.part_ids || context.partIds || []);\n\tconst dayKeys = uniqueStrings(context.day_keys || context.dayKeys || []);\n\tif (!partIds.length && !dayKeys.length && !Number(context.snapshot_count || context.snapshotCount || 0)) return null;\n\treturn { ...context, part_ids: partIds, day_keys: dayKeys };\n}\nfunction shouldRunPartInventorySnapshotProof() {\n\tconst context = readSeedPartInventorySnapshotContext();\n\tif (!context) return false;\n\tconst text = [activeRowText(), targetRoute].join(\"\\n\");\n\treturn /\\b(reportDailyInventorySnapshot|inventory-daily-snapshots|daily\\s+inventory\\s+snapshot|part\\s+inventory\\s+snapshot|warehouse_location|Parts)\\b/i.test(text);\n}\nfunction normalizePartSnapshotDayKey(value) {\n\tconst text = String(value || \"\").trim();\n\tconst match = /\\d{4}-\\d{2}-\\d{2}/.exec(text);\n\tif (match) return match[0];\n\tconst date = new Date(text);\n\treturn Number.isFinite(date.getTime()) ? date.toISOString().slice(0, 10) : \"\";\n}\nfunction partSnapshotRowPartId(row) {\n\tconst metadata = row && typeof row.metadata === \"object\" ? row.metadata : {};\n\treturn String(metadata.id_part || row.id_part || row.id_item || row.id_source || \"\").trim();\n}\nfunction partSnapshotRowYardId(row) {\n\tconst metadata = row && typeof row.metadata === \"object\" ? row.metadata : {};\n\tconst explicit = String(metadata.id_yard || row.id_yard || row.id_warehouse_location || \"\").trim();\n\tif (explicit) return explicit;\n\tconst source = String(row && row.id_source || \"\");\n\tconst sourceMatch = /^yard:([A-Za-z0-9_-]+)/i.exec(source);\n\treturn sourceMatch ? sourceMatch[1] : \"\";\n}\nfunction normalizeWarehouseName(value) {\n\treturn String(value || \"\").trim().toLowerCase().replace(/\\s+/g, \" \");\n}\nfunction methodDateFromDayKey(dayKey) {\n\treturn new Date(dayKey + \"T12:00:00.000Z\");\n}\nfunction resolveWsUrl() {\n\tif (/^https:/i.test(serverUrl)) return serverUrl.replace(/^https:/i, \"wss:\");\n\tif (/^http:/i.test(serverUrl)) return serverUrl.replace(/^http:/i, \"ws:\");\n\treturn serverUrl;\n}\nfunction callResolveIOMethodViaWs(auth, route, methodName, args) {\n\treturn new Promise((resolve, reject) => {\n\t\tconst token = auth && auth.accessToken;\n\t\tif (!token) {\n\t\t\treject(new Error(\"Missing access token for websocket method proof.\"));\n\t\t\treturn;\n\t\t}\n\t\tconst WebSocket = requireQaModule(\"ws\");\n\t\tconst { unpack } = requireQaModule(\"msgpackr\");\n\t\tconst ws = new WebSocket(resolveWsUrl(), [token], { origin: clientUrl });\n\t\tconst messageId = Date.now() + Math.floor(Math.random() * 100000);\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttry { ws.close(); } catch (error) {}\n\t\t\treject(new Error(\"Timed out waiting for \" + methodName + \" websocket response.\"));\n\t\t}, Number(process.env.RESOLVEIO_SUPPORT_QA_METHOD_PROOF_TIMEOUT_MS || process.env.RESOLVEIO_RUNNER_QA_METHOD_PROOF_TIMEOUT_MS || 30000));\n\t\tlet settled = false;\n\t\tconst finish = (error, value) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timeout);\n\t\t\ttry { ws.close(); } catch (closeError) {}\n\t\t\tif (error) reject(error);\n\t\t\telse resolve(value);\n\t\t};\n\t\tws.on(\"open\", () => {\n\t\t\tconst payload = [[route || \"/\", new Date().toISOString(), messageId, \"method\", methodName, ...(args || [])]];\n\t\t\tws.send(JSON.stringify(payload));\n\t\t});\n\t\tws.on(\"message\", (raw) => {\n\t\t\tlet messages = [];\n\t\t\tconst text = Buffer.isBuffer(raw) ? raw.toString(\"utf8\") : String(raw || \"\");\n\t\t\tif (text === \"ping\") {\n\t\t\t\ttry { ws.send(\"pong\"); } catch (error) {}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst decoded = Buffer.isBuffer(raw) ? unpack(raw) : JSON.parse(text);\n\t\t\t\tmessages = Array.isArray(decoded) ? decoded : [decoded];\n\t\t\t}\n\t\t\tcatch (error) { return; }\n\t\t\tfor (const payload of messages) {\n\t\t\t\tif (!payload || payload.messageId !== messageId) continue;\n\t\t\t\tif (payload.data === \"ACK\" && payload.hasError === false) continue;\n\t\t\t\tif (payload.hasError) finish(new Error(typeof payload.data === \"string\" ? payload.data : JSON.stringify(payload.data || {})));\n\t\t\t\telse finish(null, payload.data);\n\t\t\t}\n\t\t});\n\t\tws.on(\"error\", (error) => finish(error));\n\t});\n}\nasync function readPartInventorySnapshotProofData(context, dayKey) {\n\tconst { MongoClient } = mongoRequire();\n\tconst client = new MongoClient(safeLocalMongoUrl());\n\tawait client.connect();\n\ttry {\n\t\tconst db = client.db();\n\t\tconst query = { section: \"Parts\" };\n\t\tif (dayKey) query.day_key = dayKey;\n\t\tconst partIds = uniqueStrings(context.part_ids || []);\n\t\tif (partIds.length) query.$or = [{ \"metadata.id_part\": { $in: partIds } }, { id_part: { $in: partIds } }];\n\t\tconst snapshots = await db.collection(\"inventory-daily-snapshots\").find(query).sort({ day_key: -1, item_name: 1, location: 1 }).limit(120).toArray();\n\t\tconst yardIds = uniqueStrings(snapshots.map(partSnapshotRowYardId));\n\t\tconst yards = yardIds.length ? await db.collection(\"yards\").find({ _id: { $in: yardIds } }).project({ _id: 1, name: 1 }).toArray() : [];\n\t\tconst yardById = new Map(yards.map((yard) => [String(yard._id), yard]));\n\t\treturn { snapshots, yards, yardById };\n\t} finally {\n\t\tawait client.close().catch(() => undefined);\n\t}\n}\nasync function renderPartInventorySnapshotProofScreenshot(page, payload, rowRoute, screenshotPath) {\n\tconst escapeHtml = (value) => String(value === undefined || value === null ? \"\" : value).replace(/[&<>\"']/g, (char) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", \"\\\"\": \""\", \"'\": \"'\" }[char]));\n\tconst comparisons = (payload.comparisons || []).slice(0, 12).map((entry) => \"<tr><td>\" + escapeHtml(entry.partId || entry.itemName || \"part\") + \"</td><td>\" + escapeHtml(entry.beforeWarehouse || \"\") + \"</td><td>\" + escapeHtml(entry.expectedYardName || \"\") + \"</td><td>\" + escapeHtml(entry.afterWarehouse || \"\") + \"</td><td>\" + (entry.pass ? \"<span class=\\\"ok\\\">PASS</span>\" : \"<span class=\\\"bad\\\">FAIL</span>\") + \"</td></tr>\").join(\"\");\n\tconst html = \"<!doctype html><html><head><meta charset=\\\"utf-8\\\"><style>body{margin:0;background:#f5f7fb;color:#111827;font-family:Arial,Helvetica,sans-serif}.wrap{padding:42px 52px}.eyebrow{font-size:16px;text-transform:uppercase;color:#475569;font-weight:700}.title{font-size:34px;font-weight:800;margin:10px 0}.caption{font-size:20px;line-height:1.35;color:#1f2937;margin:0 0 22px}.grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px;margin:22px 0}.card{background:white;border:2px solid #d7dde8;border-radius:8px;padding:18px}.label{font-size:14px;color:#64748b;font-weight:700;text-transform:uppercase}.value{font-size:28px;font-weight:800;margin-top:8px}.ok{color:#047857;font-weight:800}.bad{color:#b91c1c;font-weight:800}table{width:100%;border-collapse:collapse;background:white;border:2px solid #d7dde8;border-radius:8px;overflow:hidden;font-size:17px}th{background:#111827;color:white;text-align:left;padding:12px}td{border-top:1px solid #e5e7eb;padding:12px}.footer{margin-top:20px;font-size:16px;color:#475569}.path{font-family:Menlo,Consolas,monospace;font-size:14px;color:#334155}</style></head><body><main class=\\\"wrap\\\"><div class=\\\"eyebrow\\\">ResolveIO Support QA Business Proof</div><div class=\\\"title\\\">Part Inventory Snapshot Warehouse Attribution</div><p class=\\\"caption\\\">\" + escapeHtml(payload.caption || \"\") + \"</p><section class=\\\"grid\\\"><div class=\\\"card\\\"><div class=\\\"label\\\">Report Method</div><div class=\\\"value\\\">reportDailyInventorySnapshot</div></div><div class=\\\"card\\\"><div class=\\\"label\\\">Snapshot Date</div><div class=\\\"value\\\">\" + escapeHtml(payload.dayKey || \"\") + \"</div></div><div class=\\\"card\\\"><div class=\\\"label\\\">Stale Rows Corrected</div><div class=\\\"value \" + (payload.pass ? \"ok\" : \"bad\") + \"\\\">\" + Number(payload.correctedStaleRows || 0) + \"/\" + Number(payload.staleRows || 0) + \"</div></div></section><table><thead><tr><th>Part</th><th>Before Saved Warehouse</th><th>Expected Yard</th><th>Method Response Warehouse</th><th>Result</th></tr></thead><tbody>\" + comparisons + \"</tbody></table><div class=\\\"footer\\\">Before: saved historical Parts snapshot rows contained stale warehouse_location values. Action: called reportDailyInventorySnapshot(date, [\\\"Parts\\\"]) on the local QA server. After: the method response used the authoritative yard lineage for the affected part rows.</div><div class=\\\"footer path\\\">Route: \" + escapeHtml(rowRoute || targetRoute) + \" | Artifacts: qa-part-inventory-snapshot-proof.json, aiqa-business-assertion.json, qa-coverage-matrix.json</div></main></body></html>\";\n\tawait page.setViewport({ width: Math.max(viewportWidth, 1600), height: Math.max(viewportHeight, 900) }).catch(() => undefined);\n\tawait page.setContent(html, { waitUntil: \"domcontentloaded\", timeout: 30000 });\n\tawait page.screenshot({ path: screenshotPath, type: \"png\", fullPage: false });\n}\nasync function runPartInventorySnapshotMethodProof(page, routeSummary, auth) {\n\tif (!shouldRunPartInventorySnapshotProof()) return null;\n\tconst context = readSeedPartInventorySnapshotContext();\n\tconst row = activeMatrixRow();\n\tconst rowRoute = String(row.route || row.screen || \"/print\").trim() || \"/print\";\n\tconst rowWorkflow = String(row.workflow || row.action_under_test || \"Invoke reportDailyInventorySnapshot(date, [\\\"Parts\\\"]) and verify Part warehouse_location uses authoritative yard lineage.\").trim();\n\tconst proofPath = path.join(artifactDir, \"qa-part-inventory-snapshot-proof.json\");\n\tconst businessAssertionPath = path.join(artifactDir, \"aiqa-business-assertion.json\");\n\tconst beforeAfterScreenshotPath = path.join(artifactDir, \"support-business-proof-before-after.png\");\n\tconst requestedDayKeys = uniqueStrings(context.day_keys || []).map(normalizePartSnapshotDayKey).filter(Boolean);\n\tconst dayKey = requestedDayKeys[0] || normalizePartSnapshotDayKey(new Date(Date.now() - 86400000).toISOString());\n\tconst writeFailed = async (message, extra) => {\n\t\tconst payload = { status: \"failed\", targetRoute: rowRoute, dayKey, context, error: message, ...(extra || {}), updated_at: new Date().toISOString() };\n\t\twriteJson(proofPath, payload);\n\t\twriteJson(businessAssertionPath, { assertion: String(row.assertion || row.required_proof || \"Part inventory snapshot warehouse attribution proof\"), status: \"failed\", result: \"business_assertion_failed\", outcome: \"business_assertion_failed\", workflow: rowWorkflow, route: rowRoute, before: \"\", action: \"Attempted deterministic reportDailyInventorySnapshot websocket method proof.\", expected: \"Affected Part rows return the yard named by snapshot metadata.id_yard instead of stale saved warehouse_location.\", after: \"\", observed: message, dataProof: message, mongoDelta: {}, artifactPaths: [proofPath, matrixPath], metadata: { supportDiagnosisProof: false, proofType: \"part_inventory_snapshot_report_method\", generatedBy: \"resolveio_runner_part_inventory_snapshot_business_proof\", generatedAt: new Date().toISOString() } });\n\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };\n\t\tconst rows = matrixRows(matrix);\n\t\tconst activeIndex = Math.max(0, rows.indexOf(row));\n\t\tif (rows[activeIndex]) { rows[activeIndex].status = \"failed\"; rows[activeIndex].result = \"failed\"; rows[activeIndex].acceptance_blocked = true; rows[activeIndex].blocker = message; rows[activeIndex].artifact = proofPath; }\n\t\tmatrix.rows = rows;\n\t\tmatrix.status = \"failed\";\n\t\tmatrix.part_inventory_snapshot_proof = proofPath;\n\t\tmatrix.aiqa_business_assertion = businessAssertionPath;\n\t\tmatrix.updated_at = new Date().toISOString();\n\t\twriteJson(matrixPath, matrix);\n\t\treturn payload;\n\t};\n\ttry {\n\t\tconst data = await readPartInventorySnapshotProofData(context, dayKey);\n\t\tif (!data.snapshots.length) return await writeFailed(\"No seeded Part inventory daily snapshot rows were available for day_key \" + dayKey + \".\");\n\t\tconst methodResult = await callResolveIOMethodViaWs(auth, rowRoute, \"reportDailyInventorySnapshot\", [methodDateFromDayKey(dayKey), [\"Parts\"]]);\n\t\tconst responseRows = Array.isArray(methodResult && methodResult.rows) ? methodResult.rows : [];\n\t\tconst comparisons = data.snapshots.map((snapshot) => {\n\t\t\tconst partId = partSnapshotRowPartId(snapshot);\n\t\t\tconst yardId = partSnapshotRowYardId(snapshot);\n\t\t\tconst yard = yardId ? data.yardById.get(String(yardId)) : null;\n\t\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\t\tconst beforeWarehouse = String(snapshot.warehouse_location || snapshot.location || \"\").trim();\n\t\t\tconst responseCandidates = responseRows.filter((candidate) => !partId || partSnapshotRowPartId(candidate) === partId || String(candidate.item_name || candidate.name || \"\") === String(snapshot.item_name || snapshot.name || \"\"));\n\t\t\tconst afterRow = responseCandidates.find((candidate) => expectedYardName && normalizeWarehouseName(candidate.warehouse_location || candidate.location) === normalizeWarehouseName(expectedYardName)) || responseCandidates[0] || null;\n\t\t\tconst afterWarehouse = String(afterRow && (afterRow.warehouse_location || afterRow.location) || \"\").trim();\n\t\t\tconst staleBefore = !!expectedYardName && !!beforeWarehouse && normalizeWarehouseName(beforeWarehouse) !== normalizeWarehouseName(expectedYardName);\n\t\t\treturn { partId, itemName: String(snapshot.item_name || snapshot.name || \"\"), dayKey: String(snapshot.day_key || \"\"), beforeWarehouse, expectedYardName, afterWarehouse, staleBefore, pass: staleBefore && !!afterWarehouse && normalizeWarehouseName(afterWarehouse) === normalizeWarehouseName(expectedYardName) };\n\t\t}).filter((entry) => entry.expectedYardName);\n\t\tconst staleRows = comparisons.filter((entry) => entry.staleBefore);\n\t\tconst passedRows = staleRows.filter((entry) => entry.pass);\n\t\tconst pass = staleRows.length > 0 && passedRows.length === staleRows.length;\n\t\tconst caption = pass\n\t\t\t? \"Part inventory snapshot proof passed: \" + passedRows.length + \" stale saved row(s) returned the authoritative yard warehouse in reportDailyInventorySnapshot.\"\n\t\t\t: \"Part inventory snapshot proof failed: staleRows=\" + staleRows.length + \", corrected=\" + passedRows.length + \".\";\n\t\tconst payload = { status: pass ? \"pass\" : \"failed\", targetRoute: rowRoute, dayKey, methodName: \"reportDailyInventorySnapshot\", context, snapshotCount: data.snapshots.length, responseRowCount: responseRows.length, staleRows: staleRows.length, correctedStaleRows: passedRows.length, comparisons, caption, screenshot: beforeAfterScreenshotPath, page: routeSummary, updated_at: new Date().toISOString() };\n\t\tawait renderPartInventorySnapshotProofScreenshot(page, payload, rowRoute, beforeAfterScreenshotPath).catch(() => undefined);\n\t\twriteJson(proofPath, payload);\n\t\tconst businessAssertion = {\n\t\t\tassertion: String(row.assertion || row.required_proof || \"Affected Part warehouse_location maps to authoritative yard lineage in reportDailyInventorySnapshot response.\").trim(),\n\t\t\tstatus: pass ? \"pass\" : \"failed\",\n\t\t\tresult: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",\n\t\t\toutcome: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",\n\t\t\tworkflow: rowWorkflow,\n\t\t\troute: rowRoute,\n\t\t\tbefore: \"Saved non-today Parts snapshot rows for day_key \" + dayKey + \" included \" + staleRows.length + \" stale warehouse_location value(s): \" + staleRows.map((entry) => (entry.itemName || entry.partId) + \"=\" + entry.beforeWarehouse).join(\"; \"),\n\t\t\taction: \"Called reportDailyInventorySnapshot(\" + dayKey + \", [\\\"Parts\\\"]) through the local QA websocket method path.\",\n\t\t\texpected: \"Every affected stale Part row returns the yard named by metadata.id_yard in warehouse_location.\",\n\t\t\tafter: \"Method response corrected \" + passedRows.length + \" of \" + staleRows.length + \" stale row(s): \" + passedRows.map((entry) => (entry.itemName || entry.partId) + \"=\" + entry.afterWarehouse).join(\"; \"),\n\t\t\tobserved: caption,\n\t\t\tdataProof: comparisons.map((entry) => (entry.itemName || entry.partId || \"part\") + \": before=\" + entry.beforeWarehouse + \", expected=\" + entry.expectedYardName + \", after=\" + entry.afterWarehouse + \", pass=\" + entry.pass).join(\"\\n\"),\n\t\t\tmongoDelta: { collection: \"inventory-daily-snapshots\", day_key: dayKey, staleRows: staleRows.length, correctedStaleRows: passedRows.length, responseRowCount: responseRows.length },\n\t\t\tartifactPaths: [proofPath, beforeAfterScreenshotPath, matrixPath],\n\t\t\tmetadata: { supportDiagnosisProof: pass, proofType: \"part_inventory_snapshot_report_method\", methodPath: \"server/src/methods/report.ts reportDailyInventorySnapshot\", generatedBy: \"resolveio_runner_part_inventory_snapshot_business_proof\", generatedAt: new Date().toISOString() }\n\t\t};\n\t\twriteJson(businessAssertionPath, businessAssertion);\n\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };\n\t\tconst rows = matrixRows(matrix);\n\t\tconst rowIndex = rows.findIndex((candidate) => String(candidate && candidate.workflow || \"\") === rowWorkflow) >= 0 ? rows.findIndex((candidate) => String(candidate && candidate.workflow || \"\") === rowWorkflow) : rows.findIndex((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\")));\n\t\tconst activeIndex = rowIndex >= 0 ? rowIndex : 0;\n\t\tif (rows[activeIndex]) {\n\t\t\trows[activeIndex].status = pass ? \"pass\" : \"failed\";\n\t\t\trows[activeIndex].result = pass ? \"pass\" : \"failed\";\n\t\t\trows[activeIndex].acceptance_blocked = !pass;\n\t\t\trows[activeIndex].screenshot = beforeAfterScreenshotPath;\n\t\t\trows[activeIndex].screenshots = [beforeAfterScreenshotPath, passScreenshotPath].filter(Boolean);\n\t\t\trows[activeIndex].caption = caption;\n\t\t\trows[activeIndex].artifact = proofPath;\n\t\t\trows[activeIndex].artifacts = [{ path: proofPath, caption: \"Part inventory snapshot method response proof.\" }, { screenshot: beforeAfterScreenshotPath, caption }, { path: businessAssertionPath, caption: \"AIQaBusinessAssertion for support diagnosis proof plan.\" }];\n\t\t\trows[activeIndex].persisted_assertion = businessAssertion.dataProof;\n\t\t\tif (!pass) rows[activeIndex].blocker = caption;\n\t\t}\n\t\tmatrix.rows = rows;\n\t\tmatrix.status = pass ? \"pass\" : \"failed\";\n\t\tmatrix.part_inventory_snapshot_proof = proofPath;\n\t\tmatrix.aiqa_business_assertion = businessAssertionPath;\n\t\tmatrix.updated_at = new Date().toISOString();\n\t\twriteJson(matrixPath, matrix);\n\t\treturn payload;\n\t} catch (error) {\n\t\treturn await writeFailed(error && (error.stack || error.message) || String(error));\n\t}\n}\n"]))).trim().split('\n');
|
|
2721
|
+
return String.raw(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\nfunction activeMatrixRow() {\n\tconst matrix = readJson(matrixPath) || {};\n\tconst rows = matrixRows(matrix);\n\treturn rows.find((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\"))) || rows[0] || {};\n}\nfunction readSeedPartInventorySnapshotContext() {\n\tconst seed = readJson(path.join(artifactDir, \"qa-live-data-seed-result.json\")) || {};\n\tconst selected = seed && seed.selected || {};\n\tconst context = selected.part_inventory_snapshot_context || selected.partInventorySnapshotContext || null;\n\tif (!context || typeof context !== \"object\") return null;\n\tconst partIds = uniqueStrings(context.part_ids || context.partIds || []);\n\tconst dayKeys = uniqueStrings(context.day_keys || context.dayKeys || []);\n\tif (!partIds.length && !dayKeys.length && !Number(context.snapshot_count || context.snapshotCount || 0)) return null;\n\treturn { ...context, part_ids: partIds, day_keys: dayKeys };\n}\nfunction shouldRunPartInventorySnapshotProof() {\n\tconst context = readSeedPartInventorySnapshotContext();\n\tif (!context) return false;\n\tconst text = [activeRowText(), targetRoute].join(\"\n\");\n\treturn /\b(reportDailyInventorySnapshot|inventory-daily-snapshots|dailys+inventorys+snapshot|parts+inventorys+snapshot|warehouse_location|Parts)\b/i.test(text);\n}\nfunction normalizePartSnapshotDayKey(value) {\n\tconst text = String(value || \"\").trim();\n\tconst match = /d{4}-d{2}-d{2}/.exec(text);\n\tif (match) return match[0];\n\tconst date = new Date(text);\n\treturn Number.isFinite(date.getTime()) ? date.toISOString().slice(0, 10) : \"\";\n}\nfunction partSnapshotRowPartId(row) {\n\tconst metadata = row && typeof row.metadata === \"object\" ? row.metadata : {};\n\treturn String(metadata.id_part || row.id_part || row.id_item || row.id_source || \"\").trim();\n}\nfunction partSnapshotRowYardId(row) {\n\tconst metadata = row && typeof row.metadata === \"object\" ? row.metadata : {};\n\tconst explicit = String(metadata.id_yard || row.id_yard || row.id_warehouse_location || \"\").trim();\n\tif (explicit) return explicit;\n\tconst source = String(row && row.id_source || \"\");\n\tconst sourceMatch = /^yard:([A-Za-z0-9_-]+)/i.exec(source);\n\treturn sourceMatch ? sourceMatch[1] : \"\";\n}\nfunction normalizeWarehouseName(value) {\n\treturn String(value || \"\").trim().toLowerCase().replace(/s+/g, \" \");\n}\nfunction methodDateFromDayKey(dayKey) {\n\treturn new Date(dayKey + \"T12:00:00.000Z\");\n}\nfunction resolveWsUrl() {\n\tif (/^https:/i.test(serverUrl)) return serverUrl.replace(/^https:/i, \"wss:\");\n\tif (/^http:/i.test(serverUrl)) return serverUrl.replace(/^http:/i, \"ws:\");\n\treturn serverUrl;\n}\nfunction callResolveIOMethodViaWs(auth, route, methodName, args) {\n\treturn new Promise((resolve, reject) => {\n\t\tconst token = auth && auth.accessToken;\n\t\tif (!token) {\n\t\t\treject(new Error(\"Missing access token for websocket method proof.\"));\n\t\t\treturn;\n\t\t}\n\t\tconst WebSocket = requireQaModule(\"ws\");\n\t\tconst { unpack } = requireQaModule(\"msgpackr\");\n\t\tconst ws = new WebSocket(resolveWsUrl(), [token], { origin: clientUrl });\n\t\tconst messageId = Date.now() + Math.floor(Math.random() * 100000);\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttry { ws.close(); } catch (error) {}\n\t\t\treject(new Error(\"Timed out waiting for \" + methodName + \" websocket response.\"));\n\t\t}, Number(process.env.RESOLVEIO_SUPPORT_QA_METHOD_PROOF_TIMEOUT_MS || process.env.RESOLVEIO_RUNNER_QA_METHOD_PROOF_TIMEOUT_MS || 30000));\n\t\tlet settled = false;\n\t\tconst finish = (error, value) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timeout);\n\t\t\ttry { ws.close(); } catch (closeError) {}\n\t\t\tif (error) reject(error);\n\t\t\telse resolve(value);\n\t\t};\n\t\tws.on(\"open\", () => {\n\t\t\tconst payload = [[route || \"/\", new Date().toISOString(), messageId, \"method\", methodName, ...(args || [])]];\n\t\t\tws.send(JSON.stringify(payload));\n\t\t});\n\t\tws.on(\"message\", (raw) => {\n\t\t\tlet messages = [];\n\t\t\tconst text = Buffer.isBuffer(raw) ? raw.toString(\"utf8\") : String(raw || \"\");\n\t\t\tif (text === \"ping\") {\n\t\t\t\ttry { ws.send(\"pong\"); } catch (error) {}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst decoded = Buffer.isBuffer(raw) ? unpack(raw) : JSON.parse(text);\n\t\t\t\tmessages = Array.isArray(decoded) ? decoded : [decoded];\n\t\t\t}\n\t\t\tcatch (error) { return; }\n\t\t\tfor (const payload of messages) {\n\t\t\t\tif (!payload || payload.messageId !== messageId) continue;\n\t\t\t\tif (payload.data === \"ACK\" && payload.hasError === false) continue;\n\t\t\t\tif (payload.hasError) finish(new Error(typeof payload.data === \"string\" ? payload.data : JSON.stringify(payload.data || {})));\n\t\t\t\telse finish(null, payload.data);\n\t\t\t}\n\t\t});\n\t\tws.on(\"error\", (error) => finish(error));\n\t});\n}\n\tasync function readPartInventorySnapshotProofData(context, dayKey) {\n\t\tconst { MongoClient } = mongoRequire();\n\t\tconst client = new MongoClient(safeLocalMongoUrl());\n\tawait client.connect();\n\ttry {\n\t\tconst db = client.db();\n\t\tconst query = { section: \"Parts\" };\n\t\tif (dayKey) query.day_key = dayKey;\n\t\tconst partIds = uniqueStrings(context.part_ids || []);\n\t\tif (partIds.length) query.$or = [{ \"metadata.id_part\": { $in: partIds } }, { id_part: { $in: partIds } }];\n\t\tconst snapshots = await db.collection(\"inventory-daily-snapshots\").find(query).sort({ day_key: -1, item_name: 1, location: 1 }).limit(120).toArray();\n\t\tconst yardIds = uniqueStrings(snapshots.map(partSnapshotRowYardId));\n\t\tconst yards = yardIds.length ? await db.collection(\"yards\").find({ _id: { $in: yardIds } }).project({ _id: 1, name: 1 }).toArray() : [];\n\t\tconst yardById = new Map(yards.map((yard) => [String(yard._id), yard]));\n\t\treturn { snapshots, yards, yardById };\n\t} finally {\n\t\t\tawait client.close().catch(() => undefined);\n\t\t}\n\t}\n\tfunction findPartInventorySnapshotStaleRows(data) {\n\t\tconst yardById = data && data.yardById instanceof Map ? data.yardById : new Map();\n\t\treturn (Array.isArray(data && data.snapshots) ? data.snapshots : []).filter((snapshot) => {\n\t\t\tconst yardId = partSnapshotRowYardId(snapshot);\n\t\t\tconst yard = yardId ? yardById.get(String(yardId)) : null;\n\t\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\t\tconst beforeWarehouse = String(snapshot && (snapshot.warehouse_location || snapshot.location) || \"\").trim();\n\t\t\treturn !!expectedYardName && !!beforeWarehouse && normalizeWarehouseName(beforeWarehouse) !== normalizeWarehouseName(expectedYardName);\n\t\t});\n\t}\n\tfunction chooseSyntheticPartInventoryStaleWarehouse(expectedYardName, yards) {\n\t\tconst expected = normalizeWarehouseName(expectedYardName);\n\t\tconst alternate = (Array.isArray(yards) ? yards : []).map((yard) => String(yard && yard.name || \"\").trim()).find((name) => name && normalizeWarehouseName(name) !== expected);\n\t\tif (alternate) return alternate;\n\t\treturn expected === \"midland\" ? \"Kermit\" : \"Midland\";\n\t}\n\tasync function ensurePartInventorySnapshotStaleBaseline(context, dayKey, data) {\n\t\tif (findPartInventorySnapshotStaleRows(data).length) {\n\t\t\treturn { data, syntheticStaleBaseline: false };\n\t\t}\n\t\tconst candidate = (Array.isArray(data && data.snapshots) ? data.snapshots : []).find((snapshot) => {\n\t\t\tconst yardId = partSnapshotRowYardId(snapshot);\n\t\t\tconst yard = yardId ? data.yardById.get(String(yardId)) : null;\n\t\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\t\treturn snapshot && snapshot._id && expectedYardName;\n\t\t});\n\t\tif (!candidate) {\n\t\t\treturn { data, syntheticStaleBaseline: false, syntheticSkippedReason: \"No seeded Part snapshot row had both _id and metadata.id_yard lineage.\" };\n\t\t}\n\t\tconst yardId = partSnapshotRowYardId(candidate);\n\t\tconst yard = yardId ? data.yardById.get(String(yardId)) : null;\n\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\tconst originalWarehouse = String(candidate.warehouse_location || candidate.location || \"\").trim();\n\t\tconst staleWarehouse = chooseSyntheticPartInventoryStaleWarehouse(expectedYardName, data.yards);\n\t\tconst { MongoClient } = mongoRequire();\n\t\tconst client = new MongoClient(safeLocalMongoUrl());\n\t\tawait client.connect();\n\t\ttry {\n\t\t\tawait client.db().collection(\"inventory-daily-snapshots\").updateOne(\n\t\t\t\t{ _id: candidate._id },\n\t\t\t\t{\n\t\t\t\t\t$set: {\n\t\t\t\t\t\twarehouse_location: staleWarehouse,\n\t\t\t\t\t\tlocation: staleWarehouse,\n\t\t\t\t\t\t\"metadata.resolveio_qa_synthetic_stale_baseline\": true,\n\t\t\t\t\t\t\"metadata.resolveio_qa_original_warehouse_location\": originalWarehouse,\n\t\t\t\t\t\t\"metadata.resolveio_qa_expected_warehouse_location\": expectedYardName,\n\t\t\t\t\t\t\"metadata.resolveio_qa_synthetic_stale_at\": new Date().toISOString()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\t\t} finally {\n\t\t\tawait client.close().catch(() => undefined);\n\t\t}\n\t\tconst refreshedData = await readPartInventorySnapshotProofData(context, dayKey);\n\t\treturn {\n\t\t\tdata: refreshedData,\n\t\t\tsyntheticStaleBaseline: true,\n\t\t\tsyntheticBaseline: {\n\t\t\t\tcollection: \"inventory-daily-snapshots\",\n\t\t\t\t_id: String(candidate._id || \"\"),\n\t\t\t\tpartId: partSnapshotRowPartId(candidate),\n\t\t\t\titemName: String(candidate.item_name || candidate.name || \"\"),\n\t\t\t\tdayKey,\n\t\t\t\toriginalWarehouse,\n\t\t\t\tstaleWarehouse,\n\t\t\t\texpectedYardName\n\t\t\t}\n\t\t};\n\t}\n\tasync function renderPartInventorySnapshotProofScreenshot(page, payload, rowRoute, screenshotPath) {\n\tconst escapeHtml = (value) => String(value === undefined || value === null ? \"\" : value).replace(/[&<>\"']/g, (char) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", \"\"\": \""\", \"'\": \"'\" }[char]));\n\tconst comparisons = (payload.comparisons || []).slice(0, 12).map((entry) => \"<tr><td>\" + escapeHtml(entry.partId || entry.itemName || \"part\") + \"</td><td>\" + escapeHtml(entry.beforeWarehouse || \"\") + \"</td><td>\" + escapeHtml(entry.expectedYardName || \"\") + \"</td><td>\" + escapeHtml(entry.afterWarehouse || \"\") + \"</td><td>\" + (entry.pass ? \"<span class=\"ok\">PASS</span>\" : \"<span class=\"bad\">FAIL</span>\") + \"</td></tr>\").join(\"\");\n\tconst html = \"<!doctype html><html><head><meta charset=\"utf-8\"><style>body{margin:0;background:#f5f7fb;color:#111827;font-family:Arial,Helvetica,sans-serif}.wrap{padding:42px 52px}.eyebrow{font-size:16px;text-transform:uppercase;color:#475569;font-weight:700}.title{font-size:34px;font-weight:800;margin:10px 0}.caption{font-size:20px;line-height:1.35;color:#1f2937;margin:0 0 22px}.grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px;margin:22px 0}.card{background:white;border:2px solid #d7dde8;border-radius:8px;padding:18px}.label{font-size:14px;color:#64748b;font-weight:700;text-transform:uppercase}.value{font-size:28px;font-weight:800;margin-top:8px}.ok{color:#047857;font-weight:800}.bad{color:#b91c1c;font-weight:800}table{width:100%;border-collapse:collapse;background:white;border:2px solid #d7dde8;border-radius:8px;overflow:hidden;font-size:17px}th{background:#111827;color:white;text-align:left;padding:12px}td{border-top:1px solid #e5e7eb;padding:12px}.footer{margin-top:20px;font-size:16px;color:#475569}.path{font-family:Menlo,Consolas,monospace;font-size:14px;color:#334155}</style></head><body><main class=\"wrap\"><div class=\"eyebrow\">ResolveIO Support QA Business Proof</div><div class=\"title\">Part Inventory Snapshot Warehouse Attribution</div><p class=\"caption\">\" + escapeHtml(payload.caption || \"\") + \"</p><section class=\"grid\"><div class=\"card\"><div class=\"label\">Report Method</div><div class=\"value\">reportDailyInventorySnapshot</div></div><div class=\"card\"><div class=\"label\">Snapshot Date</div><div class=\"value\">\" + escapeHtml(payload.dayKey || \"\") + \"</div></div><div class=\"card\"><div class=\"label\">Stale Rows Corrected</div><div class=\"value \" + (payload.pass ? \"ok\" : \"bad\") + \"\">\" + Number(payload.correctedStaleRows || 0) + \"/\" + Number(payload.staleRows || 0) + \"</div></div></section><table><thead><tr><th>Part</th><th>Before Saved Warehouse</th><th>Expected Yard</th><th>Method Response Warehouse</th><th>Result</th></tr></thead><tbody>\" + comparisons + \"</tbody></table><div class=\"footer\">Before: saved historical Parts snapshot rows contained stale warehouse_location values. Action: called reportDailyInventorySnapshot(date, [\"Parts\"]) on the local QA server. After: the method response used the authoritative yard lineage for the affected part rows.</div><div class=\"footer path\">Route: \" + escapeHtml(rowRoute || targetRoute) + \" | Artifacts: qa-part-inventory-snapshot-proof.json, aiqa-business-assertion.json, qa-coverage-matrix.json</div></main></body></html>\";\n\tawait page.setViewport({ width: Math.max(viewportWidth, 1600), height: Math.max(viewportHeight, 900) }).catch(() => undefined);\n\tawait page.setContent(html, { waitUntil: \"domcontentloaded\", timeout: 30000 });\n\tawait page.screenshot({ path: screenshotPath, type: \"png\", fullPage: false });\n}\nasync function runPartInventorySnapshotMethodProof(page, routeSummary, auth) {\n\tif (!shouldRunPartInventorySnapshotProof()) return null;\n\tconst context = readSeedPartInventorySnapshotContext();\n\tconst row = activeMatrixRow();\n\tconst rowRoute = String(row.route || row.screen || \"/print\").trim() || \"/print\";\n\tconst rowWorkflow = String(row.workflow || row.action_under_test || \"Invoke reportDailyInventorySnapshot(date, [\"Parts\"]) and verify Part warehouse_location uses authoritative yard lineage.\").trim();\n\tconst proofPath = path.join(artifactDir, \"qa-part-inventory-snapshot-proof.json\");\n\tconst businessAssertionPath = path.join(artifactDir, \"aiqa-business-assertion.json\");\n\tconst beforeAfterScreenshotPath = path.join(artifactDir, \"support-business-proof-before-after.png\");\n\tconst requestedDayKeys = uniqueStrings(context.day_keys || []).map(normalizePartSnapshotDayKey).filter(Boolean);\n\tconst dayKey = requestedDayKeys[0] || normalizePartSnapshotDayKey(new Date(Date.now() - 86400000).toISOString());\n\tconst writeFailed = async (message, extra) => {\n\t\tconst payload = { status: \"failed\", targetRoute: rowRoute, dayKey, context, error: message, ...(extra || {}), updated_at: new Date().toISOString() };\n\t\twriteJson(proofPath, payload);\n\t\twriteJson(businessAssertionPath, { assertion: String(row.assertion || row.required_proof || \"Part inventory snapshot warehouse attribution proof\"), status: \"failed\", result: \"business_assertion_failed\", outcome: \"business_assertion_failed\", workflow: rowWorkflow, route: rowRoute, before: \"\", action: \"Attempted deterministic reportDailyInventorySnapshot websocket method proof.\", expected: \"Affected Part rows return the yard named by snapshot metadata.id_yard instead of stale saved warehouse_location.\", after: \"\", observed: message, dataProof: message, mongoDelta: {}, artifactPaths: [proofPath, matrixPath], metadata: { supportDiagnosisProof: false, proofType: \"part_inventory_snapshot_report_method\", generatedBy: \"resolveio_runner_part_inventory_snapshot_business_proof\", generatedAt: new Date().toISOString() } });\n\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };\n\t\tconst rows = matrixRows(matrix);\n\t\tconst activeIndex = Math.max(0, rows.indexOf(row));\n\t\tif (rows[activeIndex]) { rows[activeIndex].status = \"failed\"; rows[activeIndex].result = \"failed\"; rows[activeIndex].acceptance_blocked = true; rows[activeIndex].blocker = message; rows[activeIndex].artifact = proofPath; }\n\t\tmatrix.rows = rows;\n\t\tmatrix.status = \"failed\";\n\t\tmatrix.part_inventory_snapshot_proof = proofPath;\n\t\tmatrix.aiqa_business_assertion = businessAssertionPath;\n\t\tmatrix.updated_at = new Date().toISOString();\n\t\twriteJson(matrixPath, matrix);\n\t\treturn payload;\n\t\t};\n\t\ttry {\n\t\t\tlet data = await readPartInventorySnapshotProofData(context, dayKey);\n\t\t\tif (!data.snapshots.length) return await writeFailed(\"No seeded Part inventory daily snapshot rows were available for day_key \" + dayKey + \".\");\n\t\t\tconst baseline = await ensurePartInventorySnapshotStaleBaseline(context, dayKey, data);\n\t\t\tdata = baseline.data || data;\n\t\t\tconst methodResult = await callResolveIOMethodViaWs(auth, rowRoute, \"reportDailyInventorySnapshot\", [methodDateFromDayKey(dayKey), [\"Parts\"]]);\n\t\tconst responseRows = Array.isArray(methodResult && methodResult.rows) ? methodResult.rows : [];\n\t\tconst comparisons = data.snapshots.map((snapshot) => {\n\t\t\tconst partId = partSnapshotRowPartId(snapshot);\n\t\t\tconst yardId = partSnapshotRowYardId(snapshot);\n\t\t\tconst yard = yardId ? data.yardById.get(String(yardId)) : null;\n\t\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\t\tconst beforeWarehouse = String(snapshot.warehouse_location || snapshot.location || \"\").trim();\n\t\t\tconst responseCandidates = responseRows.filter((candidate) => !partId || partSnapshotRowPartId(candidate) === partId || String(candidate.item_name || candidate.name || \"\") === String(snapshot.item_name || snapshot.name || \"\"));\n\t\t\tconst afterRow = responseCandidates.find((candidate) => expectedYardName && normalizeWarehouseName(candidate.warehouse_location || candidate.location) === normalizeWarehouseName(expectedYardName)) || responseCandidates[0] || null;\n\t\t\tconst afterWarehouse = String(afterRow && (afterRow.warehouse_location || afterRow.location) || \"\").trim();\n\t\t\tconst staleBefore = !!expectedYardName && !!beforeWarehouse && normalizeWarehouseName(beforeWarehouse) !== normalizeWarehouseName(expectedYardName);\n\t\t\treturn { partId, itemName: String(snapshot.item_name || snapshot.name || \"\"), dayKey: String(snapshot.day_key || \"\"), beforeWarehouse, expectedYardName, afterWarehouse, staleBefore, pass: staleBefore && !!afterWarehouse && normalizeWarehouseName(afterWarehouse) === normalizeWarehouseName(expectedYardName) };\n\t\t}).filter((entry) => entry.expectedYardName);\n\t\tconst staleRows = comparisons.filter((entry) => entry.staleBefore);\n\t\tconst passedRows = staleRows.filter((entry) => entry.pass);\n\t\t\tconst pass = staleRows.length > 0 && passedRows.length === staleRows.length;\n\t\t\tconst caption = pass\n\t\t\t\t? \"Part inventory snapshot proof passed: \" + passedRows.length + \" stale saved row(s) returned the authoritative yard warehouse in reportDailyInventorySnapshot\" + (baseline.syntheticStaleBaseline ? \" using a local-only stale baseline copied from seeded live data.\" : \".\")\n\t\t\t\t: \"Part inventory snapshot proof failed: staleRows=\" + staleRows.length + \", corrected=\" + passedRows.length + (baseline.syntheticSkippedReason ? \"; synthetic baseline skipped: \" + baseline.syntheticSkippedReason : \"\") + \".\";\n\t\t\tconst payload = { status: pass ? \"pass\" : \"failed\", targetRoute: rowRoute, dayKey, methodName: \"reportDailyInventorySnapshot\", context, snapshotCount: data.snapshots.length, responseRowCount: responseRows.length, staleRows: staleRows.length, correctedStaleRows: passedRows.length, syntheticStaleBaseline: !!baseline.syntheticStaleBaseline, syntheticBaseline: baseline.syntheticBaseline || null, comparisons, caption, screenshot: beforeAfterScreenshotPath, page: routeSummary, updated_at: new Date().toISOString() };\n\t\tawait renderPartInventorySnapshotProofScreenshot(page, payload, rowRoute, beforeAfterScreenshotPath).catch(() => undefined);\n\t\twriteJson(proofPath, payload);\n\t\tconst businessAssertion = {\n\t\t\tassertion: String(row.assertion || row.required_proof || \"Affected Part warehouse_location maps to authoritative yard lineage in reportDailyInventorySnapshot response.\").trim(),\n\t\t\tstatus: pass ? \"pass\" : \"failed\",\n\t\t\tresult: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",\n\t\t\toutcome: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",\n\t\t\tworkflow: rowWorkflow,\n\t\t\troute: rowRoute,\n\t\t\t\tbefore: (baseline.syntheticStaleBaseline ? \"Local QA created a stale saved Parts snapshot baseline from copied seeded data for day_key \" + dayKey + \": \" + String((baseline.syntheticBaseline && (baseline.syntheticBaseline.itemName || baseline.syntheticBaseline.partId)) || \"part\") + \"=\" + String((baseline.syntheticBaseline && baseline.syntheticBaseline.staleWarehouse) || \"\") + \" while expected yard lineage was \" + String((baseline.syntheticBaseline && baseline.syntheticBaseline.expectedYardName) || \"\") + \". \" : \"\") + \"Saved non-today Parts snapshot rows for day_key \" + dayKey + \" included \" + staleRows.length + \" stale warehouse_location value(s): \" + staleRows.map((entry) => (entry.itemName || entry.partId) + \"=\" + entry.beforeWarehouse).join(\"; \"),\n\t\t\taction: \"Called reportDailyInventorySnapshot(\" + dayKey + \", [\"Parts\"]) through the local QA websocket method path.\",\n\t\t\texpected: \"Every affected stale Part row returns the yard named by metadata.id_yard in warehouse_location.\",\n\t\t\tafter: \"Method response corrected \" + passedRows.length + \" of \" + staleRows.length + \" stale row(s): \" + passedRows.map((entry) => (entry.itemName || entry.partId) + \"=\" + entry.afterWarehouse).join(\"; \"),\n\t\t\tobserved: caption,\n\t\t\tdataProof: comparisons.map((entry) => (entry.itemName || entry.partId || \"part\") + \": before=\" + entry.beforeWarehouse + \", expected=\" + entry.expectedYardName + \", after=\" + entry.afterWarehouse + \", pass=\" + entry.pass).join(\"\n\"),\n\t\t\t\tmongoDelta: { collection: \"inventory-daily-snapshots\", day_key: dayKey, staleRows: staleRows.length, correctedStaleRows: passedRows.length, responseRowCount: responseRows.length, syntheticStaleBaseline: !!baseline.syntheticStaleBaseline, syntheticBaseline: baseline.syntheticBaseline || null },\n\t\t\t\tartifactPaths: [proofPath, beforeAfterScreenshotPath, matrixPath],\n\t\t\t\tmetadata: { supportDiagnosisProof: pass, proofType: \"part_inventory_snapshot_report_method\", methodPath: \"server/src/methods/report.ts reportDailyInventorySnapshot\", generatedBy: \"resolveio_runner_part_inventory_snapshot_business_proof\", syntheticStaleBaseline: !!baseline.syntheticStaleBaseline, generatedAt: new Date().toISOString() }\n\t\t};\n\t\twriteJson(businessAssertionPath, businessAssertion);\n\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };\n\t\tconst rows = matrixRows(matrix);\n\t\tconst rowIndex = rows.findIndex((candidate) => String(candidate && candidate.workflow || \"\") === rowWorkflow) >= 0 ? rows.findIndex((candidate) => String(candidate && candidate.workflow || \"\") === rowWorkflow) : rows.findIndex((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\")));\n\t\tconst activeIndex = rowIndex >= 0 ? rowIndex : 0;\n\t\tif (rows[activeIndex]) {\n\t\t\trows[activeIndex].status = pass ? \"pass\" : \"failed\";\n\t\t\trows[activeIndex].result = pass ? \"pass\" : \"failed\";\n\t\t\trows[activeIndex].acceptance_blocked = !pass;\n\t\t\trows[activeIndex].screenshot = beforeAfterScreenshotPath;\n\t\t\trows[activeIndex].screenshots = [beforeAfterScreenshotPath, passScreenshotPath].filter(Boolean);\n\t\t\trows[activeIndex].caption = caption;\n\t\t\trows[activeIndex].artifact = proofPath;\n\t\t\trows[activeIndex].artifacts = [{ path: proofPath, caption: \"Part inventory snapshot method response proof.\" }, { screenshot: beforeAfterScreenshotPath, caption }, { path: businessAssertionPath, caption: \"AIQaBusinessAssertion for support diagnosis proof plan.\" }];\n\t\t\trows[activeIndex].persisted_assertion = businessAssertion.dataProof;\n\t\t\tif (!pass) rows[activeIndex].blocker = caption;\n\t\t}\n\t\tmatrix.rows = rows;\n\t\tmatrix.status = pass ? \"pass\" : \"failed\";\n\t\tmatrix.part_inventory_snapshot_proof = proofPath;\n\t\tmatrix.aiqa_business_assertion = businessAssertionPath;\n\t\tmatrix.updated_at = new Date().toISOString();\n\t\twriteJson(matrixPath, matrix);\n\t\treturn payload;\n\t} catch (error) {\n\t\treturn await writeFailed(error && (error.stack || error.message) || String(error));\n\t}\n}\n"], ["\nfunction activeMatrixRow() {\n\tconst matrix = readJson(matrixPath) || {};\n\tconst rows = matrixRows(matrix);\n\treturn rows.find((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\"))) || rows[0] || {};\n}\nfunction readSeedPartInventorySnapshotContext() {\n\tconst seed = readJson(path.join(artifactDir, \"qa-live-data-seed-result.json\")) || {};\n\tconst selected = seed && seed.selected || {};\n\tconst context = selected.part_inventory_snapshot_context || selected.partInventorySnapshotContext || null;\n\tif (!context || typeof context !== \"object\") return null;\n\tconst partIds = uniqueStrings(context.part_ids || context.partIds || []);\n\tconst dayKeys = uniqueStrings(context.day_keys || context.dayKeys || []);\n\tif (!partIds.length && !dayKeys.length && !Number(context.snapshot_count || context.snapshotCount || 0)) return null;\n\treturn { ...context, part_ids: partIds, day_keys: dayKeys };\n}\nfunction shouldRunPartInventorySnapshotProof() {\n\tconst context = readSeedPartInventorySnapshotContext();\n\tif (!context) return false;\n\tconst text = [activeRowText(), targetRoute].join(\"\\n\");\n\treturn /\\b(reportDailyInventorySnapshot|inventory-daily-snapshots|daily\\s+inventory\\s+snapshot|part\\s+inventory\\s+snapshot|warehouse_location|Parts)\\b/i.test(text);\n}\nfunction normalizePartSnapshotDayKey(value) {\n\tconst text = String(value || \"\").trim();\n\tconst match = /\\d{4}-\\d{2}-\\d{2}/.exec(text);\n\tif (match) return match[0];\n\tconst date = new Date(text);\n\treturn Number.isFinite(date.getTime()) ? date.toISOString().slice(0, 10) : \"\";\n}\nfunction partSnapshotRowPartId(row) {\n\tconst metadata = row && typeof row.metadata === \"object\" ? row.metadata : {};\n\treturn String(metadata.id_part || row.id_part || row.id_item || row.id_source || \"\").trim();\n}\nfunction partSnapshotRowYardId(row) {\n\tconst metadata = row && typeof row.metadata === \"object\" ? row.metadata : {};\n\tconst explicit = String(metadata.id_yard || row.id_yard || row.id_warehouse_location || \"\").trim();\n\tif (explicit) return explicit;\n\tconst source = String(row && row.id_source || \"\");\n\tconst sourceMatch = /^yard:([A-Za-z0-9_-]+)/i.exec(source);\n\treturn sourceMatch ? sourceMatch[1] : \"\";\n}\nfunction normalizeWarehouseName(value) {\n\treturn String(value || \"\").trim().toLowerCase().replace(/\\s+/g, \" \");\n}\nfunction methodDateFromDayKey(dayKey) {\n\treturn new Date(dayKey + \"T12:00:00.000Z\");\n}\nfunction resolveWsUrl() {\n\tif (/^https:/i.test(serverUrl)) return serverUrl.replace(/^https:/i, \"wss:\");\n\tif (/^http:/i.test(serverUrl)) return serverUrl.replace(/^http:/i, \"ws:\");\n\treturn serverUrl;\n}\nfunction callResolveIOMethodViaWs(auth, route, methodName, args) {\n\treturn new Promise((resolve, reject) => {\n\t\tconst token = auth && auth.accessToken;\n\t\tif (!token) {\n\t\t\treject(new Error(\"Missing access token for websocket method proof.\"));\n\t\t\treturn;\n\t\t}\n\t\tconst WebSocket = requireQaModule(\"ws\");\n\t\tconst { unpack } = requireQaModule(\"msgpackr\");\n\t\tconst ws = new WebSocket(resolveWsUrl(), [token], { origin: clientUrl });\n\t\tconst messageId = Date.now() + Math.floor(Math.random() * 100000);\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttry { ws.close(); } catch (error) {}\n\t\t\treject(new Error(\"Timed out waiting for \" + methodName + \" websocket response.\"));\n\t\t}, Number(process.env.RESOLVEIO_SUPPORT_QA_METHOD_PROOF_TIMEOUT_MS || process.env.RESOLVEIO_RUNNER_QA_METHOD_PROOF_TIMEOUT_MS || 30000));\n\t\tlet settled = false;\n\t\tconst finish = (error, value) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timeout);\n\t\t\ttry { ws.close(); } catch (closeError) {}\n\t\t\tif (error) reject(error);\n\t\t\telse resolve(value);\n\t\t};\n\t\tws.on(\"open\", () => {\n\t\t\tconst payload = [[route || \"/\", new Date().toISOString(), messageId, \"method\", methodName, ...(args || [])]];\n\t\t\tws.send(JSON.stringify(payload));\n\t\t});\n\t\tws.on(\"message\", (raw) => {\n\t\t\tlet messages = [];\n\t\t\tconst text = Buffer.isBuffer(raw) ? raw.toString(\"utf8\") : String(raw || \"\");\n\t\t\tif (text === \"ping\") {\n\t\t\t\ttry { ws.send(\"pong\"); } catch (error) {}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst decoded = Buffer.isBuffer(raw) ? unpack(raw) : JSON.parse(text);\n\t\t\t\tmessages = Array.isArray(decoded) ? decoded : [decoded];\n\t\t\t}\n\t\t\tcatch (error) { return; }\n\t\t\tfor (const payload of messages) {\n\t\t\t\tif (!payload || payload.messageId !== messageId) continue;\n\t\t\t\tif (payload.data === \"ACK\" && payload.hasError === false) continue;\n\t\t\t\tif (payload.hasError) finish(new Error(typeof payload.data === \"string\" ? payload.data : JSON.stringify(payload.data || {})));\n\t\t\t\telse finish(null, payload.data);\n\t\t\t}\n\t\t});\n\t\tws.on(\"error\", (error) => finish(error));\n\t});\n}\n\tasync function readPartInventorySnapshotProofData(context, dayKey) {\n\t\tconst { MongoClient } = mongoRequire();\n\t\tconst client = new MongoClient(safeLocalMongoUrl());\n\tawait client.connect();\n\ttry {\n\t\tconst db = client.db();\n\t\tconst query = { section: \"Parts\" };\n\t\tif (dayKey) query.day_key = dayKey;\n\t\tconst partIds = uniqueStrings(context.part_ids || []);\n\t\tif (partIds.length) query.$or = [{ \"metadata.id_part\": { $in: partIds } }, { id_part: { $in: partIds } }];\n\t\tconst snapshots = await db.collection(\"inventory-daily-snapshots\").find(query).sort({ day_key: -1, item_name: 1, location: 1 }).limit(120).toArray();\n\t\tconst yardIds = uniqueStrings(snapshots.map(partSnapshotRowYardId));\n\t\tconst yards = yardIds.length ? await db.collection(\"yards\").find({ _id: { $in: yardIds } }).project({ _id: 1, name: 1 }).toArray() : [];\n\t\tconst yardById = new Map(yards.map((yard) => [String(yard._id), yard]));\n\t\treturn { snapshots, yards, yardById };\n\t} finally {\n\t\t\tawait client.close().catch(() => undefined);\n\t\t}\n\t}\n\tfunction findPartInventorySnapshotStaleRows(data) {\n\t\tconst yardById = data && data.yardById instanceof Map ? data.yardById : new Map();\n\t\treturn (Array.isArray(data && data.snapshots) ? data.snapshots : []).filter((snapshot) => {\n\t\t\tconst yardId = partSnapshotRowYardId(snapshot);\n\t\t\tconst yard = yardId ? yardById.get(String(yardId)) : null;\n\t\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\t\tconst beforeWarehouse = String(snapshot && (snapshot.warehouse_location || snapshot.location) || \"\").trim();\n\t\t\treturn !!expectedYardName && !!beforeWarehouse && normalizeWarehouseName(beforeWarehouse) !== normalizeWarehouseName(expectedYardName);\n\t\t});\n\t}\n\tfunction chooseSyntheticPartInventoryStaleWarehouse(expectedYardName, yards) {\n\t\tconst expected = normalizeWarehouseName(expectedYardName);\n\t\tconst alternate = (Array.isArray(yards) ? yards : []).map((yard) => String(yard && yard.name || \"\").trim()).find((name) => name && normalizeWarehouseName(name) !== expected);\n\t\tif (alternate) return alternate;\n\t\treturn expected === \"midland\" ? \"Kermit\" : \"Midland\";\n\t}\n\tasync function ensurePartInventorySnapshotStaleBaseline(context, dayKey, data) {\n\t\tif (findPartInventorySnapshotStaleRows(data).length) {\n\t\t\treturn { data, syntheticStaleBaseline: false };\n\t\t}\n\t\tconst candidate = (Array.isArray(data && data.snapshots) ? data.snapshots : []).find((snapshot) => {\n\t\t\tconst yardId = partSnapshotRowYardId(snapshot);\n\t\t\tconst yard = yardId ? data.yardById.get(String(yardId)) : null;\n\t\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\t\treturn snapshot && snapshot._id && expectedYardName;\n\t\t});\n\t\tif (!candidate) {\n\t\t\treturn { data, syntheticStaleBaseline: false, syntheticSkippedReason: \"No seeded Part snapshot row had both _id and metadata.id_yard lineage.\" };\n\t\t}\n\t\tconst yardId = partSnapshotRowYardId(candidate);\n\t\tconst yard = yardId ? data.yardById.get(String(yardId)) : null;\n\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\tconst originalWarehouse = String(candidate.warehouse_location || candidate.location || \"\").trim();\n\t\tconst staleWarehouse = chooseSyntheticPartInventoryStaleWarehouse(expectedYardName, data.yards);\n\t\tconst { MongoClient } = mongoRequire();\n\t\tconst client = new MongoClient(safeLocalMongoUrl());\n\t\tawait client.connect();\n\t\ttry {\n\t\t\tawait client.db().collection(\"inventory-daily-snapshots\").updateOne(\n\t\t\t\t{ _id: candidate._id },\n\t\t\t\t{\n\t\t\t\t\t$set: {\n\t\t\t\t\t\twarehouse_location: staleWarehouse,\n\t\t\t\t\t\tlocation: staleWarehouse,\n\t\t\t\t\t\t\"metadata.resolveio_qa_synthetic_stale_baseline\": true,\n\t\t\t\t\t\t\"metadata.resolveio_qa_original_warehouse_location\": originalWarehouse,\n\t\t\t\t\t\t\"metadata.resolveio_qa_expected_warehouse_location\": expectedYardName,\n\t\t\t\t\t\t\"metadata.resolveio_qa_synthetic_stale_at\": new Date().toISOString()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\t\t} finally {\n\t\t\tawait client.close().catch(() => undefined);\n\t\t}\n\t\tconst refreshedData = await readPartInventorySnapshotProofData(context, dayKey);\n\t\treturn {\n\t\t\tdata: refreshedData,\n\t\t\tsyntheticStaleBaseline: true,\n\t\t\tsyntheticBaseline: {\n\t\t\t\tcollection: \"inventory-daily-snapshots\",\n\t\t\t\t_id: String(candidate._id || \"\"),\n\t\t\t\tpartId: partSnapshotRowPartId(candidate),\n\t\t\t\titemName: String(candidate.item_name || candidate.name || \"\"),\n\t\t\t\tdayKey,\n\t\t\t\toriginalWarehouse,\n\t\t\t\tstaleWarehouse,\n\t\t\t\texpectedYardName\n\t\t\t}\n\t\t};\n\t}\n\tasync function renderPartInventorySnapshotProofScreenshot(page, payload, rowRoute, screenshotPath) {\n\tconst escapeHtml = (value) => String(value === undefined || value === null ? \"\" : value).replace(/[&<>\"']/g, (char) => ({ \"&\": \"&\", \"<\": \"<\", \">\": \">\", \"\\\"\": \""\", \"'\": \"'\" }[char]));\n\tconst comparisons = (payload.comparisons || []).slice(0, 12).map((entry) => \"<tr><td>\" + escapeHtml(entry.partId || entry.itemName || \"part\") + \"</td><td>\" + escapeHtml(entry.beforeWarehouse || \"\") + \"</td><td>\" + escapeHtml(entry.expectedYardName || \"\") + \"</td><td>\" + escapeHtml(entry.afterWarehouse || \"\") + \"</td><td>\" + (entry.pass ? \"<span class=\\\"ok\\\">PASS</span>\" : \"<span class=\\\"bad\\\">FAIL</span>\") + \"</td></tr>\").join(\"\");\n\tconst html = \"<!doctype html><html><head><meta charset=\\\"utf-8\\\"><style>body{margin:0;background:#f5f7fb;color:#111827;font-family:Arial,Helvetica,sans-serif}.wrap{padding:42px 52px}.eyebrow{font-size:16px;text-transform:uppercase;color:#475569;font-weight:700}.title{font-size:34px;font-weight:800;margin:10px 0}.caption{font-size:20px;line-height:1.35;color:#1f2937;margin:0 0 22px}.grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px;margin:22px 0}.card{background:white;border:2px solid #d7dde8;border-radius:8px;padding:18px}.label{font-size:14px;color:#64748b;font-weight:700;text-transform:uppercase}.value{font-size:28px;font-weight:800;margin-top:8px}.ok{color:#047857;font-weight:800}.bad{color:#b91c1c;font-weight:800}table{width:100%;border-collapse:collapse;background:white;border:2px solid #d7dde8;border-radius:8px;overflow:hidden;font-size:17px}th{background:#111827;color:white;text-align:left;padding:12px}td{border-top:1px solid #e5e7eb;padding:12px}.footer{margin-top:20px;font-size:16px;color:#475569}.path{font-family:Menlo,Consolas,monospace;font-size:14px;color:#334155}</style></head><body><main class=\\\"wrap\\\"><div class=\\\"eyebrow\\\">ResolveIO Support QA Business Proof</div><div class=\\\"title\\\">Part Inventory Snapshot Warehouse Attribution</div><p class=\\\"caption\\\">\" + escapeHtml(payload.caption || \"\") + \"</p><section class=\\\"grid\\\"><div class=\\\"card\\\"><div class=\\\"label\\\">Report Method</div><div class=\\\"value\\\">reportDailyInventorySnapshot</div></div><div class=\\\"card\\\"><div class=\\\"label\\\">Snapshot Date</div><div class=\\\"value\\\">\" + escapeHtml(payload.dayKey || \"\") + \"</div></div><div class=\\\"card\\\"><div class=\\\"label\\\">Stale Rows Corrected</div><div class=\\\"value \" + (payload.pass ? \"ok\" : \"bad\") + \"\\\">\" + Number(payload.correctedStaleRows || 0) + \"/\" + Number(payload.staleRows || 0) + \"</div></div></section><table><thead><tr><th>Part</th><th>Before Saved Warehouse</th><th>Expected Yard</th><th>Method Response Warehouse</th><th>Result</th></tr></thead><tbody>\" + comparisons + \"</tbody></table><div class=\\\"footer\\\">Before: saved historical Parts snapshot rows contained stale warehouse_location values. Action: called reportDailyInventorySnapshot(date, [\\\"Parts\\\"]) on the local QA server. After: the method response used the authoritative yard lineage for the affected part rows.</div><div class=\\\"footer path\\\">Route: \" + escapeHtml(rowRoute || targetRoute) + \" | Artifacts: qa-part-inventory-snapshot-proof.json, aiqa-business-assertion.json, qa-coverage-matrix.json</div></main></body></html>\";\n\tawait page.setViewport({ width: Math.max(viewportWidth, 1600), height: Math.max(viewportHeight, 900) }).catch(() => undefined);\n\tawait page.setContent(html, { waitUntil: \"domcontentloaded\", timeout: 30000 });\n\tawait page.screenshot({ path: screenshotPath, type: \"png\", fullPage: false });\n}\nasync function runPartInventorySnapshotMethodProof(page, routeSummary, auth) {\n\tif (!shouldRunPartInventorySnapshotProof()) return null;\n\tconst context = readSeedPartInventorySnapshotContext();\n\tconst row = activeMatrixRow();\n\tconst rowRoute = String(row.route || row.screen || \"/print\").trim() || \"/print\";\n\tconst rowWorkflow = String(row.workflow || row.action_under_test || \"Invoke reportDailyInventorySnapshot(date, [\\\"Parts\\\"]) and verify Part warehouse_location uses authoritative yard lineage.\").trim();\n\tconst proofPath = path.join(artifactDir, \"qa-part-inventory-snapshot-proof.json\");\n\tconst businessAssertionPath = path.join(artifactDir, \"aiqa-business-assertion.json\");\n\tconst beforeAfterScreenshotPath = path.join(artifactDir, \"support-business-proof-before-after.png\");\n\tconst requestedDayKeys = uniqueStrings(context.day_keys || []).map(normalizePartSnapshotDayKey).filter(Boolean);\n\tconst dayKey = requestedDayKeys[0] || normalizePartSnapshotDayKey(new Date(Date.now() - 86400000).toISOString());\n\tconst writeFailed = async (message, extra) => {\n\t\tconst payload = { status: \"failed\", targetRoute: rowRoute, dayKey, context, error: message, ...(extra || {}), updated_at: new Date().toISOString() };\n\t\twriteJson(proofPath, payload);\n\t\twriteJson(businessAssertionPath, { assertion: String(row.assertion || row.required_proof || \"Part inventory snapshot warehouse attribution proof\"), status: \"failed\", result: \"business_assertion_failed\", outcome: \"business_assertion_failed\", workflow: rowWorkflow, route: rowRoute, before: \"\", action: \"Attempted deterministic reportDailyInventorySnapshot websocket method proof.\", expected: \"Affected Part rows return the yard named by snapshot metadata.id_yard instead of stale saved warehouse_location.\", after: \"\", observed: message, dataProof: message, mongoDelta: {}, artifactPaths: [proofPath, matrixPath], metadata: { supportDiagnosisProof: false, proofType: \"part_inventory_snapshot_report_method\", generatedBy: \"resolveio_runner_part_inventory_snapshot_business_proof\", generatedAt: new Date().toISOString() } });\n\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };\n\t\tconst rows = matrixRows(matrix);\n\t\tconst activeIndex = Math.max(0, rows.indexOf(row));\n\t\tif (rows[activeIndex]) { rows[activeIndex].status = \"failed\"; rows[activeIndex].result = \"failed\"; rows[activeIndex].acceptance_blocked = true; rows[activeIndex].blocker = message; rows[activeIndex].artifact = proofPath; }\n\t\tmatrix.rows = rows;\n\t\tmatrix.status = \"failed\";\n\t\tmatrix.part_inventory_snapshot_proof = proofPath;\n\t\tmatrix.aiqa_business_assertion = businessAssertionPath;\n\t\tmatrix.updated_at = new Date().toISOString();\n\t\twriteJson(matrixPath, matrix);\n\t\treturn payload;\n\t\t};\n\t\ttry {\n\t\t\tlet data = await readPartInventorySnapshotProofData(context, dayKey);\n\t\t\tif (!data.snapshots.length) return await writeFailed(\"No seeded Part inventory daily snapshot rows were available for day_key \" + dayKey + \".\");\n\t\t\tconst baseline = await ensurePartInventorySnapshotStaleBaseline(context, dayKey, data);\n\t\t\tdata = baseline.data || data;\n\t\t\tconst methodResult = await callResolveIOMethodViaWs(auth, rowRoute, \"reportDailyInventorySnapshot\", [methodDateFromDayKey(dayKey), [\"Parts\"]]);\n\t\tconst responseRows = Array.isArray(methodResult && methodResult.rows) ? methodResult.rows : [];\n\t\tconst comparisons = data.snapshots.map((snapshot) => {\n\t\t\tconst partId = partSnapshotRowPartId(snapshot);\n\t\t\tconst yardId = partSnapshotRowYardId(snapshot);\n\t\t\tconst yard = yardId ? data.yardById.get(String(yardId)) : null;\n\t\t\tconst expectedYardName = String(yard && yard.name || \"\").trim();\n\t\t\tconst beforeWarehouse = String(snapshot.warehouse_location || snapshot.location || \"\").trim();\n\t\t\tconst responseCandidates = responseRows.filter((candidate) => !partId || partSnapshotRowPartId(candidate) === partId || String(candidate.item_name || candidate.name || \"\") === String(snapshot.item_name || snapshot.name || \"\"));\n\t\t\tconst afterRow = responseCandidates.find((candidate) => expectedYardName && normalizeWarehouseName(candidate.warehouse_location || candidate.location) === normalizeWarehouseName(expectedYardName)) || responseCandidates[0] || null;\n\t\t\tconst afterWarehouse = String(afterRow && (afterRow.warehouse_location || afterRow.location) || \"\").trim();\n\t\t\tconst staleBefore = !!expectedYardName && !!beforeWarehouse && normalizeWarehouseName(beforeWarehouse) !== normalizeWarehouseName(expectedYardName);\n\t\t\treturn { partId, itemName: String(snapshot.item_name || snapshot.name || \"\"), dayKey: String(snapshot.day_key || \"\"), beforeWarehouse, expectedYardName, afterWarehouse, staleBefore, pass: staleBefore && !!afterWarehouse && normalizeWarehouseName(afterWarehouse) === normalizeWarehouseName(expectedYardName) };\n\t\t}).filter((entry) => entry.expectedYardName);\n\t\tconst staleRows = comparisons.filter((entry) => entry.staleBefore);\n\t\tconst passedRows = staleRows.filter((entry) => entry.pass);\n\t\t\tconst pass = staleRows.length > 0 && passedRows.length === staleRows.length;\n\t\t\tconst caption = pass\n\t\t\t\t? \"Part inventory snapshot proof passed: \" + passedRows.length + \" stale saved row(s) returned the authoritative yard warehouse in reportDailyInventorySnapshot\" + (baseline.syntheticStaleBaseline ? \" using a local-only stale baseline copied from seeded live data.\" : \".\")\n\t\t\t\t: \"Part inventory snapshot proof failed: staleRows=\" + staleRows.length + \", corrected=\" + passedRows.length + (baseline.syntheticSkippedReason ? \"; synthetic baseline skipped: \" + baseline.syntheticSkippedReason : \"\") + \".\";\n\t\t\tconst payload = { status: pass ? \"pass\" : \"failed\", targetRoute: rowRoute, dayKey, methodName: \"reportDailyInventorySnapshot\", context, snapshotCount: data.snapshots.length, responseRowCount: responseRows.length, staleRows: staleRows.length, correctedStaleRows: passedRows.length, syntheticStaleBaseline: !!baseline.syntheticStaleBaseline, syntheticBaseline: baseline.syntheticBaseline || null, comparisons, caption, screenshot: beforeAfterScreenshotPath, page: routeSummary, updated_at: new Date().toISOString() };\n\t\tawait renderPartInventorySnapshotProofScreenshot(page, payload, rowRoute, beforeAfterScreenshotPath).catch(() => undefined);\n\t\twriteJson(proofPath, payload);\n\t\tconst businessAssertion = {\n\t\t\tassertion: String(row.assertion || row.required_proof || \"Affected Part warehouse_location maps to authoritative yard lineage in reportDailyInventorySnapshot response.\").trim(),\n\t\t\tstatus: pass ? \"pass\" : \"failed\",\n\t\t\tresult: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",\n\t\t\toutcome: pass ? \"business_assertion_passed\" : \"business_assertion_failed\",\n\t\t\tworkflow: rowWorkflow,\n\t\t\troute: rowRoute,\n\t\t\t\tbefore: (baseline.syntheticStaleBaseline ? \"Local QA created a stale saved Parts snapshot baseline from copied seeded data for day_key \" + dayKey + \": \" + String((baseline.syntheticBaseline && (baseline.syntheticBaseline.itemName || baseline.syntheticBaseline.partId)) || \"part\") + \"=\" + String((baseline.syntheticBaseline && baseline.syntheticBaseline.staleWarehouse) || \"\") + \" while expected yard lineage was \" + String((baseline.syntheticBaseline && baseline.syntheticBaseline.expectedYardName) || \"\") + \". \" : \"\") + \"Saved non-today Parts snapshot rows for day_key \" + dayKey + \" included \" + staleRows.length + \" stale warehouse_location value(s): \" + staleRows.map((entry) => (entry.itemName || entry.partId) + \"=\" + entry.beforeWarehouse).join(\"; \"),\n\t\t\taction: \"Called reportDailyInventorySnapshot(\" + dayKey + \", [\\\"Parts\\\"]) through the local QA websocket method path.\",\n\t\t\texpected: \"Every affected stale Part row returns the yard named by metadata.id_yard in warehouse_location.\",\n\t\t\tafter: \"Method response corrected \" + passedRows.length + \" of \" + staleRows.length + \" stale row(s): \" + passedRows.map((entry) => (entry.itemName || entry.partId) + \"=\" + entry.afterWarehouse).join(\"; \"),\n\t\t\tobserved: caption,\n\t\t\tdataProof: comparisons.map((entry) => (entry.itemName || entry.partId || \"part\") + \": before=\" + entry.beforeWarehouse + \", expected=\" + entry.expectedYardName + \", after=\" + entry.afterWarehouse + \", pass=\" + entry.pass).join(\"\\n\"),\n\t\t\t\tmongoDelta: { collection: \"inventory-daily-snapshots\", day_key: dayKey, staleRows: staleRows.length, correctedStaleRows: passedRows.length, responseRowCount: responseRows.length, syntheticStaleBaseline: !!baseline.syntheticStaleBaseline, syntheticBaseline: baseline.syntheticBaseline || null },\n\t\t\t\tartifactPaths: [proofPath, beforeAfterScreenshotPath, matrixPath],\n\t\t\t\tmetadata: { supportDiagnosisProof: pass, proofType: \"part_inventory_snapshot_report_method\", methodPath: \"server/src/methods/report.ts reportDailyInventorySnapshot\", generatedBy: \"resolveio_runner_part_inventory_snapshot_business_proof\", syntheticStaleBaseline: !!baseline.syntheticStaleBaseline, generatedAt: new Date().toISOString() }\n\t\t};\n\t\twriteJson(businessAssertionPath, businessAssertion);\n\t\tconst matrix = readJson(matrixPath) || { status: \"started\", rows: [] };\n\t\tconst rows = matrixRows(matrix);\n\t\tconst rowIndex = rows.findIndex((candidate) => String(candidate && candidate.workflow || \"\") === rowWorkflow) >= 0 ? rows.findIndex((candidate) => String(candidate && candidate.workflow || \"\") === rowWorkflow) : rows.findIndex((candidate) => !/^(pass|passed)$/i.test(String(candidate && candidate.status || \"\")));\n\t\tconst activeIndex = rowIndex >= 0 ? rowIndex : 0;\n\t\tif (rows[activeIndex]) {\n\t\t\trows[activeIndex].status = pass ? \"pass\" : \"failed\";\n\t\t\trows[activeIndex].result = pass ? \"pass\" : \"failed\";\n\t\t\trows[activeIndex].acceptance_blocked = !pass;\n\t\t\trows[activeIndex].screenshot = beforeAfterScreenshotPath;\n\t\t\trows[activeIndex].screenshots = [beforeAfterScreenshotPath, passScreenshotPath].filter(Boolean);\n\t\t\trows[activeIndex].caption = caption;\n\t\t\trows[activeIndex].artifact = proofPath;\n\t\t\trows[activeIndex].artifacts = [{ path: proofPath, caption: \"Part inventory snapshot method response proof.\" }, { screenshot: beforeAfterScreenshotPath, caption }, { path: businessAssertionPath, caption: \"AIQaBusinessAssertion for support diagnosis proof plan.\" }];\n\t\t\trows[activeIndex].persisted_assertion = businessAssertion.dataProof;\n\t\t\tif (!pass) rows[activeIndex].blocker = caption;\n\t\t}\n\t\tmatrix.rows = rows;\n\t\tmatrix.status = pass ? \"pass\" : \"failed\";\n\t\tmatrix.part_inventory_snapshot_proof = proofPath;\n\t\tmatrix.aiqa_business_assertion = businessAssertionPath;\n\t\tmatrix.updated_at = new Date().toISOString();\n\t\twriteJson(matrixPath, matrix);\n\t\treturn payload;\n\t} catch (error) {\n\t\treturn await writeFailed(error && (error.stack || error.message) || String(error));\n\t}\n}\n"]))).trim().split('\n');
|
|
2722
2722
|
}
|
|
2723
2723
|
function buildResolveIORunnerQaWorkflowProbeScript() {
|
|
2724
2724
|
return __spreadArray(__spreadArray([
|
|
@@ -3505,6 +3505,15 @@ function buildResolveIORunnerQaWorkflowProbeScript() {
|
|
|
3505
3505
|
' return payload;',
|
|
3506
3506
|
'}'
|
|
3507
3507
|
], __read(buildResolveIOPartInventorySnapshotProofScriptLines()), false), [
|
|
3508
|
+
'function specializedWorkflowProofsEnabled() {',
|
|
3509
|
+
' const flag = String(process.env.RESOLVEIO_SUPPORT_QA_AUTO_SPECIALIZED_PROOFS || process.env.RESOLVEIO_RUNNER_QA_AUTO_SPECIALIZED_PROOFS || "").trim().toLowerCase();',
|
|
3510
|
+
' if (/^(1|true|yes|on)$/.test(flag)) return true;',
|
|
3511
|
+
' if (/^(0|false|no|off)$/.test(flag)) return false;',
|
|
3512
|
+
' const matrix = readJson(matrixPath) || {};',
|
|
3513
|
+
' const row = activeMatrixRow() || {};',
|
|
3514
|
+
' const proofMode = String(row.proof_mode || row.proofMode || matrix.proof_mode || matrix.proofMode || "").trim().toLowerCase();',
|
|
3515
|
+
' return row.allow_specialized_proof === true || matrix.allow_specialized_proofs === true || proofMode === "specialized";',
|
|
3516
|
+
'}',
|
|
3508
3517
|
'function updateMatrix(status, screenshotPath, caption, assertion) {',
|
|
3509
3518
|
' const matrix = readJson(matrixPath) || { status: "started", rows: [] };',
|
|
3510
3519
|
' const routeProbePassed = status === "route_probe_pass" || status === "pass";',
|
|
@@ -3543,18 +3552,23 @@ function buildResolveIORunnerQaWorkflowProbeScript() {
|
|
|
3543
3552
|
' const caption = `Workflow route ready: ${targetRoute} loaded in authenticated local QA with live seeded data available.`;',
|
|
3544
3553
|
' await page.screenshot({ path: passScreenshotPath, type: "jpeg", quality: 82, fullPage: false });',
|
|
3545
3554
|
' updateMatrix("route_probe_pass", passScreenshotPath, caption, "Authenticated customer workflow route loaded; deeper row-specific UI/data proof still required.");',
|
|
3546
|
-
' let specializedProof =
|
|
3547
|
-
' let specializedProofPath =
|
|
3548
|
-
' let specializedProofLabel =
|
|
3549
|
-
' if (
|
|
3550
|
-
' specializedProof = await
|
|
3551
|
-
' specializedProofPath = specializedProof ? path.join(artifactDir, "qa-
|
|
3552
|
-
' specializedProofLabel = specializedProof ? "
|
|
3553
|
-
'
|
|
3554
|
-
'
|
|
3555
|
-
'
|
|
3556
|
-
'
|
|
3557
|
-
'
|
|
3555
|
+
' let specializedProof = null;',
|
|
3556
|
+
' let specializedProofPath = "";',
|
|
3557
|
+
' let specializedProofLabel = "";',
|
|
3558
|
+
' if (specializedWorkflowProofsEnabled()) {',
|
|
3559
|
+
' specializedProof = await runPricingImportProof(page, summary);',
|
|
3560
|
+
' specializedProofPath = specializedProof ? path.join(artifactDir, "qa-pricing-import-proof.json") : "";',
|
|
3561
|
+
' specializedProofLabel = specializedProof ? "Pricing import workbook business proof" : "";',
|
|
3562
|
+
' if (!specializedProof) {',
|
|
3563
|
+
' specializedProof = await runPartInventorySnapshotMethodProof(page, summary, auth);',
|
|
3564
|
+
' specializedProofPath = specializedProof ? path.join(artifactDir, "qa-part-inventory-snapshot-proof.json") : "";',
|
|
3565
|
+
' specializedProofLabel = specializedProof ? "Part inventory snapshot report method business proof" : "";',
|
|
3566
|
+
' }',
|
|
3567
|
+
' if (!specializedProof) {',
|
|
3568
|
+
' specializedProof = await runAssetLocationRowProof(page, summary);',
|
|
3569
|
+
' specializedProofPath = specializedProof ? path.join(artifactDir, "qa-asset-location-proof.json") : "";',
|
|
3570
|
+
' specializedProofLabel = specializedProof ? "Asset location list/detail/edit business proof" : "";',
|
|
3571
|
+
' }',
|
|
3558
3572
|
' }',
|
|
3559
3573
|
' if (specializedProof && specializedProof.status !== "pass") {',
|
|
3560
3574
|
' const result = { status: "failed", clientUrl, serverUrl, targetRoute, screenshot: passScreenshotPath, caption: `${specializedProofLabel || "Specialized business proof"} failed; see ${path.basename(specializedProofPath)}.`, page: summary, matrix: matrixPath, specializedProof: specializedProofPath };',
|