mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 00:52:50 +00:00
226 lines
6.6 KiB
TypeScript
226 lines
6.6 KiB
TypeScript
import { api as client } from "@/auth/http";
|
|
import { URL_CONSTANTS } from "@/constants/URLS";
|
|
import type {
|
|
RuleEngineListMeta,
|
|
RuleEngineListResult,
|
|
RuleEngineRecord,
|
|
RuleEngineResourceSlug,
|
|
} from "@/types/rule-engine";
|
|
import { unwrap } from "@/utils/endpoint";
|
|
|
|
export interface RuleEngineListParams {
|
|
search?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
isActive?: boolean;
|
|
status?: string;
|
|
sortBy?: string;
|
|
sortOrder?: "ASC" | "DESC";
|
|
requiresDirectorApproval?: boolean;
|
|
}
|
|
|
|
export interface RuleEngineReorderPayload {
|
|
ids: string[];
|
|
requiresDirectorApproval?: boolean;
|
|
}
|
|
|
|
const RESOURCE_BASE: Record<RuleEngineResourceSlug, string> = {
|
|
"cargo-types": URL_CONSTANTS.RULE_ENGINE.CARGO_TYPES,
|
|
"container-types": URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPES,
|
|
"wagon-types": URL_CONSTANTS.RULE_ENGINE.WAGON_TYPES,
|
|
"priority-configs": URL_CONSTANTS.RULE_ENGINE.PRIORITY_CONFIGS,
|
|
"service-types": URL_CONSTANTS.RULE_ENGINE.SERVICE_TYPES,
|
|
"weight-limit-rules": URL_CONSTANTS.RULE_ENGINE.WEIGHT_LIMIT_RULES,
|
|
yards: URL_CONSTANTS.RULE_ENGINE.YARDS,
|
|
"shipping-lines": URL_CONSTANTS.RULE_ENGINE.SHIPPING_LINES,
|
|
rates: URL_CONSTANTS.RULE_ENGINE.RATES,
|
|
"approval-rules": URL_CONSTANTS.RULE_ENGINE.APPROVAL_RULES,
|
|
};
|
|
|
|
const byIdPath = (resource: RuleEngineResourceSlug, id: string): string => {
|
|
switch (resource) {
|
|
case "cargo-types":
|
|
return URL_CONSTANTS.RULE_ENGINE.CARGO_TYPE_BY_ID(id);
|
|
case "container-types":
|
|
return URL_CONSTANTS.RULE_ENGINE.CONTAINER_TYPE_BY_ID(id);
|
|
case "wagon-types":
|
|
return URL_CONSTANTS.RULE_ENGINE.WAGON_TYPE_BY_ID(id);
|
|
case "priority-configs":
|
|
return URL_CONSTANTS.RULE_ENGINE.PRIORITY_CONFIG_BY_ID(id);
|
|
case "service-types":
|
|
return URL_CONSTANTS.RULE_ENGINE.SERVICE_TYPE_BY_ID(id);
|
|
case "weight-limit-rules":
|
|
return URL_CONSTANTS.RULE_ENGINE.WEIGHT_LIMIT_RULE_BY_ID(id);
|
|
case "yards":
|
|
return URL_CONSTANTS.RULE_ENGINE.YARD_BY_ID(id);
|
|
case "shipping-lines":
|
|
return URL_CONSTANTS.RULE_ENGINE.SHIPPING_LINE_BY_ID(id);
|
|
case "rates":
|
|
return URL_CONSTANTS.RULE_ENGINE.RATE_BY_ID(id);
|
|
case "approval-rules":
|
|
return URL_CONSTANTS.RULE_ENGINE.APPROVAL_RULE_BY_ID(id);
|
|
default:
|
|
return `${RESOURCE_BASE[resource]}/${id}`;
|
|
}
|
|
};
|
|
|
|
const defaultMeta = (
|
|
dataLength: number,
|
|
page = 1,
|
|
pageSize = 10,
|
|
): RuleEngineListMeta => ({
|
|
total: dataLength,
|
|
page,
|
|
pageSize,
|
|
totalPages: Math.max(1, Math.ceil(dataLength / pageSize)),
|
|
});
|
|
|
|
const isPaginatedListResult = <T extends RuleEngineRecord>(
|
|
value: unknown,
|
|
): value is RuleEngineListResult<T> =>
|
|
Boolean(value) &&
|
|
typeof value === "object" &&
|
|
"data" in (value ?? {}) &&
|
|
Array.isArray((value as RuleEngineListResult<T>).data);
|
|
|
|
const normalizeList = <T extends RuleEngineRecord>(
|
|
payload: unknown,
|
|
page = 1,
|
|
pageSize = 10,
|
|
): RuleEngineListResult<T> => {
|
|
if (isPaginatedListResult<T>(payload)) {
|
|
return {
|
|
data: payload.data,
|
|
meta: payload.meta ?? defaultMeta(payload.data.length, page, pageSize),
|
|
};
|
|
}
|
|
|
|
const body = unwrap(payload as { data: unknown }) as unknown;
|
|
|
|
if (isPaginatedListResult<T>(body)) {
|
|
return {
|
|
data: body.data,
|
|
meta: body.meta ?? defaultMeta(body.data.length, page, pageSize),
|
|
};
|
|
}
|
|
|
|
if (Array.isArray(body)) {
|
|
return {
|
|
data: body as T[],
|
|
meta: defaultMeta(body.length, page, pageSize),
|
|
};
|
|
}
|
|
|
|
return { data: [], meta: defaultMeta(0, page, pageSize) };
|
|
};
|
|
|
|
const normalizeEntity = <T extends RuleEngineRecord>(payload: unknown): T => {
|
|
return unwrap(payload as { data: T }) as T;
|
|
};
|
|
|
|
export const ruleEngineService = {
|
|
list: async <T extends RuleEngineRecord>(
|
|
resource: RuleEngineResourceSlug,
|
|
params?: RuleEngineListParams,
|
|
): Promise<RuleEngineListResult<T>> => {
|
|
const page = params?.page ?? 1;
|
|
const pageSize = params?.pageSize ?? 10;
|
|
const response = await client.get(RESOURCE_BASE[resource], {
|
|
params: {
|
|
page,
|
|
pageSize,
|
|
search: params?.search,
|
|
isActive: params?.isActive,
|
|
status: params?.status,
|
|
sortBy: params?.sortBy,
|
|
sortOrder: params?.sortOrder,
|
|
requiresDirectorApproval: params?.requiresDirectorApproval,
|
|
},
|
|
});
|
|
return normalizeList<T>(response.data, page, pageSize);
|
|
},
|
|
|
|
getById: async <T extends RuleEngineRecord>(
|
|
resource: RuleEngineResourceSlug,
|
|
id: string,
|
|
): Promise<T> => {
|
|
const response = await client.get(byIdPath(resource, id));
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
create: async <T extends RuleEngineRecord>(
|
|
resource: RuleEngineResourceSlug,
|
|
payload: Record<string, unknown>,
|
|
): Promise<T> => {
|
|
const response = await client.post(RESOURCE_BASE[resource], payload);
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
update: async <T extends RuleEngineRecord>(
|
|
resource: RuleEngineResourceSlug,
|
|
id: string,
|
|
payload: Record<string, unknown>,
|
|
): Promise<T> => {
|
|
const response = await client.patch(byIdPath(resource, id), payload);
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
remove: async (
|
|
resource: RuleEngineResourceSlug,
|
|
id: string,
|
|
): Promise<void> => {
|
|
await client.delete(byIdPath(resource, id));
|
|
},
|
|
|
|
reorder: async (
|
|
resource: RuleEngineResourceSlug,
|
|
payload: RuleEngineReorderPayload,
|
|
): Promise<void> => {
|
|
await client.post(`${RESOURCE_BASE[resource]}/reorder`, payload);
|
|
},
|
|
|
|
moveOrder: async (
|
|
resource: RuleEngineResourceSlug,
|
|
id: string,
|
|
direction: "up" | "down",
|
|
): Promise<void> => {
|
|
await client.post(`${byIdPath(resource, id)}/move-order`, { direction });
|
|
},
|
|
|
|
submitRate: async <T extends RuleEngineRecord>(id: string): Promise<T> => {
|
|
const response = await client.post(
|
|
URL_CONSTANTS.RULE_ENGINE.RATE_SUBMIT(id),
|
|
);
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
approveRate: async <T extends RuleEngineRecord>(id: string): Promise<T> => {
|
|
const response = await client.post(
|
|
URL_CONSTANTS.RULE_ENGINE.RATE_APPROVE(id),
|
|
);
|
|
return normalizeEntity<T>(response.data);
|
|
},
|
|
|
|
getApprovalChain: async (
|
|
requiresDirectorApproval = true,
|
|
): Promise<RuleEngineRecord[]> => {
|
|
const response = await client.get(
|
|
URL_CONSTANTS.RULE_ENGINE.APPROVAL_RULES_CHAIN,
|
|
{
|
|
params: { requiresDirectorApproval },
|
|
},
|
|
);
|
|
const body = unwrap(response.data) as unknown;
|
|
if (Array.isArray(body)) return body as RuleEngineRecord[];
|
|
if (
|
|
body &&
|
|
typeof body === "object" &&
|
|
"data" in body &&
|
|
Array.isArray((body as { data: unknown }).data)
|
|
) {
|
|
return (body as { data: RuleEngineRecord[] }).data;
|
|
}
|
|
return [];
|
|
},
|
|
};
|