feature/Reynolds-and-Reynolds-DMS-API-Integration - Scaffolding
This commit is contained in:
185
server/rr/rr-helpers.js
Normal file
185
server/rr/rr-helpers.js
Normal file
@@ -0,0 +1,185 @@
|
||||
const path = require("path");
|
||||
require("dotenv").config({
|
||||
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
|
||||
});
|
||||
const uuid = require("uuid").v4;
|
||||
const AxiosLib = require("axios").default;
|
||||
const axios = AxiosLib.create();
|
||||
const CreateRRLogEvent = require("./rr-logger");
|
||||
|
||||
// --- ENV / mode
|
||||
const isProduction = process.env.NODE_ENV === "production";
|
||||
|
||||
// --- Public cache keys (mirrors FortellisCacheEnums)
|
||||
const RRCacheEnums = {
|
||||
txEnvelope: "txEnvelope",
|
||||
SubscriptionMeta: "SubscriptionMeta", // keep shape parity with fortellis if you reuse UI/redis
|
||||
JobData: "JobData",
|
||||
DMSVid: "DMSVid", // vehicle id result
|
||||
DMSVeh: "DMSVeh", // vehicle read
|
||||
DMSVehCustomer: "DMSVehCustomer",
|
||||
DMSCustList: "DMSCustList",
|
||||
DMSCust: "DMSCust",
|
||||
selectedCustomerId: "selectedCustomerId",
|
||||
DMSTransHeader: "DMSTransHeader",
|
||||
transWips: "transWips",
|
||||
DMSBatchTxn: "DMSBatchTxn",
|
||||
DmsBatchTxnPost: "DmsBatchTxnPost",
|
||||
DMSVehHistory: "DMSVehHistory"
|
||||
};
|
||||
|
||||
// --- Transaction namespacing in Redis
|
||||
const getTransactionType = (jobid) => `rr:${jobid}`;
|
||||
const defaultRRTTL = 60 * 60;
|
||||
|
||||
// --- API catalog (stub URLs: swap in real ones from Rome specs)
|
||||
const RRActions = {
|
||||
SearchCustomer: {
|
||||
apiName: "RR Search Customer",
|
||||
url: isProduction ? "https://rr.example.com/api/customer/search" : "https://rr-uat.example.com/api/customer/search",
|
||||
type: "get"
|
||||
},
|
||||
ReadCustomer: {
|
||||
apiName: "RR Read Customer",
|
||||
url: isProduction ? "https://rr.example.com/api/customer/" : "https://rr-uat.example.com/api/customer/",
|
||||
type: "get" // append /{id}
|
||||
},
|
||||
CreateCustomer: {
|
||||
apiName: "RR Create Customer",
|
||||
url: isProduction ? "https://rr.example.com/api/customer" : "https://rr-uat.example.com/api/customer",
|
||||
type: "post"
|
||||
},
|
||||
InsertVehicle: {
|
||||
apiName: "RR Insert Vehicle",
|
||||
url: isProduction ? "https://rr.example.com/api/service-vehicle" : "https://rr-uat.example.com/api/service-vehicle",
|
||||
type: "post"
|
||||
},
|
||||
ReadVehicle: {
|
||||
apiName: "RR Read Vehicle",
|
||||
url: isProduction
|
||||
? "https://rr.example.com/api/service-vehicle/"
|
||||
: "https://rr-uat.example.com/api/service-vehicle/",
|
||||
type: "get" // append /{vehicleId}
|
||||
},
|
||||
GetVehicleId: {
|
||||
apiName: "RR Get Vehicle Id By VIN",
|
||||
url: isProduction
|
||||
? "https://rr.example.com/api/service-vehicle/by-vin/"
|
||||
: "https://rr-uat.example.com/api/service-vehicle/by-vin/",
|
||||
type: "get" // append /{vin}
|
||||
},
|
||||
StartWip: {
|
||||
apiName: "RR Start WIP",
|
||||
url: isProduction ? "https://rr.example.com/api/gl/start-wip" : "https://rr-uat.example.com/api/gl/start-wip",
|
||||
type: "post"
|
||||
},
|
||||
TranBatchWip: {
|
||||
apiName: "RR Trans Batch WIP",
|
||||
url: isProduction
|
||||
? "https://rr.example.com/api/gl/trans-batch-wip"
|
||||
: "https://rr-uat.example.com/api/gl/trans-batch-wip",
|
||||
type: "post"
|
||||
},
|
||||
PostBatchWip: {
|
||||
apiName: "RR Post Batch WIP",
|
||||
url: isProduction
|
||||
? "https://rr.example.com/api/gl/post-batch-wip"
|
||||
: "https://rr-uat.example.com/api/gl/post-batch-wip",
|
||||
type: "post"
|
||||
},
|
||||
QueryErrorWip: {
|
||||
apiName: "RR Query Error WIP",
|
||||
url: isProduction ? "https://rr.example.com/api/gl/error-wip/" : "https://rr-uat.example.com/api/gl/error-wip/",
|
||||
type: "get" // append /{transId}
|
||||
},
|
||||
ServiceHistoryInsert: {
|
||||
apiName: "RR Insert Service Vehicle History",
|
||||
url: isProduction
|
||||
? "https://rr.example.com/api/service-vehicle-history"
|
||||
: "https://rr-uat.example.com/api/service-vehicle-history",
|
||||
type: "post"
|
||||
}
|
||||
};
|
||||
|
||||
// --- Auth (stub). Replace with RR auth handshake from Rome specs.
|
||||
async function getRRToken() {
|
||||
// TODO: implement RR token retrieval (client credentials, basic, or session) per spec
|
||||
// Return a bearer (or session cookie) string
|
||||
return process.env.RR_FAKE_TOKEN || "rr-dev-token";
|
||||
}
|
||||
|
||||
// --- URL constructor (same shape as Fortellis)
|
||||
function constructFullUrl({ url, pathParams = "", requestSearchParams = [] }) {
|
||||
const base = url.replace(/\/+$/, "/");
|
||||
const fullPath = pathParams ? `${base}${pathParams}` : base;
|
||||
const qs = new URLSearchParams(requestSearchParams).toString();
|
||||
return qs ? `${fullPath}?${qs}` : fullPath;
|
||||
}
|
||||
|
||||
// --- General caller (same ergonomics as MakeFortellisCall)
|
||||
async function MakeRRCall({
|
||||
apiName,
|
||||
url,
|
||||
headers = {},
|
||||
body = {},
|
||||
type = "post",
|
||||
requestPathParams,
|
||||
requestSearchParams = [],
|
||||
debug = true,
|
||||
jobid,
|
||||
redisHelpers,
|
||||
socket
|
||||
}) {
|
||||
const ReqId = uuid();
|
||||
const fullUrl = constructFullUrl({ url, pathParams: requestPathParams, requestSearchParams });
|
||||
const access_token = await getRRToken();
|
||||
|
||||
if (debug) {
|
||||
console.log(`[RR] ${apiName} | ${type.toUpperCase()} ${fullUrl} | ReqId=${ReqId}`);
|
||||
if (type !== "get") console.log(`[RR] payload: ${JSON.stringify(body, null, 2)}`);
|
||||
}
|
||||
|
||||
try {
|
||||
const commonHeaders = {
|
||||
Authorization: `Bearer ${access_token}`,
|
||||
"X-Request-Id": ReqId,
|
||||
...headers
|
||||
};
|
||||
|
||||
let resp;
|
||||
switch (type) {
|
||||
case "get":
|
||||
resp = await axios.get(fullUrl, { headers: commonHeaders });
|
||||
break;
|
||||
case "put":
|
||||
resp = await axios.put(fullUrl, body, { headers: commonHeaders });
|
||||
break;
|
||||
case "post":
|
||||
default:
|
||||
resp = await axios.post(fullUrl, body, { headers: commonHeaders });
|
||||
break;
|
||||
}
|
||||
|
||||
if (debug) console.log(`[RR] ${apiName} OK | ReqId=${ReqId}`);
|
||||
return resp.data;
|
||||
} catch (error) {
|
||||
CreateRRLogEvent(socket, "ERROR", `[RR] ${apiName} failed: ${error.message}`, {
|
||||
reqId: ReqId,
|
||||
url: fullUrl,
|
||||
apiName,
|
||||
errorData: error.response?.data,
|
||||
errorStatus: error.response?.status,
|
||||
errorStatusText: error.response?.statusText,
|
||||
stack: error.stack
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
RRActions,
|
||||
MakeRRCall,
|
||||
RRCacheEnums,
|
||||
getTransactionType,
|
||||
defaultRRTTL
|
||||
};
|
||||
Reference in New Issue
Block a user