Files
FT546MWS/scripts/stockout-detail-check-mcp.js

103 lines
4.0 KiB
JavaScript

const { spawn } = require("child_process");
const config = "C:\\project\\FT546WMS-SHANDOW\\.cursorrules-mcp.json";
const database = "FT546-wms";
function createClient() {
const child = spawn("powershell.exe", [
"-NoProfile", "-ExecutionPolicy", "Bypass", "-File",
"C:\\project\\sqlserver-mcp-server\\start.ps1",
"-ConfigPath", config
], { stdio: ["pipe", "pipe", "pipe"] });
let buffer = "";
let nextId = 1;
const pending = new Map();
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const lines = buffer.split(/\r?\n/);
buffer = lines.pop();
for (const line of lines) {
if (!line.trim()) continue;
try {
const message = JSON.parse(line);
const resolve = pending.get(message.id);
if (resolve) {
pending.delete(message.id);
resolve(message);
}
} catch {
// Ignore non-protocol output.
}
}
});
function call(method, params) {
return new Promise((resolve, reject) => {
const id = nextId++;
pending.set(id, (message) => message.error
? reject(new Error(message.error.message || "MCP error"))
: resolve(message.result));
child.stdin.write(JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n");
});
}
return { child, call };
}
function parseResult(result) {
const item = (result.content || []).find((entry) => entry.type === "text");
if (!item) throw new Error("MCP returned no result text");
try {
return JSON.parse(item.text);
} catch {
throw new Error(item.text.replace(/password\s*[:=]\s*[^\s,}]+/gi, "password=[redacted]").replace(/\r?\n/g, " "));
}
}
function quote(value) {
return String(value ?? "").replaceAll("'", "''");
}
async function main() {
const client = createClient();
try {
await client.call("initialize", {
protocolVersion: "2025-06-18",
capabilities: {},
clientInfo: { name: "ft546-stockout-detail-check", version: "1.0" }
});
client.child.stdin.write(JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" }) + "\n");
async function read(query) {
return parseResult(await client.call("tools/call", {
name: "sqlserver_read_data",
arguments: { databaseName: database, query, response_format: "json" }
}));
}
const detail = await read("SELECT stockout_detail_id, warehouse_id, spare4 AS project_no, product_id FROM dbo.out_stockout_detail WHERE stockout_detail_id = 'CKD202608180003-1'");
const row = detail.rows?.[0];
const projectNo = row?.project_no == null ? null : String(row.project_no).trim();
const productNo = row?.product_id == null ? null : String(row.product_id).trim();
const projectLiteral = projectNo == null || projectNo === "" ? "NULL" : `'${quote(projectNo)}'`;
const productConditionLegacy = productNo == null || productNo === "" ? "1 = 1" : `product_id = '${quote(productNo)}'`;
const productConditionShadow = productNo == null || productNo === "" ? "1 = 1" : `product_no = '${quote(productNo)}'`;
const legacy = await read(`SELECT stock_id, warehouse_id, cargo_space_id, tray_code, spare4 AS project_no, product_id, quantity, out_quantity, stock_status, product_status FROM dbo.bas_stock WHERE spare4 = ${projectLiteral} AND ${productConditionLegacy}`);
const shadow = await read(`SELECT stock_id, space_id, tray_code, project_no, product_no, quantity, out_quantity FROM alg.v_inventory_item WHERE project_no = ${projectLiteral} AND ${productConditionShadow}`);
const sync = await read("SELECT MAX(synchronized_at) AS latest_shadow_inventory_sync FROM alg.inventory_item_snapshot WHERE warehouse_id = '01'");
console.log(JSON.stringify({
detail: detail.rows || [],
legacy_stock: legacy.rows || [],
shadow_inventory: shadow.rows || [],
latest_sync: sync.rows || []
}, null, 2));
} finally {
client.child.kill();
}
}
main().catch((error) => {
console.error("READONLY_QUERY_FAILED " + error.message);
process.exitCode = 1;
});