Merged in release/2026-04-17 (pull request #3185)

feature/IO-3638-Reynolds-OpenSearch - Add Search on DMS id in Reynolds shops
This commit is contained in:
Dave Richer
2026-04-09 15:16:48 +00:00
5 changed files with 103 additions and 38 deletions

View File

@@ -32,6 +32,7 @@ async function OpenSearchUpdateHandler(req, res) {
clm_no
clm_total
comment
dms_id
ins_co_nm
owner_owing
ownr_co_nm

View File

@@ -2442,6 +2442,9 @@ exports.ACTIVE_SHOP_BY_USER = `query ACTIVE_SHOP_BY_USER($user: String) {
associations(where: {active: {_eq: true}, useremail: {_eq: $user}}) {
id
shopid
bodyshop {
rr_dealerid
}
}
}`;

View File

@@ -4,6 +4,7 @@ const queries = require("../graphql-client/queries");
const client = require("../graphql-client/graphql-client").client;
const { pick, isNil } = require("lodash");
const { getClient } = require("../../libs/awsUtils");
const { JOB_DOCUMENT_FIELDS, getGlobalSearchQueryStringFields } = require("./os-search-config");
async function OpenSearchUpdateHandler(req, res) {
try {
@@ -21,27 +22,7 @@ async function OpenSearchUpdateHandler(req, res) {
switch (req.body.table.name) {
case "jobs":
document = pick(req.body.event.data.new, [
"id",
"bodyshopid",
"clm_no",
"clm_total",
"comment",
"ins_co_nm",
"owner_owing",
"ownr_co_nm",
"ownr_fn",
"ownr_ln",
"ownr_ph1",
"ownr_ph2",
"plate_no",
"ro_number",
"status",
"v_model_yr",
"v_make_desc",
"v_model_desc",
"v_vin"
]);
document = pick(req.body.event.data.new, JOB_DOCUMENT_FIELDS);
document.bodyshopid = req.body.event.data.new.shopid;
break;
case "vehicles":
@@ -197,15 +178,18 @@ async function OpenSearchSearchHandler(req, res) {
user: req.user.email
});
if (assocs.length === 0) {
if (assocs.associations.length === 0) {
res.sendStatus(401);
return;
}
const osClient = await getClient();
const activeAssociation = assocs.associations[0];
const bodyShopIdMatchOverride = isNil(process.env.BODY_SHOP_ID_MATCH_OVERRIDE)
? assocs.associations[0].shopid
? activeAssociation.shopid
: process.env.BODY_SHOP_ID_MATCH_OVERRIDE;
const isReynoldsEnabled = Boolean(activeAssociation.bodyshop?.rr_dealerid);
const { body } = await osClient.search({
...(index ? { index } : { index: ["jobs", "vehicles", "owners", "bills", "payments"] }),
@@ -241,21 +225,8 @@ async function OpenSearchSearchHandler(req, res) {
query: `*${search}*`,
// Weighted Fields
fields: [
"*ro_number^20",
"*clm_no^14",
"*v_vin^12",
"*plate_no^12",
"*ownr_ln^10",
"transactionid^10",
"paymentnum^10",
"invoice_number^10",
"*ownr_fn^8",
"*ownr_co_nm^8",
"*ownr_ph1^8",
"*ownr_ph2^8",
"*vendor.name^8",
"*comment^6"
// "*"
...getGlobalSearchQueryStringFields({ isReynoldsEnabled })
// "*"
]
}
}

View File

@@ -0,0 +1,69 @@
/**
* Fields to be included in the job document indexed in OpenSearch. These fields are used for both indexing and
* searching.
* @type {string[]}
*/
const JOB_DOCUMENT_FIELDS = [
"id",
"bodyshopid",
"clm_no",
"clm_total",
"comment",
"dms_id",
"ins_co_nm",
"owner_owing",
"ownr_co_nm",
"ownr_fn",
"ownr_ln",
"ownr_ph1",
"ownr_ph2",
"plate_no",
"ro_number",
"status",
"v_model_yr",
"v_make_desc",
"v_model_desc",
"v_vin"
];
/**
* Fields to be included in the global search query string. These fields are used for constructing the search query.
* @type {string[]}
*/
const BASE_GLOBAL_SEARCH_QUERY_STRING_FIELDS = [
"*ro_number^20",
"*clm_no^14",
"*v_vin^12",
"*plate_no^12",
"*ownr_ln^10",
"transactionid^10",
"paymentnum^10",
"invoice_number^10",
"*ownr_fn^8",
"*ownr_co_nm^8",
"*ownr_ph1^8",
"*ownr_ph2^8",
"*vendor.name^8",
"*comment^6"
];
/**
* Returns the fields to be included in the global search query string. If Reynolds is enabled, it includes the dms_id
* field with a higher boost.
* @param param0
* @param param0.isReynoldsEnabled
* @returns {string[]}
*/
const getGlobalSearchQueryStringFields = ({ isReynoldsEnabled = false } = {}) => {
if (!isReynoldsEnabled) {
return BASE_GLOBAL_SEARCH_QUERY_STRING_FIELDS;
}
return ["*dms_id^20", ...BASE_GLOBAL_SEARCH_QUERY_STRING_FIELDS];
};
module.exports = {
JOB_DOCUMENT_FIELDS,
BASE_GLOBAL_SEARCH_QUERY_STRING_FIELDS,
getGlobalSearchQueryStringFields
};

View File

@@ -0,0 +1,21 @@
import { describe, expect, it } from "vitest";
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const { JOB_DOCUMENT_FIELDS, BASE_GLOBAL_SEARCH_QUERY_STRING_FIELDS, getGlobalSearchQueryStringFields } = require(
"../os-search-config"
);
describe("os-search-config", () => {
it("indexes dms_id on job documents", () => {
expect(JOB_DOCUMENT_FIELDS).toContain("dms_id");
});
it("includes dms_id in global search fields for Reynolds shops", () => {
expect(getGlobalSearchQueryStringFields({ isReynoldsEnabled: true })).toContain("*dms_id^20");
});
it("keeps the default search fields unchanged for non-Reynolds shops", () => {
expect(getGlobalSearchQueryStringFields()).toEqual(BASE_GLOBAL_SEARCH_QUERY_STRING_FIELDS);
});
});