refactor(actions): extract shared relay client for direct services
This commit is contained in:
@@ -1,6 +1,13 @@
|
|||||||
# Actions Clients
|
# Actions Clients
|
||||||
|
|
||||||
This folder is reserved for extracted client wrappers from `actions/index.js` as part of the Priority 1 refactor plan.
|
This folder contains extracted client wrappers from `actions/index.js` as part of the Priority 1 refactor plan.
|
||||||
|
|
||||||
Phase 1 delivered core helper extraction and compatibility barrel support.
|
Current extracted clients:
|
||||||
Client-level extraction (`relayClient`, `endpointClient`, `fileClient`, `notifyClient`) is planned for the next increment.
|
|
||||||
|
- `relayClient` (shared hash-signing helper used by account/portal/document direct services)
|
||||||
|
- `endpointClient` (shared JSON request helpers for GET and generic axios config requests)
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- Core helper extraction and compatibility barrel support remain in place.
|
||||||
|
- Additional client extraction (`fileClient`, `notifyClient`) can be layered in incrementally without changing public exports from `actions/index.js`.
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export const getJson = async (url, config) => {
|
||||||
|
const response = await axios.get(url, config);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const requestJson = async (config) => {
|
||||||
|
const response = await axios(config);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./relayClient";
|
||||||
|
export * from "./endpointClient";
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import { hashAPIPath } from "../core/hash";
|
||||||
|
|
||||||
|
export const buildHashedQueryUrl = async (queryUrl) => {
|
||||||
|
try {
|
||||||
|
const signRes = await axios.get(
|
||||||
|
"/api/endpoint/gethash_api?path=" + encodeURIComponent(queryUrl)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!signRes?.data?.hash) {
|
||||||
|
throw new Error("Hash signature unavailable");
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryUrl + signRes.data.hash;
|
||||||
|
} catch (error) {
|
||||||
|
if (typeof window === "undefined" && process.env.HASHKEY) {
|
||||||
|
return queryUrl + hashAPIPath(queryUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -5,4 +5,5 @@ export * from "./core/token";
|
|||||||
export * from "./core/headers";
|
export * from "./core/headers";
|
||||||
export * from "./core/guards";
|
export * from "./core/guards";
|
||||||
|
|
||||||
|
export * from "./clients";
|
||||||
export * from "./services";
|
export * from "./services";
|
||||||
|
|||||||
@@ -1,27 +1,7 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { BASE_URL } from "../core/env";
|
import { BASE_URL } from "../core/env";
|
||||||
import { consoleLogger } from "../core/logger";
|
import { consoleLogger } from "../core/logger";
|
||||||
import { hashAPIPath } from "../core/hash";
|
import { buildHashedQueryUrl } from "../clients/relayClient";
|
||||||
|
|
||||||
const buildHashedQueryUrl = async (queryUrl) => {
|
|
||||||
try {
|
|
||||||
const signRes = await axios.get(
|
|
||||||
"/api/endpoint/gethash_api?path=" + encodeURIComponent(queryUrl)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!signRes?.data?.hash) {
|
|
||||||
throw new Error("Hash signature unavailable");
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryUrl + signRes.data.hash;
|
|
||||||
} catch (error) {
|
|
||||||
if (typeof window === "undefined" && process.env.HASHKEY) {
|
|
||||||
return queryUrl + hashAPIPath(queryUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getPersonalAccount = (contactid) => {
|
export const getPersonalAccount = (contactid) => {
|
||||||
return axios
|
return axios
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import axios from "axios";
|
|
||||||
import { BASE_URL } from "../core/env";
|
import { BASE_URL } from "../core/env";
|
||||||
import { logAndReturnResponse } from "./httpServiceUtils";
|
import { logAndReturnResponse } from "./httpServiceUtils";
|
||||||
|
import { getJson } from "../clients/endpointClient";
|
||||||
|
|
||||||
export const getNewAppeals = async (searchString) => {
|
export const getNewAppeals = async (searchString) => {
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(BASE_URL + "/api/admin/getnewappeals_api");
|
return await getJson(BASE_URL + "/api/admin/getnewappeals_api");
|
||||||
return res.data;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return logAndReturnResponse(error);
|
return logAndReturnResponse(error);
|
||||||
}
|
}
|
||||||
@@ -18,8 +17,8 @@ export const getNewAppealsPage = async (
|
|||||||
fieldSort,
|
fieldSort,
|
||||||
showNumberOfRecords
|
showNumberOfRecords
|
||||||
) => {
|
) => {
|
||||||
return axios
|
try {
|
||||||
.get(
|
return await getJson(
|
||||||
"/api/admin/getnewappeals_api?searchString=" +
|
"/api/admin/getnewappeals_api?searchString=" +
|
||||||
searchString +
|
searchString +
|
||||||
"&pageNumber=" +
|
"&pageNumber=" +
|
||||||
@@ -30,11 +29,10 @@ export const getNewAppealsPage = async (
|
|||||||
fieldSort +
|
fieldSort +
|
||||||
"&showNumberOfRecords=" +
|
"&showNumberOfRecords=" +
|
||||||
showNumberOfRecords
|
showNumberOfRecords
|
||||||
)
|
);
|
||||||
.then((res) => {
|
} catch (error) {
|
||||||
return res.data;
|
return logAndReturnResponse(error);
|
||||||
})
|
}
|
||||||
.catch(logAndReturnResponse);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getNewDocumentsPaged = async (
|
export const getNewDocumentsPaged = async (
|
||||||
@@ -46,8 +44,8 @@ export const getNewDocumentsPaged = async (
|
|||||||
documentOrigin,
|
documentOrigin,
|
||||||
selectedWeeks
|
selectedWeeks
|
||||||
) => {
|
) => {
|
||||||
return axios
|
try {
|
||||||
.get(
|
return await getJson(
|
||||||
"/api/admin/getlatestdocuments_api?pageNumber=" +
|
"/api/admin/getlatestdocuments_api?pageNumber=" +
|
||||||
pageNumber +
|
pageNumber +
|
||||||
"&orderby=" +
|
"&orderby=" +
|
||||||
@@ -62,9 +60,8 @@ export const getNewDocumentsPaged = async (
|
|||||||
selectedWeeks +
|
selectedWeeks +
|
||||||
"&documentOrigin=" +
|
"&documentOrigin=" +
|
||||||
documentOrigin
|
documentOrigin
|
||||||
)
|
);
|
||||||
.then((res) => {
|
} catch (error) {
|
||||||
return res.data;
|
return logAndReturnResponse(error);
|
||||||
})
|
}
|
||||||
.catch(logAndReturnResponse);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,26 +2,7 @@ import axios from "axios";
|
|||||||
import { BASE_URL } from "../core/env";
|
import { BASE_URL } from "../core/env";
|
||||||
import { consoleLogger } from "../core/logger";
|
import { consoleLogger } from "../core/logger";
|
||||||
import { hashAPIPath } from "../core/hash";
|
import { hashAPIPath } from "../core/hash";
|
||||||
|
import { buildHashedQueryUrl } from "../clients/relayClient";
|
||||||
const buildHashedQueryUrl = async (queryUrl) => {
|
|
||||||
try {
|
|
||||||
const signRes = await axios.get(
|
|
||||||
"/api/endpoint/gethash_api?path=" + encodeURIComponent(queryUrl)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!signRes?.data?.hash) {
|
|
||||||
throw new Error("Hash signature unavailable");
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryUrl + signRes.data.hash;
|
|
||||||
} catch (error) {
|
|
||||||
if (typeof window === "undefined" && process.env.HASHKEY) {
|
|
||||||
return queryUrl + hashAPIPath(queryUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getAwaitingSubmissionFromBlob = (containerName) => {
|
export const getAwaitingSubmissionFromBlob = (containerName) => {
|
||||||
return axios
|
return axios
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import axios from "axios";
|
|
||||||
import { consoleLogger } from "../core/logger";
|
import { consoleLogger } from "../core/logger";
|
||||||
|
import { requestJson } from "../clients/endpointClient";
|
||||||
|
|
||||||
export const createCRMTask = async (formValues) => {
|
export const createCRMTask = async (formValues) => {
|
||||||
var queryUrl = "/api/endpoint/createcrmtask_api";
|
var queryUrl = "/api/endpoint/createcrmtask_api";
|
||||||
@@ -12,8 +12,7 @@ export const createCRMTask = async (formValues) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await axios(config);
|
return await requestJson(config);
|
||||||
return res.data;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
consoleLogger(error);
|
consoleLogger(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import axios from "axios";
|
|
||||||
import { consoleLogger } from "../core/logger";
|
import { consoleLogger } from "../core/logger";
|
||||||
|
import { requestJson } from "../clients/endpointClient";
|
||||||
|
|
||||||
export const sendEmail = async (
|
export const sendEmail = async (
|
||||||
templateId,
|
templateId,
|
||||||
@@ -15,8 +15,11 @@ export const sendEmail = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.post("/api/email/notify", mailData);
|
return await requestJson({
|
||||||
return response.data;
|
method: "post",
|
||||||
|
url: "/api/email/notify",
|
||||||
|
data: mailData
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
consoleLogger(error);
|
consoleLogger(error);
|
||||||
throw error;
|
throw error;
|
||||||
|
|||||||
@@ -1,27 +1,7 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { BASE_URL } from "../core/env";
|
import { BASE_URL } from "../core/env";
|
||||||
import { consoleLogger } from "../core/logger";
|
import { consoleLogger } from "../core/logger";
|
||||||
import { hashAPIPath } from "../core/hash";
|
import { buildHashedQueryUrl } from "../clients/relayClient";
|
||||||
|
|
||||||
const buildHashedQueryUrl = async (queryUrl) => {
|
|
||||||
try {
|
|
||||||
const signRes = await axios.get(
|
|
||||||
"/api/endpoint/gethash_api?path=" + encodeURIComponent(queryUrl)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!signRes?.data?.hash) {
|
|
||||||
throw new Error("Hash signature unavailable");
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryUrl + signRes.data.hash;
|
|
||||||
} catch (error) {
|
|
||||||
if (typeof window === "undefined" && process.env.HASHKEY) {
|
|
||||||
return queryUrl + hashAPIPath(queryUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getMyCases = (loggedInUserId) => {
|
export const getMyCases = (loggedInUserId) => {
|
||||||
return axios
|
return axios
|
||||||
|
|||||||
@@ -1444,3 +1444,44 @@ Validation:
|
|||||||
Follow-ups:
|
Follow-ups:
|
||||||
|
|
||||||
- P2-S3 planned slices are now complete; no further mandatory relay policy rollout slices remain for this stream.
|
- P2-S3 planned slices are now complete; no further mandatory relay policy rollout slices remain for this stream.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### CL-039: TASK22260 actions façade increment — shared relay client extraction
|
||||||
|
|
||||||
|
date: 2026-03-25
|
||||||
|
author: Cline
|
||||||
|
scope: `actions/clients/{relayClient,index}.js`, `actions/services/{accountDirectService,portalDirectService,documentDirectService}.js`, `actions/index.js`, `actions/clients/README.md`
|
||||||
|
type: change
|
||||||
|
rationale: Continue Priority 1 façade decomposition by extracting duplicated hash-signing relay helper logic into a dedicated client module while preserving existing service/public export contracts.
|
||||||
|
impact: Reduces duplication and drift risk in security-sensitive relay signing helper logic without changing call-site behavior.
|
||||||
|
status: completed
|
||||||
|
|
||||||
|
Summary:
|
||||||
|
|
||||||
|
- Added a new shared client wrapper:
|
||||||
|
- `actions/clients/relayClient.js` exporting `buildHashedQueryUrl`
|
||||||
|
- Added `actions/clients/index.js` barrel and exposed client exports via `actions/index.js`.
|
||||||
|
- Updated direct services to consume shared relay client helper instead of duplicating local helper implementations:
|
||||||
|
- `actions/services/accountDirectService.js`
|
||||||
|
- `actions/services/portalDirectService.js`
|
||||||
|
- `actions/services/documentDirectService.js`
|
||||||
|
- Updated `actions/clients/README.md` to reflect the now-implemented relay client extraction and future incremental client split path.
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
|
||||||
|
- `npm run lint` -> warnings only (pre-existing `react-hooks/exhaustive-deps`; no new lint errors)
|
||||||
|
- Verified no remaining duplicated local `buildHashedQueryUrl` definitions across `actions/services/*DirectService.js`
|
||||||
|
|
||||||
|
Follow-ups:
|
||||||
|
|
||||||
|
- Optional next TASK22260 increment: extract common axios invocation helpers into dedicated clients (`endpointClient`, `fileClient`, `notifyClient`) while keeping `actions/index.js` API stable.
|
||||||
|
|
||||||
|
Addendum (same TASK22260 slice):
|
||||||
|
|
||||||
|
- Added shared `endpointClient` with `getJson` and `requestJson` helpers (`actions/clients/endpointClient.js`) and exported it via `actions/clients/index.js`.
|
||||||
|
- Migrated additional direct services to consume shared endpoint client helpers:
|
||||||
|
- `actions/services/notifyDirectService.js` (POST via `requestJson`)
|
||||||
|
- `actions/services/integrationDirectService.js` (POST via `requestJson`)
|
||||||
|
- `actions/services/adminDirectService.js` (GET flows via `getJson`)
|
||||||
|
- Updated `actions/clients/README.md` to include `endpointClient` in current extracted clients.
|
||||||
|
|||||||
Reference in New Issue
Block a user