From 92369fceba42d8dbb29418bf11954008d9cda323 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 11 Jun 2025 10:29:58 -0700 Subject: [PATCH 01/98] IO-3255 Initial parts management changes. --- client/src/App/App.jsx | 22 +- client/src/App/App.styles.scss | 4 + .../job-detail-lines/job-lines.component.jsx | 91 +++--- .../job-detail-lines/job-lines.container.jsx | 4 +- .../simplified-parts-jobs-list.component.jsx | 251 +++++++++++++++++ .../simplified-parts-jobs-list.container.jsx | 53 ++++ client/src/graphql/jobs.queries.js | 45 +++ .../jobs-detail.page.component.jsx | 2 +- .../pages/manage/manage.page.component.jsx | 1 - .../src/pages/manage/manage.page.styles.scss | 8 - ...simplified-parts-jobs-detail.component.jsx | 214 +++++++++++++++ ...simplified-parts-jobs-detail.container.jsx | 103 +++++++ .../simplified-parts-jobs.page.jsx | 36 +++ .../simplified-parts.page.component.jsx | 258 ++++++++++++++++++ .../simplified-parts.page.container.jsx | 35 +++ 15 files changed, 1054 insertions(+), 73 deletions(-) create mode 100644 client/src/components/simplified-parts-jobs-list/simplified-parts-jobs-list.component.jsx create mode 100644 client/src/components/simplified-parts-jobs-list/simplified-parts-jobs-list.container.jsx delete mode 100644 client/src/pages/manage/manage.page.styles.scss create mode 100644 client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx create mode 100644 client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx create mode 100644 client/src/pages/simplified-parts-jobs/simplified-parts-jobs.page.jsx create mode 100644 client/src/pages/simplified-parts/simplified-parts.page.component.jsx create mode 100644 client/src/pages/simplified-parts/simplified-parts.page.container.jsx diff --git a/client/src/App/App.jsx b/client/src/App/App.jsx index 3cda7fe8e..cbbaf4432 100644 --- a/client/src/App/App.jsx +++ b/client/src/App/App.jsx @@ -12,6 +12,7 @@ import LoadingSpinner from "../components/loading-spinner/loading-spinner.compon import DisclaimerPage from "../pages/disclaimer/disclaimer.page"; import LandingPage from "../pages/landing/landing.page"; import TechPageContainer from "../pages/tech/tech.page.container"; +import SimplifiedPartsPageContainer from "../pages/simplified-parts/simplified-parts.page.container.jsx"; import { setOnline } from "../redux/application/application.actions"; import { selectOnline } from "../redux/application/application.selectors"; import { checkUserSession } from "../redux/user/user.actions"; @@ -28,7 +29,6 @@ const ResetPassword = lazy(() => import("../pages/reset-password/reset-password. const ManagePage = lazy(() => import("../pages/manage/manage.page.container")); const SignInPage = lazy(() => import("../pages/sign-in/sign-in.page")); const CsiPage = lazy(() => import("../pages/csi/csi.container.page")); -const MobilePaymentContainer = lazy(() => import("../pages/mobile-payment/mobile-payment.container")); const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -188,14 +188,6 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline } /> - - - - } - /> } /> + + + + + + } + > + } /> + }> } /> diff --git a/client/src/App/App.styles.scss b/client/src/App/App.styles.scss index 9ea0a8d24..898228880 100644 --- a/client/src/App/App.styles.scss +++ b/client/src/App/App.styles.scss @@ -190,3 +190,7 @@ margin-right: 0; } } + +.content-container { + padding: 1rem; +} diff --git a/client/src/components/job-detail-lines/job-lines.component.jsx b/client/src/components/job-detail-lines/job-lines.component.jsx index 455caefd6..41eb5f21a 100644 --- a/client/src/components/job-detail-lines/job-lines.component.jsx +++ b/client/src/components/job-detail-lines/job-lines.component.jsx @@ -78,7 +78,8 @@ export function JobLinesComponent({ billsQuery, handleBillOnRowClick, handlePartsOrderOnRowClick, - handlePartsDispatchOnRowClick + handlePartsDispatchOnRowClick, + simple }) { const [deleteJobLine] = useMutation(DELETE_JOB_LINE_BY_PK); const { @@ -220,59 +221,43 @@ export function JobLinesComponent({ sorter: (a, b) => a.part_qty - b.part_qty, sortOrder: state.sortedInfo.columnKey === "part_qty" && state.sortedInfo.order }, - // { - // title: t('joblines.fields.tax_part'), - // dataIndex: 'tax_part', - // key: 'tax_part', - // render: (text, record) => , - // }, - // { - // title: t("joblines.fields.total"), - // dataIndex: "total", - // key: "total", - // sorter: (a, b) => a.act_price * a.part_qty - b.act_price * b.part_qty, - // sortOrder: - // state.sortedInfo.columnKey === "total" && state.sortedInfo.order, - // ellipsis: true, - // render: (text, record) => ( - // - // {record.act_price * record.part_qty} - // - // ), - // }, - { - title: t("joblines.fields.mod_lbr_ty"), - dataIndex: "mod_lbr_ty", - key: "mod_lbr_ty", - - sorter: (a, b) => alphaSort(a.mod_lbr_ty, b.mod_lbr_ty), - sortOrder: state.sortedInfo.columnKey === "mod_lbr_ty" && state.sortedInfo.order, - render: (text, record) => (record.mod_lbr_ty ? t(`joblines.fields.lbr_types.${record.mod_lbr_ty}`) : null) - }, - { - title: t("joblines.fields.mod_lb_hrs"), - dataIndex: "mod_lb_hrs", - key: "mod_lb_hrs", - - sorter: (a, b) => a.mod_lb_hrs - b.mod_lb_hrs, - sortOrder: state.sortedInfo.columnKey === "mod_lb_hrs" && state.sortedInfo.order - }, - { - title: t("joblines.fields.line_ind"), - dataIndex: "line_ind", - key: "line_ind", - sorter: (a, b) => alphaSort(a.line_ind, b.line_ind), - sortOrder: state.sortedInfo.columnKey === "line_ind" && state.sortedInfo.order, - responsive: ["md"] - }, - ...(Enhanced_Payroll.treatment === "on" + ...(!simple ? [ { - title: t("joblines.fields.assigned_team"), - dataIndex: "assigned_team", - key: "assigned_team", - render: (text, record) => - } + title: t("joblines.fields.mod_lbr_ty"), + dataIndex: "mod_lbr_ty", + key: "mod_lbr_ty", + + sorter: (a, b) => alphaSort(a.mod_lbr_ty, b.mod_lbr_ty), + sortOrder: state.sortedInfo.columnKey === "mod_lbr_ty" && state.sortedInfo.order, + render: (text, record) => (record.mod_lbr_ty ? t(`joblines.fields.lbr_types.${record.mod_lbr_ty}`) : null) + }, + { + title: t("joblines.fields.mod_lb_hrs"), + dataIndex: "mod_lb_hrs", + key: "mod_lb_hrs", + + sorter: (a, b) => a.mod_lb_hrs - b.mod_lb_hrs, + sortOrder: state.sortedInfo.columnKey === "mod_lb_hrs" && state.sortedInfo.order + }, + { + title: t("joblines.fields.line_ind"), + dataIndex: "line_ind", + key: "line_ind", + sorter: (a, b) => alphaSort(a.line_ind, b.line_ind), + sortOrder: state.sortedInfo.columnKey === "line_ind" && state.sortedInfo.order, + responsive: ["md"] + }, + ...(Enhanced_Payroll.treatment === "on" + ? [ + { + title: t("joblines.fields.assigned_team"), + dataIndex: "assigned_team", + key: "assigned_team", + render: (text, record) => + } + ] + : []) ] : []), @@ -288,7 +273,7 @@ export function JobLinesComponent({ key: "location", render: (text, record) => }, - ...(HasFeatureAccess({ featureName: "bills", bodyshop }) + ...(!simple && HasFeatureAccess({ featureName: "bills", bodyshop }) ? [ { title: t("joblines.labels.billref"), diff --git a/client/src/components/job-detail-lines/job-lines.container.jsx b/client/src/components/job-detail-lines/job-lines.container.jsx index 8ed70dbdc..5d4567418 100644 --- a/client/src/components/job-detail-lines/job-lines.container.jsx +++ b/client/src/components/job-detail-lines/job-lines.container.jsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState } from "react"; +import { useMemo, useState } from "react"; import JobLinesComponent from "./job-lines.component"; function JobLinesContainer({ @@ -10,6 +10,7 @@ function JobLinesContainer({ handlePartsDispatchOnRowClick, refetch, form, + simple = false, ...rest }) { const [searchText, setSearchText] = useState(""); @@ -43,6 +44,7 @@ function JobLinesContainer({ setSearchText={setSearchText} job={job} form={form} + simple={simple} /> ); diff --git a/client/src/components/simplified-parts-jobs-list/simplified-parts-jobs-list.component.jsx b/client/src/components/simplified-parts-jobs-list/simplified-parts-jobs-list.component.jsx new file mode 100644 index 000000000..db57f62b5 --- /dev/null +++ b/client/src/components/simplified-parts-jobs-list/simplified-parts-jobs-list.component.jsx @@ -0,0 +1,251 @@ +import { SyncOutlined } from "@ant-design/icons"; +import { Button, Card, Input, Space, Table, Typography } from "antd"; +import axios from "axios"; +import _ from "lodash"; +import queryString from "query-string"; +import { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { Link, useLocation, useNavigate } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +import CurrencyFormatter from "../../utils/CurrencyFormatter"; +import { pageLimit } from "../../utils/config"; +import { alphaSort, statusSort } from "../../utils/sorters"; +import useLocalStorage from "../../utils/useLocalStorage"; +import OwnerNameDisplay from "../owner-name-display/owner-name-display.component"; +import JobPartsQueueCount from "../job-parts-queue-count/job-parts-queue-count.component"; + +const mapStateToProps = createStructuredSelector({ + //currentUser: selectCurrentUser + bodyshop: selectBodyshop +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) +}); + +export function SimplifiedPartsJobsListComponent({ bodyshop, refetch, loading, jobs, total }) { + const search = queryString.parse(useLocation().search); + const [openSearchResults, setOpenSearchResults] = useState([]); + const [searchLoading, setSearchLoading] = useState(false); + const [filter, setFilter] = useLocalStorage("filter_jobs_all", null); + const { page, sortcolumn, sortorder } = search; + const history = useNavigate(); + + const { t } = useTranslation(); + const columns = [ + { + title: t("jobs.fields.ro_number"), + dataIndex: "ro_number", + key: "ro_number", + sorter: search?.search + ? (a, b) => + parseInt((a.ro_number || "0").replace(/\D/g, "")) - parseInt((b.ro_number || "0").replace(/\D/g, "")) + : true, + sortOrder: sortcolumn === "ro_number" && sortorder, + render: (text, record) => ( + {record.ro_number || t("general.labels.na")} + ) + }, + { + title: t("jobs.fields.owner"), + dataIndex: "ownr_ln", + key: "ownr_ln", + ellipsis: true, + //sorter: true, // (a, b) => alphaSort(a.ownr_ln, b.ownr_ln), + //sortOrder: sortcolumn === "ownr_ln" && sortorder, + render: (text, record) => { + return record.ownerid ? ( + + + + ) : ( + + + + ); + } + }, + + { + title: t("jobs.fields.status"), + dataIndex: "status", + key: "status", + + ellipsis: true, + sorter: search?.search ? (a, b) => statusSort(a.status, b.status, bodyshop.md_ro_statuses.active_statuses) : true, + sortOrder: sortcolumn === "status" && sortorder, + render: (text, record) => { + return record.status || t("general.labels.na"); + }, + filteredValue: filter?.status || null, + filters: bodyshop.md_ro_statuses.statuses.map((s) => { + return { text: s, value: [s] }; + }), + onFilter: (value, record) => value.includes(record.status) + }, + { + title: t("jobs.fields.vehicle"), + dataIndex: "vehicle", + key: "vehicle", + ellipsis: true, + render: (text, record) => { + return record.vehicleid ? ( + + {`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${record.v_model_desc || ""}`} + + ) : ( + {`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${record.v_model_desc || ""}`} + ); + } + }, + { + title: t("vehicles.fields.plate_no"), + dataIndex: "plate_no", + key: "plate_no", + ellipsis: true, + sorter: search?.search ? (a, b) => alphaSort(a.plate_no, b.plate_no) : true, + sortOrder: sortcolumn === "plate_no" && sortorder, + render: (text, record) => { + return record.plate_no ? record.plate_no : ""; + } + }, + { + title: t("jobs.fields.clm_no"), + dataIndex: "clm_no", + key: "clm_no", + ellipsis: true, + sorter: search?.search ? (a, b) => alphaSort(a.clm_no, b.clm_no) : true, + sortOrder: sortcolumn === "clm_no" && sortorder, + render: (text, record) => `${record.clm_no || ""}${record.po_number ? ` (PO: ${record.po_number})` : ""}` + }, + { + title: t("jobs.fields.ins_co_nm"), + dataIndex: "ins_co_nm", + key: "ins_co_nm", + ellipsis: true + }, + { + title: t("jobs.fields.clm_total"), + dataIndex: "clm_total", + key: "clm_total", + sorter: search?.search ? (a, b) => a.clm_total - b.clm_total : true, + sortOrder: sortcolumn === "clm_total" && sortorder, + render: (text, record) => { + return record.clm_total ? ( + {record.clm_total} + ) : ( + t("general.labels.unknown") + ); + } + }, + { + title: t("jobs.fields.partsstatus"), + dataIndex: "partsstatus", + key: "partsstatus", + render: (text, record) => + }, + { + title: t("jobs.fields.comment"), + dataIndex: "comment", + key: "comment", + ellipsis: true + } + ]; + + const handleTableChange = (pagination, filters, sorter) => { + search.page = pagination.current; + search.sortcolumn = sorter.column && sorter.column.key; + search.sortorder = sorter.order; + if (filters.status) { + search.statusFilters = JSON.stringify(_.flattenDeep(filters.status)); + } else { + delete search.statusFilters; + } + setFilter(filters); + history({ search: queryString.stringify(search) }); + }; + + useEffect(() => { + if (search.search && search.search.trim() !== "") { + searchJobs(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + async function searchJobs(value) { + try { + setSearchLoading(true); + const searchData = await axios.post("/search", { + search: value || search.search, + index: "jobs" + }); + setOpenSearchResults(searchData.data.hits.hits.map((s) => s._source)); + } catch (error) { + console.log("Error while fetching search results", error); + } finally { + setSearchLoading(false); + } + } + + return ( + + {search.search && ( + <> + + {t("general.labels.searchresults", { search: search.search })} + + + + )} + + { + search.search = value; + history({ search: queryString.stringify(search) }); + searchJobs(value); + }} + loading={loading || searchLoading} + enterButton + /> + + } + > + + + ); +} + +export default connect(mapStateToProps, mapDispatchToProps)(SimplifiedPartsJobsListComponent); diff --git a/client/src/components/simplified-parts-jobs-list/simplified-parts-jobs-list.container.jsx b/client/src/components/simplified-parts-jobs-list/simplified-parts-jobs-list.container.jsx new file mode 100644 index 000000000..916108a80 --- /dev/null +++ b/client/src/components/simplified-parts-jobs-list/simplified-parts-jobs-list.container.jsx @@ -0,0 +1,53 @@ +import { useQuery } from "@apollo/client"; +import queryString from "query-string"; +import { connect } from "react-redux"; +import { useLocation } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import AlertComponent from "../../components/alert/alert.component"; +import { QUERY_SIMPLIFIED_PARTS_PAGINATED_STATUS_FILTERED } from "../../graphql/jobs.queries"; +import { setBreadcrumbs, setSelectedHeader } from "../../redux/application/application.actions"; +import { pageLimit } from "../../utils/config"; +import SimplifiedPartsJobsListComponent from "./simplified-parts-jobs-list.component"; + +const mapStateToProps = createStructuredSelector({ + //bodyshop: selectBodyshop, +}); + +const mapDispatchToProps = (dispatch) => ({ + setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)), + setSelectedHeader: (key) => dispatch(setSelectedHeader(key)) +}); + +export function SimplifiedPartsJobsListContainer({ setBreadcrumbs, setSelectedHeader }) { + const searchParams = queryString.parse(useLocation().search); + const { page, sortcolumn, sortorder, statusFilters } = searchParams; + + const { loading, error, data, refetch } = useQuery(QUERY_SIMPLIFIED_PARTS_PAGINATED_STATUS_FILTERED, { + fetchPolicy: "network-only", + nextFetchPolicy: "network-only", + variables: { + offset: page ? (page - 1) * pageLimit : 0, + limit: pageLimit, + ...(statusFilters ? { statusList: JSON.parse(statusFilters) } : {}), + order: [ + { + [sortcolumn || "ro_number"]: + sortorder && sortorder !== "false" ? (sortorder === "descend" ? "desc" : "asc") : "desc" + } + ] + } + }); + + if (error) return ; + return ( + + ); +} + +export default connect(mapStateToProps, mapDispatchToProps)(SimplifiedPartsJobsListContainer); diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index 68c8adfbe..119263c01 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -1836,6 +1836,51 @@ export const QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED = gql` } } `; +export const QUERY_SIMPLIFIED_PARTS_PAGINATED_STATUS_FILTERED = gql` + query QUERY_ALL_JOBS_PAGINATED_STATUS_FILTERED( + $offset: Int + $limit: Int + $order: [jobs_order_by!] + $statusList: [String!] + ) { + jobs(offset: $offset, limit: $limit, order_by: $order, where: { status: { _in: $statusList } }) { + comment + ownr_fn + ownr_ln + ownr_co_nm + ownr_ph1 + ownr_ph2 + plate_no + plate_st + v_vin + v_model_yr + v_model_desc + v_make_desc + v_color + vehicleid + id + ins_co_nm + clm_no + clm_total + owner_owing + ro_number + po_number + status + updated_at + ded_amt + joblines_status { + count + part_type + status + } + } + jobs_aggregate(where: { status: { _in: $statusList } }) { + aggregate { + count(distinct: true) + } + } + } +`; export const QUERY_JOB_CLOSE_DETAILS = gql` query QUERY_JOB_CLOSE_DETAILS($id: uuid!) { diff --git a/client/src/pages/jobs-detail/jobs-detail.page.component.jsx b/client/src/pages/jobs-detail/jobs-detail.page.component.jsx index 6afe3ba15..7b797ee31 100644 --- a/client/src/pages/jobs-detail/jobs-detail.page.component.jsx +++ b/client/src/pages/jobs-detail/jobs-detail.page.component.jsx @@ -487,7 +487,7 @@ export function JobsDetailPage({ export default connect(mapStateToProps, mapDispatchToProps)(JobsDetailPage); -const transformJobToForm = (job) => { +export const transformJobToForm = (job) => { const transformedJob = { ...job }; transformedJob.parts_tax_rates = Object.keys(transformedJob.parts_tax_rates).reduce((acc, parttype) => { diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx index d8a9b4b84..bd2657818 100644 --- a/client/src/pages/manage/manage.page.component.jsx +++ b/client/src/pages/manage/manage.page.component.jsx @@ -23,7 +23,6 @@ import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-st import { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors"; import UpdateAlert from "../../components/update-alert/update-alert.component"; import InstanceRenderManager from "../../utils/instanceRenderMgr.js"; -import "./manage.page.styles.scss"; import WssStatusDisplayComponent from "../../components/wss-status-display/wss-status-display.component.jsx"; import { selectAlerts } from "../../redux/application/application.selectors.js"; import { addAlerts } from "../../redux/application/application.actions.js"; diff --git a/client/src/pages/manage/manage.page.styles.scss b/client/src/pages/manage/manage.page.styles.scss deleted file mode 100644 index 9084e96bb..000000000 --- a/client/src/pages/manage/manage.page.styles.scss +++ /dev/null @@ -1,8 +0,0 @@ -.content-container { - padding: 1rem; -} - -.layout-container { - // height: 100vh; - // overflow-y: auto; -} diff --git a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx new file mode 100644 index 000000000..faff65ce0 --- /dev/null +++ b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx @@ -0,0 +1,214 @@ +import { BarsOutlined, PrinterFilled, SyncOutlined, ToolFilled } from "@ant-design/icons"; +import { PageHeader } from "@ant-design/pro-layout"; +import { useQuery } from "@apollo/client"; +import { Button, Divider, Form, Space, Tabs } from "antd"; +import Axios from "axios"; +import _ from "lodash"; +import queryString from "query-string"; +import { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { useLocation, useNavigate } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import FormFieldsChanged from "../../components/form-fields-changed-alert/form-fields-changed-alert.component.jsx"; +import JobsLinesContainer from "../../components/job-detail-lines/job-lines.container.jsx"; +import JobLineUpsertModalContainer from "../../components/job-lines-upsert-modal/job-lines-upsert-modal.container.jsx"; +import JobProfileDataWarning from "../../components/job-profile-data-warning/job-profile-data-warning.component.jsx"; +import JobsChangeStatus from "../../components/jobs-change-status/jobs-change-status.component.jsx"; +import JobsDetailHeaderActions from "../../components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx"; +import JobsDetailHeader from "../../components/jobs-detail-header/jobs-detail-header.component.jsx"; +import JobsDetailPliContainer from "../../components/jobs-detail-pli/jobs-detail-pli.container.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; +import { useSocket } from "../../contexts/SocketIO/useSocket.js"; +import { QUERY_PARTS_BILLS_BY_JOBID } from "../../graphql/bills.queries.js"; +import { insertAuditTrail } from "../../redux/application/application.actions.js"; +import { selectJobReadOnly } from "../../redux/application/application.selectors.js"; +import { setModalContext } from "../../redux/modals/modals.actions.js"; +import { selectBodyshop } from "../../redux/user/user.selectors.js"; +import AuditTrailMapping from "../../utils/AuditTrailMappings.js"; +import { DateTimeFormat } from "../../utils/DateFormatter.jsx"; +import dayjs from "../../utils/day.js"; +import UndefinedToNull from "../../utils/undefinedtonull.js"; +import { transformJobToForm } from "../jobs-detail/jobs-detail.page.component.jsx"; + +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop, + jobRO: selectJobReadOnly +}); +const mapDispatchToProps = (dispatch) => ({ + setPrintCenterContext: (context) => + dispatch( + setModalContext({ + context: context, + modal: "printCenter" + }) + ), + insertAuditTrail: ({ jobid, operation, type }) => + dispatch( + insertAuditTrail({ + jobid, + operation, + type + }) + ) +}); + +export function SimplifiedPartsJobDetailComponent({ + bodyshop, + setPrintCenterContext, + jobRO, + job, + mutationUpdateJob, + insertAuditTrail, + refetch +}) { + const { t } = useTranslation(); + const [form] = Form.useForm(); + const history = useNavigate(); + const [loading, setLoading] = useState(false); + const search = queryString.parse(useLocation().search); + const formItemLayout = { + layout: "vertical" + }; + const billsQuery = useQuery(QUERY_PARTS_BILLS_BY_JOBID, { + variables: { jobid: job.id }, + fetchPolicy: "network-only", + nextFetchPolicy: "network-only" + }); + const notification = useNotification(); + const { scenarioNotificationsOn } = useSocket(); + + useEffect(() => { + //form.setFieldsValue(transormJobToForm(job)); + form.resetFields(); + }, [form, job]); + + const handleBillOnRowClick = (record) => { + if (record) { + if (record.id) { + search.billid = record.id; + history({ search: queryString.stringify(search) }); + } + } else { + delete search.billid; + history({ search: queryString.stringify(search) }); + } + }; + + const handlePartsOrderOnRowClick = (record) => { + if (record) { + if (record.id) { + search.partsorderid = record.id; + history({ search: queryString.stringify(search) }); + } + } else { + delete search.partsorderid; + history({ search: queryString.stringify(search) }); + } + }; + + const handlePartsDispatchOnRowClick = (record) => { + if (record) { + if (record.id) { + search.partsdispatchid = record.id; + history.push({ search: queryString.stringify(search) }); + } + } else { + delete search.partsdispatchid; + history.push({ search: queryString.stringify(search) }); + } + }; + + const menuExtra = ( + + + + + + + + + ); + + return ( +
+ + + {job.ro_number || t("general.labels.na")}} extra={menuExtra} /> + + + + + history({ search: `?tab=${key}` })} + tabBarStyle={{ fontWeight: "bold", borderBottom: "10px" }} + items={[ + { + key: "repairdata", + icon: , + id: "job-details-repairdata", + label: t("menus.jobsdetail.repairdata"), + forceRender: true, + children: ( + + ) + }, + + { + key: "partssublet", + id: "job-details-partssublet", + icon: , + label: t("menus.jobsdetail.partssublet"), + children: ( + + ) + } + ]} + /> +
+ ); +} + +export default connect(mapStateToProps, mapDispatchToProps)(SimplifiedPartsJobDetailComponent); diff --git a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx new file mode 100644 index 000000000..2728118d0 --- /dev/null +++ b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx @@ -0,0 +1,103 @@ +import { useQuery } from "@apollo/client"; +import { useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { useParams } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import AlertComponent from "../../components/alert/alert.component"; +import SpinComponent from "../../components/loading-spinner/loading-spinner.component"; +import NotFound from "../../components/not-found/not-found.component"; +import { OwnerNameDisplayFunction } from "../../components/owner-name-display/owner-name-display.component"; +import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component"; +import { GET_JOB_BY_PK } from "../../graphql/jobs.queries"; +import { + addRecentItem, + setBreadcrumbs, + setJobReadOnly, + setSelectedHeader +} from "../../redux/application/application.actions"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +import { CreateRecentItem } from "../../utils/create-recent-item"; +import InstanceRenderManager from "../../utils/instanceRenderMgr"; +import IsJobReadOnly from "../../utils/jobReadOnly"; +import SimplifiedPartsJobsDetailComponent from "./simplified-parts-jobs-detail.component"; + +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop +}); + +const mapDispatchToProps = (dispatch) => ({ + setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)), + addRecentItem: (item) => dispatch(addRecentItem(item)), + setSelectedHeader: (key) => dispatch(setSelectedHeader(key)), + setJobReadOnly: (bool) => dispatch(setJobReadOnly(bool)) +}); + +function SimplifiedPartsJobsDetailContainer({ setBreadcrumbs, addRecentItem, setSelectedHeader, setJobReadOnly }) { + const { jobId } = useParams(); + const { t } = useTranslation(); + + const { loading, error, data, refetch } = useQuery(GET_JOB_BY_PK, { + variables: { id: jobId }, + fetchPolicy: "network-only", + nextFetchPolicy: "network-only" + }); + + useEffect(() => { + setSelectedHeader("activejobs"); + document.title = loading + ? InstanceRenderManager({ + imex: t("titles.imexonline"), + rome: t("titles.romeonline") + }) + : error + ? InstanceRenderManager({ + imex: t("titles.imexonline"), + rome: t("titles.romeonline") + }) + : t("titles.jobsdetail", { + app: InstanceRenderManager({ + imex: "$t(titles.imexonline)", + rome: "$t(titles.romeonline)" + }), + ro_number: (data.jobs_by_pk && data.jobs_by_pk.ro_number) || t("general.labels.na") + }); + setBreadcrumbs([ + { link: "/parts/jobs", label: t("titles.bc.jobs") }, + { + link: `/parts/jobs/${jobId}`, + label: t("titles.bc.jobs-detail", { + number: (data && data.jobs_by_pk && data.jobs_by_pk.ro_number) || t("general.labels.na") + }) + } + ]); + + if (data && data.jobs_by_pk) { + setJobReadOnly(IsJobReadOnly(data.jobs_by_pk)); + + addRecentItem( + CreateRecentItem( + jobId, + "job", + + `${data.jobs_by_pk.ro_number || t("general.labels.na")} | ${OwnerNameDisplayFunction(data.jobs_by_pk)}`, + `/manage/jobs/${jobId}` + ) + ); + } + }, [loading, data, t, error, setBreadcrumbs, jobId, addRecentItem, setSelectedHeader, setJobReadOnly]); + + if (loading) return ; + if (error) return ; + if (!data.jobs_by_pk) return ; + + return data.jobs_by_pk ? ( + + + + ) : ( + + ); +} + +export default connect(mapStateToProps, mapDispatchToProps)(SimplifiedPartsJobsDetailContainer); diff --git a/client/src/pages/simplified-parts-jobs/simplified-parts-jobs.page.jsx b/client/src/pages/simplified-parts-jobs/simplified-parts-jobs.page.jsx new file mode 100644 index 000000000..ed7215e69 --- /dev/null +++ b/client/src/pages/simplified-parts-jobs/simplified-parts-jobs.page.jsx @@ -0,0 +1,36 @@ +import { useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component"; +import SimplifiedPartsJobsListContainer from "../../components/simplified-parts-jobs-list/simplified-parts-jobs-list.container"; +import { setBreadcrumbs, setSelectedHeader } from "../../redux/application/application.actions"; +import InstanceRenderManager from "../../utils/instanceRenderMgr"; + +const mapDispatchToProps = (dispatch) => ({ + setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)), + setSelectedHeader: (key) => dispatch(setSelectedHeader(key)) +}); + +export function SimplifiedPartsJobsPage({ setBreadcrumbs, setSelectedHeader }) { + const { t } = useTranslation(); + + useEffect(() => { + document.title = t("titles.simplified-parts-jobs", { + app: InstanceRenderManager({ + imex: "$t(titles.imexonline)", + rome: "$t(titles.romeonline)" + }) + }); + setSelectedHeader("parts-queue"); + setBreadcrumbs([{ link: "/parts", label: t("titles.bc.simplified-parts-jobs") }]); + }, [setBreadcrumbs, t, setSelectedHeader]); + + return ( + + + {/* */} + + ); +} + +export default connect(null, mapDispatchToProps)(SimplifiedPartsJobsPage); diff --git a/client/src/pages/simplified-parts/simplified-parts.page.component.jsx b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx new file mode 100644 index 000000000..a7a30c198 --- /dev/null +++ b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx @@ -0,0 +1,258 @@ +import { AlertOutlined, BulbOutlined } from "@ant-design/icons"; +import * as Sentry from "@sentry/react"; +import { Button, FloatButton, Layout, Space, Spin } from "antd"; +import { lazy, Suspense, useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { Link, Route, Routes } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import BreadCrumbs from "../../components/breadcrumbs/breadcrumbs.component.jsx"; +import ConflictComponent from "../../components/conflict/conflict.component.jsx"; +import ErrorBoundary from "../../components/error-boundary/error-boundary.component.jsx"; +import HeaderContainer from "../../components/header/header.container.jsx"; +import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component.jsx"; +import PrintCenterModalContainer from "../../components/print-center-modal/print-center-modal.container.jsx"; +import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-status.component.jsx"; +import UpdateAlert from "../../components/update-alert/update-alert.component.jsx"; +import WssStatusDisplayComponent from "../../components/wss-status-display/wss-status-display.component.jsx"; +import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; +import { useSocket } from "../../contexts/SocketIO/useSocket.js"; +import { addAlerts } from "../../redux/application/application.actions.js"; +import { selectAlerts } from "../../redux/application/application.selectors.js"; +import { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors.js"; +import InstanceRenderManager from "../../utils/instanceRenderMgr.js"; + +const SimplifiedPartsJobsPage = lazy(() => import("../simplified-parts-jobs/simplified-parts-jobs.page.jsx")); +const SimplifiedPartsJobsDetailPage = lazy( + () => import("../simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx") +); +const ShopPage = lazy(() => import("../shop/shop.page.component.jsx")); +const ShopVendorPageContainer = lazy(() => import("../shop-vendor/shop-vendor.page.container.jsx")); +const EmailOverlayContainer = lazy(() => import("../../components/email-overlay/email-overlay.container.jsx")); +const FeatureRequestPage = lazy(() => import("../feature-request/feature-request.page.jsx")); +const JobCostingModal = lazy(() => import("../../components/job-costing-modal/job-costing-modal.container.jsx")); +const ReportCenterModal = lazy(() => import("../../components/report-center-modal/report-center-modal.container.jsx")); +const BillEnterModalContainer = lazy(() => import("../../components/bill-enter-modal/bill-enter-modal.container.jsx")); +const Help = lazy(() => import("../help/help.page.jsx")); + +const { Content, Footer } = Layout; + +const mapStateToProps = createStructuredSelector({ + conflict: selectInstanceConflict, + bodyshop: selectBodyshop, + alerts: selectAlerts +}); + +const ALERT_FILE_URL = InstanceRenderManager({ + imex: "https://images.imex.online/alerts/alerts-imex.json", + rome: "https://images.imex.online/alerts/alerts-rome.json" +}); + +const mapDispatchToProps = (dispatch) => ({ + setAlerts: (alerts) => dispatch(addAlerts(alerts)) +}); + +export function SimplifiedPartsPage({ conflict, bodyshop, alerts, setAlerts }) { + const { t } = useTranslation(); + const { socket, clientId } = useSocket(); + const notification = useNotification(); + + // State to track displayed alerts + const [displayedAlertIds, setDisplayedAlertIds] = useState([]); + + // Fetch displayed alerts from localStorage on mount + useEffect(() => { + const displayedAlerts = JSON.parse(localStorage.getItem("displayedAlerts") || "[]"); + setDisplayedAlertIds(displayedAlerts); + }, []); + + // Fetch alerts from the JSON file and dispatch to Redux store + useEffect(() => { + const fetchAlerts = async () => { + try { + const response = await fetch(ALERT_FILE_URL); + const fetchedAlerts = await response.json(); + setAlerts(fetchedAlerts); + } catch (error) { + console.warn("Error fetching alerts:", error.message); + } + }; + + fetchAlerts().catch((err) => `Error fetching Bodyshop Alerts: ${err?.message || ""}`); + }, [setAlerts]); + + // Use useEffect to watch for new alerts + useEffect(() => { + if (alerts && Object.keys(alerts).length > 0) { + // Convert the alerts object into an array + const alertArray = Object.values(alerts); + + // Filter out alerts that have already been dismissed + const newAlerts = alertArray.filter((alert) => !displayedAlertIds.includes(alert.id)); + + newAlerts.forEach((alert) => { + // Display the notification + notification.open({ + key: "notification-alerts-" + alert.id, + message: alert.message, + description: alert.description, + type: alert.type || "info", + duration: 0, + closable: true, + onClose: () => { + // When the notification is closed, update displayed alerts state and localStorage + setDisplayedAlertIds((prevIds) => { + const updatedIds = [...prevIds, alert.id]; + localStorage.setItem("displayedAlerts", JSON.stringify(updatedIds)); + return updatedIds; + }); + } + }); + }); + } + }, [alerts, displayedAlertIds, notification]); + + useEffect(() => { + window.Canny("initChangelog", { + appID: "680bd2c7ee501290377f6686", + position: "top", + align: "left", + theme: "light" // options: light [default], dark, auto + }); + }, []); + + useEffect(() => { + document.title = InstanceRenderManager({ + imex: t("titles.imexonline"), + rome: t("titles.romeonline") + }); + }, [t]); + + const AppRouteTable = ( + + } + > + + + + + + + + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + }> + + + } + /> + } /> + + }> + + + } + /> + + + ); + + let PageContent; + + if (conflict) PageContent = ; + else if (bodyshop && bodyshop.sub_status !== "active") PageContent = ; + else PageContent = AppRouteTable; + + const broadcastMessage = () => { + if (socket && bodyshop && bodyshop.id) { + console.log(`Broadcasting message to bodyshop ${bodyshop.id}:`); + socket.emit("broadcast-to-bodyshop", bodyshop.id, `Hello from ${clientId}`); + } + }; + + return ( + <> + + + {/* */} + + } showDialog> + {PageContent} + + + +
+
+ + + + + +
+ {`${InstanceRenderManager({ + imex: t("titles.imexonline"), + rome: t("titles.romeonline") + })} - ${import.meta.env.VITE_APP_GIT_SHA_DATE}`} +
+ +
+ + Disclaimer & Notices + +
+
+
+ + ); +} + +export default connect(mapStateToProps, mapDispatchToProps)(SimplifiedPartsPage); diff --git a/client/src/pages/simplified-parts/simplified-parts.page.container.jsx b/client/src/pages/simplified-parts/simplified-parts.page.container.jsx new file mode 100644 index 000000000..b76323e10 --- /dev/null +++ b/client/src/pages/simplified-parts/simplified-parts.page.container.jsx @@ -0,0 +1,35 @@ +import { useQuery } from "@apollo/client"; +import { useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import AlertComponent from "../../components/alert/alert.component"; +import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component"; +import { QUERY_BODYSHOP } from "../../graphql/bodyshop.queries"; +import { setBodyshop } from "../../redux/user/user.actions"; +import SimplifiedPartsPage from "./simplified-parts.page.component"; + +const mapDispatchToProps = (dispatch) => ({ + setBodyshop: (bs) => dispatch(setBodyshop(bs)) +}); + +function SimplifiedPartsPageContainer({ setBodyshop }) { + const { loading, error, data } = useQuery(QUERY_BODYSHOP, { + fetchPolicy: "network-only", + nextFetchPolicy: "network-only" + }); + + const { t } = useTranslation(); + + useEffect(() => { + if (data) { + setBodyshop(data.bodyshops[0] || { notfound: true }); + } + }, [data, setBodyshop]); + + if (loading) return ; + if (error) return ; + + return ; +} + +export default connect(null, mapDispatchToProps)(SimplifiedPartsPageContainer); From 8af6c8dd247783c559f2c439fa5aa839e35b1ef7 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Thu, 12 Jun 2025 12:05:40 -0400 Subject: [PATCH 02/98] feature/IO-3255-simplified-parts-management --- client/package-lock.json | 332 +++++++++++++++++++-------------------- client/package.json | 22 +-- package-lock.json | 220 +++++++++++++------------- package.json | 20 +-- 4 files changed, 297 insertions(+), 297 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 189f1fbe3..30de262cd 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,23 +9,23 @@ "version": "0.2.1", "hasInstallScript": true, "dependencies": { - "@ant-design/pro-layout": "^7.22.4", + "@ant-design/pro-layout": "^7.22.6", "@apollo/client": "^3.13.6", "@emotion/is-prop-valid": "^1.3.1", "@fingerprintjs/fingerprintjs": "^4.6.1", "@firebase/analytics": "^0.10.16", "@firebase/app": "^0.13.1", - "@firebase/auth": "^1.10.6", + "@firebase/auth": "^1.10.7", "@firebase/firestore": "^4.7.17", "@firebase/messaging": "^0.12.21", "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.27.0", + "@sentry/react": "^9.28.1", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.25.4", + "antd": "^5.26.0", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -40,7 +40,7 @@ "exifr": "^7.1.3", "graphql": "^16.11.0", "i18next": "^24.2.3", - "i18next-browser-languagedetector": "^8.1.0", + "i18next-browser-languagedetector": "^8.2.0", "immutability-helper": "^3.1.1", "libphonenumber-js": "^1.12.9", "logrocket": "^9.0.2", @@ -53,7 +53,7 @@ "query-string": "^9.2.0", "raf-schd": "^4.0.3", "react": "^18.3.1", - "react-big-calendar": "^1.19.2", + "react-big-calendar": "^1.19.3", "react-color": "^2.19.3", "react-cookie": "^8.0.1", "react-dom": "^18.3.1", @@ -79,7 +79,7 @@ "redux-saga": "^1.3.0", "redux-state-sync": "^3.1.4", "reselect": "^5.1.1", - "sass": "^1.89.1", + "sass": "^1.89.2", "socket.io-client": "^4.8.1", "styled-components": "^6.1.18", "subscriptions-transport-ws": "^0.11.0", @@ -91,16 +91,16 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.44.1", + "@dotenvx/dotenvx": "^1.44.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", "@eslint/js": "^9.28.0", - "@playwright/test": "^1.51.1", + "@playwright/test": "^1.53.0", "@sentry/webpack-plugin": "^3.5.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", - "@vitejs/plugin-react": "^4.5.1", + "@vitejs/plugin-react": "^4.5.2", "browserslist": "^4.25.0", "browserslist-to-esbuild": "^2.1.1", "chalk": "^5.4.1", @@ -111,7 +111,7 @@ "jsdom": "^26.0.0", "memfs": "^4.17.2", "os-browserify": "^0.3.0", - "playwright": "^1.51.1", + "playwright": "^1.53.0", "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", @@ -232,15 +232,15 @@ "license": "MIT" }, "node_modules/@ant-design/pro-layout": { - "version": "7.22.4", - "resolved": "https://registry.npmjs.org/@ant-design/pro-layout/-/pro-layout-7.22.4.tgz", - "integrity": "sha512-X2WO4L2itXemX4zhS+0NG+8kXQD5SX9sG+zjx/15BmIO3FvsUGqOHgoCg0vhd424EiyPj7WtdMZJ39G1xdgDwA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@ant-design/pro-layout/-/pro-layout-7.22.6.tgz", + "integrity": "sha512-4DGK9nZ7B0FGVpJkMCUDrksBhTHc/pg72BMOBguqMOZCdsuEuJAyIl12eYK8gasGcbYtHzjvdYCamR+TJR8Low==", "license": "MIT", "dependencies": { "@ant-design/cssinjs": "^1.21.1", "@ant-design/icons": "^5.0.0", - "@ant-design/pro-provider": "2.15.4", - "@ant-design/pro-utils": "2.17.0", + "@ant-design/pro-provider": "2.16.1", + "@ant-design/pro-utils": "2.17.2", "@babel/runtime": "^7.18.0", "@umijs/route-utils": "^4.0.0", "@umijs/use-params": "^1.0.9", @@ -301,9 +301,9 @@ } }, "node_modules/@ant-design/pro-provider": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/@ant-design/pro-provider/-/pro-provider-2.15.4.tgz", - "integrity": "sha512-DBX0JNUNOYXAucVqd/zTdqtXckCDqr2Lo85KIku2YzWdhptDPDZRTNqL04JShjGejDl8fzwQ8yREHgVUfzn6Gg==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/@ant-design/pro-provider/-/pro-provider-2.16.1.tgz", + "integrity": "sha512-9kSiptgoEybRleajA9KiMqnGqLTbIGdm7TDclBS4QGGrjkHfcXDw+GruiDwghOHvTwTkZT98Xttvw4w1XfrS+g==", "license": "MIT", "dependencies": { "@ant-design/cssinjs": "^1.21.1", @@ -320,13 +320,13 @@ } }, "node_modules/@ant-design/pro-utils": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/@ant-design/pro-utils/-/pro-utils-2.17.0.tgz", - "integrity": "sha512-hHKUISjMEoS+E5ltJWyvNTrlEA3IimZNxtDrEhorRIbgVYAlmEN5Mj/ESSofzDM3+UlxiI5+A/Y6IHkByTfDEA==", + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/@ant-design/pro-utils/-/pro-utils-2.17.2.tgz", + "integrity": "sha512-DE7H14nfmdTyPwmJA1mgxHzcedOHSBYpTcqCvEAooK8fi8yXpcwpUs7XuUTeFHPj1gHYl/17X8Mzc3ngB8s63Q==", "license": "MIT", "dependencies": { "@ant-design/icons": "^5.0.0", - "@ant-design/pro-provider": "2.15.4", + "@ant-design/pro-provider": "2.16.1", "@babel/runtime": "^7.18.0", "classnames": "^2.3.2", "dayjs": "^1.11.10", @@ -343,9 +343,9 @@ } }, "node_modules/@ant-design/pro-utils/node_modules/@ant-design/colors": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.2.0.tgz", - "integrity": "sha512-bjTObSnZ9C/O8MB/B4OUtd/q9COomuJAR2SYfhxLyHvCKn4EKwCN3e+fWGMo7H5InAyV0wL17jdE9ALrdOW/6A==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.2.1.tgz", + "integrity": "sha512-lCHDcEzieu4GA3n8ELeZ5VQ8pKQAWcGGLRTQ50aQM2iqPpq2evTxER84jfdPvsPAtEcZ7m44NI45edFMo8oOYQ==", "license": "MIT", "dependencies": { "@ant-design/fast-color": "^2.0.6" @@ -495,30 +495,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz", + "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", - "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "version": "7.27.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz", + "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.10", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.10", - "@babel/parser": "^7.26.10", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.10", - "@babel/types": "^7.26.10", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.27.3", + "@babel/helpers": "^7.27.4", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.27.4", + "@babel/types": "^7.27.3", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -569,13 +569,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz", - "integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==", + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", + "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.27.1", - "@babel/types": "^7.27.1", + "@babel/parser": "^7.27.5", + "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -598,13 +598,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", - "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.8", - "@babel/helper-validator-option": "^7.25.9", + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -698,14 +698,14 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" }, "engines": { "node": ">=6.9.0" @@ -830,25 +830,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", - "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", "license": "MIT", "dependencies": { - "@babel/template": "^7.27.0", - "@babel/types": "^7.27.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.1.tgz", - "integrity": "sha512-I0dZ3ZpCrJ1c04OqlNsQcKiZlsrXf/kkE4FXzID9rIOYICsAbA8mMDzhW/luRNAHdCNt7os/u8wenklZDlUVUQ==", + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", + "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.27.1" + "@babel/types": "^7.27.3" }, "bin": { "parser": "bin/babel-parser.js" @@ -1957,13 +1957,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", - "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1973,13 +1973,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", - "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -2410,13 +2410,13 @@ } }, "node_modules/@babel/template": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.1.tgz", - "integrity": "sha512-Fyo3ghWMqkHHpHQCoBs2VnYjR4iWFFjguTDEqA5WgZDOrFesVjMhMM2FSqTKSoUSDO1VQtavj8NFpdRBEvJTtg==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.1", + "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" }, "engines": { @@ -2424,16 +2424,16 @@ } }, "node_modules/@babel/traverse": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz", - "integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==", + "version": "7.27.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", + "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.1", - "@babel/parser": "^7.27.1", - "@babel/template": "^7.27.1", - "@babel/types": "^7.27.1", + "@babel/generator": "^7.27.3", + "@babel/parser": "^7.27.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2451,9 +2451,9 @@ } }, "node_modules/@babel/types": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", - "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", + "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -2588,9 +2588,9 @@ } }, "node_modules/@dotenvx/dotenvx": { - "version": "1.44.1", - "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.44.1.tgz", - "integrity": "sha512-j1QImCqf/XJmhIjC1OPpgiZV9g370HG9MNT9s/CDwCKsoYzNCPEKK+GfsidahJx7yIlBbm+4dPLlGec+bKn7oA==", + "version": "1.44.2", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.44.2.tgz", + "integrity": "sha512-2C44+G2dch4cB6zw7+oGQ9VcFQuuVhc5xOzfVvY7iUEj2PRhiVMIB6SpNMK1V5TvpdqrAqCYFjclK18Mh9vwNQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2967,9 +2967,9 @@ } }, "node_modules/@firebase/auth": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.6.tgz", - "integrity": "sha512-cFbo2FymQltog4atI9cKTO6CxKxS0dOMXslTQrlNZRH7qhDG44/d7QeI6GXLweFZtrnlecf52ESnNz1DU6ek8w==", + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.7.tgz", + "integrity": "sha512-77o0aBKCfchdL1gkahARdawHyYefh+wRYn7o60tbwW6bfJNq2idbrRb3WSYCT4yBKWL0+9kKdwxBHPZ6DEiB+g==", "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.17", @@ -3519,13 +3519,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz", - "integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==", + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.0.tgz", + "integrity": "sha512-15hjKreZDcp7t6TL/7jkAo6Df5STZN09jGiv5dbP9A6vMVncXRqE7/B2SncsyOwrkZRBH2i6/TPOL8BVmm3c7w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.52.0" + "playwright": "1.53.0" }, "bin": { "playwright": "cli.js" @@ -3887,9 +3887,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.9", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz", - "integrity": "sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==", + "version": "1.0.0-beta.11", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz", + "integrity": "sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==", "dev": true, "license": "MIT" }, @@ -4469,50 +4469,50 @@ "license": "MIT" }, "node_modules/@sentry-internal/browser-utils": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.27.0.tgz", - "integrity": "sha512-SJa7f6Ct1BzP8rWEomnshSGN1CmT+axNKvT+StrbFPD6AyHnYfFLJpKgc2iToIJHB/pmeuOI9dUwqtzVx+5nSw==", + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.28.1.tgz", + "integrity": "sha512-P/FEZkT7UqTw9P/2n/Y4Aa1OtGP6dnCvyqzPPkjiRdVa7Ep7S5ElBJloGv7077TLLBtAfCsEUVRlM1F6/jQoaA==", "license": "MIT", "dependencies": { - "@sentry/core": "9.27.0" + "@sentry/core": "9.28.1" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/feedback": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.27.0.tgz", - "integrity": "sha512-e7L8eG0y63RulN352lmafoCCfQGg4jLVT8YLx6096eWu/YKLkgmVpgi8livsT5WREnH+HB+iFSrejOwK7cRkhw==", + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.28.1.tgz", + "integrity": "sha512-HOk/c26D3nlClO/xEefev8fIJzRA621PFQvNFPu/y0Z5HujEqSmIsrff0cXszPPYD95h4Mwk63E0ZYdspdeXcw==", "license": "MIT", "dependencies": { - "@sentry/core": "9.27.0" + "@sentry/core": "9.28.1" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.27.0.tgz", - "integrity": "sha512-n2kO1wOfCG7GxkMAqbYYkpgTqJM5tuVLdp0JuNCqTOLTXWvw6svWGaYKlYpKUgsK9X/GDzJYSXZmfe+Dbg+FJQ==", + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.28.1.tgz", + "integrity": "sha512-Tv9pkfAX+1bmhxF42TL0c4uTiK2+rp5LMYEPdz6JBfpfvG/Z1unPGsuB7fQmHYKyfHBQJmi92DZV+smljm7w/g==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.27.0", - "@sentry/core": "9.27.0" + "@sentry-internal/browser-utils": "9.28.1", + "@sentry/core": "9.28.1" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.27.0.tgz", - "integrity": "sha512-44rVSt3LCH6qePYRQrl4WUBwnkOk9dzinmnKmuwRksEdDOkVq5KBRhi/IDr7omwSpX8C+KrX5alfKhOx1cP0gQ==", + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.28.1.tgz", + "integrity": "sha512-RtkogfcIpXLFCyV8CTnXmVTH2QauT/KwmUAXBbeOz3rRWsM19yjN1moHrsjxn7OdjTv+D4qWSCA8Ka1aKSpr7g==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "9.27.0", - "@sentry/core": "9.27.0" + "@sentry-internal/replay": "9.28.1", + "@sentry/core": "9.28.1" }, "engines": { "node": ">=18" @@ -4528,16 +4528,16 @@ } }, "node_modules/@sentry/browser": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.27.0.tgz", - "integrity": "sha512-geR3lhRJOmUQqi1WgovLSYcD/f66zYnctdnDEa7j1BW2XIB1nlTJn0mpYyAHghXKkUN/pBpp1Z+Jk0XlVwFYVg==", + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.28.1.tgz", + "integrity": "sha512-XAS46iQSq8lXTnv9udQP025JTf3PwSVRE9ePJVQhx25QBWxedqGhEOv5qqX9b1Ijf8KiZYXXhBWMQxBBXVzUaw==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.27.0", - "@sentry-internal/feedback": "9.27.0", - "@sentry-internal/replay": "9.27.0", - "@sentry-internal/replay-canvas": "9.27.0", - "@sentry/core": "9.27.0" + "@sentry-internal/browser-utils": "9.28.1", + "@sentry-internal/feedback": "9.28.1", + "@sentry-internal/replay": "9.28.1", + "@sentry-internal/replay-canvas": "9.28.1", + "@sentry/core": "9.28.1" }, "engines": { "node": ">=18" @@ -4914,22 +4914,22 @@ } }, "node_modules/@sentry/core": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.27.0.tgz", - "integrity": "sha512-Zb2SSAdWXQjTem+sVWrrAq9L6YYfxyoTwtapaE6C6qZBR5C8Uak0wcYww8StaCFH7dDA/PSW+VxOwjNXocrQHQ==", + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.28.1.tgz", + "integrity": "sha512-6q59r/71MeE+4StkvwdKAAyhBBNpWcii0HeiWBZ3l1gaFYQlb6bChjZJRZmxSzF5dnvkdF4duQbAC3JmjeIbPA==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@sentry/react": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.27.0.tgz", - "integrity": "sha512-UT7iaGEwTqe06O4mgHfKGTRBHg+U0JSI/id+QxrOji6ksosOsSnSC3Vdq+gPs9pzCCFE+6+DkH6foYNNLIN0lw==", + "version": "9.28.1", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.28.1.tgz", + "integrity": "sha512-XnEURhb2wG7FFCGMuW/IJc8YeDMb9LM7cZSBwBDcplR11mCRsLpf4AGm6K1nWmAn5ZvWrXRO/TBAf9DNRAfnfg==", "license": "MIT", "dependencies": { - "@sentry/browser": "9.27.0", - "@sentry/core": "9.27.0", + "@sentry/browser": "9.28.1", + "@sentry/core": "9.28.1", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -5822,16 +5822,16 @@ "license": "ISC" }, "node_modules/@vitejs/plugin-react": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.1.tgz", - "integrity": "sha512-uPZBqSI0YD4lpkIru6M35sIfylLGTyhGHvDZbNLuMA73lMlwJKz5xweH7FajfcCAc2HnINciejA9qTz0dr0M7A==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.2.tgz", + "integrity": "sha512-QNVT3/Lxx99nMQWJWF7K4N6apUEuT0KlZA3mx/mVaoGj3smm/8rc8ezz15J1pcbcjDK0V15rpHetVfya08r76Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.26.10", - "@babel/plugin-transform-react-jsx-self": "^7.25.9", - "@babel/plugin-transform-react-jsx-source": "^7.25.9", - "@rolldown/pluginutils": "1.0.0-beta.9", + "@babel/core": "^7.27.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.11", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, @@ -5839,7 +5839,7 @@ "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" } }, "node_modules/@vitest/expect": { @@ -6123,9 +6123,9 @@ } }, "node_modules/antd": { - "version": "5.25.4", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.25.4.tgz", - "integrity": "sha512-yXdWqq1NJSZnD1HoPZWnWuQJGVYYnB3h0Ufsz4sbt3T0N9SdJ4G9GPpLMk8Gn9zWtwBekfR4THPVZ9uzAyhBHQ==", + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.0.tgz", + "integrity": "sha512-iMPYKFTo2HvIRGutUOuN5AG+Uf+B2QaqcGQbdPp/100fqV3FAil6vFZLVuV3C4XEUOlDNkkUlJKhLR9V5rzIEg==", "license": "MIT", "dependencies": { "@ant-design/colors": "^7.2.1", @@ -6167,7 +6167,7 @@ "rc-slider": "~11.1.8", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", - "rc-table": "~7.50.5", + "rc-table": "~7.51.0", "rc-tabs": "~15.6.1", "rc-textarea": "~1.10.0", "rc-tooltip": "~6.4.0", @@ -10342,9 +10342,9 @@ } }, "node_modules/i18next-browser-languagedetector": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.1.0.tgz", - "integrity": "sha512-mHZxNx1Lq09xt5kCauZ/4bsXOEA2pfpwSoU11/QTJB+pD94iONFwp+ohqi///PwiFvjFOxe1akYCdHyFo1ng5Q==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.0.tgz", + "integrity": "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.2" @@ -13340,13 +13340,13 @@ } }, "node_modules/playwright": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz", - "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==", + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.0.tgz", + "integrity": "sha512-ghGNnIEYZC4E+YtclRn4/p6oYbdPiASELBIYkBXfaTVKreQUYbMUYQDwS12a8F0/HtIjr/CkGjtwABeFPGcS4Q==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.52.0" + "playwright-core": "1.53.0" }, "bin": { "playwright": "cli.js" @@ -13359,9 +13359,9 @@ } }, "node_modules/playwright-core": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz", - "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==", + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.0.tgz", + "integrity": "sha512-mGLg8m0pm4+mmtB7M89Xw/GSqoNC+twivl8ITteqvAndachozYe2ZA7srU6uleV1vEdAHYqjq+SV8SNxRRFYBw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -14141,9 +14141,9 @@ } }, "node_modules/rc-table": { - "version": "7.50.5", - "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.50.5.tgz", - "integrity": "sha512-FDZu8aolhSYd3v9KOc3lZOVAU77wmRRu44R0Wfb8Oj1dXRUsloFaXMSl6f7yuWZUxArJTli7k8TEOX2mvhDl4A==", + "version": "7.51.0", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.51.0.tgz", + "integrity": "sha512-7ZlvW6lB0IDKaSFInD6OfJsCepSJJtfsQv2PZLtzEeZd/PLzQnKliXPaoZqkqDdLdJ3jxE2x4sane4DjxcAg+g==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.1", @@ -14314,9 +14314,9 @@ } }, "node_modules/react-big-calendar": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.19.2.tgz", - "integrity": "sha512-2orH+TOXPJBlQGwSl9ZnTK2WZR9OfVf0r1s8mnbpjvtENZfmWHP6nXqxmten1vkvzOMqefVGjh5GurM27HHOZw==", + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.19.3.tgz", + "integrity": "sha512-+P/9X54QxvBcbJhtyxSBoXEj3enSXSxJw76RWlP8IUhHUQQREpwdzld0dcJpfDTvp8c/aFzzKx7KZjZtiOusdA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.7", @@ -15419,9 +15419,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.89.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.1.tgz", - "integrity": "sha512-eMLLkl+qz7tx/0cJ9wI+w09GQ2zodTkcE/aVfywwdlRcI3EO19xGnbmJwg/JMIm+5MxVJ6outddLZ4Von4E++Q==", + "version": "1.89.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", + "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", "license": "MIT", "dependencies": { "chokidar": "^4.0.0", diff --git a/client/package.json b/client/package.json index b8de01625..39205af35 100644 --- a/client/package.json +++ b/client/package.json @@ -8,23 +8,23 @@ "private": true, "proxy": "http://localhost:4000", "dependencies": { - "@ant-design/pro-layout": "^7.22.4", + "@ant-design/pro-layout": "^7.22.6", "@apollo/client": "^3.13.6", "@emotion/is-prop-valid": "^1.3.1", "@fingerprintjs/fingerprintjs": "^4.6.1", "@firebase/analytics": "^0.10.16", "@firebase/app": "^0.13.1", - "@firebase/auth": "^1.10.6", + "@firebase/auth": "^1.10.7", "@firebase/firestore": "^4.7.17", "@firebase/messaging": "^0.12.21", "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.27.0", + "@sentry/react": "^9.28.1", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.25.4", + "antd": "^5.26.0", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -39,7 +39,7 @@ "exifr": "^7.1.3", "graphql": "^16.11.0", "i18next": "^24.2.3", - "i18next-browser-languagedetector": "^8.1.0", + "i18next-browser-languagedetector": "^8.2.0", "immutability-helper": "^3.1.1", "libphonenumber-js": "^1.12.9", "logrocket": "^9.0.2", @@ -52,7 +52,7 @@ "query-string": "^9.2.0", "raf-schd": "^4.0.3", "react": "^18.3.1", - "react-big-calendar": "^1.19.2", + "react-big-calendar": "^1.19.3", "react-color": "^2.19.3", "react-cookie": "^8.0.1", "react-dom": "^18.3.1", @@ -78,7 +78,7 @@ "redux-saga": "^1.3.0", "redux-state-sync": "^3.1.4", "reselect": "^5.1.1", - "sass": "^1.89.1", + "sass": "^1.89.2", "socket.io-client": "^4.8.1", "styled-components": "^6.1.18", "subscriptions-transport-ws": "^0.11.0", @@ -131,16 +131,16 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.44.1", + "@dotenvx/dotenvx": "^1.44.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", "@eslint/js": "^9.28.0", - "@playwright/test": "^1.51.1", + "@playwright/test": "^1.53.0", "@sentry/webpack-plugin": "^3.5.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", - "@vitejs/plugin-react": "^4.5.1", + "@vitejs/plugin-react": "^4.5.2", "browserslist": "^4.25.0", "browserslist-to-esbuild": "^2.1.1", "chalk": "^5.4.1", @@ -151,7 +151,7 @@ "jsdom": "^26.0.0", "memfs": "^4.17.2", "os-browserify": "^0.3.0", - "playwright": "^1.51.1", + "playwright": "^1.53.0", "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", diff --git a/package-lock.json b/package-lock.json index 82ec89bb2..184fcfe4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,14 @@ "version": "0.2.0", "license": "UNLICENSED", "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.826.0", - "@aws-sdk/client-elasticache": "^3.826.0", - "@aws-sdk/client-s3": "^3.826.0", - "@aws-sdk/client-secrets-manager": "^3.826.0", - "@aws-sdk/client-ses": "^3.826.0", - "@aws-sdk/credential-provider-node": "^3.826.0", - "@aws-sdk/lib-storage": "^3.826.0", - "@aws-sdk/s3-request-presigner": "^3.826.0", + "@aws-sdk/client-cloudwatch-logs": "^3.828.0", + "@aws-sdk/client-elasticache": "^3.828.0", + "@aws-sdk/client-s3": "^3.828.0", + "@aws-sdk/client-secrets-manager": "^3.828.0", + "@aws-sdk/client-ses": "^3.828.0", + "@aws-sdk/credential-provider-node": "^3.828.0", + "@aws-sdk/lib-storage": "^3.828.0", + "@aws-sdk/s3-request-presigner": "^3.828.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -31,7 +31,7 @@ "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.55.0", + "dd-trace": "^5.56.0", "dinero.js": "^1.9.1", "dotenv": "^16.4.5", "express": "^4.21.1", @@ -58,7 +58,7 @@ "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "ssh2-sftp-client": "^11.0.0", - "twilio": "^5.7.0", + "twilio": "^5.7.1", "uuid": "^11.1.0", "winston": "^3.17.0", "winston-cloudwatch": "^6.3.0", @@ -284,24 +284,24 @@ } }, "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.826.0.tgz", - "integrity": "sha512-eldrBVavaXqSGIMbhje0oKQntGNAdAXGqKeuWPa1Igl10KVGvQke/MA1Qqh7Tp+JL/FSfr2BhCjATdooPDb0hA==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.828.0.tgz", + "integrity": "sha512-EeDYXwwWv+1Xk5lVehpf+9SH0N2xMU1ypJ9o7ifYL/G4dXI0us7k23Ds0UHescziQMFJKGJ9yAmCTY791QAsyw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.826.0", + "@aws-sdk/credential-provider-node": "3.828.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.826.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.826.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/eventstream-serde-browser": "^4.0.4", @@ -352,24 +352,24 @@ } }, "node_modules/@aws-sdk/client-elasticache": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.826.0.tgz", - "integrity": "sha512-NUaHi6Yl7HC3COYO09D4Gudy3a5N/OKk0OGF0Er4qcSv+1V+hjIffmjWTgDODreBgRdsCXjCfiPfY6T/FFLb1g==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.828.0.tgz", + "integrity": "sha512-N9mJwke+ax96Oc50fnrH2jiQrqMAJkTi7iK+eJiiN3Pu1eXvCYAvtz2Vf66/55Me7lfjV0xyrXSIhF9YgcI0uw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.826.0", + "@aws-sdk/credential-provider-node": "3.828.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.826.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.826.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", @@ -403,16 +403,16 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.826.0.tgz", - "integrity": "sha512-odX3C3CEbcBoxB06vgBjJ9jQheFsIFwHmvCIMXn8duuVyIL/klgp14+ICzbEwIgPv7xVjSlycaiURcKS876QHA==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.828.0.tgz", + "integrity": "sha512-TvFyrEfJkf9NN3cq5mXCgFv/sPaA8Rm5tEPgV5emuLedeGsORlWmVpdSKqfZ4lSoED1tMfNM6LY4uA9D8/RS5g==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.826.0", + "@aws-sdk/credential-provider-node": "3.828.0", "@aws-sdk/middleware-bucket-endpoint": "3.821.0", "@aws-sdk/middleware-expect-continue": "3.821.0", "@aws-sdk/middleware-flexible-checksums": "3.826.0", @@ -422,13 +422,13 @@ "@aws-sdk/middleware-recursion-detection": "3.821.0", "@aws-sdk/middleware-sdk-s3": "3.826.0", "@aws-sdk/middleware-ssec": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.826.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/signature-v4-multi-region": "3.826.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.826.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@aws-sdk/xml-builder": "3.821.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", @@ -470,24 +470,24 @@ } }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.826.0.tgz", - "integrity": "sha512-Uqy9UyQqhsMoxOk0HLv0c7RMwMu2tRnjHKL6be0Spsy41Q+cZuJRjPvq1AmHUblvam8olbQwud99A6cFO/8Efw==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.828.0.tgz", + "integrity": "sha512-q6PO03nzWn4DCaZjwobB9GPjhaF2C0PUeCsmqymNbSjMPn1rVgpi1fbeCE6ZnS2jmv1lOF6FTAXfG0cGF+iT4Q==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.826.0", + "@aws-sdk/credential-provider-node": "3.828.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.826.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.826.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", @@ -535,24 +535,24 @@ } }, "node_modules/@aws-sdk/client-ses": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.826.0.tgz", - "integrity": "sha512-rCuj6Fd8pyDA/gZKyI/C4nAHTRT2w1L+DpEecxfQikFJLwUGZ8Nvk3JxRt0XADqDbdOmrgH/cc11kpEjO7sjEw==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.828.0.tgz", + "integrity": "sha512-j2w9HugNIJUA202o9YKGuN84GY+swNIjHch6vSrpARYISkzUr+zIYp7u/ygmUjeBtsnjM6RsmGU7miGs9Xt7bA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.826.0", + "@aws-sdk/credential-provider-node": "3.828.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.826.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.826.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", @@ -586,9 +586,9 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.826.0.tgz", - "integrity": "sha512-/FEKnUC3xPkLL4RuRydwzx+y4b55HIX6qLPbGnyIs+sNmCUyc/62ijtV1Ml+b++YzEF6jWNBsJOxeyZdgrJ3Ig==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.828.0.tgz", + "integrity": "sha512-qxw8JcPTaFaBwTBUr4YmLajaMh3En65SuBWAKEtjctbITRRekzR7tvr/TkwoyVOh+XoAtkwOn+BQeQbX+/wgHw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -597,12 +597,12 @@ "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.826.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.826.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", @@ -698,18 +698,18 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.826.0.tgz", - "integrity": "sha512-g7n+qSklq/Lzjxe2Ke5QFNCgYn26a3ydZnbFIk8QqYin4pzG+qiunaqJjpV3c/EeHMlfK8bBc7MXAylKzGRccQ==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.828.0.tgz", + "integrity": "sha512-T3DJMo2/j7gCPpFg2+xEHWgua05t8WP89ye7PaZxA2Fc6CgScHkZsJZTri1QQIU2h+eOZ75EZWkeFLIPgN0kRQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.826.0", "@aws-sdk/credential-provider-env": "3.826.0", "@aws-sdk/credential-provider-http": "3.826.0", "@aws-sdk/credential-provider-process": "3.826.0", - "@aws-sdk/credential-provider-sso": "3.826.0", - "@aws-sdk/credential-provider-web-identity": "3.826.0", - "@aws-sdk/nested-clients": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.828.0", + "@aws-sdk/credential-provider-web-identity": "3.828.0", + "@aws-sdk/nested-clients": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -722,17 +722,17 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.826.0.tgz", - "integrity": "sha512-UfIJXxHjmSxH6bea00HBPLkjNI2D04enQA/xNLZvB+4xtzt1/gYdCis1P4/73f5aGVVVB4/zQMobBbnjkrmbQw==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.828.0.tgz", + "integrity": "sha512-9z3iPwVYOQYNzVZj8qycZaS/BOSKRXWA+QVNQlfEnQ4sA4sOcKR4kmV2h+rJcuBsSFfmOF62ZDxyIBGvvM4t/w==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/credential-provider-env": "3.826.0", "@aws-sdk/credential-provider-http": "3.826.0", - "@aws-sdk/credential-provider-ini": "3.826.0", + "@aws-sdk/credential-provider-ini": "3.828.0", "@aws-sdk/credential-provider-process": "3.826.0", - "@aws-sdk/credential-provider-sso": "3.826.0", - "@aws-sdk/credential-provider-web-identity": "3.826.0", + "@aws-sdk/credential-provider-sso": "3.828.0", + "@aws-sdk/credential-provider-web-identity": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -762,14 +762,14 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.826.0.tgz", - "integrity": "sha512-F19J3zcfoom6OnQ0MyAtvduVKQXPgkz9i5ExSO01J2CzjbyMhCDA99qAjHYe+LwhW+W7P/jzBPd0+uOQ2Nhh9Q==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.828.0.tgz", + "integrity": "sha512-9CEAXzUDSzOjOCb3XfM15TZhTaM+l07kumZyx2z8NC6T2U4qbCJqn4h8mFlRvYrs6cBj2SN40sD3r5Wp0Cq2Kw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.826.0", + "@aws-sdk/client-sso": "3.828.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/token-providers": "3.826.0", + "@aws-sdk/token-providers": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -781,13 +781,13 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.826.0.tgz", - "integrity": "sha512-o27GZ6Hy7qhuvMFVUL2eFEpBzf33Jaa/x3u3SHwU0nL7ko7jmbpeF0x4+wmagpI9X2IvVlUxIs0VaQ3YayPLEA==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.828.0.tgz", + "integrity": "sha512-MguDhGHlQBeK9CQ/P4NOY0whAJ4HJU4x+f1dphg3I1sGlccFqfB8Moor2vXNKu0Th2kvAwkn9pr7gGb/+NGR9g==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.826.0", - "@aws-sdk/nested-clients": "3.826.0", + "@aws-sdk/nested-clients": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -798,9 +798,9 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.826.0.tgz", - "integrity": "sha512-NmZJVnP09ZGTVVz8ZCD8sQeVMfvyX5c2/NEJHSdavmWi2sJHuln09i/YQg90LFGL4eCFslzME/mP3pMtLQEeKQ==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.828.0.tgz", + "integrity": "sha512-nBJmRzveYtdqL0u76tv62JGtkUfvyyZhAKNHFlzO8lCO7lxa0muRTG/ptUSS0ruFHq1K2MXHnDtLX90xiErIsQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.0.4", @@ -815,7 +815,7 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.826.0" + "@aws-sdk/client-s3": "^3.828.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { @@ -973,14 +973,14 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.826.0.tgz", - "integrity": "sha512-j404+EcfBbtTlAhyObjXbdKwwDXO1pCxHvR5Fw8FXNvp/H330j6YnXgs3SJ6d3bZUwUJ/ztPx2S5AlBbLVLDFw==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", + "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.826.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@smithy/core": "^3.5.3", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", @@ -991,9 +991,9 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.826.0.tgz", - "integrity": "sha512-p7olPq0uTtHqGuXI1GSc/gzKDvV55PMbLtnmupEDfnY9SoRu+QatbWQ6da9sI1lhOcNmRMgiNQBXFzaUFrG+SQ==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.828.0.tgz", + "integrity": "sha512-xmeOILiR9LvfC8MctgeRXXN8nQTwbOvO4wHvgE8tDRsjnBpyyO0j50R4+viHXdMUGtgGkHEXRv8fFNBq54RgnA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -1002,12 +1002,12 @@ "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.826.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.821.0", + "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.826.0", + "@aws-sdk/util-user-agent-node": "3.828.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", @@ -1057,9 +1057,9 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.826.0.tgz", - "integrity": "sha512-47IcILH3CfVzUmGwJhwuZQyuZ5zXNsFyvtpQWR2s2dkoT7TJCMAKY0MtWE+y2T99b20OGbUhQHz/9qlx7dR3zw==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.828.0.tgz", + "integrity": "sha512-6817h11Xi6LqnmTnHIwZf4PQB0rIMaRFwkq8/mfR9oOn+hsahxBVDbpgu+q4xzP5q+W3m5Y/din0cJPVrnP6yQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/signature-v4-multi-region": "3.826.0", @@ -1093,13 +1093,13 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.826.0.tgz", - "integrity": "sha512-iCOcVAqGPSHtQL8ZBXifZMEcHyUl9wJ8HvLZ5l1ohA/3ZNP+dqEPGi7jfhR5jZKs+xyp2jxByFqfil9PjI9c5A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.828.0.tgz", + "integrity": "sha512-JdOjI/TxkfQpY/bWbdGMdCiePESXTbtl6MfnJxz35zZ3tfHvBnxAWCoYJirdmjzY/j/dFo5oEyS6mQuXAG9w2w==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.826.0", - "@aws-sdk/nested-clients": "3.826.0", + "@aws-sdk/nested-clients": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -1136,9 +1136,9 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.821.0.tgz", - "integrity": "sha512-Uknt/zUZnLE76zaAAPEayOeF5/4IZ2puTFXvcSCWHsi9m3tqbb9UozlnlVqvCZLCRWfQryZQoG2W4XSS3qgk5A==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", + "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", @@ -1190,12 +1190,12 @@ } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.826.0.tgz", - "integrity": "sha512-wHw6bZQWIMcFF/8r03aY9Itp6JLBYY4absGGhCDK1dc3tPEfi8NVSdb05a/Oz+g4TVaDdxLo0OQ/OKMS1DFRHQ==", + "version": "3.828.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", + "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.826.0", + "@aws-sdk/middleware-user-agent": "3.828.0", "@aws-sdk/types": "3.821.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -1290,9 +1290,9 @@ } }, "node_modules/@datadog/pprof": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.8.0.tgz", - "integrity": "sha512-3FL2qpkFWvIEptSk7x9RVs1PJeF+VCrGxQpKViloQkrnH5mjcwaIQiWyNZYyV1H1vhKJIS+ummSBcsOLkV49qA==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.8.2.tgz", + "integrity": "sha512-M+bO4v4TaxYK6k2qJBxnhf7Vh25Wode64y4LfxzGs5kLTFr8eFTp6HJai3/af7U5gjTHX/4s+CHv2bxja97pbw==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -5498,9 +5498,9 @@ } }, "node_modules/dd-trace": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.55.0.tgz", - "integrity": "sha512-nXg5W0s/8kl5Btj9hIG1YgzkARoezAEqT03/cJ/VF3G41fB8KfBWUTY1+aw795UZ6Cv2dXD3yPYdckJeuCwjVQ==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.56.0.tgz", + "integrity": "sha512-1GiAh1UATmn8uZxk+nqZAdfJppiOq4kxJKiozMNvupffbcbAuDj5qnfYF9Hz3oqsk+Jtt2oheQeR05c4JRshXw==", "hasInstallScript": true, "license": "(Apache-2.0 OR BSD-3-Clause)", "dependencies": { @@ -5508,7 +5508,7 @@ "@datadog/native-appsec": "8.5.2", "@datadog/native-iast-taint-tracking": "4.0.0", "@datadog/native-metrics": "^3.1.1", - "@datadog/pprof": "5.8.0", + "@datadog/pprof": "5.8.2", "@datadog/sketches-js": "^2.1.1", "@datadog/wasm-js-rewriter": "4.0.1", "@isaacs/ttlcache": "^1.4.1", @@ -11850,9 +11850,9 @@ "license": "Unlicense" }, "node_modules/twilio": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.7.0.tgz", - "integrity": "sha512-AcN9jo/C0sFitprIg2G6CJF+EACvff+8fiTMxf7Puz+6jtmc0NgJTwmyQbPiAnJcpXWOrPdI92Obr3PV4ZKXkw==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.7.1.tgz", + "integrity": "sha512-BcoVK6FR580HRX94z2u3b+foHkvFj39DDzLU4Xv+N/7ejDIGgQdrtg7CgRqIT04UNs98HJAvjuAOzkYetI6ExQ==", "license": "MIT", "dependencies": { "axios": "^1.8.3", diff --git a/package.json b/package.json index b57c9f6b2..6a905c90b 100644 --- a/package.json +++ b/package.json @@ -16,14 +16,14 @@ "job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js" }, "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.826.0", - "@aws-sdk/client-elasticache": "^3.826.0", - "@aws-sdk/client-s3": "^3.826.0", - "@aws-sdk/client-secrets-manager": "^3.826.0", - "@aws-sdk/client-ses": "^3.826.0", - "@aws-sdk/credential-provider-node": "^3.826.0", - "@aws-sdk/lib-storage": "^3.826.0", - "@aws-sdk/s3-request-presigner": "^3.826.0", + "@aws-sdk/client-cloudwatch-logs": "^3.828.0", + "@aws-sdk/client-elasticache": "^3.828.0", + "@aws-sdk/client-s3": "^3.828.0", + "@aws-sdk/client-secrets-manager": "^3.828.0", + "@aws-sdk/client-ses": "^3.828.0", + "@aws-sdk/credential-provider-node": "^3.828.0", + "@aws-sdk/lib-storage": "^3.828.0", + "@aws-sdk/s3-request-presigner": "^3.828.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -38,7 +38,7 @@ "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.55.0", + "dd-trace": "^5.56.0", "dinero.js": "^1.9.1", "dotenv": "^16.4.5", "express": "^4.21.1", @@ -65,7 +65,7 @@ "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "ssh2-sftp-client": "^11.0.0", - "twilio": "^5.7.0", + "twilio": "^5.7.1", "uuid": "^11.1.0", "winston": "^3.17.0", "winston-cloudwatch": "^6.3.0", From 4b75504d9ea1e13bf5d719a6bf7efeae80081e1b Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Wed, 18 Jun 2025 11:22:23 -0400 Subject: [PATCH 03/98] feature/IO-3255-simplified-parts-management - Checkpoint --- client/package-lock.json | 159 ++++---- client/package.json | 20 +- ...simplified-parts-jobs-detail.component.jsx | 7 - .../simplified-parts.page.component.jsx | 87 +++-- package-lock.json | 232 ++++++------ package.json | 28 +- .../partsManagementProvisioning.js | 13 +- ...rtsManagementVehicleDamageEstimateAddRq.js | 356 ++++++++++++++++++ server/routes/intergrationRoutes.js | 6 + static-analysis.datadog.yml | 10 + 10 files changed, 638 insertions(+), 280 deletions(-) create mode 100644 server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js create mode 100644 static-analysis.datadog.yml diff --git a/client/package-lock.json b/client/package-lock.json index 30de262cd..eb559a8f2 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -21,15 +21,15 @@ "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.28.1", + "@sentry/react": "^9.30.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.0", + "antd": "^5.26.1", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", - "axios": "^1.8.4", + "axios": "^1.10.0", "classnames": "^2.5.1", "css-box-model": "^1.2.1", "dayjs": "^1.11.13", @@ -48,19 +48,19 @@ "memoize-one": "^6.0.0", "normalize-url": "^8.0.2", "object-hash": "^3.0.0", - "phone": "^3.1.59", + "phone": "^3.1.62", "prop-types": "^15.8.1", - "query-string": "^9.2.0", + "query-string": "^9.2.1", "raf-schd": "^4.0.3", "react": "^18.3.1", - "react-big-calendar": "^1.19.3", + "react-big-calendar": "^1.19.4", "react-color": "^2.19.3", "react-cookie": "^8.0.1", "react-dom": "^18.3.1", "react-drag-listview": "^2.0.0", "react-grid-gallery": "^1.0.1", "react-grid-layout": "1.3.4", - "react-i18next": "^15.5.2", + "react-i18next": "^15.5.3", "react-icons": "^5.5.0", "react-image-lightbox": "^5.1.4", "react-markdown": "^10.1.0", @@ -71,7 +71,7 @@ "react-resizable": "^3.0.5", "react-router-dom": "^6.30.0", "react-sticky": "^6.0.3", - "react-virtuoso": "^4.12.8", + "react-virtuoso": "^4.13.0", "recharts": "^2.15.2", "redux": "^5.0.1", "redux-actions": "^3.0.3", @@ -81,7 +81,7 @@ "reselect": "^5.1.1", "sass": "^1.89.2", "socket.io-client": "^4.8.1", - "styled-components": "^6.1.18", + "styled-components": "^6.1.19", "subscriptions-transport-ws": "^0.11.0", "use-memo-one": "^1.1.3", "vite-plugin-ejs": "^1.7.0", @@ -94,7 +94,7 @@ "@dotenvx/dotenvx": "^1.44.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", - "@eslint/js": "^9.28.0", + "@eslint/js": "^9.29.0", "@playwright/test": "^1.53.0", "@sentry/webpack-plugin": "^3.5.0", "@testing-library/dom": "^10.4.0", @@ -2398,13 +2398,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", - "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, "engines": { "node": ">=6.9.0" } @@ -2913,9 +2910,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.28.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", - "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", + "version": "9.29.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", + "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", "dev": true, "license": "MIT", "engines": { @@ -4469,50 +4466,50 @@ "license": "MIT" }, "node_modules/@sentry-internal/browser-utils": { - "version": "9.28.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.28.1.tgz", - "integrity": "sha512-P/FEZkT7UqTw9P/2n/Y4Aa1OtGP6dnCvyqzPPkjiRdVa7Ep7S5ElBJloGv7077TLLBtAfCsEUVRlM1F6/jQoaA==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.30.0.tgz", + "integrity": "sha512-e6ZlN8oWheCB0YJSGlBNUlh6UPnY5Ecj1P+/cgeKBhNm7c3bIx4J50485hB8LQsu+b7Q11L2o/wucZ//Pb6FCg==", "license": "MIT", "dependencies": { - "@sentry/core": "9.28.1" + "@sentry/core": "9.30.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/feedback": { - "version": "9.28.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.28.1.tgz", - "integrity": "sha512-HOk/c26D3nlClO/xEefev8fIJzRA621PFQvNFPu/y0Z5HujEqSmIsrff0cXszPPYD95h4Mwk63E0ZYdspdeXcw==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.30.0.tgz", + "integrity": "sha512-qAZ7xxLqZM7GlEvmSUmTHnoueg+fc7esMQD4vH8pS7HI3n9C5MjGn3HHlndRpD8lL7iUUQ0TPZQgU6McbzMDyw==", "license": "MIT", "dependencies": { - "@sentry/core": "9.28.1" + "@sentry/core": "9.30.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay": { - "version": "9.28.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.28.1.tgz", - "integrity": "sha512-Tv9pkfAX+1bmhxF42TL0c4uTiK2+rp5LMYEPdz6JBfpfvG/Z1unPGsuB7fQmHYKyfHBQJmi92DZV+smljm7w/g==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.30.0.tgz", + "integrity": "sha512-+6wkqQGLJuFUzvGRzbh3iIhFGyxQx/Oxc0ODDKmz9ag2xYRjCYb3UUQXmQX9navAF0HXUsq8ajoJPm2L1ZyWVg==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.28.1", - "@sentry/core": "9.28.1" + "@sentry-internal/browser-utils": "9.30.0", + "@sentry/core": "9.30.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "9.28.1", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.28.1.tgz", - "integrity": "sha512-RtkogfcIpXLFCyV8CTnXmVTH2QauT/KwmUAXBbeOz3rRWsM19yjN1moHrsjxn7OdjTv+D4qWSCA8Ka1aKSpr7g==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.30.0.tgz", + "integrity": "sha512-I4MxS27rfV7vnOU29L80y4baZ4I1XqpnYvC/yLN7C17nA8eDCufQ8WVomli41y8JETnfcxlm68z7CS0sO4RCSA==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "9.28.1", - "@sentry/core": "9.28.1" + "@sentry-internal/replay": "9.30.0", + "@sentry/core": "9.30.0" }, "engines": { "node": ">=18" @@ -4528,16 +4525,16 @@ } }, "node_modules/@sentry/browser": { - "version": "9.28.1", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.28.1.tgz", - "integrity": "sha512-XAS46iQSq8lXTnv9udQP025JTf3PwSVRE9ePJVQhx25QBWxedqGhEOv5qqX9b1Ijf8KiZYXXhBWMQxBBXVzUaw==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.30.0.tgz", + "integrity": "sha512-sRyW6A9nIieTTI26MYXk1DmWEhmphTjZevusNWla+vvUigCmSjuH+xZw19w43OyvF3bu261Skypnm/mAalOTwg==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.28.1", - "@sentry-internal/feedback": "9.28.1", - "@sentry-internal/replay": "9.28.1", - "@sentry-internal/replay-canvas": "9.28.1", - "@sentry/core": "9.28.1" + "@sentry-internal/browser-utils": "9.30.0", + "@sentry-internal/feedback": "9.30.0", + "@sentry-internal/replay": "9.30.0", + "@sentry-internal/replay-canvas": "9.30.0", + "@sentry/core": "9.30.0" }, "engines": { "node": ">=18" @@ -4914,22 +4911,22 @@ } }, "node_modules/@sentry/core": { - "version": "9.28.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.28.1.tgz", - "integrity": "sha512-6q59r/71MeE+4StkvwdKAAyhBBNpWcii0HeiWBZ3l1gaFYQlb6bChjZJRZmxSzF5dnvkdF4duQbAC3JmjeIbPA==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.30.0.tgz", + "integrity": "sha512-JfEpeQ8a1qVJEb9DxpFTFy1J1gkNdlgKAPiqYGNnm4yQbnfl2Kb/iEo1if70FkiHc52H8fJwISEF90pzMm6lPg==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@sentry/react": { - "version": "9.28.1", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.28.1.tgz", - "integrity": "sha512-XnEURhb2wG7FFCGMuW/IJc8YeDMb9LM7cZSBwBDcplR11mCRsLpf4AGm6K1nWmAn5ZvWrXRO/TBAf9DNRAfnfg==", + "version": "9.30.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.30.0.tgz", + "integrity": "sha512-asA49AkZ/g9CCeW0eA0Ent0DF60S4k2IHxbu+Q1mqgbRRmbn859oL2Bgsu/EvzWf5edeQtuUml8LIo4YoFwfMA==", "license": "MIT", "dependencies": { - "@sentry/browser": "9.28.1", - "@sentry/core": "9.28.1", + "@sentry/browser": "9.30.0", + "@sentry/core": "9.30.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -6123,9 +6120,9 @@ } }, "node_modules/antd": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.0.tgz", - "integrity": "sha512-iMPYKFTo2HvIRGutUOuN5AG+Uf+B2QaqcGQbdPp/100fqV3FAil6vFZLVuV3C4XEUOlDNkkUlJKhLR9V5rzIEg==", + "version": "5.26.1", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.1.tgz", + "integrity": "sha512-CiLGZ2Ftld+fuoj+U3OL8uouuqUppqFJnW4O/4bOgSWzM9XsJGibpNtUa9QArhrZ5ndfnzlPP/4RVXUK/xfSvQ==", "license": "MIT", "dependencies": { "@ant-design/colors": "^7.2.1", @@ -6585,9 +6582,9 @@ } }, "node_modules/axios": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -13299,9 +13296,9 @@ "license": "MIT" }, "node_modules/phone": { - "version": "3.1.59", - "resolved": "https://registry.npmjs.org/phone/-/phone-3.1.59.tgz", - "integrity": "sha512-CUv22jw0Zgrb/h7v3sEd262zJXS/66h7zyCCRIynx+2FswAJuuFsXsJkIxMUT4UcosKxDx1bJwdZeGnDELLsCw==", + "version": "3.1.62", + "resolved": "https://registry.npmjs.org/phone/-/phone-3.1.62.tgz", + "integrity": "sha512-mxUdq2nULKg6ukgVr4GSF9/sQiAa6e3AJy2HNE3UJA+lqdEF+Cko2RhKHhZRHtFaLKuBLPptitIwjv0uHG+vhw==", "license": "MIT", "engines": { "node": ">=12" @@ -13613,9 +13610,9 @@ } }, "node_modules/query-string": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-9.2.0.tgz", - "integrity": "sha512-YIRhrHujoQxhexwRLxfy3VSjOXmvZRd2nyw1PwL1UUqZ/ys1dEZd1+NSgXkne2l/4X/7OXkigEAuhTX0g/ivJQ==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-9.2.1.tgz", + "integrity": "sha512-3jTGGLRzlhu/1ws2zlr4Q+GVMLCQTLFOj8CMX5x44cdZG9FQE07x2mQhaNxaKVPNmIDu0mvJ/cEwtY7Pim7hqA==", "license": "MIT", "dependencies": { "decode-uri-component": "^0.4.1", @@ -14314,9 +14311,9 @@ } }, "node_modules/react-big-calendar": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.19.3.tgz", - "integrity": "sha512-+P/9X54QxvBcbJhtyxSBoXEj3enSXSxJw76RWlP8IUhHUQQREpwdzld0dcJpfDTvp8c/aFzzKx7KZjZtiOusdA==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.19.4.tgz", + "integrity": "sha512-FrvbDx2LF6JAWFD96LU1jjloppC5OgIvMYUYIPzAw5Aq+ArYFPxAjLqXc4DyxfsQDN0TJTMuS/BIbcSB7Pg0YA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.7", @@ -14444,12 +14441,12 @@ } }, "node_modules/react-i18next": { - "version": "15.5.2", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.5.2.tgz", - "integrity": "sha512-ePODyXgmZQAOYTbZXQn5rRsSBu3Gszo69jxW6aKmlSgxKAI1fOhDwSu6bT4EKHciWPKQ7v7lPrjeiadR6Gi+1A==", + "version": "15.5.3", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.5.3.tgz", + "integrity": "sha512-ypYmOKOnjqPEJZO4m1BI0kS8kWqkBNsKYyhVUfij0gvjy9xJNoG/VcGkxq5dRlVwzmrmY1BQMAmpbbUBLwC4Kw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.25.0", + "@babel/runtime": "^7.27.6", "html-parse-stringify": "^3.0.1" }, "peerDependencies": { @@ -14742,9 +14739,9 @@ } }, "node_modules/react-virtuoso": { - "version": "4.12.8", - "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.12.8.tgz", - "integrity": "sha512-NMMKfDBr/+xZZqCQF3tN1SZsh6FwOJkYgThlfnsPLkaEhdyQo0EuWUzu3ix6qjnI7rYwJhMwRGoJBi+aiDfGsA==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.13.0.tgz", + "integrity": "sha512-XHv2Fglpx80yFPdjZkV9d1baACKghg/ucpDFEXwaix7z0AfVQj+mF6lM+YQR6UC/TwzXG2rJKydRMb3+7iV3PA==", "license": "MIT", "peerDependencies": { "react": ">=16 || >=17 || >= 18 || >= 19", @@ -14981,12 +14978,6 @@ "node": ">=4" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "license": "MIT" - }, "node_modules/regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", @@ -16339,9 +16330,9 @@ } }, "node_modules/styled-components": { - "version": "6.1.18", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.18.tgz", - "integrity": "sha512-Mvf3gJFzZCkhjY2Y/Fx9z1m3dxbza0uI9H1CbNZm/jSHCojzJhQ0R7bByrlFJINnMzz/gPulpoFFGymNwrsMcw==", + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.19.tgz", + "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==", "license": "MIT", "dependencies": { "@emotion/is-prop-valid": "1.2.2", diff --git a/client/package.json b/client/package.json index 39205af35..c85b2eb5f 100644 --- a/client/package.json +++ b/client/package.json @@ -20,15 +20,15 @@ "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.28.1", + "@sentry/react": "^9.30.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.0", + "antd": "^5.26.1", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", - "axios": "^1.8.4", + "axios": "^1.10.0", "classnames": "^2.5.1", "css-box-model": "^1.2.1", "dayjs": "^1.11.13", @@ -47,19 +47,19 @@ "memoize-one": "^6.0.0", "normalize-url": "^8.0.2", "object-hash": "^3.0.0", - "phone": "^3.1.59", + "phone": "^3.1.62", "prop-types": "^15.8.1", - "query-string": "^9.2.0", + "query-string": "^9.2.1", "raf-schd": "^4.0.3", "react": "^18.3.1", - "react-big-calendar": "^1.19.3", + "react-big-calendar": "^1.19.4", "react-color": "^2.19.3", "react-cookie": "^8.0.1", "react-dom": "^18.3.1", "react-drag-listview": "^2.0.0", "react-grid-gallery": "^1.0.1", "react-grid-layout": "1.3.4", - "react-i18next": "^15.5.2", + "react-i18next": "^15.5.3", "react-icons": "^5.5.0", "react-image-lightbox": "^5.1.4", "react-markdown": "^10.1.0", @@ -70,7 +70,7 @@ "react-resizable": "^3.0.5", "react-router-dom": "^6.30.0", "react-sticky": "^6.0.3", - "react-virtuoso": "^4.12.8", + "react-virtuoso": "^4.13.0", "recharts": "^2.15.2", "redux": "^5.0.1", "redux-actions": "^3.0.3", @@ -80,7 +80,7 @@ "reselect": "^5.1.1", "sass": "^1.89.2", "socket.io-client": "^4.8.1", - "styled-components": "^6.1.18", + "styled-components": "^6.1.19", "subscriptions-transport-ws": "^0.11.0", "use-memo-one": "^1.1.3", "vite-plugin-ejs": "^1.7.0", @@ -134,7 +134,7 @@ "@dotenvx/dotenvx": "^1.44.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", - "@eslint/js": "^9.28.0", + "@eslint/js": "^9.29.0", "@playwright/test": "^1.53.0", "@sentry/webpack-plugin": "^3.5.0", "@testing-library/dom": "^10.4.0", diff --git a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx index faff65ce0..195f1da18 100644 --- a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx +++ b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx @@ -2,8 +2,6 @@ import { BarsOutlined, PrinterFilled, SyncOutlined, ToolFilled } from "@ant-desi import { PageHeader } from "@ant-design/pro-layout"; import { useQuery } from "@apollo/client"; import { Button, Divider, Form, Space, Tabs } from "antd"; -import Axios from "axios"; -import _ from "lodash"; import queryString from "query-string"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -25,11 +23,6 @@ import { insertAuditTrail } from "../../redux/application/application.actions.js import { selectJobReadOnly } from "../../redux/application/application.selectors.js"; import { setModalContext } from "../../redux/modals/modals.actions.js"; import { selectBodyshop } from "../../redux/user/user.selectors.js"; -import AuditTrailMapping from "../../utils/AuditTrailMappings.js"; -import { DateTimeFormat } from "../../utils/DateFormatter.jsx"; -import dayjs from "../../utils/day.js"; -import UndefinedToNull from "../../utils/undefinedtonull.js"; -import { transformJobToForm } from "../jobs-detail/jobs-detail.page.component.jsx"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, diff --git a/client/src/pages/simplified-parts/simplified-parts.page.component.jsx b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx index a7a30c198..5180feaff 100644 --- a/client/src/pages/simplified-parts/simplified-parts.page.component.jsx +++ b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx @@ -9,7 +9,6 @@ import { createStructuredSelector } from "reselect"; import BreadCrumbs from "../../components/breadcrumbs/breadcrumbs.component.jsx"; import ConflictComponent from "../../components/conflict/conflict.component.jsx"; import ErrorBoundary from "../../components/error-boundary/error-boundary.component.jsx"; -import HeaderContainer from "../../components/header/header.container.jsx"; import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component.jsx"; import PrintCenterModalContainer from "../../components/print-center-modal/print-center-modal.container.jsx"; import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-status.component.jsx"; @@ -208,50 +207,48 @@ export function SimplifiedPartsPage({ conflict, bodyshop, alerts, setAlerts }) { }; return ( - <> - - - {/* */} - - } showDialog> - {PageContent} - - - -
-
- - - - - -
- {`${InstanceRenderManager({ - imex: t("titles.imexonline"), - rome: t("titles.romeonline") - })} - ${import.meta.env.VITE_APP_GIT_SHA_DATE}`} -
- -
- - Disclaimer & Notices - -
-
-
- + + + {/* */} + + } showDialog> + {PageContent} + + + +
+
+ + + + + +
+ {`${InstanceRenderManager({ + imex: t("titles.imexonline"), + rome: t("titles.romeonline") + })} - ${import.meta.env.VITE_APP_GIT_SHA_DATE}`} +
+ +
+ + Disclaimer & Notices + +
+
+
); } diff --git a/package-lock.json b/package-lock.json index 184fcfe4b..e99e38a05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,23 +9,23 @@ "version": "0.2.0", "license": "UNLICENSED", "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.828.0", - "@aws-sdk/client-elasticache": "^3.828.0", - "@aws-sdk/client-s3": "^3.828.0", - "@aws-sdk/client-secrets-manager": "^3.828.0", - "@aws-sdk/client-ses": "^3.828.0", - "@aws-sdk/credential-provider-node": "^3.828.0", - "@aws-sdk/lib-storage": "^3.828.0", - "@aws-sdk/s3-request-presigner": "^3.828.0", + "@aws-sdk/client-cloudwatch-logs": "^3.830.0", + "@aws-sdk/client-elasticache": "^3.830.0", + "@aws-sdk/client-s3": "^3.830.0", + "@aws-sdk/client-secrets-manager": "^3.830.0", + "@aws-sdk/client-ses": "^3.830.0", + "@aws-sdk/credential-provider-node": "^3.830.0", + "@aws-sdk/lib-storage": "^3.830.0", + "@aws-sdk/s3-request-presigner": "^3.830.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", "archiver": "^7.0.1", "aws4": "^1.13.2", - "axios": "^1.8.4", + "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.53.2", - "chart.js": "^4.4.8", + "bullmq": "^5.54.2", + "chart.js": "^4.5.0", "cloudinary": "^2.6.1", "compression": "^1.8.0", "cookie-parser": "^1.4.7", @@ -49,7 +49,7 @@ "multer": "^1.4.5-lts.1", "node-persist": "^4.0.4", "nodemailer": "^6.10.0", - "phone": "^3.1.58", + "phone": "^3.1.62", "query-string": "7.1.3", "recursive-diff": "^1.0.9", "rimraf": "^6.0.1", @@ -66,8 +66,8 @@ "xmlbuilder2": "^3.1.1" }, "devDependencies": { - "@eslint/js": "^9.28.0", - "eslint": "^9.28.0", + "@eslint/js": "^9.29.0", + "eslint": "^9.29.0", "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "mock-require": "^3.0.3", @@ -284,15 +284,15 @@ } }, "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.828.0.tgz", - "integrity": "sha512-EeDYXwwWv+1Xk5lVehpf+9SH0N2xMU1ypJ9o7ifYL/G4dXI0us7k23Ds0UHescziQMFJKGJ9yAmCTY791QAsyw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.830.0.tgz", + "integrity": "sha512-jg4kpECjBcNemGtVr5IK3ZMKRZzrmG4VbxhgECHgxqNPgb+HeAcSOMa3ZsgStRnpwDEazfgYTJyBktZIC/XuuA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.828.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", @@ -352,15 +352,15 @@ } }, "node_modules/@aws-sdk/client-elasticache": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.828.0.tgz", - "integrity": "sha512-N9mJwke+ax96Oc50fnrH2jiQrqMAJkTi7iK+eJiiN3Pu1eXvCYAvtz2Vf66/55Me7lfjV0xyrXSIhF9YgcI0uw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.830.0.tgz", + "integrity": "sha512-ln7OISYRUasEL54B0+UEeJLISd3vG2zkdRCCIEVUzh7SOGiHADgCaQAk6WFiGAy4F9uGUWiI5qDkvddTBZT3tw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.828.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", @@ -403,17 +403,17 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.828.0.tgz", - "integrity": "sha512-TvFyrEfJkf9NN3cq5mXCgFv/sPaA8Rm5tEPgV5emuLedeGsORlWmVpdSKqfZ4lSoED1tMfNM6LY4uA9D8/RS5g==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.830.0.tgz", + "integrity": "sha512-Cti+zj1lqvQIScXFQv8/t1xo3pvcvk/ObmGIbyLzfgcYpKMHaIWhzhi6aN+z4dYEv1EwrukC9tNoqScyShc5tw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.828.0", - "@aws-sdk/middleware-bucket-endpoint": "3.821.0", + "@aws-sdk/credential-provider-node": "3.830.0", + "@aws-sdk/middleware-bucket-endpoint": "3.830.0", "@aws-sdk/middleware-expect-continue": "3.821.0", "@aws-sdk/middleware-flexible-checksums": "3.826.0", "@aws-sdk/middleware-host-header": "3.821.0", @@ -470,15 +470,15 @@ } }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.828.0.tgz", - "integrity": "sha512-q6PO03nzWn4DCaZjwobB9GPjhaF2C0PUeCsmqymNbSjMPn1rVgpi1fbeCE6ZnS2jmv1lOF6FTAXfG0cGF+iT4Q==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.830.0.tgz", + "integrity": "sha512-St2EK5i91vwv9LmDUmWevZYl+Y/TYRP/AHm7gxZm1LkEf1VEjkSizUMm91JOnH6y+0Clok9mqe6jZ/XossMXlw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.828.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", @@ -535,15 +535,15 @@ } }, "node_modules/@aws-sdk/client-ses": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.828.0.tgz", - "integrity": "sha512-j2w9HugNIJUA202o9YKGuN84GY+swNIjHch6vSrpARYISkzUr+zIYp7u/ygmUjeBtsnjM6RsmGU7miGs9Xt7bA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.830.0.tgz", + "integrity": "sha512-Y2XaJkqHJ7qM4cpCw3YS96fMZgT44mP3HLP+9dU0ct29L+iwf3zhigJGQzakieMdJfuTFZe7Vi6s1RbcWv5v5w==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.828.0", + "@aws-sdk/credential-provider-node": "3.830.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", @@ -586,9 +586,9 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.828.0.tgz", - "integrity": "sha512-qxw8JcPTaFaBwTBUr4YmLajaMh3En65SuBWAKEtjctbITRRekzR7tvr/TkwoyVOh+XoAtkwOn+BQeQbX+/wgHw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", + "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -698,18 +698,18 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.828.0.tgz", - "integrity": "sha512-T3DJMo2/j7gCPpFg2+xEHWgua05t8WP89ye7PaZxA2Fc6CgScHkZsJZTri1QQIU2h+eOZ75EZWkeFLIPgN0kRQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", + "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.826.0", "@aws-sdk/credential-provider-env": "3.826.0", "@aws-sdk/credential-provider-http": "3.826.0", "@aws-sdk/credential-provider-process": "3.826.0", - "@aws-sdk/credential-provider-sso": "3.828.0", - "@aws-sdk/credential-provider-web-identity": "3.828.0", - "@aws-sdk/nested-clients": "3.828.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -722,17 +722,17 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.828.0.tgz", - "integrity": "sha512-9z3iPwVYOQYNzVZj8qycZaS/BOSKRXWA+QVNQlfEnQ4sA4sOcKR4kmV2h+rJcuBsSFfmOF62ZDxyIBGvvM4t/w==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", + "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/credential-provider-env": "3.826.0", "@aws-sdk/credential-provider-http": "3.826.0", - "@aws-sdk/credential-provider-ini": "3.828.0", + "@aws-sdk/credential-provider-ini": "3.830.0", "@aws-sdk/credential-provider-process": "3.826.0", - "@aws-sdk/credential-provider-sso": "3.828.0", - "@aws-sdk/credential-provider-web-identity": "3.828.0", + "@aws-sdk/credential-provider-sso": "3.830.0", + "@aws-sdk/credential-provider-web-identity": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -762,14 +762,14 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.828.0.tgz", - "integrity": "sha512-9CEAXzUDSzOjOCb3XfM15TZhTaM+l07kumZyx2z8NC6T2U4qbCJqn4h8mFlRvYrs6cBj2SN40sD3r5Wp0Cq2Kw==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", + "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.828.0", + "@aws-sdk/client-sso": "3.830.0", "@aws-sdk/core": "3.826.0", - "@aws-sdk/token-providers": "3.828.0", + "@aws-sdk/token-providers": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -781,13 +781,13 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.828.0.tgz", - "integrity": "sha512-MguDhGHlQBeK9CQ/P4NOY0whAJ4HJU4x+f1dphg3I1sGlccFqfB8Moor2vXNKu0Th2kvAwkn9pr7gGb/+NGR9g==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", + "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.826.0", - "@aws-sdk/nested-clients": "3.828.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -798,9 +798,9 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.828.0.tgz", - "integrity": "sha512-nBJmRzveYtdqL0u76tv62JGtkUfvyyZhAKNHFlzO8lCO7lxa0muRTG/ptUSS0ruFHq1K2MXHnDtLX90xiErIsQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.830.0.tgz", + "integrity": "sha512-jHNM1HhOmwMB5sguttXozL1HiDPf0yovu2o2L3ijMvexSUlrtqE2b2JjevMfVq7xZ5RYhBnQ+T8Q4MUclI8GnQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.0.4", @@ -815,13 +815,13 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.828.0" + "@aws-sdk/client-s3": "^3.830.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.821.0.tgz", - "integrity": "sha512-cebgeytKlWOgGczLo3BPvNY9XlzAzGZQANSysgJ2/8PSldmUpXRIF+GKPXDVhXeInWYHIfB8zZi3RqrPoXcNYQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.830.0.tgz", + "integrity": "sha512-ElVeCReZSH5Ds+/pkL5ebneJjuo8f49e9JXV1cYizuH0OAOQfYaBU9+M+7+rn61pTttOFE8W//qKzrXBBJhfMg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", @@ -991,9 +991,9 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.828.0.tgz", - "integrity": "sha512-xmeOILiR9LvfC8MctgeRXXN8nQTwbOvO4wHvgE8tDRsjnBpyyO0j50R4+viHXdMUGtgGkHEXRv8fFNBq54RgnA==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", + "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -1057,9 +1057,9 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.828.0.tgz", - "integrity": "sha512-6817h11Xi6LqnmTnHIwZf4PQB0rIMaRFwkq8/mfR9oOn+hsahxBVDbpgu+q4xzP5q+W3m5Y/din0cJPVrnP6yQ==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.830.0.tgz", + "integrity": "sha512-IEiSJfuf/hcf9WvCmvV35ci1yGcV3IYKS0e6l5xPRLYDNBrAWao9j8mrp0N4WCD3Nr+3xZRY5JglEFAH6CN3OQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/signature-v4-multi-region": "3.826.0", @@ -1093,13 +1093,13 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.828.0.tgz", - "integrity": "sha512-JdOjI/TxkfQpY/bWbdGMdCiePESXTbtl6MfnJxz35zZ3tfHvBnxAWCoYJirdmjzY/j/dFo5oEyS6mQuXAG9w2w==", + "version": "3.830.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", + "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "3.826.0", - "@aws-sdk/nested-clients": "3.828.0", + "@aws-sdk/nested-clients": "3.830.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -1806,9 +1806,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz", - "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz", + "integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1881,9 +1881,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.28.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", - "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", + "version": "9.29.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", + "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", "dev": true, "license": "MIT", "engines": { @@ -4054,9 +4054,9 @@ } }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -4472,9 +4472,9 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", - "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -4659,9 +4659,9 @@ } }, "node_modules/bullmq": { - "version": "5.53.2", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.53.2.tgz", - "integrity": "sha512-xHgxrP/yNJHD7VCw1h+eRBh+2TCPBCM39uC9gCyksYc6ufcJP+HTZ/A2lzB2x7qMFWrvsX7tM40AT2BmdkYL/Q==", + "version": "5.54.2", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.54.2.tgz", + "integrity": "sha512-Qm75wtgKLP1FH92N+l01D1AErX+uLdMlfadvY2XMBmE4gx5qeTbat4b2Zil1U82Ipqn5Vz7kpNE0cgw/hznAGA==", "license": "MIT", "dependencies": { "cron-parser": "^4.9.0", @@ -4817,9 +4817,9 @@ } }, "node_modules/chart.js": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.9.tgz", - "integrity": "sha512-EyZ9wWKgpAU0fLJ43YAEIF8sr5F2W3LqbS40ZJyHIner2lY14ufqv2VMp69MAiZ2rpwxEUxEhIH/0U3xyRynxg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.0.tgz", + "integrity": "sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==", "license": "MIT", "dependencies": { "@kurkle/color": "^0.3.0" @@ -6273,19 +6273,19 @@ } }, "node_modules/eslint": { - "version": "9.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.28.0.tgz", - "integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==", + "version": "9.29.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz", + "integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.0", + "@eslint/config-array": "^0.20.1", "@eslint/config-helpers": "^0.2.1", "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.28.0", + "@eslint/js": "9.29.0", "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -6297,9 +6297,9 @@ "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -6377,9 +6377,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -6394,9 +6394,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -6407,15 +6407,15 @@ } }, "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.14.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -9726,9 +9726,9 @@ } }, "node_modules/phone": { - "version": "3.1.59", - "resolved": "https://registry.npmjs.org/phone/-/phone-3.1.59.tgz", - "integrity": "sha512-CUv22jw0Zgrb/h7v3sEd262zJXS/66h7zyCCRIynx+2FswAJuuFsXsJkIxMUT4UcosKxDx1bJwdZeGnDELLsCw==", + "version": "3.1.62", + "resolved": "https://registry.npmjs.org/phone/-/phone-3.1.62.tgz", + "integrity": "sha512-mxUdq2nULKg6ukgVr4GSF9/sQiAa6e3AJy2HNE3UJA+lqdEF+Cko2RhKHhZRHtFaLKuBLPptitIwjv0uHG+vhw==", "license": "MIT", "engines": { "node": ">=12" diff --git a/package.json b/package.json index 6a905c90b..951fc588a 100644 --- a/package.json +++ b/package.json @@ -16,23 +16,23 @@ "job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js" }, "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.828.0", - "@aws-sdk/client-elasticache": "^3.828.0", - "@aws-sdk/client-s3": "^3.828.0", - "@aws-sdk/client-secrets-manager": "^3.828.0", - "@aws-sdk/client-ses": "^3.828.0", - "@aws-sdk/credential-provider-node": "^3.828.0", - "@aws-sdk/lib-storage": "^3.828.0", - "@aws-sdk/s3-request-presigner": "^3.828.0", + "@aws-sdk/client-cloudwatch-logs": "^3.830.0", + "@aws-sdk/client-elasticache": "^3.830.0", + "@aws-sdk/client-s3": "^3.830.0", + "@aws-sdk/client-secrets-manager": "^3.830.0", + "@aws-sdk/client-ses": "^3.830.0", + "@aws-sdk/credential-provider-node": "^3.830.0", + "@aws-sdk/lib-storage": "^3.830.0", + "@aws-sdk/s3-request-presigner": "^3.830.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", "archiver": "^7.0.1", "aws4": "^1.13.2", - "axios": "^1.8.4", + "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.53.2", - "chart.js": "^4.4.8", + "bullmq": "^5.54.2", + "chart.js": "^4.5.0", "cloudinary": "^2.6.1", "compression": "^1.8.0", "cookie-parser": "^1.4.7", @@ -56,7 +56,7 @@ "multer": "^1.4.5-lts.1", "node-persist": "^4.0.4", "nodemailer": "^6.10.0", - "phone": "^3.1.58", + "phone": "^3.1.62", "query-string": "7.1.3", "recursive-diff": "^1.0.9", "rimraf": "^6.0.1", @@ -73,8 +73,8 @@ "xmlbuilder2": "^3.1.1" }, "devDependencies": { - "@eslint/js": "^9.28.0", - "eslint": "^9.28.0", + "@eslint/js": "^9.29.0", + "eslint": "^9.29.0", "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "mock-require": "^3.0.3", diff --git a/server/integrations/partsManagement/partsManagementProvisioning.js b/server/integrations/partsManagement/partsManagementProvisioning.js index 8e2213bdf..4fe5970e9 100644 --- a/server/integrations/partsManagement/partsManagementProvisioning.js +++ b/server/integrations/partsManagement/partsManagementProvisioning.js @@ -1,4 +1,3 @@ -const crypto = require("crypto"); const admin = require("firebase-admin"); const client = require("../../graphql-client/graphql-client").client; const DefaultNewShop = require("./defaultNewShop.json"); @@ -243,11 +242,17 @@ const partsManagementProvisioning = async (req, res) => { // Cleanup on failure if (err.userRecord) { - await deleteFirebaseUser(err.userRecord.uid).catch(() => {}); + await deleteFirebaseUser(err.userRecord.uid).catch(() => { + // Ignore errors during user deletion cleanup + }); } if (err.newShopId) { - await deleteVendorsByShop(err.newShopId).catch(() => {}); - await deleteBodyshop(err.newShopId).catch(() => {}); + await deleteVendorsByShop(err.newShopId).catch(() => { + // Ignore errors during vendor deletion cleanup + }); + await deleteBodyshop(err.newShopId).catch(() => { + // Ignore errors during shop deletion cleanup + }); } return res.status(err.status || 500).json({ error: err.message || "Internal server error" }); diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js new file mode 100644 index 000000000..03a68ca0d --- /dev/null +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -0,0 +1,356 @@ +const xml2js = require("xml2js"); +const client = require("../../graphql-client/graphql-client").client; + +// GraphQL statements +const INSERT_JOB_WITH_LINES = ` + mutation InsertJob($job: jobs_insert_input!) { + insert_jobs_one(object: $job) { + id + joblines { id unq_seq } + } + } +`; + +const INSERT_PARTS_ORDERS = ` + mutation InsertPartsOrders($po: [parts_orders_insert_input!]!) { + insert_parts_orders(objects: $po) { + returning { id order_number } + } + } +`; + +/** + * Handles incoming VehicleDamageEstimateAddRq XML, + * parses every known field, inserts a Job + nested JobLines, + * then any PartsOrders (grouped per SupplierRefNum). + */ +const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { + const { logger } = req; + const xml = req.body; + + let payload; + try { + payload = await xml2js.parseStringPromise(xml, { + explicitArray: false, + tagNameProcessors: [xml2js.processors.stripPrefix] + }); + logger.log("parts-xml-parse", "debug", null, null, { success: true }); + } catch (err) { + logger.log("parts-xml-parse-error", "error", null, null, { error: err }); + return res.status(400).send("Invalid XML"); + } + + const rq = payload.VehicleDamageEstimateAddRq; + if (!rq) { + logger.log("parts-missing-root", "error"); + return res.status(400).send("Missing "); + } + + try { + // + // ── SHOP ID ─────────────────────────────────────────────────────────────────── + // + // pulled directly from in your XML + // + const shopId = rq.ShopID || rq.shopId; + if (!shopId) { + throw { status: 400, message: "Missing in XML" }; + } + + // + // ── DOCUMENT INFO ───────────────────────────────────────────────────────────── + // + const { RqUID, RefClaimNum } = rq; + const doc = rq.DocumentInfo || {}; + const comment = doc.Comment || null; + const transmitDate = doc.TransmitDateTime || null; + + // capture all entries + const docVers = doc.DocumentVer ? (Array.isArray(doc.DocumentVer) ? doc.DocumentVer : [doc.DocumentVer]) : []; + const documentVersions = docVers.map((dv) => ({ + code: dv.DocumentVerCode, + num: dv.DocumentVerNum + })); + + // pull out any OtherReferenceInfo (RO Number + Job UUID) + const otherRefs = doc.ReferenceInfo?.OtherReferenceInfo + ? Array.isArray(doc.ReferenceInfo.OtherReferenceInfo) + ? doc.ReferenceInfo.OtherReferenceInfo + : [doc.ReferenceInfo.OtherReferenceInfo] + : []; + const originalRoNumber = otherRefs.find((r) => r.OtherReferenceName === "RO Number")?.OtherRefNum; + const originalJobUuid = otherRefs.find((r) => r.OtherReferenceName === "Job UUID")?.OtherRefNum; + + // + // ── EVENT INFO ──────────────────────────────────────────────────────────────── + // + const ev = rq.EventInfo || {}; + const assignEv = ev.AssignmentEvent || {}; + const assignmentEvent = { + number: assignEv.AssignmentNumber, + type: assignEv.AssignmentType, + date: assignEv.AssignmentDate, + createdAt: assignEv.CreateDateTime + }; + const repairEv = ev.RepairEvent || {}; + const scheduled_completion = repairEv.TargetCompletionDateTime || null; + const scheduled_in = repairEv.RequestedPickUpDateTime || null; + + // + // ── CLAIM INFO ──────────────────────────────────────────────────────────────── + // + const ci = rq.ClaimInfo || {}; + const clm_no = ci.ClaimNum; + const ClaimStatus = ci.ClaimStatus || null; + const policy_no = ci.PolicyInfo?.PolicyNum || null; + const ded_amt = parseFloat(ci.PolicyInfo?.CoverageInfo?.Coverage?.DeductibleInfo?.DeductibleAmt || 0); + // if your XML ever has a `` you'd parse it here + const clm_total = parseFloat(ci.Cieca_ttl || 0); + + // + // ── OWNER ───────────────────────────────────────────────────────────────────── + // + const ownerParty = rq.AdminInfo?.Owner?.Party || {}; + const ownerName = ownerParty.PersonInfo?.PersonName || {}; + const ownerOrg = ownerParty.OrgInfo || {}; + const ownerAddr = ownerParty.PersonInfo?.Communications?.Address || {}; + const ownerComms = ownerParty.ContactInfo?.Communications + ? Array.isArray(ownerParty.ContactInfo.Communications) + ? ownerParty.ContactInfo.Communications + : [ownerParty.ContactInfo.Communications] + : []; + let ownerPhone = null, + ownerEmail = null; + ownerComms.forEach((c) => { + if (c.CommQualifier === "CP") ownerPhone = c.CommPhone; + if (c.CommQualifier === "EM") ownerEmail = c.CommEmail; + }); + const ownerPrefContact = ownerParty.PreferredContactMethod || null; + + // + // ── VEHICLE INFO ────────────────────────────────────────────────────────────── + // + const vin = rq.VehicleInfo?.VINInfo?.VINNum || null; + const plate_no = rq.VehicleInfo?.License?.LicensePlateNum || null; + const plate_st = rq.VehicleInfo?.License?.LicensePlateStateProvince || null; + const desc = rq.VehicleInfo?.VehicleDesc || {}; + const v_model_yr = desc.ModelYear || null; + const v_make_desc = desc.MakeDesc || null; + const v_model_desc = desc.ModelName || null; + const body_style = desc.BodyStyle || null; + const engine_desc = desc.EngineDesc || null; + const production_date = desc.ProductionDate || null; + const sub_model_desc = desc.SubModelDesc || null; + const fuel_type = desc.FuelType || null; + const v_color = rq.VehicleInfo?.Paint?.Exterior?.ColorName || null; + const drivable = rq.VehicleInfo?.Condition?.DrivableInd === "Y"; + + // + // ── PROFILE & RATES ─────────────────────────────────────────────────────────── + // + const rateInfos = rq.ProfileInfo?.RateInfo + ? Array.isArray(rq.ProfileInfo.RateInfo) + ? rq.ProfileInfo.RateInfo + : [rq.ProfileInfo.RateInfo] + : []; + const rates = {}; // main { rate_lab, rate_laf, … } + const rateTier = {}; // e.g. { MA2S: [ {tier, pct}, … ] } + const materialCalc = {}; // e.g. { LAR: { CalcMethodCode, CalcMaxHours }, … } + + rateInfos.forEach((r) => { + if (!r || !r.RateType) return; + const t = r.RateType; + // main per‐unit rate + if (r.Rate) rates[`rate_${t.toLowerCase()}`] = parseFloat(r.Rate) || 0; + // any tier settings + if (r.RateTierInfo) { + const tiers = Array.isArray(r.RateTierInfo) ? r.RateTierInfo : [r.RateTierInfo]; + rateTier[t] = tiers.map((ti) => ({ + tier: ti.TierNum, + pct: parseFloat(ti.Percentage) || 0 + })); + } + // any material‐calc limits + if (r.MaterialCalcSettings) { + materialCalc[t] = r.MaterialCalcSettings; + } + }); + + // + // ── DAMAGE LINES → joblinesData ───────────────────────────────────────────── + // + const damageLines = Array.isArray(rq.DamageLineInfo) ? rq.DamageLineInfo : [rq.DamageLineInfo]; + const joblinesData = damageLines.map((line) => ({ + line_no: parseInt(line.LineNum, 10), + unq_seq: parseInt(line.UniqueSequenceNum, 10), + manual_line: line.ManualLineInd === "1", + automated_entry: line.AutomatedEntry === "1", + desc_judgment_ind: line.DescJudgmentInd === "1", + status: line.LineStatusCode || null, + line_desc: line.LineDesc || null, + + // parts + part_type: line.PartInfo.PartType || null, + part_qty: parseInt(line.PartInfo.Quantity || 0, 10), + db_price: parseFloat(line.PartInfo.PartPrice || 0), + act_price: parseFloat(line.PartInfo.PartPrice || 0), + oem_partno: line.PartInfo.OEMPartNum || null, + + // non-OEM block + non_oem_part_num: line.PartInfo?.NonOEM?.NonOEMPartNum || null, + non_oem_part_price: parseFloat(line.PartInfo?.NonOEM?.NonOEMPartPrice || 0), + supplier_ref_num: line.PartInfo?.NonOEM?.SupplierRefNum || null, + part_selected_ind: line.PartInfo?.NonOEM?.PartSelectedInd === "1", + + after_market_usage: line.PartInfo.AfterMarketUsage || null, + certification_type: line.PartInfo.CertificationType || null, + tax_part: line.PartInfo.TaxableInd === "1", + glass_flag: line.PartInfo.GlassPartInd === "1", + price_j: line.PriceJudgmentInd === "1", + price_inc: line.PriceInclInd === "1", + order_by_application_ind: String(line.PartInfo.OrderByApplicationInd).toLowerCase() === "true", + + // labor + mod_lbr_ty: line.LaborInfo?.LaborType || null, + mod_lb_hrs: parseFloat(line.LaborInfo?.LaborHours || 0), + lbr_op: line.LaborInfo?.LaborOperation || null, + lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), + + // linkage & memo + parent_line_no: line.ParentLineNum ? parseInt(line.ParentLineNum, 10) : null, + notes: line.LineMemo || null + })); + + // + // ── BUILD & INSERT THE JOB ─────────────────────────────────────────────────── + // + const jobInput = { + shopid: shopId, + + // identifiers + ro_number: RefClaimNum, + original_ro_number: originalRoNumber, + original_job_uuid: originalJobUuid, + + // claim & policy + clm_no, + status: ClaimStatus, + clm_total, + policy_no, + ded_amt, + + // timestamps & comments + comment, + date_exported: transmitDate, + + // owner + ownr_fn: ownerName.FirstName || null, + ownr_ln: ownerName.LastName || null, + ownr_co_nm: ownerOrg.CompanyName || null, + ownr_addr1: ownerAddr.Address1 || null, + ownr_city: ownerAddr.City || null, + ownr_st: ownerAddr.StateProvince || null, + ownr_zip: ownerAddr.PostalCode || null, + ownr_country: ownerAddr.Country || null, + ownr_ph1: ownerPhone, + ownr_ea: ownerEmail, + ownr_pref_contact: ownerPrefContact, + + // vehicle + v_vin: vin, + plate_no, + plate_st, + v_model_yr, + v_make_desc, + v_model_desc, + v_color, + body_style, + engine_desc, + production_date, + sub_model_desc, + fuel_type, + drivable, + + // labor & material rates + ...rates, + + // everything extra in one JSON column + production_vars: { + rqUid: RqUID, + documentVersions, + assignmentEvent, + scheduled_completion, + scheduled_in, + rateTier, + materialCalc + }, + + // nested joblines + joblines: { data: joblinesData } + }; + + logger.log("parts-insert-job", "debug", null, null, { jobInput }); + const jobResp = await client.request(INSERT_JOB_WITH_LINES, { + job: jobInput + }); + const newJob = jobResp.insert_jobs_one; + const jobId = newJob.id; + logger.log("parts-job-created", "info", jobId, null); + + // + // ── BUILD & INSERT PARTS ORDERS ──────────────────────────────────────────── + // + // group lines by their SupplierRefNum + const insertedMap = newJob.joblines.reduce((m, ln) => { + m[ln.unq_seq] = ln.id; + return m; + }, {}); + const poGroups = {}; + damageLines.forEach((line) => { + const pt = line.PartInfo.PartType; + const qty = parseInt(line.PartInfo.Quantity || 0, 10); + if (["PAN", "PAC", "PAM", "PAA"].includes(pt) && qty > 0) { + const vendorid = line.PartInfo?.NonOEM?.SupplierRefNum || process.env.DEFAULT_VENDOR_ID; + if (!poGroups[vendorid]) poGroups[vendorid] = []; + poGroups[vendorid].push({ + line, + unq_seq: parseInt(line.UniqueSequenceNum, 10) + }); + } + }); + + const partsOrders = Object.entries(poGroups).map(([vendorid, entries]) => ({ + jobid: jobId, + vendorid, + order_number: `${clm_no}-${entries[0].line.LineNum}`, + parts_order_lines: { + data: entries.map(({ line, unq_seq }) => ({ + job_line_id: insertedMap[unq_seq], + part_type: line.PartInfo.PartType, + quantity: parseInt(line.PartInfo.Quantity || 0, 10), + act_price: parseFloat(line.PartInfo.PartPrice || 0), + db_price: parseFloat(line.PartInfo.PartPrice || 0), + line_desc: line.LineDesc, + non_oem_part_num: line.PartInfo?.NonOEM?.NonOEMPartNum || null, + non_oem_part_price: parseFloat(line.PartInfo?.NonOEM?.NonOEMPartPrice || 0), + part_selected_ind: line.PartInfo?.NonOEM?.PartSelectedInd === "1" + })) + } + })); + + if (partsOrders.length) { + logger.log("parts-insert-orders", "debug", null, null, { + partsOrders + }); + await client.request(INSERT_PARTS_ORDERS, { po: partsOrders }); + logger.log("parts-orders-created", "info", jobId, null); + } + + return res.status(200).json({ success: true, jobId }); + } catch (err) { + logger.log("parts-route-error", "error", null, null, { error: err }); + return res.status(err.status || 500).json({ error: err.message || "Internal error" }); + } +}; + +module.exports = partsManagementVehicleDamageEstimateAddRq; diff --git a/server/routes/intergrationRoutes.js b/server/routes/intergrationRoutes.js index 46826d28e..38b8d44fb 100644 --- a/server/routes/intergrationRoutes.js +++ b/server/routes/intergrationRoutes.js @@ -18,8 +18,14 @@ if (typeof VSSTA_INTEGRATION_SECRET === "string" && VSSTA_INTEGRATION_SECRET.len if (typeof PARTS_MANAGEMENT_INTEGRATION_SECRET === "string" && PARTS_MANAGEMENT_INTEGRATION_SECRET.length > 0) { const partsManagementProvisioning = require("../integrations/partsManagement/partsManagementProvisioning"); const partsManagementIntegrationMiddleware = require("../middleware/partsManagementIntegrationMiddleware"); + const partsManagementVehicleDamageEstimateAddRq = require("../integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq"); router.post("/parts-management/provision", partsManagementIntegrationMiddleware, partsManagementProvisioning); + router.post( + "/parts-management/VehicleDamageEstimateAddRq", + partsManagementIntegrationMiddleware, + partsManagementVehicleDamageEstimateAddRq + ); } else { console.warn("PARTS_MANAGEMENT_INTEGRATION_SECRET is not set — skipping /parts-management/provision route"); } diff --git a/static-analysis.datadog.yml b/static-analysis.datadog.yml new file mode 100644 index 000000000..223543d2c --- /dev/null +++ b/static-analysis.datadog.yml @@ -0,0 +1,10 @@ +schema-version: v1 +rulesets: + - javascript-best-practices + - javascript-browser-security + - javascript-code-style + - javascript-common-security + - javascript-express + - javascript-inclusive + - javascript-node-security + - jsx-react From 2505edede7a20835728b82baa5b030b79613f3f4 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Thu, 19 Jun 2025 13:08:48 -0400 Subject: [PATCH 04/98] feature/IO-3255-simplified-parts-management - Checkpoint --- client/package-lock.json | 130 +++--- client/package.json | 6 +- package-lock.json | 357 +++++++++-------- package.json | 14 +- ...rtsManagementVehicleDamageEstimateAddRq.js | 375 ++++++++++-------- .../partsManagement/sampleBody.xml | 340 ++++++++++++++++ server/routes/intergrationRoutes.js | 6 +- 7 files changed, 818 insertions(+), 410 deletions(-) create mode 100644 server/integrations/partsManagement/sampleBody.xml diff --git a/client/package-lock.json b/client/package-lock.json index eb559a8f2..6d710e174 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -95,7 +95,7 @@ "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", "@eslint/js": "^9.29.0", - "@playwright/test": "^1.53.0", + "@playwright/test": "^1.53.1", "@sentry/webpack-plugin": "^3.5.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", @@ -111,7 +111,7 @@ "jsdom": "^26.0.0", "memfs": "^4.17.2", "os-browserify": "^0.3.0", - "playwright": "^1.53.0", + "playwright": "^1.53.1", "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", @@ -121,7 +121,7 @@ "vite-plugin-node-polyfills": "^0.23.0", "vite-plugin-pwa": "^1.0.0", "vite-plugin-style-import": "^2.0.0", - "vitest": "^3.2.3", + "vitest": "^3.2.4", "workbox-window": "^7.3.0" }, "engines": { @@ -3516,13 +3516,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.0.tgz", - "integrity": "sha512-15hjKreZDcp7t6TL/7jkAo6Df5STZN09jGiv5dbP9A6vMVncXRqE7/B2SncsyOwrkZRBH2i6/TPOL8BVmm3c7w==", + "version": "1.53.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.1.tgz", + "integrity": "sha512-Z4c23LHV0muZ8hfv4jw6HngPJkbbtZxTkxPNIg7cJcTc9C28N/p2q7g3JZS2SiKBBHJ3uM1dgDye66bB7LEk5w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.53.0" + "playwright": "1.53.1" }, "bin": { "playwright": "cli.js" @@ -5840,15 +5840,15 @@ } }, "node_modules/@vitest/expect": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.3.tgz", - "integrity": "sha512-W2RH2TPWVHA1o7UmaFKISPvdicFJH+mjykctJFoAkUw+SPTJTGjUNdKscFBrqM7IPnCVu6zihtKYa7TkZS1dkQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.3", - "@vitest/utils": "3.2.3", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -5857,13 +5857,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.3.tgz", - "integrity": "sha512-cP6fIun+Zx8he4rbWvi+Oya6goKQDZK+Yq4hhlggwQBbrlOQ4qtZ+G4nxB6ZnzI9lyIb+JnvyiJnPC2AGbKSPA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.3", + "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -5904,9 +5904,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.3.tgz", - "integrity": "sha512-yFglXGkr9hW/yEXngO+IKMhP0jxyFw2/qys/CK4fFUZnSltD+MU7dVYGrH8rvPcK/O6feXQA+EU33gjaBBbAng==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", "dev": true, "license": "MIT", "dependencies": { @@ -5917,13 +5917,13 @@ } }, "node_modules/@vitest/runner": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.3.tgz", - "integrity": "sha512-83HWYisT3IpMaU9LN+VN+/nLHVBCSIUKJzGxC5RWUOsK1h3USg7ojL+UXQR3b4o4UBIWCYdD2fxuzM7PQQ1u8w==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.3", + "@vitest/utils": "3.2.4", "pathe": "^2.0.3", "strip-literal": "^3.0.0" }, @@ -5939,13 +5939,13 @@ "license": "MIT" }, "node_modules/@vitest/snapshot": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.3.tgz", - "integrity": "sha512-9gIVWx2+tysDqUmmM1L0hwadyumqssOL1r8KJipwLx5JVYyxvVRfxvMq7DaWbZZsCqZnu/dZedaZQh4iYTtneA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.3", + "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -5971,9 +5971,9 @@ "license": "MIT" }, "node_modules/@vitest/spy": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.3.tgz", - "integrity": "sha512-JHu9Wl+7bf6FEejTCREy+DmgWe+rQKbK+y32C/k5f4TBIAlijhJbRBIRIOCEpVevgRsCQR2iHRUH2/qKVM/plw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", "dev": true, "license": "MIT", "dependencies": { @@ -5984,14 +5984,14 @@ } }, "node_modules/@vitest/utils": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.3.tgz", - "integrity": "sha512-4zFBCU5Pf+4Z6v+rwnZ1HU1yzOKKvDkMXZrymE2PBlbjKJRlrOxbvpfPSvJTGRIwGoahaOGvp+kbCoxifhzJ1Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.3", - "loupe": "^3.1.3", + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" }, "funding": { @@ -11622,9 +11622,9 @@ } }, "node_modules/loupe": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", - "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz", + "integrity": "sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==", "dev": true, "license": "MIT" }, @@ -13337,13 +13337,13 @@ } }, "node_modules/playwright": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.0.tgz", - "integrity": "sha512-ghGNnIEYZC4E+YtclRn4/p6oYbdPiASELBIYkBXfaTVKreQUYbMUYQDwS12a8F0/HtIjr/CkGjtwABeFPGcS4Q==", + "version": "1.53.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.1.tgz", + "integrity": "sha512-LJ13YLr/ocweuwxyGf1XNFWIU4M2zUSo149Qbp+A4cpwDjsxRPj7k6H25LBrEHiEwxvRbD8HdwvQmRMSvquhYw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.53.0" + "playwright-core": "1.53.1" }, "bin": { "playwright": "cli.js" @@ -13356,9 +13356,9 @@ } }, "node_modules/playwright-core": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.0.tgz", - "integrity": "sha512-mGLg8m0pm4+mmtB7M89Xw/GSqoNC+twivl8ITteqvAndachozYe2ZA7srU6uleV1vEdAHYqjq+SV8SNxRRFYBw==", + "version": "1.53.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.1.tgz", + "integrity": "sha512-Z46Oq7tLAyT0lGoFx4DOuB1IA9D1TPj0QkYxpPVUnGDqHHvDpCftu1J2hM2PiWsNMoZh8+LQaarAWcDfPBc6zg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -16694,9 +16694,9 @@ } }, "node_modules/tinypool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.0.tgz", - "integrity": "sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "dev": true, "license": "MIT", "engines": { @@ -17588,9 +17588,9 @@ } }, "node_modules/vite-node": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.3.tgz", - "integrity": "sha512-gc8aAifGuDIpZHrPjuHyP4dpQmYXqWw7D1GmDnWeNWP654UEXzVfQ5IHPSK5HaHkwB/+p1atpYpSdw/2kOv8iQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dev": true, "license": "MIT", "dependencies": { @@ -17786,20 +17786,20 @@ } }, "node_modules/vitest": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.3.tgz", - "integrity": "sha512-E6U2ZFXe3N/t4f5BwUaVCKRLHqUpk1CBWeMh78UT4VaTPH/2dyvH6ALl29JTovEPu9dVKr/K/J4PkXgrMbw4Ww==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.3", - "@vitest/mocker": "3.2.3", - "@vitest/pretty-format": "^3.2.3", - "@vitest/runner": "3.2.3", - "@vitest/snapshot": "3.2.3", - "@vitest/spy": "3.2.3", - "@vitest/utils": "3.2.3", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", @@ -17810,10 +17810,10 @@ "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", - "tinypool": "^1.1.0", + "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.3", + "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "bin": { @@ -17829,8 +17829,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.3", - "@vitest/ui": "3.2.3", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, diff --git a/client/package.json b/client/package.json index c85b2eb5f..955a343b2 100644 --- a/client/package.json +++ b/client/package.json @@ -135,7 +135,7 @@ "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", "@eslint/js": "^9.29.0", - "@playwright/test": "^1.53.0", + "@playwright/test": "^1.53.1", "@sentry/webpack-plugin": "^3.5.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", @@ -151,7 +151,7 @@ "jsdom": "^26.0.0", "memfs": "^4.17.2", "os-browserify": "^0.3.0", - "playwright": "^1.53.0", + "playwright": "^1.53.1", "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", @@ -161,7 +161,7 @@ "vite-plugin-node-polyfills": "^0.23.0", "vite-plugin-pwa": "^1.0.0", "vite-plugin-style-import": "^2.0.0", - "vitest": "^3.2.3", + "vitest": "^3.2.4", "workbox-window": "^7.3.0" } } diff --git a/package-lock.json b/package-lock.json index e99e38a05..e598c0600 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,14 @@ "version": "0.2.0", "license": "UNLICENSED", "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.830.0", + "@aws-sdk/client-cloudwatch-logs": "^3.832.0", "@aws-sdk/client-elasticache": "^3.830.0", - "@aws-sdk/client-s3": "^3.830.0", + "@aws-sdk/client-s3": "^3.832.0", "@aws-sdk/client-secrets-manager": "^3.830.0", "@aws-sdk/client-ses": "^3.830.0", "@aws-sdk/credential-provider-node": "^3.830.0", - "@aws-sdk/lib-storage": "^3.830.0", - "@aws-sdk/s3-request-presigner": "^3.830.0", + "@aws-sdk/lib-storage": "^3.832.0", + "@aws-sdk/s3-request-presigner": "^3.832.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -24,9 +24,9 @@ "aws4": "^1.13.2", "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.54.2", + "bullmq": "^5.54.3", "chart.js": "^4.5.0", - "cloudinary": "^2.6.1", + "cloudinary": "^2.7.0", "compression": "^1.8.0", "cookie-parser": "^1.4.7", "cors": "^2.8.5", @@ -74,7 +74,7 @@ "p-limit": "^3.1.0", "prettier": "^3.5.3", "supertest": "^7.1.1", - "vitest": "^3.2.3" + "vitest": "^3.2.4" }, "engines": { "node": ">=22.13.0", @@ -284,9 +284,9 @@ } }, "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.830.0.tgz", - "integrity": "sha512-jg4kpECjBcNemGtVr5IK3ZMKRZzrmG4VbxhgECHgxqNPgb+HeAcSOMa3ZsgStRnpwDEazfgYTJyBktZIC/XuuA==", + "version": "3.832.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.832.0.tgz", + "integrity": "sha512-Xpu1HKMafA9j7j/ttvKYcv0a4XRFCOBQFjKvsZTrKeGZoVzoEP+IKBfy8+pGI3zLZEm5N6J5d1ifXbZ+9F0icA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -403,9 +403,9 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.830.0.tgz", - "integrity": "sha512-Cti+zj1lqvQIScXFQv8/t1xo3pvcvk/ObmGIbyLzfgcYpKMHaIWhzhi6aN+z4dYEv1EwrukC9tNoqScyShc5tw==", + "version": "3.832.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.832.0.tgz", + "integrity": "sha512-S+md1zCe71SEuaRDuLHq4mzhYYkVxR1ENa8NwrgInfYoC4xo8/pESoR6i0ZZpcLs0Jw4EyVInWYs4GgDHW70qQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", @@ -463,12 +463,27 @@ "@smithy/util-stream": "^4.2.2", "@smithy/util-utf8": "^4.0.0", "@smithy/util-waiter": "^4.0.5", - "tslib": "^2.6.2" + "@types/uuid": "^9.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" }, "engines": { "node": ">=18.0.0" } }, + "node_modules/@aws-sdk/client-s3/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@aws-sdk/client-secrets-manager": { "version": "3.830.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.830.0.tgz", @@ -798,9 +813,9 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.830.0.tgz", - "integrity": "sha512-jHNM1HhOmwMB5sguttXozL1HiDPf0yovu2o2L3ijMvexSUlrtqE2b2JjevMfVq7xZ5RYhBnQ+T8Q4MUclI8GnQ==", + "version": "3.832.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.832.0.tgz", + "integrity": "sha512-NM+q0WD8TCreo+tvKy0AZytHQQC19zXVG8iapDhafLNs1W72zAQ659pTfVzsC00Zvwtsp0LI/b2FWTjkjTAAdA==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.0.4", @@ -815,7 +830,7 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.830.0" + "@aws-sdk/client-s3": "^3.832.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { @@ -1057,9 +1072,9 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.830.0.tgz", - "integrity": "sha512-IEiSJfuf/hcf9WvCmvV35ci1yGcV3IYKS0e6l5xPRLYDNBrAWao9j8mrp0N4WCD3Nr+3xZRY5JglEFAH6CN3OQ==", + "version": "3.832.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.832.0.tgz", + "integrity": "sha512-zXuwfaAYu99LUF7/6iBr3UlKCMaMImBwfmLXJQlvtE3ebrERXQuISME9Vjd2oG+hJ6XcX6RJqkeIvZBytMzvRw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/signature-v4-multi-region": "3.826.0", @@ -2566,9 +2581,9 @@ "license": "BSD-3-Clause" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.42.0.tgz", - "integrity": "sha512-gldmAyS9hpj+H6LpRNlcjQWbuKUtb94lodB9uCz71Jm+7BxK1VIOo7y62tZZwxhA7j1ylv/yQz080L5WkS+LoQ==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.0.tgz", + "integrity": "sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==", "cpu": [ "arm" ], @@ -2580,9 +2595,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.42.0.tgz", - "integrity": "sha512-bpRipfTgmGFdCZDFLRvIkSNO1/3RGS74aWkJJTFJBH7h3MRV4UijkaEUeOMbi9wxtxYmtAbVcnMtHTPBhLEkaw==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.0.tgz", + "integrity": "sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==", "cpu": [ "arm64" ], @@ -2594,9 +2609,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.42.0.tgz", - "integrity": "sha512-JxHtA081izPBVCHLKnl6GEA0w3920mlJPLh89NojpU2GsBSB6ypu4erFg/Wx1qbpUbepn0jY4dVWMGZM8gplgA==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.0.tgz", + "integrity": "sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==", "cpu": [ "arm64" ], @@ -2608,9 +2623,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.42.0.tgz", - "integrity": "sha512-rv5UZaWVIJTDMyQ3dCEK+m0SAn6G7H3PRc2AZmExvbDvtaDc+qXkei0knQWcI3+c9tEs7iL/4I4pTQoPbNL2SA==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.0.tgz", + "integrity": "sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==", "cpu": [ "x64" ], @@ -2622,9 +2637,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.42.0.tgz", - "integrity": "sha512-fJcN4uSGPWdpVmvLuMtALUFwCHgb2XiQjuECkHT3lWLZhSQ3MBQ9pq+WoWeJq2PrNxr9rPM1Qx+IjyGj8/c6zQ==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.0.tgz", + "integrity": "sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==", "cpu": [ "arm64" ], @@ -2636,9 +2651,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.42.0.tgz", - "integrity": "sha512-CziHfyzpp8hJpCVE/ZdTizw58gr+m7Y2Xq5VOuCSrZR++th2xWAz4Nqk52MoIIrV3JHtVBhbBsJcAxs6NammOQ==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.0.tgz", + "integrity": "sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==", "cpu": [ "x64" ], @@ -2650,9 +2665,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.42.0.tgz", - "integrity": "sha512-UsQD5fyLWm2Fe5CDM7VPYAo+UC7+2Px4Y+N3AcPh/LdZu23YcuGPegQly++XEVaC8XUTFVPscl5y5Cl1twEI4A==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.0.tgz", + "integrity": "sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==", "cpu": [ "arm" ], @@ -2664,9 +2679,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.42.0.tgz", - "integrity": "sha512-/i8NIrlgc/+4n1lnoWl1zgH7Uo0XK5xK3EDqVTf38KvyYgCU/Rm04+o1VvvzJZnVS5/cWSd07owkzcVasgfIkQ==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.0.tgz", + "integrity": "sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==", "cpu": [ "arm" ], @@ -2678,9 +2693,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.42.0.tgz", - "integrity": "sha512-eoujJFOvoIBjZEi9hJnXAbWg+Vo1Ov8n/0IKZZcPZ7JhBzxh2A+2NFyeMZIRkY9iwBvSjloKgcvnjTbGKHE44Q==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.0.tgz", + "integrity": "sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==", "cpu": [ "arm64" ], @@ -2692,9 +2707,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.42.0.tgz", - "integrity": "sha512-/3NrcOWFSR7RQUQIuZQChLND36aTU9IYE4j+TB40VU78S+RA0IiqHR30oSh6P1S9f9/wVOenHQnacs/Byb824g==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.0.tgz", + "integrity": "sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==", "cpu": [ "arm64" ], @@ -2706,9 +2721,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.42.0.tgz", - "integrity": "sha512-O8AplvIeavK5ABmZlKBq9/STdZlnQo7Sle0LLhVA7QT+CiGpNVe197/t8Aph9bhJqbDVGCHpY2i7QyfEDDStDg==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.0.tgz", + "integrity": "sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==", "cpu": [ "loong64" ], @@ -2720,9 +2735,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.42.0.tgz", - "integrity": "sha512-6Qb66tbKVN7VyQrekhEzbHRxXXFFD8QKiFAwX5v9Xt6FiJ3BnCVBuyBxa2fkFGqxOCSGGYNejxd8ht+q5SnmtA==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.0.tgz", + "integrity": "sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==", "cpu": [ "ppc64" ], @@ -2734,9 +2749,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.42.0.tgz", - "integrity": "sha512-KQETDSEBamQFvg/d8jajtRwLNBlGc3aKpaGiP/LvEbnmVUKlFta1vqJqTrvPtsYsfbE/DLg5CC9zyXRX3fnBiA==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.0.tgz", + "integrity": "sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==", "cpu": [ "riscv64" ], @@ -2748,9 +2763,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.42.0.tgz", - "integrity": "sha512-qMvnyjcU37sCo/tuC+JqeDKSuukGAd+pVlRl/oyDbkvPJ3awk6G6ua7tyum02O3lI+fio+eM5wsVd66X0jQtxw==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.0.tgz", + "integrity": "sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==", "cpu": [ "riscv64" ], @@ -2762,9 +2777,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.42.0.tgz", - "integrity": "sha512-I2Y1ZUgTgU2RLddUHXTIgyrdOwljjkmcZ/VilvaEumtS3Fkuhbw4p4hgHc39Ypwvo2o7sBFNl2MquNvGCa55Iw==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.0.tgz", + "integrity": "sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==", "cpu": [ "s390x" ], @@ -2776,9 +2791,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.42.0.tgz", - "integrity": "sha512-Gfm6cV6mj3hCUY8TqWa63DB8Mx3NADoFwiJrMpoZ1uESbK8FQV3LXkhfry+8bOniq9pqY1OdsjFWNsSbfjPugw==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.0.tgz", + "integrity": "sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==", "cpu": [ "x64" ], @@ -2790,9 +2805,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.42.0.tgz", - "integrity": "sha512-g86PF8YZ9GRqkdi0VoGlcDUb4rYtQKyTD1IVtxxN4Hpe7YqLBShA7oHMKU6oKTCi3uxwW4VkIGnOaH/El8de3w==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.0.tgz", + "integrity": "sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==", "cpu": [ "x64" ], @@ -2804,9 +2819,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.42.0.tgz", - "integrity": "sha512-+axkdyDGSp6hjyzQ5m1pgcvQScfHnMCcsXkx8pTgy/6qBmWVhtRVlgxjWwDp67wEXXUr0x+vD6tp5W4x6V7u1A==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.0.tgz", + "integrity": "sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==", "cpu": [ "arm64" ], @@ -2818,9 +2833,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.42.0.tgz", - "integrity": "sha512-F+5J9pelstXKwRSDq92J0TEBXn2nfUrQGg+HK1+Tk7VOL09e0gBqUHugZv7SW4MGrYj41oNCUe3IKCDGVlis2g==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.0.tgz", + "integrity": "sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==", "cpu": [ "ia32" ], @@ -2832,9 +2847,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.42.0.tgz", - "integrity": "sha512-LpHiJRwkaVz/LqjHjK8LCi8osq7elmpwujwbXKNW88bM8eeGxavJIKKjkjpMHAh/2xfnrt1ZSnhTv41WYUHYmA==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.0.tgz", + "integrity": "sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==", "cpu": [ "x64" ], @@ -3717,9 +3732,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -3881,15 +3896,15 @@ "license": "MIT" }, "node_modules/@vitest/expect": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.3.tgz", - "integrity": "sha512-W2RH2TPWVHA1o7UmaFKISPvdicFJH+mjykctJFoAkUw+SPTJTGjUNdKscFBrqM7IPnCVu6zihtKYa7TkZS1dkQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.3", - "@vitest/utils": "3.2.3", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -3898,13 +3913,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.3.tgz", - "integrity": "sha512-cP6fIun+Zx8he4rbWvi+Oya6goKQDZK+Yq4hhlggwQBbrlOQ4qtZ+G4nxB6ZnzI9lyIb+JnvyiJnPC2AGbKSPA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.3", + "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -3925,9 +3940,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.3.tgz", - "integrity": "sha512-yFglXGkr9hW/yEXngO+IKMhP0jxyFw2/qys/CK4fFUZnSltD+MU7dVYGrH8rvPcK/O6feXQA+EU33gjaBBbAng==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", "dev": true, "license": "MIT", "dependencies": { @@ -3938,13 +3953,13 @@ } }, "node_modules/@vitest/runner": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.3.tgz", - "integrity": "sha512-83HWYisT3IpMaU9LN+VN+/nLHVBCSIUKJzGxC5RWUOsK1h3USg7ojL+UXQR3b4o4UBIWCYdD2fxuzM7PQQ1u8w==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.3", + "@vitest/utils": "3.2.4", "pathe": "^2.0.3", "strip-literal": "^3.0.0" }, @@ -3953,13 +3968,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.3.tgz", - "integrity": "sha512-9gIVWx2+tysDqUmmM1L0hwadyumqssOL1r8KJipwLx5JVYyxvVRfxvMq7DaWbZZsCqZnu/dZedaZQh4iYTtneA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.3", + "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -3968,9 +3983,9 @@ } }, "node_modules/@vitest/spy": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.3.tgz", - "integrity": "sha512-JHu9Wl+7bf6FEejTCREy+DmgWe+rQKbK+y32C/k5f4TBIAlijhJbRBIRIOCEpVevgRsCQR2iHRUH2/qKVM/plw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", "dev": true, "license": "MIT", "dependencies": { @@ -3981,14 +3996,14 @@ } }, "node_modules/@vitest/utils": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.3.tgz", - "integrity": "sha512-4zFBCU5Pf+4Z6v+rwnZ1HU1yzOKKvDkMXZrymE2PBlbjKJRlrOxbvpfPSvJTGRIwGoahaOGvp+kbCoxifhzJ1Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.3", - "loupe": "^3.1.3", + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" }, "funding": { @@ -4659,9 +4674,9 @@ } }, "node_modules/bullmq": { - "version": "5.54.2", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.54.2.tgz", - "integrity": "sha512-Qm75wtgKLP1FH92N+l01D1AErX+uLdMlfadvY2XMBmE4gx5qeTbat4b2Zil1U82Ipqn5Vz7kpNE0cgw/hznAGA==", + "version": "5.54.3", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.54.3.tgz", + "integrity": "sha512-MVK2pOkB3hvrIcubwI8dS4qWHJLNKakKPpgRBTw91sIpPZArmvZ4t2hvryyEaJXJbAS/JHd6pKYOUd+RGRkWQQ==", "license": "MIT", "dependencies": { "cron-parser": "^4.9.0", @@ -4974,9 +4989,9 @@ } }, "node_modules/cloudinary": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-2.6.1.tgz", - "integrity": "sha512-Dt7o3p4VzxYoTi+EqWkVQmGy6WiXIyMcG5Gbr9kPR/EQ+jZa+3FFzlDKfDx1uDsaB1aTR1gYeO6wZqrgLFaByQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-2.7.0.tgz", + "integrity": "sha512-qrqDn31+qkMCzKu1GfRpzPNAO86jchcNwEHCUiqvPHNSFqu7FTNF9FuAkBUyvM1CFFgFPu64NT0DyeREwLwK0w==", "license": "MIT", "dependencies": { "lodash": "^4.17.21", @@ -6734,9 +6749,9 @@ } }, "node_modules/fdir": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz", - "integrity": "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -8766,9 +8781,9 @@ } }, "node_modules/loupe": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", - "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz", + "integrity": "sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==", "dev": true, "license": "MIT" }, @@ -9765,9 +9780,9 @@ } }, "node_modules/postcss": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", - "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -10344,13 +10359,13 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.42.0.tgz", - "integrity": "sha512-LW+Vse3BJPyGJGAJt1j8pWDKPd73QM8cRXYK1IxOBgL2AGLu7Xd2YOW0M2sLUBCkF5MshXXtMApyEAEzMVMsnw==", + "version": "4.44.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.0.tgz", + "integrity": "sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.7" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -10360,26 +10375,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.42.0", - "@rollup/rollup-android-arm64": "4.42.0", - "@rollup/rollup-darwin-arm64": "4.42.0", - "@rollup/rollup-darwin-x64": "4.42.0", - "@rollup/rollup-freebsd-arm64": "4.42.0", - "@rollup/rollup-freebsd-x64": "4.42.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.42.0", - "@rollup/rollup-linux-arm-musleabihf": "4.42.0", - "@rollup/rollup-linux-arm64-gnu": "4.42.0", - "@rollup/rollup-linux-arm64-musl": "4.42.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.42.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.42.0", - "@rollup/rollup-linux-riscv64-gnu": "4.42.0", - "@rollup/rollup-linux-riscv64-musl": "4.42.0", - "@rollup/rollup-linux-s390x-gnu": "4.42.0", - "@rollup/rollup-linux-x64-gnu": "4.42.0", - "@rollup/rollup-linux-x64-musl": "4.42.0", - "@rollup/rollup-win32-arm64-msvc": "4.42.0", - "@rollup/rollup-win32-ia32-msvc": "4.42.0", - "@rollup/rollup-win32-x64-msvc": "4.42.0", + "@rollup/rollup-android-arm-eabi": "4.44.0", + "@rollup/rollup-android-arm64": "4.44.0", + "@rollup/rollup-darwin-arm64": "4.44.0", + "@rollup/rollup-darwin-x64": "4.44.0", + "@rollup/rollup-freebsd-arm64": "4.44.0", + "@rollup/rollup-freebsd-x64": "4.44.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.44.0", + "@rollup/rollup-linux-arm-musleabihf": "4.44.0", + "@rollup/rollup-linux-arm64-gnu": "4.44.0", + "@rollup/rollup-linux-arm64-musl": "4.44.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.44.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.44.0", + "@rollup/rollup-linux-riscv64-gnu": "4.44.0", + "@rollup/rollup-linux-riscv64-musl": "4.44.0", + "@rollup/rollup-linux-s390x-gnu": "4.44.0", + "@rollup/rollup-linux-x64-gnu": "4.44.0", + "@rollup/rollup-linux-x64-musl": "4.44.0", + "@rollup/rollup-win32-arm64-msvc": "4.44.0", + "@rollup/rollup-win32-ia32-msvc": "4.44.0", + "@rollup/rollup-win32-x64-msvc": "4.44.0", "fsevents": "~2.3.2" } }, @@ -11760,9 +11775,9 @@ } }, "node_modules/tinypool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.0.tgz", - "integrity": "sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "dev": true, "license": "MIT", "engines": { @@ -12198,9 +12213,9 @@ } }, "node_modules/vite-node": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.3.tgz", - "integrity": "sha512-gc8aAifGuDIpZHrPjuHyP4dpQmYXqWw7D1GmDnWeNWP654UEXzVfQ5IHPSK5HaHkwB/+p1atpYpSdw/2kOv8iQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", "dev": true, "license": "MIT", "dependencies": { @@ -12221,20 +12236,20 @@ } }, "node_modules/vitest": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.3.tgz", - "integrity": "sha512-E6U2ZFXe3N/t4f5BwUaVCKRLHqUpk1CBWeMh78UT4VaTPH/2dyvH6ALl29JTovEPu9dVKr/K/J4PkXgrMbw4Ww==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.3", - "@vitest/mocker": "3.2.3", - "@vitest/pretty-format": "^3.2.3", - "@vitest/runner": "3.2.3", - "@vitest/snapshot": "3.2.3", - "@vitest/spy": "3.2.3", - "@vitest/utils": "3.2.3", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", @@ -12245,10 +12260,10 @@ "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", - "tinypool": "^1.1.0", + "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.3", + "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "bin": { @@ -12264,8 +12279,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.3", - "@vitest/ui": "3.2.3", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, diff --git a/package.json b/package.json index 951fc588a..656a0c36c 100644 --- a/package.json +++ b/package.json @@ -16,14 +16,14 @@ "job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js" }, "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.830.0", + "@aws-sdk/client-cloudwatch-logs": "^3.832.0", "@aws-sdk/client-elasticache": "^3.830.0", - "@aws-sdk/client-s3": "^3.830.0", + "@aws-sdk/client-s3": "^3.832.0", "@aws-sdk/client-secrets-manager": "^3.830.0", "@aws-sdk/client-ses": "^3.830.0", "@aws-sdk/credential-provider-node": "^3.830.0", - "@aws-sdk/lib-storage": "^3.830.0", - "@aws-sdk/s3-request-presigner": "^3.830.0", + "@aws-sdk/lib-storage": "^3.832.0", + "@aws-sdk/s3-request-presigner": "^3.832.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -31,9 +31,9 @@ "aws4": "^1.13.2", "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.54.2", + "bullmq": "^5.54.3", "chart.js": "^4.5.0", - "cloudinary": "^2.6.1", + "cloudinary": "^2.7.0", "compression": "^1.8.0", "cookie-parser": "^1.4.7", "cors": "^2.8.5", @@ -81,6 +81,6 @@ "p-limit": "^3.1.0", "prettier": "^3.5.3", "supertest": "^7.1.1", - "vitest": "^3.2.3" + "vitest": "^3.2.4" } } diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index 03a68ca0d..661ef40fd 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -1,3 +1,8 @@ +// no-dd-sa:javascript-code-style/assignment-name +// The above disables camel case inspection for the file, +// CamelCase is used for GraphQL and database fields, and it is easier +// to maintain consistency with the existing codebase. + const xml2js = require("xml2js"); const client = require("../../graphql-client/graphql-client").client; @@ -21,13 +26,15 @@ const INSERT_PARTS_ORDERS = ` /** * Handles incoming VehicleDamageEstimateAddRq XML, - * parses every known field, inserts a Job + nested JobLines, + * parses every known field (including estimator, adjuster, + * repair facility), nests Vehicle and JobLines inserts, * then any PartsOrders (grouped per SupplierRefNum). */ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const { logger } = req; const xml = req.body; + // ── PARSE XML ──────────────────────────────────────────────────────────────── let payload; try { payload = await xml2js.parseStringPromise(xml, { @@ -37,6 +44,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { logger.log("parts-xml-parse", "debug", null, null, { success: true }); } catch (err) { logger.log("parts-xml-parse-error", "error", null, null, { error: err }); + console.dir(err); return res.status(400).send("Invalid XML"); } @@ -47,89 +55,118 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { } try { - // - // ── SHOP ID ─────────────────────────────────────────────────────────────────── - // - // pulled directly from in your XML - // + // ── SHOP ID ──────────────────────────────────────────────────────────────── const shopId = rq.ShopID || rq.shopId; if (!shopId) { throw { status: 400, message: "Missing in XML" }; } - // - // ── DOCUMENT INFO ───────────────────────────────────────────────────────────── - // - const { RqUID, RefClaimNum } = rq; + // ── DOCUMENT INFO ────────────────────────────────────────────────────────── + const { RefClaimNum } = rq; const doc = rq.DocumentInfo || {}; const comment = doc.Comment || null; - const transmitDate = doc.TransmitDateTime || null; + const date_exported = doc.TransmitDateTime || null; - // capture all entries const docVers = doc.DocumentVer ? (Array.isArray(doc.DocumentVer) ? doc.DocumentVer : [doc.DocumentVer]) : []; const documentVersions = docVers.map((dv) => ({ code: dv.DocumentVerCode, num: dv.DocumentVerNum })); - // pull out any OtherReferenceInfo (RO Number + Job UUID) - const otherRefs = doc.ReferenceInfo?.OtherReferenceInfo - ? Array.isArray(doc.ReferenceInfo.OtherReferenceInfo) - ? doc.ReferenceInfo.OtherReferenceInfo - : [doc.ReferenceInfo.OtherReferenceInfo] - : []; - const originalRoNumber = otherRefs.find((r) => r.OtherReferenceName === "RO Number")?.OtherRefNum; - const originalJobUuid = otherRefs.find((r) => r.OtherReferenceName === "Job UUID")?.OtherRefNum; - - // - // ── EVENT INFO ──────────────────────────────────────────────────────────────── - // + // ── EVENT INFO ────────────────────────────────────────────────────────────── const ev = rq.EventInfo || {}; - const assignEv = ev.AssignmentEvent || {}; - const assignmentEvent = { - number: assignEv.AssignmentNumber, - type: assignEv.AssignmentType, - date: assignEv.AssignmentDate, - createdAt: assignEv.CreateDateTime - }; - const repairEv = ev.RepairEvent || {}; - const scheduled_completion = repairEv.TargetCompletionDateTime || null; - const scheduled_in = repairEv.RequestedPickUpDateTime || null; + const asgn = ev.AssignmentEvent || {}; + const asgn_no = asgn.AssignmentNumber || null; + const asgn_type = asgn.AssignmentType || null; + const asgn_date = asgn.AssignmentDate || null; + const scheduled_completion = ev.RepairEvent?.TargetCompletionDateTime || null; + const scheduled_in = ev.RepairEvent?.RequestedPickUpDateTime || null; - // - // ── CLAIM INFO ──────────────────────────────────────────────────────────────── - // + // ── CLAIM INFO ────────────────────────────────────────────────────────────── const ci = rq.ClaimInfo || {}; - const clm_no = ci.ClaimNum; - const ClaimStatus = ci.ClaimStatus || null; + const clm_no = ci.ClaimNum || null; + const status = ci.ClaimStatus || null; const policy_no = ci.PolicyInfo?.PolicyNum || null; const ded_amt = parseFloat(ci.PolicyInfo?.CoverageInfo?.Coverage?.DeductibleInfo?.DeductibleAmt || 0); - // if your XML ever has a `` you'd parse it here const clm_total = parseFloat(ci.Cieca_ttl || 0); - // - // ── OWNER ───────────────────────────────────────────────────────────────────── - // - const ownerParty = rq.AdminInfo?.Owner?.Party || {}; - const ownerName = ownerParty.PersonInfo?.PersonName || {}; - const ownerOrg = ownerParty.OrgInfo || {}; - const ownerAddr = ownerParty.PersonInfo?.Communications?.Address || {}; - const ownerComms = ownerParty.ContactInfo?.Communications + // ── ADMIN / OWNER INFO ────────────────────────────────────────────────────── + const admin = rq.AdminInfo || {}; + + // Owner + const ownerParty = admin.Owner?.Party || {}; + const ownr_fn = ownerParty.PersonInfo?.PersonName?.FirstName || null; + const ownr_ln = ownerParty.PersonInfo?.PersonName?.LastName || null; + const ownr_co_nm = ownerParty.OrgInfo?.CompanyName || null; + const adr = ownerParty.PersonInfo?.Communications?.Address || {}; + const ownr_addr1 = adr.Address1 || null; + const ownr_addr2 = adr.Address2 || null; + const ownr_city = adr.City || null; + const ownr_st = adr.StateProvince || null; + const ownr_zip = adr.PostalCode || null; + const ownr_ctry = adr.Country || null; + + const ownrComms = ownerParty.ContactInfo?.Communications ? Array.isArray(ownerParty.ContactInfo.Communications) ? ownerParty.ContactInfo.Communications : [ownerParty.ContactInfo.Communications] : []; - let ownerPhone = null, - ownerEmail = null; - ownerComms.forEach((c) => { - if (c.CommQualifier === "CP") ownerPhone = c.CommPhone; - if (c.CommQualifier === "EM") ownerEmail = c.CommEmail; + let ownr_ph1 = null, + ownr_ph2 = null, + ownr_fax = null, + ownr_ea = null; + ownrComms.forEach((c) => { + if (c.CommQualifier === "CP") ownr_ph1 = c.CommPhone; + if (c.CommQualifier === "WP") ownr_ph2 = c.CommPhone; + if (c.CommQualifier === "FX") ownr_fax = c.CommPhone; + if (c.CommQualifier === "EM") ownr_ea = c.CommEmail; }); - const ownerPrefContact = ownerParty.PreferredContactMethod || null; + const preferred_contact = ownerParty.PreferredContactMethod || null; - // - // ── VEHICLE INFO ────────────────────────────────────────────────────────────── - // + // Estimator → map to est_… fields + const estParty = admin.Estimator?.Party || {}; + const est_fn = estParty.PersonInfo?.PersonName?.FirstName || null; + const est_ln = estParty.PersonInfo?.PersonName?.LastName || null; + const est_aff = admin.Estimator?.Affiliation || null; + const estComms = estParty.ContactInfo?.Communications + ? Array.isArray(estParty.ContactInfo.Communications) + ? estParty.ContactInfo.Communications + : [estParty.ContactInfo.Communications] + : []; + const est_ea = estComms.find((c) => c.CommQualifier === "EM")?.CommEmail || null; + + // Adjuster → map to agt_… fields + const adjParty = admin.Adjuster?.Party || {}; + const agt_ct_fn = adjParty.PersonInfo?.PersonName?.FirstName || null; + const agt_ct_ln = adjParty.PersonInfo?.PersonName?.LastName || null; + const adjComms = adjParty.ContactInfo?.Communications + ? Array.isArray(adjParty.ContactInfo.Communications) + ? adjParty.ContactInfo.Communications + : [adjParty.ContactInfo.Communications] + : []; + const agt_ct_ph = adjComms.find((c) => c.CommQualifier === "CP")?.CommPhone || null; + const agt_ea = adjComms.find((c) => c.CommQualifier === "EM")?.CommEmail || null; + + // Repair Facility → map to servicing_dealer, servicing_dealer_contact + const rfParty = admin.RepairFacility?.Party || {}; + const servicing_dealer = rfParty.OrgInfo?.CompanyName || null; + const rfAdr = rfParty.OrgInfo?.Communications?.Address || {}; + const servicing_dealer_addr1 = rfAdr.Address1 || null; + const servicing_dealer_city = rfAdr.City || null; + const servicing_dealer_st = rfAdr.StateProvince || null; + const servicing_dealer_zip = rfAdr.PostalCode || null; + const servicing_dealer_ctry = rfAdr.Country || null; + const rfComms = rfParty.ContactInfo?.Communications + ? Array.isArray(rfParty.ContactInfo.Communications) + ? rfParty.ContactInfo.Communications + : [rfParty.ContactInfo.Communications] + : []; + const servicing_dealer_contact = + rfComms.find((c) => c.CommQualifier === "WP")?.CommPhone || + rfComms.find((c) => c.CommQualifier === "FX")?.CommPhone || + null; + + // ── VEHICLE INFO (nested relationship) ────────────────────────────────────── const vin = rq.VehicleInfo?.VINInfo?.VINNum || null; const plate_no = rq.VehicleInfo?.License?.LicensePlateNum || null; const plate_st = rq.VehicleInfo?.License?.LicensePlateStateProvince || null; @@ -137,32 +174,44 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const v_model_yr = desc.ModelYear || null; const v_make_desc = desc.MakeDesc || null; const v_model_desc = desc.ModelName || null; + const v_color = rq.VehicleInfo?.Paint?.Exterior?.ColorName || null; const body_style = desc.BodyStyle || null; const engine_desc = desc.EngineDesc || null; const production_date = desc.ProductionDate || null; - const sub_model_desc = desc.SubModelDesc || null; - const fuel_type = desc.FuelType || null; - const v_color = rq.VehicleInfo?.Paint?.Exterior?.ColorName || null; - const drivable = rq.VehicleInfo?.Condition?.DrivableInd === "Y"; + const v_options = desc.SubModelDesc || null; + const v_type = desc.FuelType || null; + const driveable = rq.VehicleInfo?.Condition?.DrivableInd === "Y"; - // - // ── PROFILE & RATES ─────────────────────────────────────────────────────────── - // + const vehicleData = { + shopid: shopId, + vin, + plate_no, + plate_st, + year: v_model_yr, + make: v_make_desc, + model: v_model_desc, + color: v_color, + bstyle: body_style, + engine: engine_desc, + prod_dt: production_date, + options: v_options, + type: v_type, + condition: driveable + }; + + // ── PROFILE & RATES ───────────────────────────────────────────────────────── const rateInfos = rq.ProfileInfo?.RateInfo ? Array.isArray(rq.ProfileInfo.RateInfo) ? rq.ProfileInfo.RateInfo : [rq.ProfileInfo.RateInfo] : []; - const rates = {}; // main { rate_lab, rate_laf, … } - const rateTier = {}; // e.g. { MA2S: [ {tier, pct}, … ] } - const materialCalc = {}; // e.g. { LAR: { CalcMethodCode, CalcMaxHours }, … } - + const rates = {}, + rateTier = {}, + materialCalc = {}; rateInfos.forEach((r) => { - if (!r || !r.RateType) return; - const t = r.RateType; - // main per‐unit rate - if (r.Rate) rates[`rate_${t.toLowerCase()}`] = parseFloat(r.Rate) || 0; - // any tier settings + if (!r.RateType) return; + const t = r.RateType.toLowerCase(); + if (r.Rate) rates[`rate_${t}`] = parseFloat(r.Rate) || 0; if (r.RateTierInfo) { const tiers = Array.isArray(r.RateTierInfo) ? r.RateTierInfo : [r.RateTierInfo]; rateTier[t] = tiers.map((ti) => ({ @@ -170,15 +219,12 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { pct: parseFloat(ti.Percentage) || 0 })); } - // any material‐calc limits if (r.MaterialCalcSettings) { materialCalc[t] = r.MaterialCalcSettings; } }); - // - // ── DAMAGE LINES → joblinesData ───────────────────────────────────────────── - // + // ── DAMAGE LINES → joblinesData ──────────────────────────────────────────── const damageLines = Array.isArray(rq.DamageLineInfo) ? rq.DamageLineInfo : [rq.DamageLineInfo]; const joblinesData = damageLines.map((line) => ({ line_no: parseInt(line.LineNum, 10), @@ -190,25 +236,21 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { line_desc: line.LineDesc || null, // parts - part_type: line.PartInfo.PartType || null, - part_qty: parseInt(line.PartInfo.Quantity || 0, 10), - db_price: parseFloat(line.PartInfo.PartPrice || 0), - act_price: parseFloat(line.PartInfo.PartPrice || 0), - oem_partno: line.PartInfo.OEMPartNum || null, + part_type: line.PartInfo?.PartType || null, + part_qty: parseInt(line.PartInfo?.Quantity || 0, 10), + db_price: parseFloat(line.PartInfo?.PartPrice || 0), + act_price: parseFloat(line.PartInfo?.PartPrice || 0), + oem_partno: line.PartInfo?.OEMPartNum || null, - // non-OEM block - non_oem_part_num: line.PartInfo?.NonOEM?.NonOEMPartNum || null, - non_oem_part_price: parseFloat(line.PartInfo?.NonOEM?.NonOEMPartPrice || 0), - supplier_ref_num: line.PartInfo?.NonOEM?.SupplierRefNum || null, - part_selected_ind: line.PartInfo?.NonOEM?.PartSelectedInd === "1", + // non-OEM → not persisted at jobline level - after_market_usage: line.PartInfo.AfterMarketUsage || null, - certification_type: line.PartInfo.CertificationType || null, - tax_part: line.PartInfo.TaxableInd === "1", - glass_flag: line.PartInfo.GlassPartInd === "1", + after_market_usage: line.PartInfo?.AfterMarketUsage || null, + certification_type: line.PartInfo?.CertificationType || null, + tax_part: line.PartInfo?.TaxableInd === "1", + glass_flag: line.PartInfo?.GlassPartInd === "1", price_j: line.PriceJudgmentInd === "1", price_inc: line.PriceInclInd === "1", - order_by_application_ind: String(line.PartInfo.OrderByApplicationInd).toLowerCase() === "true", + order_by_application_ind: String(line.PartInfo?.OrderByApplicationInd).toLowerCase() === "true", // labor mod_lbr_ty: line.LaborInfo?.LaborType || null, @@ -216,103 +258,101 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { lbr_op: line.LaborInfo?.LaborOperation || null, lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), - // linkage & memo parent_line_no: line.ParentLineNum ? parseInt(line.ParentLineNum, 10) : null, notes: line.LineMemo || null })); - // - // ── BUILD & INSERT THE JOB ─────────────────────────────────────────────────── - // + // ── BUILD & INSERT THE JOB ────────────────────────────────────────────────── const jobInput = { shopid: shopId, - - // identifiers ro_number: RefClaimNum, - original_ro_number: originalRoNumber, - original_job_uuid: originalJobUuid, - // claim & policy clm_no, - status: ClaimStatus, + status, clm_total, policy_no, ded_amt, - // timestamps & comments comment, - date_exported: transmitDate, + date_exported, + asgn_no, + asgn_type, + asgn_date, + scheduled_completion, + scheduled_in, - // owner - ownr_fn: ownerName.FirstName || null, - ownr_ln: ownerName.LastName || null, - ownr_co_nm: ownerOrg.CompanyName || null, - ownr_addr1: ownerAddr.Address1 || null, - ownr_city: ownerAddr.City || null, - ownr_st: ownerAddr.StateProvince || null, - ownr_zip: ownerAddr.PostalCode || null, - ownr_country: ownerAddr.Country || null, - ownr_ph1: ownerPhone, - ownr_ea: ownerEmail, - ownr_pref_contact: ownerPrefContact, + ownr_fn, + ownr_ln, + ownr_co_nm, + ownr_addr1, + ownr_addr2, + ownr_city, + ownr_st, + ownr_zip, + ownr_ctry, + ownr_ph1, + ownr_ph2, + ownr_fax, + ownr_ea, + preferred_contact, - // vehicle - v_vin: vin, - plate_no, - plate_st, - v_model_yr, - v_make_desc, - v_model_desc, - v_color, - body_style, - engine_desc, - production_date, - sub_model_desc, - fuel_type, - drivable, + est_co_id: est_aff, + est_ct_fn: est_fn, + est_ct_ln: est_ln, + est_ea, + + agt_ct_fn, + agt_ct_ln, + agt_ct_ph, + agt_ea, + + servicing_dealer, + servicing_dealer_addr1, + servicing_dealer_city, + servicing_dealer_st, + servicing_dealer_zip, + servicing_dealer_ctry, + servicing_dealer_contact, - // labor & material rates ...rates, - // everything extra in one JSON column production_vars: { - rqUid: RqUID, documentVersions, - assignmentEvent, - scheduled_completion, - scheduled_in, rateTier, materialCalc }, - // nested joblines + vehicle: { data: vehicleData }, joblines: { data: joblinesData } }; logger.log("parts-insert-job", "debug", null, null, { jobInput }); - const jobResp = await client.request(INSERT_JOB_WITH_LINES, { - job: jobInput - }); - const newJob = jobResp.insert_jobs_one; + const { insert_jobs_one: newJob } = await client.request(INSERT_JOB_WITH_LINES, { job: jobInput }); const jobId = newJob.id; logger.log("parts-job-created", "info", jobId, null); - // // ── BUILD & INSERT PARTS ORDERS ──────────────────────────────────────────── - // - // group lines by their SupplierRefNum - const insertedMap = newJob.joblines.reduce((m, ln) => { - m[ln.unq_seq] = ln.id; - return m; + const seqToId = newJob.joblines.reduce((map, ln) => { + map[ln.unq_seq] = ln.id; + return map; }, {}); + + const currentDate = new Date().toISOString().slice(0, 10); + // TODO: we should not need to capture the order status from the XML, + const defaultStatus = process.env.DEFAULT_PARTS_ORDER_STATUS || ""; + + // TODO: This will be the username of the bodyshop user used for the integration. + const userEmail = req.headers["x-hasura-user-id"] || "system@example.com"; + + // group by vendor const poGroups = {}; damageLines.forEach((line) => { - const pt = line.PartInfo.PartType; - const qty = parseInt(line.PartInfo.Quantity || 0, 10); + const pt = line.PartInfo?.PartType; + const qty = parseInt(line.PartInfo?.Quantity || 0, 10); if (["PAN", "PAC", "PAM", "PAA"].includes(pt) && qty > 0) { - const vendorid = line.PartInfo?.NonOEM?.SupplierRefNum || process.env.DEFAULT_VENDOR_ID; - if (!poGroups[vendorid]) poGroups[vendorid] = []; - poGroups[vendorid].push({ + // TODO: We should not need to capture the vendor ID from the XML + const vid = line.PartInfo?.NonOEM?.SupplierRefNum || process.env.DEFAULT_VENDOR_ID || null; + (poGroups[vid] = poGroups[vid] || []).push({ line, unq_seq: parseInt(line.UniqueSequenceNum, 10) }); @@ -323,18 +363,27 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { jobid: jobId, vendorid, order_number: `${clm_no}-${entries[0].line.LineNum}`, + order_date: currentDate, + orderedby: "XML-API", + user_email: userEmail, + status: defaultStatus, parts_order_lines: { - data: entries.map(({ line, unq_seq }) => ({ - job_line_id: insertedMap[unq_seq], - part_type: line.PartInfo.PartType, - quantity: parseInt(line.PartInfo.Quantity || 0, 10), - act_price: parseFloat(line.PartInfo.PartPrice || 0), - db_price: parseFloat(line.PartInfo.PartPrice || 0), - line_desc: line.LineDesc, - non_oem_part_num: line.PartInfo?.NonOEM?.NonOEMPartNum || null, - non_oem_part_price: parseFloat(line.PartInfo?.NonOEM?.NonOEMPartPrice || 0), - part_selected_ind: line.PartInfo?.NonOEM?.PartSelectedInd === "1" - })) + data: entries.map(({ line, unq_seq }) => { + const pi = line.PartInfo || {}; + const nonOEM = pi.NonOEM || {}; + return { + job_line_id: seqToId[unq_seq], + line_desc: line.LineDesc || null, + oem_partno: pi.OEMPartNum || null, + db_price: parseFloat(pi.PartPrice || 0), + act_price: parseFloat(pi.PartPrice || 0), + line_remarks: line.LineMemo || null, + quantity: parseInt(pi.Quantity || 1, 10), + part_type: pi.PartType || null, + cost: nonOEM.NonOEMPartPrice ? parseFloat(nonOEM.NonOEMPartPrice) : null, + cm_received: null + }; + }) } })); diff --git a/server/integrations/partsManagement/sampleBody.xml b/server/integrations/partsManagement/sampleBody.xml new file mode 100644 index 000000000..53926ddbe --- /dev/null +++ b/server/integrations/partsManagement/sampleBody.xml @@ -0,0 +1,340 @@ + + + + 12345 + + + 17e5ccc4-cdfb-4cf3-a08d-ecfa8d145d6f + CLM123 + + + + + SV + 1 + + + VN + 1 + + + + RO Number + RO-987 + + + Job UUID + abcde-12345-uuid + + + Include OEM where possible + 2025-06-18T12:00:00Z + + + + + + 1 + Estimate + 2025-06-18T11:30:00Z + 2025-06-18T11:29:00Z + + + 2025-06-25T17:00:00Z + 2025-06-22T09:00:00Z + + + + + + CLM123 + Open + + POL456 + + + + 500.00 + + + + + 1500.50 + + + + + + + + + + John + Doe + + + AL +
+ 100 Main St + Metropolis + NY + 10001 + USA +
+
+
+ + + CP + 5551234567 + + + EM + john.doe@example.com + + +
+
+ + + + + + + Jane + Smith + + + + + EM + jane.smith@example.com + + + + EST001 + + + + + + + AutoFix + + AL +
+ 200 Repair Rd + Mechanicsburg + PA + 17055 + USA +
+
+
+ + + WP + 5559876543 + + + FX + 5559876544 + + +
+
+ + + + + + + Alice + Johnson + + + + + + + + + + PartsRUs + + + + + + + + + XmlSender + + + + + + + + + ThirdPartyAdmin + + + TPA + +
+ + + + + LABOR + 100.0 + + 1 + 50.0 + + + + + + + + 1HGCM82633A004352 + + + ABC1234 + CA + + + 2020 + Honda + Accord + Sedan + 2.0L + 2019-10-10 + Sport + Gasoline + + + + Blue + + + + Y + + + + + + 1 + 1001 + 0 + 0 + 1 + 0 + Draft + Front Bumper + + PAA + 1 + 200.00 + OEM123 + + NONOEM123 + 180.00 + VEND1 + 1 + + 1 + OV + C + 0 + 0 + 0 + false + + + LAB + OP1 + 2.5 + 250.00 + + Replace bumper + + + + + 2 + 1002 + 0 + 0 + 0 + 0 + Draft + Windshield + + PAG + 1 + 572.06 + 5610104082 + + 5610104082 + 572.06 + VEND2 + 1 + + 1 + NU + 1 + 0 + 0 + false + + + LAB + OP11 + 3.7 + 370.00 + + Replace windshield + + + + + 3 + 1003 + 0 + 0 + 1 + 0 + Draft + Sublet Upholstery Repair + + UpholsteryCo + 200.00 + 2.0 + + Stitching match required + + + + + 4 + 1004 + 0 + 0 + 1 + 0 + Draft + Dent Repair Door + + LAD + OP3 + 1.5 + 150.00 + + Requires touch-up + +
diff --git a/server/routes/intergrationRoutes.js b/server/routes/intergrationRoutes.js index 38b8d44fb..4af112a97 100644 --- a/server/routes/intergrationRoutes.js +++ b/server/routes/intergrationRoutes.js @@ -1,5 +1,6 @@ const express = require("express"); const router = express.Router(); +const bodyParser = require("body-parser"); // Add body-parser dependency // Pull secrets from env const { VSSTA_INTEGRATION_SECRET, PARTS_MANAGEMENT_INTEGRATION_SECRET } = process.env; @@ -20,12 +21,15 @@ if (typeof PARTS_MANAGEMENT_INTEGRATION_SECRET === "string" && PARTS_MANAGEMENT_ const partsManagementIntegrationMiddleware = require("../middleware/partsManagementIntegrationMiddleware"); const partsManagementVehicleDamageEstimateAddRq = require("../integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq"); - router.post("/parts-management/provision", partsManagementIntegrationMiddleware, partsManagementProvisioning); + // Add XML parsing middleware for the VehicleDamageEstimateAddRq route router.post( "/parts-management/VehicleDamageEstimateAddRq", + bodyParser.raw({ type: "application/xml", limit: "10mb" }), // Parse XML body partsManagementIntegrationMiddleware, partsManagementVehicleDamageEstimateAddRq ); + + router.post("/parts-management/provision", partsManagementIntegrationMiddleware, partsManagementProvisioning); } else { console.warn("PARTS_MANAGEMENT_INTEGRATION_SECRET is not set — skipping /parts-management/provision route"); } From dc3e9b722613565c7e260803425512919b89c818 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 20 Jun 2025 13:25:48 -0400 Subject: [PATCH 05/98] feature/IO-3255-simplified-parts-management - Checkpoint --- ...rtsManagementVehicleDamageEstimateAddRq.js | 59 ++++++++++--------- .../partsManagement/sampleBody.xml | 4 +- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index 661ef40fd..4ffe37546 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -154,8 +154,8 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const servicing_dealer_addr1 = rfAdr.Address1 || null; const servicing_dealer_city = rfAdr.City || null; const servicing_dealer_st = rfAdr.StateProvince || null; - const servicing_dealer_zip = rfAdr.PostalCode || null; - const servicing_dealer_ctry = rfAdr.Country || null; + // const servicing_dealer_zip = rfAdr.PostalCode || null; + // const servicing_dealer_ctry = rfAdr.Country || null; const rfComms = rfParty.ContactInfo?.Communications ? Array.isArray(rfParty.ContactInfo.Communications) ? rfParty.ContactInfo.Communications @@ -184,19 +184,19 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const vehicleData = { shopid: shopId, - vin, + // vin, plate_no, - plate_st, - year: v_model_yr, - make: v_make_desc, - model: v_model_desc, - color: v_color, - bstyle: body_style, - engine: engine_desc, - prod_dt: production_date, - options: v_options, - type: v_type, - condition: driveable + plate_st + // year: v_model_yr, + // make: v_make_desc + // model: v_model_desc + // color: v_color, + // bstyle: body_style, + // engine: engine_desc + // prod_dt: production_date, + // options: v_options, + // type: v_type, + // condition: driveable }; // ── PROFILE & RATES ───────────────────────────────────────────────────────── @@ -230,8 +230,8 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { line_no: parseInt(line.LineNum, 10), unq_seq: parseInt(line.UniqueSequenceNum, 10), manual_line: line.ManualLineInd === "1", - automated_entry: line.AutomatedEntry === "1", - desc_judgment_ind: line.DescJudgmentInd === "1", + // automated_entry: line.AutomatedEntry === "1", + // desc_judgment_ind: line.DescJudgmentInd === "1", status: line.LineStatusCode || null, line_desc: line.LineDesc || null, @@ -244,13 +244,14 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { // non-OEM → not persisted at jobline level - after_market_usage: line.PartInfo?.AfterMarketUsage || null, - certification_type: line.PartInfo?.CertificationType || null, + // after_market_usage: line.PartInfo?.AfterMarketUsage || null, + // certification_type: line.PartInfo?.CertificationType || null, + // certification_type: line.PartInfo?.CertificationType || null, tax_part: line.PartInfo?.TaxableInd === "1", glass_flag: line.PartInfo?.GlassPartInd === "1", price_j: line.PriceJudgmentInd === "1", price_inc: line.PriceInclInd === "1", - order_by_application_ind: String(line.PartInfo?.OrderByApplicationInd).toLowerCase() === "true", + // order_by_application_ind: String(line.PartInfo?.OrderByApplicationInd).toLowerCase() === "true", // labor mod_lbr_ty: line.LaborInfo?.LaborType || null, @@ -258,7 +259,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { lbr_op: line.LaborInfo?.LaborOperation || null, lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), - parent_line_no: line.ParentLineNum ? parseInt(line.ParentLineNum, 10) : null, + // parent_line_no: line.ParentLineNum ? parseInt(line.ParentLineNum, 10) : null, notes: line.LineMemo || null })); @@ -294,9 +295,9 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { ownr_ph2, ownr_fax, ownr_ea, - preferred_contact, + // preferred_contact, - est_co_id: est_aff, + // est_co_id: est_aff, est_ct_fn: est_fn, est_ct_ln: est_ln, est_ea, @@ -307,14 +308,14 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { agt_ea, servicing_dealer, - servicing_dealer_addr1, - servicing_dealer_city, - servicing_dealer_st, - servicing_dealer_zip, - servicing_dealer_ctry, + // servicing_dealer_addr1, + // servicing_dealer_city, + // servicing_dealer_st, + // servicing_dealer_zip, + // servicing_dealer_ctry, servicing_dealer_contact, - ...rates, + // ...rates, production_vars: { documentVersions, @@ -362,7 +363,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const partsOrders = Object.entries(poGroups).map(([vendorid, entries]) => ({ jobid: jobId, vendorid, - order_number: `${clm_no}-${entries[0].line.LineNum}`, + order_number: `${entries[0].line.LineNum}`, order_date: currentDate, orderedby: "XML-API", user_email: userEmail, diff --git a/server/integrations/partsManagement/sampleBody.xml b/server/integrations/partsManagement/sampleBody.xml index 53926ddbe..b643f032c 100644 --- a/server/integrations/partsManagement/sampleBody.xml +++ b/server/integrations/partsManagement/sampleBody.xml @@ -1,11 +1,11 @@ - 12345 + 71f8494c-89f0-43e0-8eb2-820b52d723bc 17e5ccc4-cdfb-4cf3-a08d-ecfa8d145d6f - CLM123 + 200 From 79bf30b299cf52e4499144efd09c8b94b2ea6af5 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 20 Jun 2025 13:30:49 -0400 Subject: [PATCH 06/98] feature/IO-3255-simplified-parts-management - Checkpoint --- ...rtsManagementVehicleDamageEstimateAddRq.js | 227 ++---------------- 1 file changed, 16 insertions(+), 211 deletions(-) diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index 4ffe37546..2eadc17ee 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -16,20 +16,6 @@ const INSERT_JOB_WITH_LINES = ` } `; -const INSERT_PARTS_ORDERS = ` - mutation InsertPartsOrders($po: [parts_orders_insert_input!]!) { - insert_parts_orders(objects: $po) { - returning { id order_number } - } - } -`; - -/** - * Handles incoming VehicleDamageEstimateAddRq XML, - * parses every known field (including estimator, adjuster, - * repair facility), nests Vehicle and JobLines inserts, - * then any PartsOrders (grouped per SupplierRefNum). - */ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const { logger } = req; const xml = req.body; @@ -91,10 +77,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const clm_total = parseFloat(ci.Cieca_ttl || 0); // ── ADMIN / OWNER INFO ────────────────────────────────────────────────────── - const admin = rq.AdminInfo || {}; - - // Owner - const ownerParty = admin.Owner?.Party || {}; + const ownerParty = rq.AdminInfo?.Owner?.Party || {}; const ownr_fn = ownerParty.PersonInfo?.PersonName?.FirstName || null; const ownr_ln = ownerParty.PersonInfo?.PersonName?.LastName || null; const ownr_co_nm = ownerParty.OrgInfo?.CompanyName || null; @@ -123,135 +106,32 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { }); const preferred_contact = ownerParty.PreferredContactMethod || null; - // Estimator → map to est_… fields - const estParty = admin.Estimator?.Party || {}; - const est_fn = estParty.PersonInfo?.PersonName?.FirstName || null; - const est_ln = estParty.PersonInfo?.PersonName?.LastName || null; - const est_aff = admin.Estimator?.Affiliation || null; - const estComms = estParty.ContactInfo?.Communications - ? Array.isArray(estParty.ContactInfo.Communications) - ? estParty.ContactInfo.Communications - : [estParty.ContactInfo.Communications] - : []; - const est_ea = estComms.find((c) => c.CommQualifier === "EM")?.CommEmail || null; - - // Adjuster → map to agt_… fields - const adjParty = admin.Adjuster?.Party || {}; - const agt_ct_fn = adjParty.PersonInfo?.PersonName?.FirstName || null; - const agt_ct_ln = adjParty.PersonInfo?.PersonName?.LastName || null; - const adjComms = adjParty.ContactInfo?.Communications - ? Array.isArray(adjParty.ContactInfo.Communications) - ? adjParty.ContactInfo.Communications - : [adjParty.ContactInfo.Communications] - : []; - const agt_ct_ph = adjComms.find((c) => c.CommQualifier === "CP")?.CommPhone || null; - const agt_ea = adjComms.find((c) => c.CommQualifier === "EM")?.CommEmail || null; - - // Repair Facility → map to servicing_dealer, servicing_dealer_contact - const rfParty = admin.RepairFacility?.Party || {}; - const servicing_dealer = rfParty.OrgInfo?.CompanyName || null; - const rfAdr = rfParty.OrgInfo?.Communications?.Address || {}; - const servicing_dealer_addr1 = rfAdr.Address1 || null; - const servicing_dealer_city = rfAdr.City || null; - const servicing_dealer_st = rfAdr.StateProvince || null; - // const servicing_dealer_zip = rfAdr.PostalCode || null; - // const servicing_dealer_ctry = rfAdr.Country || null; - const rfComms = rfParty.ContactInfo?.Communications - ? Array.isArray(rfParty.ContactInfo.Communications) - ? rfParty.ContactInfo.Communications - : [rfParty.ContactInfo.Communications] - : []; - const servicing_dealer_contact = - rfComms.find((c) => c.CommQualifier === "WP")?.CommPhone || - rfComms.find((c) => c.CommQualifier === "FX")?.CommPhone || - null; - // ── VEHICLE INFO (nested relationship) ────────────────────────────────────── - const vin = rq.VehicleInfo?.VINInfo?.VINNum || null; - const plate_no = rq.VehicleInfo?.License?.LicensePlateNum || null; - const plate_st = rq.VehicleInfo?.License?.LicensePlateStateProvince || null; const desc = rq.VehicleInfo?.VehicleDesc || {}; - const v_model_yr = desc.ModelYear || null; - const v_make_desc = desc.MakeDesc || null; - const v_model_desc = desc.ModelName || null; - const v_color = rq.VehicleInfo?.Paint?.Exterior?.ColorName || null; - const body_style = desc.BodyStyle || null; - const engine_desc = desc.EngineDesc || null; - const production_date = desc.ProductionDate || null; - const v_options = desc.SubModelDesc || null; - const v_type = desc.FuelType || null; - const driveable = rq.VehicleInfo?.Condition?.DrivableInd === "Y"; - const vehicleData = { shopid: shopId, - // vin, - plate_no, - plate_st - // year: v_model_yr, - // make: v_make_desc - // model: v_model_desc - // color: v_color, - // bstyle: body_style, - // engine: engine_desc - // prod_dt: production_date, - // options: v_options, - // type: v_type, - // condition: driveable + plate_no: rq.VehicleInfo?.License?.LicensePlateNum || null, + plate_st: rq.VehicleInfo?.License?.LicensePlateStateProvince || null }; - // ── PROFILE & RATES ───────────────────────────────────────────────────────── - const rateInfos = rq.ProfileInfo?.RateInfo - ? Array.isArray(rq.ProfileInfo.RateInfo) - ? rq.ProfileInfo.RateInfo - : [rq.ProfileInfo.RateInfo] - : []; - const rates = {}, - rateTier = {}, - materialCalc = {}; - rateInfos.forEach((r) => { - if (!r.RateType) return; - const t = r.RateType.toLowerCase(); - if (r.Rate) rates[`rate_${t}`] = parseFloat(r.Rate) || 0; - if (r.RateTierInfo) { - const tiers = Array.isArray(r.RateTierInfo) ? r.RateTierInfo : [r.RateTierInfo]; - rateTier[t] = tiers.map((ti) => ({ - tier: ti.TierNum, - pct: parseFloat(ti.Percentage) || 0 - })); - } - if (r.MaterialCalcSettings) { - materialCalc[t] = r.MaterialCalcSettings; - } - }); - // ── DAMAGE LINES → joblinesData ──────────────────────────────────────────── const damageLines = Array.isArray(rq.DamageLineInfo) ? rq.DamageLineInfo : [rq.DamageLineInfo]; const joblinesData = damageLines.map((line) => ({ line_no: parseInt(line.LineNum, 10), unq_seq: parseInt(line.UniqueSequenceNum, 10), - manual_line: line.ManualLineInd === "1", - // automated_entry: line.AutomatedEntry === "1", - // desc_judgment_ind: line.DescJudgmentInd === "1", status: line.LineStatusCode || null, line_desc: line.LineDesc || null, - // parts + // parts (only fields for jobline table) part_type: line.PartInfo?.PartType || null, part_qty: parseInt(line.PartInfo?.Quantity || 0, 10), db_price: parseFloat(line.PartInfo?.PartPrice || 0), act_price: parseFloat(line.PartInfo?.PartPrice || 0), oem_partno: line.PartInfo?.OEMPartNum || null, - - // non-OEM → not persisted at jobline level - - // after_market_usage: line.PartInfo?.AfterMarketUsage || null, - // certification_type: line.PartInfo?.CertificationType || null, - // certification_type: line.PartInfo?.CertificationType || null, tax_part: line.PartInfo?.TaxableInd === "1", glass_flag: line.PartInfo?.GlassPartInd === "1", price_j: line.PriceJudgmentInd === "1", price_inc: line.PriceInclInd === "1", - // order_by_application_ind: String(line.PartInfo?.OrderByApplicationInd).toLowerCase() === "true", // labor mod_lbr_ty: line.LaborInfo?.LaborType || null, @@ -259,7 +139,6 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { lbr_op: line.LaborInfo?.LaborOperation || null, lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), - // parent_line_no: line.ParentLineNum ? parseInt(line.ParentLineNum, 10) : null, notes: line.LineMemo || null })); @@ -267,13 +146,11 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const jobInput = { shopid: shopId, ro_number: RefClaimNum, - clm_no, status, clm_total, policy_no, ded_amt, - comment, date_exported, asgn_no, @@ -297,34 +174,13 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { ownr_ea, // preferred_contact, - // est_co_id: est_aff, - est_ct_fn: est_fn, - est_ct_ln: est_ln, - est_ea, - - agt_ct_fn, - agt_ct_ln, - agt_ct_ph, - agt_ea, - - servicing_dealer, - // servicing_dealer_addr1, - // servicing_dealer_city, - // servicing_dealer_st, - // servicing_dealer_zip, - // servicing_dealer_ctry, - servicing_dealer_contact, - - // ...rates, + // nest vehicle & joblines + vehicle: { data: vehicleData }, + joblines: { data: joblinesData }, production_vars: { - documentVersions, - rateTier, - materialCalc - }, - - vehicle: { data: vehicleData }, - joblines: { data: joblinesData } + documentVersions + } }; logger.log("parts-insert-job", "debug", null, null, { jobInput }); @@ -332,69 +188,18 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const jobId = newJob.id; logger.log("parts-job-created", "info", jobId, null); - // ── BUILD & INSERT PARTS ORDERS ──────────────────────────────────────────── + /* + // ── PARTS ORDERS ───────────────────────────────────────────────────────── + // The integration no longer requires parts_orders, + // all related logic is commented out. + const seqToId = newJob.joblines.reduce((map, ln) => { map[ln.unq_seq] = ln.id; return map; }, {}); - const currentDate = new Date().toISOString().slice(0, 10); - // TODO: we should not need to capture the order status from the XML, - const defaultStatus = process.env.DEFAULT_PARTS_ORDER_STATUS || ""; - - // TODO: This will be the username of the bodyshop user used for the integration. - const userEmail = req.headers["x-hasura-user-id"] || "system@example.com"; - - // group by vendor - const poGroups = {}; - damageLines.forEach((line) => { - const pt = line.PartInfo?.PartType; - const qty = parseInt(line.PartInfo?.Quantity || 0, 10); - if (["PAN", "PAC", "PAM", "PAA"].includes(pt) && qty > 0) { - // TODO: We should not need to capture the vendor ID from the XML - const vid = line.PartInfo?.NonOEM?.SupplierRefNum || process.env.DEFAULT_VENDOR_ID || null; - (poGroups[vid] = poGroups[vid] || []).push({ - line, - unq_seq: parseInt(line.UniqueSequenceNum, 10) - }); - } - }); - - const partsOrders = Object.entries(poGroups).map(([vendorid, entries]) => ({ - jobid: jobId, - vendorid, - order_number: `${entries[0].line.LineNum}`, - order_date: currentDate, - orderedby: "XML-API", - user_email: userEmail, - status: defaultStatus, - parts_order_lines: { - data: entries.map(({ line, unq_seq }) => { - const pi = line.PartInfo || {}; - const nonOEM = pi.NonOEM || {}; - return { - job_line_id: seqToId[unq_seq], - line_desc: line.LineDesc || null, - oem_partno: pi.OEMPartNum || null, - db_price: parseFloat(pi.PartPrice || 0), - act_price: parseFloat(pi.PartPrice || 0), - line_remarks: line.LineMemo || null, - quantity: parseInt(pi.Quantity || 1, 10), - part_type: pi.PartType || null, - cost: nonOEM.NonOEMPartPrice ? parseFloat(nonOEM.NonOEMPartPrice) : null, - cm_received: null - }; - }) - } - })); - - if (partsOrders.length) { - logger.log("parts-insert-orders", "debug", null, null, { - partsOrders - }); - await client.request(INSERT_PARTS_ORDERS, { po: partsOrders }); - logger.log("parts-orders-created", "info", jobId, null); - } + // ... grouping logic and mutation calls removed ... + */ return res.status(200).json({ success: true, jobId }); } catch (err) { From 3c719020478df138b25d4b222c23e523041c13fe Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 20 Jun 2025 13:48:58 -0400 Subject: [PATCH 07/98] feature/IO-3255-simplified-parts-management - Checkpoint --- ...rtsManagementVehicleDamageEstimateAddRq.js | 194 ++++++++++++------ 1 file changed, 129 insertions(+), 65 deletions(-) diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index 2eadc17ee..acddc6f52 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -1,7 +1,5 @@ // no-dd-sa:javascript-code-style/assignment-name -// The above disables camel case inspection for the file, -// CamelCase is used for GraphQL and database fields, and it is easier -// to maintain consistency with the existing codebase. +// CamelCase is used for GraphQL and database fields. const xml2js = require("xml2js"); const client = require("../../graphql-client/graphql-client").client; @@ -30,7 +28,6 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { logger.log("parts-xml-parse", "debug", null, null, { success: true }); } catch (err) { logger.log("parts-xml-parse-error", "error", null, null, { error: err }); - console.dir(err); return res.status(400).send("Invalid XML"); } @@ -41,23 +38,22 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { } try { - // ── SHOP ID ──────────────────────────────────────────────────────────────── + // ── SHOP & CLAIM IDs ──────────────────────────────────────────────────────── const shopId = rq.ShopID || rq.shopId; - if (!shopId) { - throw { status: 400, message: "Missing in XML" }; - } + if (!shopId) throw { status: 400, message: "Missing in XML" }; + const { RefClaimNum } = rq; // ── DOCUMENT INFO ────────────────────────────────────────────────────────── - const { RefClaimNum } = rq; const doc = rq.DocumentInfo || {}; const comment = doc.Comment || null; const date_exported = doc.TransmitDateTime || null; - - const docVers = doc.DocumentVer ? (Array.isArray(doc.DocumentVer) ? doc.DocumentVer : [doc.DocumentVer]) : []; - const documentVersions = docVers.map((dv) => ({ - code: dv.DocumentVerCode, - num: dv.DocumentVerNum - })); + // capture CIECA ID & totals + const ciecaid = rq.RqUID || null; + const cieca_ttl = parseFloat(rq.Cieca_ttl || 0); + // map DocumentInfo fields to our category/class fields + const cat_no = doc.VendorCode || null; + const category = doc.DocumentType || null; + const classType = doc.DocumentStatus || null; // ── EVENT INFO ────────────────────────────────────────────────────────────── const ev = rq.EventInfo || {}; @@ -65,18 +61,17 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const asgn_no = asgn.AssignmentNumber || null; const asgn_type = asgn.AssignmentType || null; const asgn_date = asgn.AssignmentDate || null; - const scheduled_completion = ev.RepairEvent?.TargetCompletionDateTime || null; const scheduled_in = ev.RepairEvent?.RequestedPickUpDateTime || null; + const scheduled_completion = ev.RepairEvent?.TargetCompletionDateTime || null; - // ── CLAIM INFO ────────────────────────────────────────────────────────────── + // ── CLAIM & POLICY ────────────────────────────────────────────────────────── const ci = rq.ClaimInfo || {}; const clm_no = ci.ClaimNum || null; const status = ci.ClaimStatus || null; const policy_no = ci.PolicyInfo?.PolicyNum || null; const ded_amt = parseFloat(ci.PolicyInfo?.CoverageInfo?.Coverage?.DeductibleInfo?.DeductibleAmt || 0); - const clm_total = parseFloat(ci.Cieca_ttl || 0); - // ── ADMIN / OWNER INFO ────────────────────────────────────────────────────── + // ── OWNER ──────────────────────────────────────────────────────────────────── const ownerParty = rq.AdminInfo?.Owner?.Party || {}; const ownr_fn = ownerParty.PersonInfo?.PersonName?.FirstName || null; const ownr_ln = ownerParty.PersonInfo?.PersonName?.LastName || null; @@ -88,30 +83,89 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const ownr_st = adr.StateProvince || null; const ownr_zip = adr.PostalCode || null; const ownr_ctry = adr.Country || null; - - const ownrComms = ownerParty.ContactInfo?.Communications - ? Array.isArray(ownerParty.ContactInfo.Communications) - ? ownerParty.ContactInfo.Communications - : [ownerParty.ContactInfo.Communications] - : []; - let ownr_ph1 = null, - ownr_ph2 = null, - ownr_fax = null, - ownr_ea = null; - ownrComms.forEach((c) => { + let ownr_ph1; + let ownr_ph2; + let ownr_fax; + let ownr_ea; + (Array.isArray(ownerParty.ContactInfo?.Communications) + ? ownerParty.ContactInfo.Communications + : [ownerParty.ContactInfo?.Communications || {}] + ).forEach((c) => { if (c.CommQualifier === "CP") ownr_ph1 = c.CommPhone; if (c.CommQualifier === "WP") ownr_ph2 = c.CommPhone; if (c.CommQualifier === "FX") ownr_fax = c.CommPhone; if (c.CommQualifier === "EM") ownr_ea = c.CommEmail; }); - const preferred_contact = ownerParty.PreferredContactMethod || null; - // ── VEHICLE INFO (nested relationship) ────────────────────────────────────── + // Estimator → map to est_… fields + const estParty = rq.AdminInfo?.Estimator?.Party || {}; + // grab raw first/last + const est_fn = estParty.PersonInfo?.PersonName?.FirstName || null; + const est_ln = estParty.PersonInfo?.PersonName?.LastName || null; + // now alias into the GraphQL names + const est_ct_fn = est_fn; + const est_ct_ln = est_ln; + + const est_aff = rq.AdminInfo?.Estimator?.Affiliation || null; + const estComms = Array.isArray(estParty.ContactInfo?.Communications) + ? estParty.ContactInfo.Communications + : [estParty.ContactInfo?.Communications || {}]; + const est_ea = estComms.find((c) => c.CommQualifier === "EM")?.CommEmail || null; + + // ── ADJUSTER ──────────────────────────────────────────────────────────────── + const adjParty = rq.AdminInfo?.Adjuster?.Party || {}; + const agt_ct_fn = adjParty.PersonInfo?.PersonName?.FirstName || null; + const agt_ct_ln = adjParty.PersonInfo?.PersonName?.LastName || null; + const agt_ct_ph = + (Array.isArray(adjParty.ContactInfo?.Communications) + ? adjParty.ContactInfo.Communications + : [adjParty.ContactInfo?.Communications || {}] + ).find((c) => c.CommQualifier === "CP")?.CommPhone || null; + const agt_ea = + (Array.isArray(adjParty.ContactInfo?.Communications) + ? adjParty.ContactInfo.Communications + : [adjParty.ContactInfo?.Communications || {}] + ).find((c) => c.CommQualifier === "EM")?.CommEmail || null; + + // ── REPAIR FACILITY ───────────────────────────────────────────────────────── + const rfParty = rq.AdminInfo?.RepairFacility?.Party || {}; + const servicing_dealer = rfParty.OrgInfo?.CompanyName || null; + const servicing_dealer_contact = + (Array.isArray(rfParty.ContactInfo?.Communications) + ? rfParty.ContactInfo.Communications + : [rfParty.ContactInfo?.Communications || {}] + ).find((c) => c.CommQualifier === "WP" || c.CommQualifier === "FX")?.CommPhone || null; + + // ── VEHICLE (one-to-one) ───────────────────────────────────────────────────── + const vin = rq.VehicleInfo?.VINInfo?.VINNum || null; + const plate_no = rq.VehicleInfo?.License?.LicensePlateNum || null; + const plate_st = rq.VehicleInfo?.License?.LicensePlateStateProvince || null; const desc = rq.VehicleInfo?.VehicleDesc || {}; + const v_model_yr = desc.ModelYear || null; + const v_make_desc = desc.MakeDesc || null; + const v_model_desc = desc.ModelName || null; + const body_style = desc.BodyStyle || null; + const engine_desc = desc.EngineDesc || null; + const production_date = desc.ProductionDate || null; + const v_options = desc.SubModelDesc || null; + const v_type = desc.FuelType || null; + const v_cond = rq.VehicleInfo?.Condition?.DrivableInd; + const vehicleData = { shopid: shopId, - plate_no: rq.VehicleInfo?.License?.LicensePlateNum || null, - plate_st: rq.VehicleInfo?.License?.LicensePlateStateProvince || null + v_vin: vin, + plate_no, + plate_st, + v_model_yr, + v_make_desc, + v_model_desc, + v_color: rq.VehicleInfo?.Paint?.Exterior?.ColorName || null, + v_bstyle: body_style, + v_engine: engine_desc, + // prod_dt: production_date, + v_options, + v_type, + v_cond }; // ── DAMAGE LINES → joblinesData ──────────────────────────────────────────── @@ -122,16 +176,12 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { status: line.LineStatusCode || null, line_desc: line.LineDesc || null, - // parts (only fields for jobline table) + // parts part_type: line.PartInfo?.PartType || null, - part_qty: parseInt(line.PartInfo?.Quantity || 0, 10), + part_qty: parseFloat(line.PartInfo?.Quantity || 0), + oem_partno: line.PartInfo?.OEMPartNum || null, db_price: parseFloat(line.PartInfo?.PartPrice || 0), act_price: parseFloat(line.PartInfo?.PartPrice || 0), - oem_partno: line.PartInfo?.OEMPartNum || null, - tax_part: line.PartInfo?.TaxableInd === "1", - glass_flag: line.PartInfo?.GlassPartInd === "1", - price_j: line.PriceJudgmentInd === "1", - price_inc: line.PriceInclInd === "1", // labor mod_lbr_ty: line.LaborInfo?.LaborType || null, @@ -146,19 +196,31 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const jobInput = { shopid: shopId, ro_number: RefClaimNum, + + // IDs & CIECA metadata + ciecaid, + cieca_ttl, + cat_no, + category, + class: classType, + + // claim & policy clm_no, status, - clm_total, + clm_total: cieca_ttl, policy_no, ded_amt, + + // document & events comment, date_exported, asgn_no, asgn_type, asgn_date, - scheduled_completion, scheduled_in, + scheduled_completion, + // owner ownr_fn, ownr_ln, ownr_co_nm, @@ -172,36 +234,38 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { ownr_ph2, ownr_fax, ownr_ea, - // preferred_contact, - // nest vehicle & joblines - vehicle: { data: vehicleData }, - joblines: { data: joblinesData }, + // estimator + // est_co_id: est_aff, + est_ct_fn, + est_ct_ln, + est_ea, + // adjuster + agt_ct_fn, + agt_ct_ln, + agt_ct_ph, + agt_ea, + + // repair facility + servicing_dealer, + servicing_dealer_contact, + + // stash any extra CIECA stuff we didn’t map above production_vars: { - documentVersions - } + documentVersions: [] // we’ve flattened these + }, + + // nested relationships + vehicle: { data: vehicleData }, + joblines: { data: joblinesData } }; logger.log("parts-insert-job", "debug", null, null, { jobInput }); const { insert_jobs_one: newJob } = await client.request(INSERT_JOB_WITH_LINES, { job: jobInput }); - const jobId = newJob.id; - logger.log("parts-job-created", "info", jobId, null); + logger.log("parts-job-created", "info", newJob.id, null); - /* - // ── PARTS ORDERS ───────────────────────────────────────────────────────── - // The integration no longer requires parts_orders, - // all related logic is commented out. - - const seqToId = newJob.joblines.reduce((map, ln) => { - map[ln.unq_seq] = ln.id; - return map; - }, {}); - - // ... grouping logic and mutation calls removed ... - */ - - return res.status(200).json({ success: true, jobId }); + return res.status(200).json({ success: true, jobId: newJob.id }); } catch (err) { logger.log("parts-route-error", "error", null, null, { error: err }); return res.status(err.status || 500).json({ error: err.message || "Internal error" }); From b0283f827e3efaf393e2cc56afc53f8d0e85f865 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 20 Jun 2025 14:51:30 -0400 Subject: [PATCH 08/98] feature/IO-3255-simplified-parts-management - Checkpoint --- .../partsManagementVehicleDamageEstimateAddRq.js | 10 +++++----- server/integrations/partsManagement/sampleBody.xml | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index acddc6f52..b6bff71b4 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -106,7 +106,9 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const est_ct_fn = est_fn; const est_ct_ln = est_ln; + // TODO: SHould be the estimator insurance company name est_co_name const est_aff = rq.AdminInfo?.Estimator?.Affiliation || null; + const estComms = Array.isArray(estParty.ContactInfo?.Communications) ? estParty.ContactInfo.Communications : [estParty.ContactInfo?.Communications || {}]; @@ -146,7 +148,6 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const v_model_desc = desc.ModelName || null; const body_style = desc.BodyStyle || null; const engine_desc = desc.EngineDesc || null; - const production_date = desc.ProductionDate || null; const v_options = desc.SubModelDesc || null; const v_type = desc.FuelType || null; const v_cond = rq.VehicleInfo?.Condition?.DrivableInd; @@ -206,7 +207,8 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { // claim & policy clm_no, - status, + // default job: bodyshop.md_status.default_open + status: status || "OPEN", clm_total: cieca_ttl, policy_no, ded_amt, @@ -252,9 +254,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { servicing_dealer_contact, // stash any extra CIECA stuff we didn’t map above - production_vars: { - documentVersions: [] // we’ve flattened these - }, + production_vars: {}, // nested relationships vehicle: { data: vehicleData }, diff --git a/server/integrations/partsManagement/sampleBody.xml b/server/integrations/partsManagement/sampleBody.xml index b643f032c..d85ccc220 100644 --- a/server/integrations/partsManagement/sampleBody.xml +++ b/server/integrations/partsManagement/sampleBody.xml @@ -5,7 +5,7 @@ 17e5ccc4-cdfb-4cf3-a08d-ecfa8d145d6f - 200 + CLM123 @@ -244,7 +244,7 @@ NONOEM123 180.00 - VEND1 + 4c2ff2c4-af2b-4a5f-970e-3e026f0bbf9f 1 1 @@ -264,7 +264,7 @@ Replace bumper - + From 4b83330db98df376b7f25a54dbec73bb66e6f45e Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 23 Jun 2025 14:00:58 -0400 Subject: [PATCH 09/98] feature/IO-3255-simplified-parts-management - Checkpoint --- client/package-lock.json | 94 ++++++------ client/package.json | 6 +- package-lock.json | 16 +- package.json | 4 +- ...rtsManagementVehicleDamageEstimateAddRq.js | 144 ++++++++++++++++-- 5 files changed, 193 insertions(+), 71 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 6d710e174..b357aab33 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -21,7 +21,7 @@ "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.30.0", + "@sentry/react": "^9.31.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", @@ -91,7 +91,7 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.44.2", + "@dotenvx/dotenvx": "^1.45.1", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", "@eslint/js": "^9.29.0", @@ -100,7 +100,7 @@ "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", - "@vitejs/plugin-react": "^4.5.2", + "@vitejs/plugin-react": "^4.6.0", "browserslist": "^4.25.0", "browserslist-to-esbuild": "^2.1.1", "chalk": "^5.4.1", @@ -2585,9 +2585,9 @@ } }, "node_modules/@dotenvx/dotenvx": { - "version": "1.44.2", - "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.44.2.tgz", - "integrity": "sha512-2C44+G2dch4cB6zw7+oGQ9VcFQuuVhc5xOzfVvY7iUEj2PRhiVMIB6SpNMK1V5TvpdqrAqCYFjclK18Mh9vwNQ==", + "version": "1.45.1", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.45.1.tgz", + "integrity": "sha512-wKHPD+/NMMJVBPg3i98uD9jsURDy+Ck6RQRiWf39TlOAzC+Ge1FkmDk3sgeljYZxA3qF6E7SJmvRqC70XQuuVA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -3884,9 +3884,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.11", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz", - "integrity": "sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==", + "version": "1.0.0-beta.19", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz", + "integrity": "sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==", "dev": true, "license": "MIT" }, @@ -4466,50 +4466,50 @@ "license": "MIT" }, "node_modules/@sentry-internal/browser-utils": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.30.0.tgz", - "integrity": "sha512-e6ZlN8oWheCB0YJSGlBNUlh6UPnY5Ecj1P+/cgeKBhNm7c3bIx4J50485hB8LQsu+b7Q11L2o/wucZ//Pb6FCg==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.31.0.tgz", + "integrity": "sha512-rviu/jUmeQbY4rSO8l4pubOtRIhFtH5Gu/ryRNMTlpJRdomp4uxddqthHUDH5g6xCXZsMTyJEIdx0aTqbgr/GQ==", "license": "MIT", "dependencies": { - "@sentry/core": "9.30.0" + "@sentry/core": "9.31.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/feedback": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.30.0.tgz", - "integrity": "sha512-qAZ7xxLqZM7GlEvmSUmTHnoueg+fc7esMQD4vH8pS7HI3n9C5MjGn3HHlndRpD8lL7iUUQ0TPZQgU6McbzMDyw==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.31.0.tgz", + "integrity": "sha512-Ygi/8UZ7p2B4DhXQjZDtOc45vNUHkfk2XETBTBGkByEQkE8vygzSiKhgRcnVpzwq+8xKFMRy+PxvpcCo+PNQew==", "license": "MIT", "dependencies": { - "@sentry/core": "9.30.0" + "@sentry/core": "9.31.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.30.0.tgz", - "integrity": "sha512-+6wkqQGLJuFUzvGRzbh3iIhFGyxQx/Oxc0ODDKmz9ag2xYRjCYb3UUQXmQX9navAF0HXUsq8ajoJPm2L1ZyWVg==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.31.0.tgz", + "integrity": "sha512-V5rvcO/xSj8JMw4ZnZT2cBYC+UOuIiZ2Flj4EoIurxMrTgowE1uMXUBA32EBfuB5/vQSJXB6W5uAudhk7LjBPQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.30.0", - "@sentry/core": "9.30.0" + "@sentry-internal/browser-utils": "9.31.0", + "@sentry/core": "9.31.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.30.0.tgz", - "integrity": "sha512-I4MxS27rfV7vnOU29L80y4baZ4I1XqpnYvC/yLN7C17nA8eDCufQ8WVomli41y8JETnfcxlm68z7CS0sO4RCSA==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.31.0.tgz", + "integrity": "sha512-VGqfvQCIuXQZeecrBf8bd4sj8lYGzUA/2CffTAkad1nB1Onyz0Kzo54qLWemivCxA3ufHf6DCpNA3Loa/0ywFQ==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "9.30.0", - "@sentry/core": "9.30.0" + "@sentry-internal/replay": "9.31.0", + "@sentry/core": "9.31.0" }, "engines": { "node": ">=18" @@ -4525,16 +4525,16 @@ } }, "node_modules/@sentry/browser": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.30.0.tgz", - "integrity": "sha512-sRyW6A9nIieTTI26MYXk1DmWEhmphTjZevusNWla+vvUigCmSjuH+xZw19w43OyvF3bu261Skypnm/mAalOTwg==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.31.0.tgz", + "integrity": "sha512-DzG72JJTqHzE0Qo2fHeHm3xgFs97InaSQStmTMxOA59yPqvAXbweNPcsgCNu1q76+jZyaJcoy1qOwahnLuEVDg==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.30.0", - "@sentry-internal/feedback": "9.30.0", - "@sentry-internal/replay": "9.30.0", - "@sentry-internal/replay-canvas": "9.30.0", - "@sentry/core": "9.30.0" + "@sentry-internal/browser-utils": "9.31.0", + "@sentry-internal/feedback": "9.31.0", + "@sentry-internal/replay": "9.31.0", + "@sentry-internal/replay-canvas": "9.31.0", + "@sentry/core": "9.31.0" }, "engines": { "node": ">=18" @@ -4911,22 +4911,22 @@ } }, "node_modules/@sentry/core": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.30.0.tgz", - "integrity": "sha512-JfEpeQ8a1qVJEb9DxpFTFy1J1gkNdlgKAPiqYGNnm4yQbnfl2Kb/iEo1if70FkiHc52H8fJwISEF90pzMm6lPg==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.31.0.tgz", + "integrity": "sha512-6JeoPGvBgT9m2YFIf2CrW+KrrOYzUqb9+Xwr/Dw25kPjVKy+WJjWqK8DKCNLgkBA22OCmSOmHuRwFR0YxGVdZQ==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@sentry/react": { - "version": "9.30.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.30.0.tgz", - "integrity": "sha512-asA49AkZ/g9CCeW0eA0Ent0DF60S4k2IHxbu+Q1mqgbRRmbn859oL2Bgsu/EvzWf5edeQtuUml8LIo4YoFwfMA==", + "version": "9.31.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.31.0.tgz", + "integrity": "sha512-cZT/AwRiawRED7pB4Ug6ZRbcWd92HQxOPc12KKe5ZUQFEc9jUqH6HqwzQUSMzkg86NrE9Hc6XXga+JZ3Q1Lzow==", "license": "MIT", "dependencies": { - "@sentry/browser": "9.30.0", - "@sentry/core": "9.30.0", + "@sentry/browser": "9.31.0", + "@sentry/core": "9.31.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -5819,16 +5819,16 @@ "license": "ISC" }, "node_modules/@vitejs/plugin-react": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.2.tgz", - "integrity": "sha512-QNVT3/Lxx99nMQWJWF7K4N6apUEuT0KlZA3mx/mVaoGj3smm/8rc8ezz15J1pcbcjDK0V15rpHetVfya08r76Q==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.6.0.tgz", + "integrity": "sha512-5Kgff+m8e2PB+9j51eGHEpn5kUzRKH2Ry0qGoe8ItJg7pqnkPrYPkDQZGgGmTa0EGarHrkjLvOdU3b1fzI8otQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.27.4", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.11", + "@rolldown/pluginutils": "1.0.0-beta.19", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, diff --git a/client/package.json b/client/package.json index 955a343b2..67de920bf 100644 --- a/client/package.json +++ b/client/package.json @@ -20,7 +20,7 @@ "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.30.0", + "@sentry/react": "^9.31.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", @@ -131,7 +131,7 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.44.2", + "@dotenvx/dotenvx": "^1.45.1", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", "@eslint/js": "^9.29.0", @@ -140,7 +140,7 @@ "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", - "@vitejs/plugin-react": "^4.5.2", + "@vitejs/plugin-react": "^4.6.0", "browserslist": "^4.25.0", "browserslist-to-esbuild": "^2.1.1", "chalk": "^5.4.1", diff --git a/package-lock.json b/package-lock.json index e598c0600..58ac9324e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "aws4": "^1.13.2", "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.54.3", + "bullmq": "^5.56.0", "chart.js": "^4.5.0", "cloudinary": "^2.7.0", "compression": "^1.8.0", @@ -72,7 +72,7 @@ "globals": "^15.15.0", "mock-require": "^3.0.3", "p-limit": "^3.1.0", - "prettier": "^3.5.3", + "prettier": "^3.6.0", "supertest": "^7.1.1", "vitest": "^3.2.4" }, @@ -4674,9 +4674,9 @@ } }, "node_modules/bullmq": { - "version": "5.54.3", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.54.3.tgz", - "integrity": "sha512-MVK2pOkB3hvrIcubwI8dS4qWHJLNKakKPpgRBTw91sIpPZArmvZ4t2hvryyEaJXJbAS/JHd6pKYOUd+RGRkWQQ==", + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.56.0.tgz", + "integrity": "sha512-j5ct2tdc9M8PKcjhJw+euO24BsO1wXBAkNGXYI1R1qvh7FvRldZ5wtLixLWqQ4/crafj0Vrwi+y1kXFXMwBJFA==", "license": "MIT", "dependencies": { "cron-parser": "^4.9.0", @@ -9825,9 +9825,9 @@ } }, "node_modules/prettier": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", - "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.0.tgz", + "integrity": "sha512-ujSB9uXHJKzM/2GBuE0hBOUgC77CN3Bnpqa+g80bkv3T3A93wL/xlzDATHhnhkzifz/UE2SNOvmbTz5hSkDlHw==", "dev": true, "license": "MIT", "bin": { diff --git a/package.json b/package.json index 656a0c36c..61eaf07d8 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "aws4": "^1.13.2", "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.54.3", + "bullmq": "^5.56.0", "chart.js": "^4.5.0", "cloudinary": "^2.7.0", "compression": "^1.8.0", @@ -79,7 +79,7 @@ "globals": "^15.15.0", "mock-require": "^3.0.3", "p-limit": "^3.1.0", - "prettier": "^3.5.3", + "prettier": "^3.6.0", "supertest": "^7.1.1", "vitest": "^3.2.4" } diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index b6bff71b4..fde4b2082 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -4,6 +4,9 @@ const xml2js = require("xml2js"); const client = require("../../graphql-client/graphql-client").client; +// Defaults +const FALLBACK_DEFAULT_ORDER_STATUS = "OPEN"; // Default status if not found in bodyshop + // GraphQL statements const INSERT_JOB_WITH_LINES = ` mutation InsertJob($job: jobs_insert_input!) { @@ -14,6 +17,30 @@ const INSERT_JOB_WITH_LINES = ` } `; +const GET_BODYSHOP_STATUS = ` + query GetBodyshopStatus($id: uuid!) { + bodyshops_by_pk(id: $id) { + md_order_statuses + } + } +`; + +const INSERT_OWNER = ` + mutation InsertOwner($owner: owners_insert_input!) { + insert_owners_one(object: $owner) { + id + } + } +`; + +// Do they call the add call first, future ones will be updates, we need to upcycle. Or we need to send a new add request, we treat it as an upsert. + +/** + * Handles the VehicleDamageEstimateAddRq XML request from parts management. + * @param req + * @param res + * @returns {Promise<*>} + */ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const { logger } = req; const xml = req.body; @@ -23,9 +50,11 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { try { payload = await xml2js.parseStringPromise(xml, { explicitArray: false, - tagNameProcessors: [xml2js.processors.stripPrefix] + tagNameProcessors: [xml2js.processors.stripPrefix], + attrNameProcessors: [xml2js.processors.stripPrefix] + // ignoreAttrs: false, + // xmlns: false }); - logger.log("parts-xml-parse", "debug", null, null, { success: true }); } catch (err) { logger.log("parts-xml-parse-error", "error", null, null, { error: err }); return res.status(400).send("Invalid XML"); @@ -43,6 +72,14 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { if (!shopId) throw { status: 400, message: "Missing in XML" }; const { RefClaimNum } = rq; + let defaultStatus = FALLBACK_DEFAULT_ORDER_STATUS; + + try { + const { bodyshop_by_pk } = await client.request(GET_BODYSHOP_STATUS, { id: shopId }); + defaultStatus = bodyshop_by_pk?.md_order_statuses?.default_open || defaultStatus; + } catch (err) { + logger.log("parts-bodyshop-fetch-failed", "warn", shopId, null, { error: err }); + } // ── DOCUMENT INFO ────────────────────────────────────────────────────────── const doc = rq.DocumentInfo || {}; const comment = doc.Comment || null; @@ -55,6 +92,68 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const category = doc.DocumentType || null; const classType = doc.DocumentStatus || null; + // ── PARTS TAX RATES STRUCTURE ─────────────────────────────────────────────── + // Known rate types that map to your parts_tax_rates keys + const knownPartRateTypes = [ + "PAA", + "PAC", + "PAG", + "PAL", + "PAM", + "PAN", + "PAO", + "PAP", + "PAR", + "PAS", + "PASL", + "CCC", + "CCD", + "CCF", + "CCM", + "CCDR" + ]; + + const profile = rq.ProfileInfo || {}; + const rateInfos = Array.isArray(profile.RateInfo) ? profile.RateInfo : [profile.RateInfo || {}]; + + const parts_tax_rates = {}; + + for (const code of knownPartRateTypes) { + const rateInfo = rateInfos.find((r) => (r?.RateType || "").toUpperCase() === code); + if (!rateInfo) { + parts_tax_rates[code] = {}; + continue; + } + + const taxInfo = rateInfo.TaxInfo; + const taxTier = taxInfo?.TaxTierInfo; + + // Try to find Percentage first + let percentage = parseFloat(taxTier?.Percentage ?? "NaN"); + if (isNaN(percentage)) { + // fallback to RateTierInfo.Rate if that's where it might be + const tierRate = Array.isArray(rateInfo.RateTierInfo) + ? rateInfo.RateTierInfo[0]?.Rate + : rateInfo.RateTierInfo?.Rate; + + percentage = parseFloat(tierRate ?? "NaN"); + } + + // Still no tax rate? fallback to null object + if (isNaN(percentage)) { + parts_tax_rates[code] = {}; + continue; + } + + parts_tax_rates[code] = { + prt_discp: 0, + prt_mktyp: false, + prt_mkupp: 0, + prt_tax_in: true, + prt_tax_rt: percentage / 100 + }; + } + // ── EVENT INFO ────────────────────────────────────────────────────────────── const ev = rq.EventInfo || {}; const asgn = ev.AssignmentEvent || {}; @@ -106,8 +205,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const est_ct_fn = est_fn; const est_ct_ln = est_ln; - // TODO: SHould be the estimator insurance company name est_co_name - const est_aff = rq.AdminInfo?.Estimator?.Affiliation || null; + const est_co_nm = rq.AdminInfo?.Estimator?.Affiliation || null; const estComms = Array.isArray(estParty.ContactInfo?.Communications) ? estParty.ContactInfo.Communications @@ -193,9 +291,34 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { notes: line.LineMemo || null })); + const ownerInput = { + shopid: shopId, + ownr_fn, + ownr_ln, + ownr_co_nm, + ownr_addr1, + ownr_addr2, + ownr_city, + ownr_st, + ownr_zip, + ownr_ctry, + ownr_ph1, + ownr_ph2, + ownr_ea + }; + + let ownerid = null; + try { + const { insert_owners_one } = await client.request(INSERT_OWNER, { owner: ownerInput }); + ownerid = insert_owners_one?.id; + } catch (err) { + logger.log("parts-owner-insert-failed", "warn", null, null, { error: err }); + } + // ── BUILD & INSERT THE JOB ────────────────────────────────────────────────── const jobInput = { shopid: shopId, + ownerid, ro_number: RefClaimNum, // IDs & CIECA metadata @@ -205,10 +328,12 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { category, class: classType, + // tax + parts_tax_rates, + // claim & policy clm_no, - // default job: bodyshop.md_status.default_open - status: status || "OPEN", + status: status || defaultStatus, clm_total: cieca_ttl, policy_no, ded_amt, @@ -238,7 +363,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { ownr_ea, // estimator - // est_co_id: est_aff, + est_co_nm, est_ct_fn, est_ct_ln, est_ea, @@ -253,16 +378,13 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { servicing_dealer, servicing_dealer_contact, - // stash any extra CIECA stuff we didn’t map above - production_vars: {}, - // nested relationships vehicle: { data: vehicleData }, joblines: { data: joblinesData } }; - logger.log("parts-insert-job", "debug", null, null, { jobInput }); const { insert_jobs_one: newJob } = await client.request(INSERT_JOB_WITH_LINES, { job: jobInput }); + logger.log("parts-job-created", "info", newJob.id, null); return res.status(200).json({ success: true, jobId: newJob.id }); From 09e1887609c6e543a8b99a4894d2a1928731e680 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 23 Jun 2025 14:24:15 -0400 Subject: [PATCH 10/98] feature/IO-3255-simplified-parts-management - Checkpoint --- ...rtsManagementVehicleDamageEstimateAddRq.js | 52 ++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index fde4b2082..31ca61031 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -94,6 +94,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { // ── PARTS TAX RATES STRUCTURE ─────────────────────────────────────────────── // Known rate types that map to your parts_tax_rates keys + // If this has become an issue, default it to an empty object for version 1 const knownPartRateTypes = [ "PAA", "PAC", @@ -269,27 +270,41 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { // ── DAMAGE LINES → joblinesData ──────────────────────────────────────────── const damageLines = Array.isArray(rq.DamageLineInfo) ? rq.DamageLineInfo : [rq.DamageLineInfo]; - const joblinesData = damageLines.map((line) => ({ - line_no: parseInt(line.LineNum, 10), - unq_seq: parseInt(line.UniqueSequenceNum, 10), - status: line.LineStatusCode || null, - line_desc: line.LineDesc || null, + const joblinesData = damageLines.map((line) => { + const jobLine = { + line_no: parseInt(line.LineNum, 10), + unq_seq: parseInt(line.UniqueSequenceNum, 10), + status: line.LineStatusCode || null, + line_desc: line.LineDesc || null, - // parts - part_type: line.PartInfo?.PartType || null, - part_qty: parseFloat(line.PartInfo?.Quantity || 0), - oem_partno: line.PartInfo?.OEMPartNum || null, - db_price: parseFloat(line.PartInfo?.PartPrice || 0), - act_price: parseFloat(line.PartInfo?.PartPrice || 0), + // parts + part_type: line.PartInfo?.PartType || null, + part_qty: parseFloat(line.PartInfo?.Quantity || 0), + oem_partno: line.PartInfo?.OEMPartNum || null, + db_price: parseFloat(line.PartInfo?.PartPrice || 0), + act_price: parseFloat(line.PartInfo?.PartPrice || 0), - // labor - mod_lbr_ty: line.LaborInfo?.LaborType || null, - mod_lb_hrs: parseFloat(line.LaborInfo?.LaborHours || 0), - lbr_op: line.LaborInfo?.LaborOperation || null, - lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), + // labor + mod_lbr_ty: line.LaborInfo?.LaborType || null, + mod_lb_hrs: parseFloat(line.LaborInfo?.LaborHours || 0), + lbr_op: line.LaborInfo?.LaborOperation || null, + lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), - notes: line.LineMemo || null - })); + notes: line.LineMemo || null + }; + + // TODO: Commented out as not clear if needed for version 1, this only applies to Imex and not rome on the front + // end + + // if ((jobLine.part_type === "PASL" || jobLine.part_type === "PAS") && jobLine.lbr_op !== "OP11") { + // jobLine.tax_part = true; + // } + // if (line.db_ref === "900510") { + // jobLine.tax_part = true; + // } + + return jobLine; + }); const ownerInput = { shopid: shopId, @@ -308,6 +323,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { }; let ownerid = null; + try { const { insert_owners_one } = await client.request(INSERT_OWNER, { owner: ownerInput }); ownerid = insert_owners_one?.id; From cbb6c43ec34648203f380824fded7a1a65dcc7d7 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 23 Jun 2025 14:00:25 -0700 Subject: [PATCH 11/98] IO-3255 Clean up front end components for pm. --- .../global-footer/global-footer.component.jsx | 73 +++++++ .../job-detail-lines/job-lines.component.jsx | 183 ++++++++-------- .../jobs-lines-expander-simple.component.jsx | 83 ++++++++ .../jobs-detail-header.component.jsx | 199 +++++++++--------- .../jobs-detail-pli.component.jsx | 71 +++++-- ...arts-order-list-table-drawer.component.jsx | 109 +++++----- .../parts-order-list-table.component.jsx | 113 +++++----- client/src/graphql/jobs.queries.js | 1 + .../pages/manage/manage.page.component.jsx | 50 +---- ...simplified-parts-jobs-detail.component.jsx | 23 +- ...simplified-parts-jobs-detail.container.jsx | 4 +- .../simplified-parts.page.component.jsx | 54 +---- client/src/redux/user/user.actions.js | 5 + client/src/redux/user/user.reducer.js | 7 +- client/src/redux/user/user.sagas.js | 19 +- client/src/redux/user/user.selectors.js | 5 + client/src/redux/user/user.types.js | 3 +- 17 files changed, 588 insertions(+), 414 deletions(-) create mode 100644 client/src/components/global-footer/global-footer.component.jsx create mode 100644 client/src/components/job-detail-lines/jobs-lines-expander-simple.component.jsx diff --git a/client/src/components/global-footer/global-footer.component.jsx b/client/src/components/global-footer/global-footer.component.jsx new file mode 100644 index 000000000..7a5cefa62 --- /dev/null +++ b/client/src/components/global-footer/global-footer.component.jsx @@ -0,0 +1,73 @@ +import { AlertOutlined, BulbOutlined } from "@ant-design/icons"; +import { Button, Layout, Space } from "antd"; +import { useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { Link } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import WssStatusDisplayComponent from "../../components/wss-status-display/wss-status-display.component.jsx"; +import { addAlerts } from "../../redux/application/application.actions.js"; +import { selectAlerts } from "../../redux/application/application.selectors.js"; +import { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors"; +import InstanceRenderManager from "../../utils/instanceRenderMgr.js"; +const { Footer } = Layout; + +const mapStateToProps = createStructuredSelector({ + conflict: selectInstanceConflict, + bodyshop: selectBodyshop, + alerts: selectAlerts +}); + +const mapDispatchToProps = (dispatch) => ({ + setAlerts: (alerts) => dispatch(addAlerts(alerts)) +}); + +export function GlobalFooter() { + const { t } = useTranslation(); + + useEffect(() => { + window.Canny("initChangelog", { + appID: "680bd2c7ee501290377f6686", + position: "top", + align: "left", + theme: "light" // options: light [default], dark, auto + }); + }, []); + + return ( +
+
+ + + + + +
+ {`${InstanceRenderManager({ + imex: t("titles.imexonline"), + rome: t("titles.romeonline") + })} - ${import.meta.env.VITE_APP_GIT_SHA_DATE}`} +
+ +
+ + Disclaimer & Notices + +
+
+ ); +} + +export default connect(mapStateToProps, mapDispatchToProps)(GlobalFooter); diff --git a/client/src/components/job-detail-lines/job-lines.component.jsx b/client/src/components/job-detail-lines/job-lines.component.jsx index 41eb5f21a..29bbea71d 100644 --- a/client/src/components/job-detail-lines/job-lines.component.jsx +++ b/client/src/components/job-detail-lines/job-lines.component.jsx @@ -12,7 +12,7 @@ import { PageHeader } from "@ant-design/pro-layout"; import { useMutation } from "@apollo/client"; import { Button, Dropdown, Input, Space, Table, Tag } from "antd"; import axios from "axios"; -import React, { useState } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; @@ -32,7 +32,7 @@ import JobLinesBillRefernece from "../job-lines-bill-reference/job-lines-bill-re import { useSplitTreatments } from "@splitsoftware/splitio-react"; import _ from "lodash"; import { FaTasks } from "react-icons/fa"; -import { selectBodyshop } from "../../redux/user/user.selectors"; +import { selectBodyshop, selectPartsManagementOnly } from "../../redux/user/user.selectors"; import dayjs from "../../utils/day"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component"; @@ -45,11 +45,13 @@ import PartsOrderDrawer from "../parts-order-list-table/parts-order-list-table-d import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container"; import JobLinesExpander from "./job-lines-expander.component"; import JobLinesPartPriceChange from "./job-lines-part-price-change.component"; +import JobLinesExpanderSimple from "./jobs-lines-expander-simple.component"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, jobRO: selectJobReadOnly, - technician: selectTechnician + technician: selectTechnician, + partsManagementOnly: selectPartsManagementOnly }); const mapDispatchToProps = (dispatch) => ({ @@ -79,7 +81,7 @@ export function JobLinesComponent({ handleBillOnRowClick, handlePartsOrderOnRowClick, handlePartsDispatchOnRowClick, - simple + partsManagementOnly }) { const [deleteJobLine] = useMutation(DELETE_JOB_LINE_BY_PK); const { @@ -93,7 +95,13 @@ export function JobLinesComponent({ const [selectedLines, setSelectedLines] = useState([]); const [state, setState] = useState({ sortedInfo: {}, - filteredInfo: {} + filteredInfo: { + ...(partsManagementOnly + ? { + part_type: ["PAN", "PAC", "PAR", "PAL", "PAA", "PAM", "PAP", "PAS", "PASL", "PAG"] + } + : {}) + } }); const { t } = useTranslation(); const jobIsPrivate = bodyshop.md_ins_cos.find((c) => c.name === job.ins_co_nm)?.private; @@ -221,7 +229,7 @@ export function JobLinesComponent({ sorter: (a, b) => a.part_qty - b.part_qty, sortOrder: state.sortedInfo.columnKey === "part_qty" && state.sortedInfo.order }, - ...(!simple + ...(!partsManagementOnly ? [ { title: t("joblines.fields.mod_lbr_ty"), @@ -273,7 +281,7 @@ export function JobLinesComponent({ key: "location", render: (text, record) => }, - ...(!simple && HasFeatureAccess({ featureName: "bills", bodyshop }) + ...(!partsManagementOnly && HasFeatureAccess({ featureName: "bills", bodyshop }) ? [ { title: t("joblines.labels.billref"), @@ -307,70 +315,74 @@ export function JobLinesComponent({ onFilter: (value, record) => value.includes(record.status), render: (text, record) => }, - { - title: t("general.labels.actions"), - dataIndex: "actions", - key: "actions", - render: (text, record) => ( - - {(record.manual_line || jobIsPrivate) && !technician && ( - <> - - - )} - - {(record.manual_line || jobIsPrivate) && !technician && ( - <> - + + )} + + {(record.manual_line || jobIsPrivate) && !technician && ( + <> + - - )} - - ) - } + }); + await axios.post("/job/totalsssu", { + id: job.id + }); + refetch && refetch(); + }} + > + + + + )} + + ) + } + ] + : [] ]; const handleTableChange = (pagination, filters, sorter) => { @@ -543,17 +555,19 @@ export function JobLinesComponent({ - + {!partsManagementOnly && ( + + )} {InstanceRenderManager({ rome: })} , + expandedRowRender: (record) => + partsManagementOnly ? ( + + ) : ( + + ), rowExpandable: (record) => true, //expandRowByClick: true, expandIcon: ({ expanded, onExpand, record }) => diff --git a/client/src/components/job-detail-lines/jobs-lines-expander-simple.component.jsx b/client/src/components/job-detail-lines/jobs-lines-expander-simple.component.jsx new file mode 100644 index 000000000..4fa50c9fa --- /dev/null +++ b/client/src/components/job-detail-lines/jobs-lines-expander-simple.component.jsx @@ -0,0 +1,83 @@ +import { useQuery } from "@apollo/client"; +import { Col, Row, Skeleton, Timeline, Typography } from "antd"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { Link } from "react-router-dom"; +import { createStructuredSelector } from "reselect"; +import { GET_JOB_LINE_ORDERS } from "../../graphql/jobs.queries"; +import { selectTechnician } from "../../redux/tech/tech.selectors.js"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +import { DateFormatter } from "../../utils/DateFormatter"; +import AlertComponent from "../alert/alert.component"; + +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop, + technician: selectTechnician +}); + +const mapDispatchToProps = (dispatch) => ({}); + +export default connect(mapStateToProps, mapDispatchToProps)(JobLinesExpanderSimple); + +export function JobLinesExpanderSimple({ jobline, jobid, bodyshop, technician }) { + const { t } = useTranslation(); + const { loading, error, data } = useQuery(GET_JOB_LINE_ORDERS, { + fetchPolicy: "network-only", + nextFetchPolicy: "network-only", + variables: { + joblineid: jobline.id + } + }); + + if (loading) return ; + if (error) return ; + + return ( + +
+ {t("parts_orders.labels.parts_orders")} + 0 + ? data.parts_order_lines.map((line) => ({ + key: line.id, + children: ( + + + {!technician ? ( + <> + + {line.parts_order.order_number} + + + ) : ( + `${line.parts_order.order_number}` + )} + + + {line.parts_order.order_date} + + {line.parts_order.vendor.name} + {line.backordered_eta ? ( + + + {`${t("parts_orders.fields.backordered_eta")}: `} + {line.backordered_eta} + + + ) : null} + + ) + })) + : [ + { + key: "no-orders", + children: t("parts_orders.labels.notyetordered") + } + ] + } + /> + + + ); +} diff --git a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx index 141cab456..b3d49dfdc 100644 --- a/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx +++ b/client/src/components/jobs-detail-header/jobs-detail-header.component.jsx @@ -11,7 +11,7 @@ import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { insertAuditTrail } from "../../redux/application/application.actions.js"; import { selectJobReadOnly } from "../../redux/application/application.selectors"; import { setModalContext } from "../../redux/modals/modals.actions"; -import { selectBodyshop } from "../../redux/user/user.selectors"; +import { selectBodyshop, selectPartsManagementOnly } from "../../redux/user/user.selectors"; import AuditTrailMapping from "../../utils/AuditTrailMappings.js"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { DateTimeFormatter, DateTimeFormatterFunction } from "../../utils/DateFormatter"; @@ -30,7 +30,8 @@ import "./jobs-detail-header.styles.scss"; const mapStateToProps = createStructuredSelector({ jobRO: selectJobReadOnly, - bodyshop: selectBodyshop + bodyshop: selectBodyshop, + partsManagementOnly: selectPartsManagementOnly }); const mapDispatchToProps = (dispatch) => ({ @@ -51,19 +52,20 @@ const mapDispatchToProps = (dispatch) => ({ ) }); -const colSpan = { - xs: { span: 24 }, - sm: { span: 24 }, - md: { span: 12 }, - lg: { span: 6 }, - xl: { span: 6 } -}; - -export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail }) { +export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail, partsManagementOnly }) { const { t } = useTranslation(); const { notification } = useNotification(); const [notesClamped, setNotesClamped] = useState(true); const [updateJob] = useMutation(UPDATE_JOB); + + const colSpan = { + xs: { span: 24 }, + sm: { span: 24 }, + md: { span: partsManagementOnly ? 8 : 12 }, + lg: { span: partsManagementOnly ? 8 : 6 }, + xl: { span: partsManagementOnly ? 8 : 6 } + }; + const vehicleTitle = `${job.v_model_yr || ""} ${job.v_color || ""} ${job.v_make_desc || ""} ${job.v_model_desc || ""}`.trim(); const bodyHrs = job.joblines.filter((j) => j.mod_lbr_ty !== "LAR").reduce((acc, val) => acc + val.mod_lb_hrs, 0); @@ -143,81 +145,86 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail }) /{job.owner_owing} - - {job.alt_transport} - - - {job?.cccontracts?.length > 0 && ( - - {job.cccontracts.map((c, index) => ( - - - {`${c.agreementnumber} - ${c.courtesycar.fleetnumber} ${c.courtesycar.year} ${c.courtesycar.make} ${c.courtesycar.model}`} - {index !== job.cccontracts.length - 1 ? "," : null} - + + {!partsManagementOnly && ( + <> + + {job.alt_transport} + + + {job?.cccontracts?.length > 0 && ( + + {job.cccontracts.map((c, index) => ( + + + {`${c.agreementnumber} - ${c.courtesycar.fleetnumber} ${c.courtesycar.year} ${c.courtesycar.make} ${c.courtesycar.model}`} + {index !== job.cccontracts.length - 1 ? "," : null} + + + ))} + + )} + + + + + + handleCheckboxChange("estimate_sent_approval", e.target.checked)} + disabled={disabled} + > + {job.estimate_sent_approval && ( + + {job.estimate_sent_approval} + + )} + - ))} - + + + + handleCheckboxChange("estimate_approved", e.target.checked)} + disabled={disabled} + > + {job.estimate_approved && ( + + {job.estimate_approved} + + )} + + + + + {job.special_coverage_policy && ( + + + + {t("jobs.labels.specialcoveragepolicy")} + + + )} + {job.ca_gst_registrant && ( + + + + {t("jobs.fields.ca_gst_registrant")} + + + )} + {job.hit_and_run && ( + + + + {t("jobs.fields.hit_and_run")} + + + )} + + )} - - - - - - handleCheckboxChange("estimate_sent_approval", e.target.checked)} - disabled={disabled} - > - {job.estimate_sent_approval && ( - - {job.estimate_sent_approval} - - )} - - - - - - handleCheckboxChange("estimate_approved", e.target.checked)} - disabled={disabled} - > - {job.estimate_approved && ( - - {job.estimate_approved} - - )} - - - - - {job.special_coverage_policy && ( - - - - {t("jobs.labels.specialcoveragepolicy")} - - - )} - {job.ca_gst_registrant && ( - - - - {t("jobs.fields.ca_gst_registrant")} - - - )} - {job.hit_and_run && ( - - - - {t("jobs.fields.hit_and_run")} - - - )} - @@ -334,17 +341,19 @@ export function JobsDetailHeader({ job, bodyshop, disabled, insertAuditTrail }) - - -
- - - - {bodyHrs.toFixed(1)} / {refinishHrs.toFixed(1)} / {(bodyHrs + refinishHrs).toFixed(1)} - -
-
- + {!partsManagementOnly && ( + + +
+ + + + {bodyHrs.toFixed(1)} / {refinishHrs.toFixed(1)} / {(bodyHrs + refinishHrs).toFixed(1)} + +
+
+ + )} ); } diff --git a/client/src/components/jobs-detail-pli/jobs-detail-pli.component.jsx b/client/src/components/jobs-detail-pli/jobs-detail-pli.component.jsx index 704ed9d10..f207bb8af 100644 --- a/client/src/components/jobs-detail-pli/jobs-detail-pli.component.jsx +++ b/client/src/components/jobs-detail-pli/jobs-detail-pli.component.jsx @@ -8,27 +8,27 @@ import PartsDispatchTable from "../parts-dispatch-table/parts-dispatch-table.com import PartsOrderListTableComponent from "../parts-order-list-table/parts-order-list-table.component"; import PartsOrderModal from "../parts-order-modal/parts-order-modal.container"; -export default function JobsDetailPliComponent({ +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { selectPartsManagementOnly } from "../../redux/user/user.selectors"; +const mapStateToProps = createStructuredSelector({ + //currentUser: selectCurrentUser + partsManagementOnly: selectPartsManagementOnly +}); +const mapDispatchToProps = (dispatch) => ({}); +export default connect(mapStateToProps, mapDispatchToProps)(JobsDetailPliComponent); + +export function JobsDetailPliComponent({ job, billsQuery, handleBillOnRowClick, handlePartsOrderOnRowClick, - handlePartsDispatchOnRowClick + handlePartsDispatchOnRowClick, + partsManagementOnly }) { - return ( -
- - {billsQuery.error ? : null} - + if (partsManagementOnly) { + return ( -
- - - - - - - - - - ); + ); + } else { + return ( +
+ + {billsQuery.error ? : null} + + +
+ + + + + + + + + + + + + + ); + } } diff --git a/client/src/components/parts-order-list-table/parts-order-list-table-drawer.component.jsx b/client/src/components/parts-order-list-table/parts-order-list-table-drawer.component.jsx index 3fe23ca4c..0b551fcb6 100644 --- a/client/src/components/parts-order-list-table/parts-order-list-table-drawer.component.jsx +++ b/client/src/components/parts-order-list-table/parts-order-list-table-drawer.component.jsx @@ -14,7 +14,7 @@ import { QUERY_BILL_BY_PK } from "../../graphql/bills.queries"; import { DELETE_PARTS_ORDER } from "../../graphql/parts-orders.queries"; import { selectJobReadOnly } from "../../redux/application/application.selectors"; import { setModalContext } from "../../redux/modals/modals.actions"; -import { selectBodyshop } from "../../redux/user/user.selectors"; +import { selectBodyshop, selectPartsManagementOnly } from "../../redux/user/user.selectors"; import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { DateFormatter } from "../../utils/DateFormatter"; import { TemplateList } from "../../utils/TemplateConstants"; @@ -31,7 +31,8 @@ import PrintWrapper from "../print-wrapper/print-wrapper.component"; const mapStateToProps = createStructuredSelector({ jobRO: selectJobReadOnly, - bodyshop: selectBodyshop + bodyshop: selectBodyshop, + partsManagementOnly: selectPartsManagementOnly }); const mapDispatchToProps = (dispatch) => ({ @@ -60,7 +61,8 @@ export function PartsOrderListTableDrawerComponent({ billsQuery, handleOnRowClick, setPartsReceiveContext, - setTaskUpsertContext + setTaskUpsertContext, + partsManagementOnly }) { const selectedBreakpoint = Object.entries(Grid.useBreakpoint()) .filter((screen) => !!screen[1]) @@ -134,19 +136,21 @@ export function PartsOrderListTableDrawerComponent({ > {t("parts_orders.actions.receive")} - + {!partsManagementOnly && ( + + )} - - + }); + }} + > + {t("parts_orders.actions.receivebill")} + + )} ({ @@ -52,7 +53,8 @@ export function PartsOrderListTableComponent({ billsQuery, handleOnRowClick, setPartsReceiveContext, - setTaskUpsertContext + setTaskUpsertContext, + partsManagementOnly }) { const responsibilityCenters = bodyshop.md_responsibility_centers; const Templates = TemplateList("partsorder", { job }); @@ -106,18 +108,23 @@ export function PartsOrderListTableComponent({ > {t("parts_orders.actions.receive")} - + }); + }} + > + {t("parts_orders.actions.receivebill")} + + )} import("../jobs/jobs.page")); @@ -658,38 +657,7 @@ export function Manage({ conflict, bodyshop, alerts, setAlerts }) { -
-
- - - - - -
- {`${InstanceRenderManager({ - imex: t("titles.imexonline"), - rome: t("titles.romeonline") - })} - ${import.meta.env.VITE_APP_GIT_SHA_DATE}`} -
- -
- - Disclaimer & Notices - -
-
+ ); diff --git a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx index 195f1da18..4b5cca325 100644 --- a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx +++ b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx @@ -22,11 +22,12 @@ import { QUERY_PARTS_BILLS_BY_JOBID } from "../../graphql/bills.queries.js"; import { insertAuditTrail } from "../../redux/application/application.actions.js"; import { selectJobReadOnly } from "../../redux/application/application.selectors.js"; import { setModalContext } from "../../redux/modals/modals.actions.js"; -import { selectBodyshop } from "../../redux/user/user.selectors.js"; +import { selectBodyshop, selectPartsManagementOnly } from "../../redux/user/user.selectors.js"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, - jobRO: selectJobReadOnly + jobRO: selectJobReadOnly, + partsManagementOnly: selectPartsManagementOnly }); const mapDispatchToProps = (dispatch) => ({ setPrintCenterContext: (context) => @@ -53,7 +54,8 @@ export function SimplifiedPartsJobDetailComponent({ job, mutationUpdateJob, insertAuditTrail, - refetch + refetch, + partsManagementOnly }) { const { t } = useTranslation(); const [form] = Form.useForm(); @@ -141,10 +143,14 @@ export function SimplifiedPartsJobDetailComponent({ {t("jobs.actions.printCenter")} - - + {!partsManagementOnly && ( + <> + + + + )} ); @@ -153,7 +159,7 @@ export function SimplifiedPartsJobDetailComponent({ {job.ro_number || t("general.labels.na")}} extra={menuExtra} /> - + @@ -178,7 +184,6 @@ export function SimplifiedPartsJobDetailComponent({ handlePartsDispatchOnRowClick={handlePartsDispatchOnRowClick} refetch={refetch} form={form} - simple /> ) }, diff --git a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx index 2728118d0..12bb15473 100644 --- a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx +++ b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx @@ -63,7 +63,7 @@ function SimplifiedPartsJobsDetailContainer({ setBreadcrumbs, addRecentItem, set ro_number: (data.jobs_by_pk && data.jobs_by_pk.ro_number) || t("general.labels.na") }); setBreadcrumbs([ - { link: "/parts/jobs", label: t("titles.bc.jobs") }, + { link: "/parts/", label: t("titles.bc.jobs") }, { link: `/parts/jobs/${jobId}`, label: t("titles.bc.jobs-detail", { @@ -81,7 +81,7 @@ function SimplifiedPartsJobsDetailContainer({ setBreadcrumbs, addRecentItem, set "job", `${data.jobs_by_pk.ro_number || t("general.labels.na")} | ${OwnerNameDisplayFunction(data.jobs_by_pk)}`, - `/manage/jobs/${jobId}` + `/parts/jobs/${jobId}` ) ); } diff --git a/client/src/pages/simplified-parts/simplified-parts.page.component.jsx b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx index 5180feaff..aa906834f 100644 --- a/client/src/pages/simplified-parts/simplified-parts.page.component.jsx +++ b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx @@ -1,26 +1,24 @@ -import { AlertOutlined, BulbOutlined } from "@ant-design/icons"; import * as Sentry from "@sentry/react"; -import { Button, FloatButton, Layout, Space, Spin } from "antd"; +import { FloatButton, Layout, Spin } from "antd"; import { lazy, Suspense, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; -import { Link, Route, Routes } from "react-router-dom"; +import { Route, Routes } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import BreadCrumbs from "../../components/breadcrumbs/breadcrumbs.component.jsx"; import ConflictComponent from "../../components/conflict/conflict.component.jsx"; import ErrorBoundary from "../../components/error-boundary/error-boundary.component.jsx"; +import GlobalFooter from "../../components/global-footer/global-footer.component.jsx"; import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component.jsx"; import PrintCenterModalContainer from "../../components/print-center-modal/print-center-modal.container.jsx"; import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-status.component.jsx"; import UpdateAlert from "../../components/update-alert/update-alert.component.jsx"; -import WssStatusDisplayComponent from "../../components/wss-status-display/wss-status-display.component.jsx"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; import { useSocket } from "../../contexts/SocketIO/useSocket.js"; import { addAlerts } from "../../redux/application/application.actions.js"; import { selectAlerts } from "../../redux/application/application.selectors.js"; import { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors.js"; import InstanceRenderManager from "../../utils/instanceRenderMgr.js"; - const SimplifiedPartsJobsPage = lazy(() => import("../simplified-parts-jobs/simplified-parts-jobs.page.jsx")); const SimplifiedPartsJobsDetailPage = lazy( () => import("../simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx") @@ -29,12 +27,10 @@ const ShopPage = lazy(() => import("../shop/shop.page.component.jsx")); const ShopVendorPageContainer = lazy(() => import("../shop-vendor/shop-vendor.page.container.jsx")); const EmailOverlayContainer = lazy(() => import("../../components/email-overlay/email-overlay.container.jsx")); const FeatureRequestPage = lazy(() => import("../feature-request/feature-request.page.jsx")); -const JobCostingModal = lazy(() => import("../../components/job-costing-modal/job-costing-modal.container.jsx")); const ReportCenterModal = lazy(() => import("../../components/report-center-modal/report-center-modal.container.jsx")); -const BillEnterModalContainer = lazy(() => import("../../components/bill-enter-modal/bill-enter-modal.container.jsx")); const Help = lazy(() => import("../help/help.page.jsx")); -const { Content, Footer } = Layout; +const { Content } = Layout; const mapStateToProps = createStructuredSelector({ conflict: selectInstanceConflict, @@ -141,8 +137,6 @@ export function SimplifiedPartsPage({ conflict, bodyshop, alerts, setAlerts }) { } > - - @@ -199,13 +193,6 @@ export function SimplifiedPartsPage({ conflict, bodyshop, alerts, setAlerts }) { else if (bodyshop && bodyshop.sub_status !== "active") PageContent = ; else PageContent = AppRouteTable; - const broadcastMessage = () => { - if (socket && bodyshop && bodyshop.id) { - console.log(`Broadcasting message to bodyshop ${bodyshop.id}:`); - socket.emit("broadcast-to-bodyshop", bodyshop.id, `Hello from ${clientId}`); - } - }; - return ( @@ -216,38 +203,7 @@ export function SimplifiedPartsPage({ conflict, bodyshop, alerts, setAlerts }) { -
-
- - - - - -
- {`${InstanceRenderManager({ - imex: t("titles.imexonline"), - rome: t("titles.romeonline") - })} - ${import.meta.env.VITE_APP_GIT_SHA_DATE}`} -
- -
- - Disclaimer & Notices - -
-
+
); } diff --git a/client/src/redux/user/user.actions.js b/client/src/redux/user/user.actions.js index 01ba22534..3d1d6fb9e 100644 --- a/client/src/redux/user/user.actions.js +++ b/client/src/redux/user/user.actions.js @@ -123,3 +123,8 @@ export const setImexShopId = (imexshopid) => ({ type: UserActionTypes.SET_IMEX_SHOP_ID, payload: imexshopid }); + +export const setPartsManagementOnly = (partsManagementOnly) => ({ + type: UserActionTypes.SET_PARTS_MANAGEMENT_ONLY, + payload: partsManagementOnly +}); \ No newline at end of file diff --git a/client/src/redux/user/user.reducer.js b/client/src/redux/user/user.reducer.js index eebb32433..89d489f3a 100644 --- a/client/src/redux/user/user.reducer.js +++ b/client/src/redux/user/user.reducer.js @@ -7,6 +7,7 @@ const INITIAL_STATE = { //language: "en-US" }, bodyshop: null, + partsManagementOnly: null, loginLoading: false, fingerprint: null, error: null, @@ -125,7 +126,11 @@ const userReducer = (state = INITIAL_STATE, action) => { ...state, imexshopid: action.payload }; - + case UserActionTypes.SET_PARTS_MANAGEMENT_ONLY: + return { + ...state, + partsManagementOnly: action.payload + }; default: return state; } diff --git a/client/src/redux/user/user.sagas.js b/client/src/redux/user/user.sagas.js index 79e3926f7..649551ff6 100644 --- a/client/src/redux/user/user.sagas.js +++ b/client/src/redux/user/user.sagas.js @@ -38,6 +38,7 @@ import { setInstanceConflict, setInstanceId, setLocalFingerprint, + setPartsManagementOnly, signInFailure, signInSuccess, signOutFailure, @@ -344,13 +345,13 @@ export function* SetAuthLevelFromShopDetails({ payload }) { payload.features?.allAccess === true ? window.$crisp.push(["set", "session:segments", [["allAccess"]]]) : (() => { - const featureKeys = Object.keys(payload.features).filter( - (key) => - payload.features[key] === true || - (typeof payload.features[key] === "string" && !isNaN(Date.parse(payload.features[key]))) - ); - window.$crisp.push(["set", "session:segments", [["basic", ...featureKeys]]]); - })(); + const featureKeys = Object.keys(payload.features).filter( + (key) => + payload.features[key] === true || + (typeof payload.features[key] === "string" && !isNaN(Date.parse(payload.features[key]))) + ); + window.$crisp.push(["set", "session:segments", [["basic", ...featureKeys]]]); + })(); InstanceRenderManager({ executeFunction: true, @@ -359,6 +360,10 @@ export function* SetAuthLevelFromShopDetails({ payload }) { window.$zoho.salesiq.visitor.info({ "Shop Name": payload.shopname }); } }); + + //Set whether it is for parts management only. + + yield put(setPartsManagementOnly(true || payload.features.partsManagementOnly)); } catch (error) { console.warn("Couldnt find $crisp.", error.message); } diff --git a/client/src/redux/user/user.selectors.js b/client/src/redux/user/user.selectors.js index a2afd47a8..b08b12931 100644 --- a/client/src/redux/user/user.selectors.js +++ b/client/src/redux/user/user.selectors.js @@ -1,3 +1,4 @@ +import { create } from "lodash"; import { createSelector } from "reselect"; const selectUser = (state) => state.user; @@ -17,3 +18,7 @@ export const selectAuthLevel = createSelector([selectUser], (user) => user.authL export const selectLoginLoading = createSelector([selectUser], (user) => user.loginLoading); export const selectCurrentEula = createSelector([selectUser], (user) => user.currentEula); +export const selectPartsManagementOnly = createSelector( + [selectUser], + (user) => user.partsManagementOnly +); \ No newline at end of file diff --git a/client/src/redux/user/user.types.js b/client/src/redux/user/user.types.js index d9cd6fe62..e6c9ca7fc 100644 --- a/client/src/redux/user/user.types.js +++ b/client/src/redux/user/user.types.js @@ -33,6 +33,7 @@ const UserActionTypes = { CHECK_ACTION_CODE_FAILURE: "CHECK_ACTION_CODE_FAILURE", SET_CURRENT_EULA: "SET_CURRENT_EULA", EULA_ACCEPTED: "EULA_ACCEPTED", - SET_IMEX_SHOP_ID: "SET_IMEX_SHOP_ID" + SET_IMEX_SHOP_ID: "SET_IMEX_SHOP_ID", + SET_PARTS_MANAGEMENT_ONLY: "SET_PARTS_MANAGEMENT_ONLY", }; export default UserActionTypes; From 7d930045efad0dbf32684ccaaf4034e4760bbef5 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Tue, 24 Jun 2025 14:38:13 -0400 Subject: [PATCH 12/98] feature/IO-3255-simplified-parts-management - Checkpoint --- .../partsManagement.queries.js | 40 + ...rtsManagementVehicleDamageEstimateAddRq.js | 751 +++++++++--------- 2 files changed, 436 insertions(+), 355 deletions(-) create mode 100644 server/integrations/partsManagement/partsManagement.queries.js diff --git a/server/integrations/partsManagement/partsManagement.queries.js b/server/integrations/partsManagement/partsManagement.queries.js new file mode 100644 index 000000000..45a88ad58 --- /dev/null +++ b/server/integrations/partsManagement/partsManagement.queries.js @@ -0,0 +1,40 @@ +// GraphQL Queries and Mutations +const GET_BODYSHOP_STATUS = ` + query GetBodyshopStatus($id: uuid!) { + bodyshops_by_pk(id: $id) { + md_order_statuses + } + } +`; + +const GET_VEHICLE_BY_SHOP_VIN = ` + query GetVehicleByShopVin($shopid: uuid!, $v_vin: String!) { + vehicles(where: { shopid: { _eq: $shopid }, v_vin: { _eq: $v_vin } }, limit: 1) { + id + } + } +`; + +const INSERT_OWNER = ` + mutation InsertOwner($owner: owners_insert_input!) { + insert_owners_one(object: $owner) { + id + } + } +`; + +const INSERT_JOB_WITH_LINES = ` + mutation InsertJob($job: jobs_insert_input!) { + insert_jobs_one(object: $job) { + id + joblines { id unq_seq } + } + } +`; + +module.exports = { + GET_BODYSHOP_STATUS, + GET_VEHICLE_BY_SHOP_VIN, + INSERT_OWNER, + INSERT_JOB_WITH_LINES +}; diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index 31ca61031..c163a51da 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -4,357 +4,370 @@ const xml2js = require("xml2js"); const client = require("../../graphql-client/graphql-client").client; +// GraphQL Queries and Mutations +const { + GET_BODYSHOP_STATUS, + GET_VEHICLE_BY_SHOP_VIN, + INSERT_OWNER, + INSERT_JOB_WITH_LINES +} = require("./partsManagement.queries"); + // Defaults -const FALLBACK_DEFAULT_ORDER_STATUS = "OPEN"; // Default status if not found in bodyshop +const FALLBACK_DEFAULT_ORDER_STATUS = "OPEN"; -// GraphQL statements -const INSERT_JOB_WITH_LINES = ` - mutation InsertJob($job: jobs_insert_input!) { - insert_jobs_one(object: $job) { - id - joblines { id unq_seq } - } - } -`; - -const GET_BODYSHOP_STATUS = ` - query GetBodyshopStatus($id: uuid!) { - bodyshops_by_pk(id: $id) { - md_order_statuses - } - } -`; - -const INSERT_OWNER = ` - mutation InsertOwner($owner: owners_insert_input!) { - insert_owners_one(object: $owner) { - id - } - } -`; - -// Do they call the add call first, future ones will be updates, we need to upcycle. Or we need to send a new add request, we treat it as an upsert. +// Known part rate types for tax rates +const KNOWN_PART_RATE_TYPES = [ + "PAA", + "PAC", + "PAG", + "PAL", + "PAM", + "PAN", + "PAO", + "PAP", + "PAR", + "PAS", + "PASL", + "CCC", + "CCD", + "CCF", + "CCM", + "CCDR" +]; /** - * Handles the VehicleDamageEstimateAddRq XML request from parts management. - * @param req - * @param res - * @returns {Promise<*>} + * Parses XML string into a JavaScript object. + * @param {string} xml - The XML string to parse. + * @param {object} logger - The logger instance. + * @returns {Promise} The parsed XML object. + * @throws {Error} If XML parsing fails. */ -const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { - const { logger } = req; - const xml = req.body; - - // ── PARSE XML ──────────────────────────────────────────────────────────────── - let payload; +const parseXml = async (xml, logger) => { try { - payload = await xml2js.parseStringPromise(xml, { + return await xml2js.parseStringPromise(xml, { explicitArray: false, tagNameProcessors: [xml2js.processors.stripPrefix], attrNameProcessors: [xml2js.processors.stripPrefix] - // ignoreAttrs: false, - // xmlns: false }); } catch (err) { logger.log("parts-xml-parse-error", "error", null, null, { error: err }); - return res.status(400).send("Invalid XML"); + throw new Error("Invalid XML"); + } +}; + +/** + * Fetches the default order status for a bodyshop. + * @param {string} shopId - The bodyshop UUID. + * @param {object} logger - The logger instance. + * @returns {Promise} The default status or fallback. + */ +const getDefaultOrderStatus = async (shopId, logger) => { + try { + const { bodyshop_by_pk } = await client.request(GET_BODYSHOP_STATUS, { id: shopId }); + return bodyshop_by_pk?.md_order_statuses?.default_open || FALLBACK_DEFAULT_ORDER_STATUS; + } catch (err) { + logger.log("parts-bodyshop-fetch-failed", "warn", shopId, null, { error: err }); + return FALLBACK_DEFAULT_ORDER_STATUS; + } +}; + +/** + * Extracts and processes parts tax rates from profile info. + * @param {object} profile - The ProfileInfo object from XML. + * @returns {object} The parts tax rates object. + */ +const extractPartsTaxRates = (profile = {}) => { + const rateInfos = Array.isArray(profile.RateInfo) ? profile.RateInfo : [profile.RateInfo || {}]; + const partsTaxRates = {}; + + for (const code of KNOWN_PART_RATE_TYPES) { + const rateInfo = rateInfos.find((r) => (r?.RateType || "").toUpperCase() === code); + if (!rateInfo) { + partsTaxRates[code] = {}; + continue; + } + + const taxInfo = rateInfo.TaxInfo; + const taxTier = taxInfo?.TaxTierInfo; + let percentage = parseFloat(taxTier?.Percentage ?? "NaN"); + + if (isNaN(percentage)) { + const tierRate = Array.isArray(rateInfo.RateTierInfo) + ? rateInfo.RateTierInfo[0]?.Rate + : rateInfo.RateTierInfo?.Rate; + percentage = parseFloat(tierRate ?? "NaN"); + } + + partsTaxRates[code] = isNaN(percentage) + ? {} + : { + prt_discp: 0, + prt_mktyp: false, + prt_mkupp: 0, + prt_tax_in: true, + prt_tax_rt: percentage / 100 + }; } - const rq = payload.VehicleDamageEstimateAddRq; - if (!rq) { - logger.log("parts-missing-root", "error"); - return res.status(400).send("Missing "); - } + return partsTaxRates; +}; + +/** + * Extracts job-related data from the XML request. + * @param {object} rq - The VehicleDamageEstimateAddRq object. + * @returns {object} Extracted job data. + */ +const extractJobData = (rq) => { + const doc = rq.DocumentInfo || {}; + const ev = rq.EventInfo || {}; + const asgn = ev.AssignmentEvent || {}; + const ci = rq.ClaimInfo || {}; + + return { + shopId: rq.ShopID || rq.shopId, + refClaimNum: rq.RefClaimNum, + ciecaid: rq.RqUID || null, + cieca_ttl: parseFloat(rq.Cieca_ttl || 0), + cat_no: doc.VendorCode || null, + category: doc.DocumentType || null, + classType: doc.DocumentStatus || null, + comment: doc.Comment || null, + date_exported: doc.TransmitDateTime || null, + asgn_no: asgn.AssignmentNumber || null, + asgn_type: asgn.AssignmentType || null, + asgn_date: asgn.AssignmentDate || null, + scheduled_in: ev.RepairEvent?.RequestedPickUpDateTime || null, + scheduled_completion: ev.RepairEvent?.TargetCompletionDateTime || null, + clm_no: ci.ClaimNum || null, + status: ci.ClaimStatus || null, + policy_no: ci.PolicyInfo?.PolicyNum || null, + ded_amt: parseFloat(ci.PolicyInfo?.CoverageInfo?.Coverage?.DeductibleInfo?.DeductibleAmt || 0) + }; +}; + +/** + * Extracts owner data from the XML request. + * @param {object} rq - The VehicleDamageEstimateAddRq object. + * @param {string} shopId - The bodyshop UUID. + * @returns {object} Owner data for insertion and inline use. + */ +const extractOwnerData = (rq, shopId) => { + const ownerParty = rq.AdminInfo?.Owner?.Party || {}; + const adr = ownerParty.PersonInfo?.Communications?.Address || {}; + let ownr_ph1, ownr_ph2, ownr_ea; + + (Array.isArray(ownerParty.ContactInfo?.Communications) + ? ownerParty.ContactInfo.Communications + : [ownerParty.ContactInfo?.Communications || {}] + ).forEach((c) => { + if (c.CommQualifier === "CP") ownr_ph1 = c.CommPhone; + if (c.CommQualifier === "WP") ownr_ph2 = c.CommPhone; + if (c.CommQualifier === "EM") ownr_ea = c.CommEmail; + }); + + return { + shopid: shopId, + ownr_fn: ownerParty.PersonInfo?.PersonName?.FirstName || null, + ownr_ln: ownerParty.PersonInfo?.PersonName?.LastName || null, + ownr_co_nm: ownerParty.OrgInfo?.CompanyName || null, + ownr_addr1: adr.Address1 || null, + ownr_addr2: adr.Address2 || null, + ownr_city: adr.City || null, + ownr_st: adr.StateProvince || null, + ownr_zip: adr.PostalCode || null, + ownr_ctry: adr.Country || null, + ownr_ph1, + ownr_ph2, + ownr_ea + }; +}; + +/** + * Extracts estimator data from the XML request. + * @param {object} rq - The VehicleDamageEstimateAddRq object. + * @returns {object} Estimator data. + */ +const extractEstimatorData = (rq) => { + const estParty = rq.AdminInfo?.Estimator?.Party || {}; + const estComms = Array.isArray(estParty.ContactInfo?.Communications) + ? estParty.ContactInfo.Communications + : [estParty.ContactInfo?.Communications || {}]; + + return { + est_co_nm: rq.AdminInfo?.Estimator?.Affiliation || null, + est_ct_fn: estParty.PersonInfo?.PersonName?.FirstName || null, + est_ct_ln: estParty.PersonInfo?.PersonName?.LastName || null, + est_ea: estComms.find((c) => c.CommQualifier === "EM")?.CommEmail || null + }; +}; + +/** + * Extracts adjuster data from the XML request. + * @param {object} rq - The VehicleDamageEstimateAddRq object. + * @returns {object} Adjuster data. + */ +const extractAdjusterData = (rq) => { + const adjParty = rq.AdminInfo?.Adjuster?.Party || {}; + const adjComms = Array.isArray(adjParty.ContactInfo?.Communications) + ? adjParty.ContactInfo.Communications + : [adjParty.ContactInfo?.Communications || {}]; + + return { + agt_ct_fn: adjParty.PersonInfo?.PersonName?.FirstName || null, + agt_ct_ln: adjParty.PersonInfo?.PersonName?.LastName || null, + agt_ct_ph: adjComms.find((c) => c.CommQualifier === "CP")?.CommPhone || null, + agt_ea: adjComms.find((c) => c.CommQualifier === "EM")?.CommEmail || null + }; +}; + +/** + * Extracts repair facility data from the XML request. + * @param {object} rq - The VehicleDamageEstimateAddRq object. + * @returns {object} Repair facility data. + */ +const extractRepairFacilityData = (rq) => { + const rfParty = rq.AdminInfo?.RepairFacility?.Party || {}; + const rfComms = Array.isArray(rfParty.ContactInfo?.Communications) + ? rfParty.ContactInfo.Communications + : [rfParty.ContactInfo?.Communications || {}]; + + return { + servicing_dealer: rfParty.OrgInfo?.CompanyName || null, + servicing_dealer_contact: + rfComms.find((c) => c.CommQualifier === "WP" || c.CommQualifier === "FX")?.CommPhone || null + }; +}; + +/** + * Extracts vehicle data from the XML request. + * @param {object} rq - The VehicleDamageEstimateAddRq object. + * @param {string} shopId - The bodyshop UUID. + * @returns {object} Vehicle data for insertion and inline use. + */ +const extractVehicleData = (rq, shopId) => { + const desc = rq.VehicleInfo?.VehicleDesc || {}; + + return { + shopid: shopId, + v_vin: rq.VehicleInfo?.VINInfo?.VIN?.VINNum || null, + plate_no: rq.VehicleInfo?.License?.LicensePlateNum || null, + plate_st: rq.VehicleInfo?.License?.LicensePlateStateProvince || null, + v_model_yr: desc.ModelYear || null, + v_make_desc: desc.MakeDesc || null, + v_model_desc: desc.ModelName || null, + v_color: rq.VehicleInfo?.Paint?.Exterior?.ColorName || null, + v_bstyle: desc.BodyStyle || null, + v_engine: desc.EngineDesc || null, + v_options: desc.SubModelDesc || null, + v_type: desc.FuelType || null, + v_cond: rq.VehicleInfo?.Condition?.DrivableInd + }; +}; + +/** + * Extracts job lines from the XML request. + * @param {object} rq - The VehicleDamageEstimateAddRq object. + * @returns {object[]} Array of job line objects. + */ +const extractJobLines = (rq) => { + const damageLines = Array.isArray(rq.DamageLineInfo) ? rq.DamageLineInfo : [rq.DamageLineInfo]; + + return damageLines.map((line) => { + const jobLine = { + line_no: parseInt(line.LineNum, 10), + unq_seq: parseInt(line.UniqueSequenceNum, 10), + status: line.LineStatusCode || null, + line_desc: line.LineDesc || null, + part_type: line.PartInfo?.PartType || null, + part_qty: parseFloat(line.PartInfo?.Quantity || 0), + oem_partno: line.PartInfo?.OEMPartNum || null, + db_price: parseFloat(line.PartInfo?.PartPrice || 0), + act_price: parseFloat(line.PartInfo?.PartPrice || 0), + mod_lbr_ty: line.LaborInfo?.LaborType || null, + mod_lb_hrs: parseFloat(line.LaborInfo?.LaborHours || 0), + lbr_op: line.LaborInfo?.LaborOperation || null, + lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), + notes: line.LineMemo || null + }; + + // TODO: Commented out as not clear if needed for version 1, this only applies to Imex and not rome on the front + // end + // if ((jobLine.part_type === "PASL" || jobLine.part_type === "PAS") && jobLine.lbr_op !== "OP11") { + // jobLine.tax_part = true; + // } + // if (line.db_ref === "900510") { + // jobLine.tax_part = true; + // } + + return jobLine; + }); +}; + +/** + * Finds an existing vehicle by shopId and VIN. + * @param {string} shopId - The bodyshop UUID. + * @param {string} v_vin - The vehicle VIN. + * @param {object} logger - The logger instance. + * @returns {Promise} The vehicle ID or null if not found. + */ +const findExistingVehicle = async (shopId, v_vin, logger) => { + if (!v_vin) return null; try { - // ── SHOP & CLAIM IDs ──────────────────────────────────────────────────────── - const shopId = rq.ShopID || rq.shopId; - if (!shopId) throw { status: 400, message: "Missing in XML" }; - const { RefClaimNum } = rq; - - let defaultStatus = FALLBACK_DEFAULT_ORDER_STATUS; - - try { - const { bodyshop_by_pk } = await client.request(GET_BODYSHOP_STATUS, { id: shopId }); - defaultStatus = bodyshop_by_pk?.md_order_statuses?.default_open || defaultStatus; - } catch (err) { - logger.log("parts-bodyshop-fetch-failed", "warn", shopId, null, { error: err }); + const { vehicles } = await client.request(GET_VEHICLE_BY_SHOP_VIN, { shopid: shopId, v_vin }); + if (vehicles?.length > 0) { + logger.log("parts-vehicle-found", "info", vehicles[0].id, null, { shopid: shopId, v_vin }); + return vehicles[0].id; } - // ── DOCUMENT INFO ────────────────────────────────────────────────────────── - const doc = rq.DocumentInfo || {}; - const comment = doc.Comment || null; - const date_exported = doc.TransmitDateTime || null; - // capture CIECA ID & totals - const ciecaid = rq.RqUID || null; - const cieca_ttl = parseFloat(rq.Cieca_ttl || 0); - // map DocumentInfo fields to our category/class fields - const cat_no = doc.VendorCode || null; - const category = doc.DocumentType || null; - const classType = doc.DocumentStatus || null; + } catch (err) { + logger.log("parts-vehicle-fetch-failed", "warn", null, null, { error: err }); + } + return null; +}; - // ── PARTS TAX RATES STRUCTURE ─────────────────────────────────────────────── - // Known rate types that map to your parts_tax_rates keys - // If this has become an issue, default it to an empty object for version 1 - const knownPartRateTypes = [ - "PAA", - "PAC", - "PAG", - "PAL", - "PAM", - "PAN", - "PAO", - "PAP", - "PAR", - "PAS", - "PASL", - "CCC", - "CCD", - "CCF", - "CCM", - "CCDR" - ]; +/** + * Inserts an owner and returns the owner ID. + * @param {object} ownerInput - The owner data to insert. + * @param {object} logger - The logger instance. + * @returns {Promise} The owner ID or null if insertion fails. + */ +const insertOwner = async (ownerInput, logger) => { + try { + const { insert_owners_one } = await client.request(INSERT_OWNER, { owner: ownerInput }); + return insert_owners_one?.id; + } catch (err) { + logger.log("parts-owner-insert-failed", "warn", null, null, { error: err }); + return null; + } +}; - const profile = rq.ProfileInfo || {}; - const rateInfos = Array.isArray(profile.RateInfo) ? profile.RateInfo : [profile.RateInfo || {}]; +/** + * Handles the VehicleDamageEstimateAddRq XML request from parts management. + * @param {object} req - The HTTP request object. + * @param {object} res - The HTTP response object. + * @returns {Promise} + */ +const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { + const { logger } = req; - const parts_tax_rates = {}; - - for (const code of knownPartRateTypes) { - const rateInfo = rateInfos.find((r) => (r?.RateType || "").toUpperCase() === code); - if (!rateInfo) { - parts_tax_rates[code] = {}; - continue; - } - - const taxInfo = rateInfo.TaxInfo; - const taxTier = taxInfo?.TaxTierInfo; - - // Try to find Percentage first - let percentage = parseFloat(taxTier?.Percentage ?? "NaN"); - if (isNaN(percentage)) { - // fallback to RateTierInfo.Rate if that's where it might be - const tierRate = Array.isArray(rateInfo.RateTierInfo) - ? rateInfo.RateTierInfo[0]?.Rate - : rateInfo.RateTierInfo?.Rate; - - percentage = parseFloat(tierRate ?? "NaN"); - } - - // Still no tax rate? fallback to null object - if (isNaN(percentage)) { - parts_tax_rates[code] = {}; - continue; - } - - parts_tax_rates[code] = { - prt_discp: 0, - prt_mktyp: false, - prt_mkupp: 0, - prt_tax_in: true, - prt_tax_rt: percentage / 100 - }; + try { + // Parse XML + const payload = await parseXml(req.body, logger); + const rq = payload.VehicleDamageEstimateAddRq; + if (!rq) { + logger.log("parts-missing-root", "error"); + return res.status(400).send("Missing "); } - // ── EVENT INFO ────────────────────────────────────────────────────────────── - const ev = rq.EventInfo || {}; - const asgn = ev.AssignmentEvent || {}; - const asgn_no = asgn.AssignmentNumber || null; - const asgn_type = asgn.AssignmentType || null; - const asgn_date = asgn.AssignmentDate || null; - const scheduled_in = ev.RepairEvent?.RequestedPickUpDateTime || null; - const scheduled_completion = ev.RepairEvent?.TargetCompletionDateTime || null; - - // ── CLAIM & POLICY ────────────────────────────────────────────────────────── - const ci = rq.ClaimInfo || {}; - const clm_no = ci.ClaimNum || null; - const status = ci.ClaimStatus || null; - const policy_no = ci.PolicyInfo?.PolicyNum || null; - const ded_amt = parseFloat(ci.PolicyInfo?.CoverageInfo?.Coverage?.DeductibleInfo?.DeductibleAmt || 0); - - // ── OWNER ──────────────────────────────────────────────────────────────────── - const ownerParty = rq.AdminInfo?.Owner?.Party || {}; - const ownr_fn = ownerParty.PersonInfo?.PersonName?.FirstName || null; - const ownr_ln = ownerParty.PersonInfo?.PersonName?.LastName || null; - const ownr_co_nm = ownerParty.OrgInfo?.CompanyName || null; - const adr = ownerParty.PersonInfo?.Communications?.Address || {}; - const ownr_addr1 = adr.Address1 || null; - const ownr_addr2 = adr.Address2 || null; - const ownr_city = adr.City || null; - const ownr_st = adr.StateProvince || null; - const ownr_zip = adr.PostalCode || null; - const ownr_ctry = adr.Country || null; - let ownr_ph1; - let ownr_ph2; - let ownr_fax; - let ownr_ea; - (Array.isArray(ownerParty.ContactInfo?.Communications) - ? ownerParty.ContactInfo.Communications - : [ownerParty.ContactInfo?.Communications || {}] - ).forEach((c) => { - if (c.CommQualifier === "CP") ownr_ph1 = c.CommPhone; - if (c.CommQualifier === "WP") ownr_ph2 = c.CommPhone; - if (c.CommQualifier === "FX") ownr_fax = c.CommPhone; - if (c.CommQualifier === "EM") ownr_ea = c.CommEmail; - }); - - // Estimator → map to est_… fields - const estParty = rq.AdminInfo?.Estimator?.Party || {}; - // grab raw first/last - const est_fn = estParty.PersonInfo?.PersonName?.FirstName || null; - const est_ln = estParty.PersonInfo?.PersonName?.LastName || null; - // now alias into the GraphQL names - const est_ct_fn = est_fn; - const est_ct_ln = est_ln; - - const est_co_nm = rq.AdminInfo?.Estimator?.Affiliation || null; - - const estComms = Array.isArray(estParty.ContactInfo?.Communications) - ? estParty.ContactInfo.Communications - : [estParty.ContactInfo?.Communications || {}]; - const est_ea = estComms.find((c) => c.CommQualifier === "EM")?.CommEmail || null; - - // ── ADJUSTER ──────────────────────────────────────────────────────────────── - const adjParty = rq.AdminInfo?.Adjuster?.Party || {}; - const agt_ct_fn = adjParty.PersonInfo?.PersonName?.FirstName || null; - const agt_ct_ln = adjParty.PersonInfo?.PersonName?.LastName || null; - const agt_ct_ph = - (Array.isArray(adjParty.ContactInfo?.Communications) - ? adjParty.ContactInfo.Communications - : [adjParty.ContactInfo?.Communications || {}] - ).find((c) => c.CommQualifier === "CP")?.CommPhone || null; - const agt_ea = - (Array.isArray(adjParty.ContactInfo?.Communications) - ? adjParty.ContactInfo.Communications - : [adjParty.ContactInfo?.Communications || {}] - ).find((c) => c.CommQualifier === "EM")?.CommEmail || null; - - // ── REPAIR FACILITY ───────────────────────────────────────────────────────── - const rfParty = rq.AdminInfo?.RepairFacility?.Party || {}; - const servicing_dealer = rfParty.OrgInfo?.CompanyName || null; - const servicing_dealer_contact = - (Array.isArray(rfParty.ContactInfo?.Communications) - ? rfParty.ContactInfo.Communications - : [rfParty.ContactInfo?.Communications || {}] - ).find((c) => c.CommQualifier === "WP" || c.CommQualifier === "FX")?.CommPhone || null; - - // ── VEHICLE (one-to-one) ───────────────────────────────────────────────────── - const vin = rq.VehicleInfo?.VINInfo?.VINNum || null; - const plate_no = rq.VehicleInfo?.License?.LicensePlateNum || null; - const plate_st = rq.VehicleInfo?.License?.LicensePlateStateProvince || null; - const desc = rq.VehicleInfo?.VehicleDesc || {}; - const v_model_yr = desc.ModelYear || null; - const v_make_desc = desc.MakeDesc || null; - const v_model_desc = desc.ModelName || null; - const body_style = desc.BodyStyle || null; - const engine_desc = desc.EngineDesc || null; - const v_options = desc.SubModelDesc || null; - const v_type = desc.FuelType || null; - const v_cond = rq.VehicleInfo?.Condition?.DrivableInd; - - const vehicleData = { - shopid: shopId, - v_vin: vin, - plate_no, - plate_st, - v_model_yr, - v_make_desc, - v_model_desc, - v_color: rq.VehicleInfo?.Paint?.Exterior?.ColorName || null, - v_bstyle: body_style, - v_engine: engine_desc, - // prod_dt: production_date, - v_options, - v_type, - v_cond - }; - - // ── DAMAGE LINES → joblinesData ──────────────────────────────────────────── - const damageLines = Array.isArray(rq.DamageLineInfo) ? rq.DamageLineInfo : [rq.DamageLineInfo]; - const joblinesData = damageLines.map((line) => { - const jobLine = { - line_no: parseInt(line.LineNum, 10), - unq_seq: parseInt(line.UniqueSequenceNum, 10), - status: line.LineStatusCode || null, - line_desc: line.LineDesc || null, - - // parts - part_type: line.PartInfo?.PartType || null, - part_qty: parseFloat(line.PartInfo?.Quantity || 0), - oem_partno: line.PartInfo?.OEMPartNum || null, - db_price: parseFloat(line.PartInfo?.PartPrice || 0), - act_price: parseFloat(line.PartInfo?.PartPrice || 0), - - // labor - mod_lbr_ty: line.LaborInfo?.LaborType || null, - mod_lb_hrs: parseFloat(line.LaborInfo?.LaborHours || 0), - lbr_op: line.LaborInfo?.LaborOperation || null, - lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), - - notes: line.LineMemo || null - }; - - // TODO: Commented out as not clear if needed for version 1, this only applies to Imex and not rome on the front - // end - - // if ((jobLine.part_type === "PASL" || jobLine.part_type === "PAS") && jobLine.lbr_op !== "OP11") { - // jobLine.tax_part = true; - // } - // if (line.db_ref === "900510") { - // jobLine.tax_part = true; - // } - - return jobLine; - }); - - const ownerInput = { - shopid: shopId, - ownr_fn, - ownr_ln, - ownr_co_nm, - ownr_addr1, - ownr_addr2, - ownr_city, - ownr_st, - ownr_zip, - ownr_ctry, - ownr_ph1, - ownr_ph2, - ownr_ea - }; - - let ownerid = null; - - try { - const { insert_owners_one } = await client.request(INSERT_OWNER, { owner: ownerInput }); - ownerid = insert_owners_one?.id; - } catch (err) { - logger.log("parts-owner-insert-failed", "warn", null, null, { error: err }); - } - - // ── BUILD & INSERT THE JOB ────────────────────────────────────────────────── - const jobInput = { - shopid: shopId, - ownerid, - ro_number: RefClaimNum, - - // IDs & CIECA metadata + // Extract job data + const { + shopId, + refClaimNum, ciecaid, cieca_ttl, cat_no, category, - class: classType, - - // tax - parts_tax_rates, - - // claim & policy - clm_no, - status: status || defaultStatus, - clm_total: cieca_ttl, - policy_no, - ded_amt, - - // document & events + classType, comment, date_exported, asgn_no, @@ -362,45 +375,73 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { asgn_date, scheduled_in, scheduled_completion, + clm_no, + status, + policy_no, + ded_amt + } = extractJobData(rq); - // owner - ownr_fn, - ownr_ln, - ownr_co_nm, - ownr_addr1, - ownr_addr2, - ownr_city, - ownr_st, - ownr_zip, - ownr_ctry, - ownr_ph1, - ownr_ph2, - ownr_fax, - ownr_ea, + if (!shopId) { + throw { status: 400, message: "Missing in XML" }; + } - // estimator - est_co_nm, - est_ct_fn, - est_ct_ln, - est_ea, + // Get default status + const defaultStatus = await getDefaultOrderStatus(shopId, logger); - // adjuster - agt_ct_fn, - agt_ct_ln, - agt_ct_ph, - agt_ea, + // Extract additional data + const parts_tax_rates = extractPartsTaxRates(rq.ProfileInfo); + const ownerData = extractOwnerData(rq, shopId); + const estimatorData = extractEstimatorData(rq); + const adjusterData = extractAdjusterData(rq); + const repairFacilityData = extractRepairFacilityData(rq); + const vehicleData = extractVehicleData(rq, shopId); + const joblinesData = extractJobLines(rq); - // repair facility - servicing_dealer, - servicing_dealer_contact, + // Find or create relationships + const ownerid = await insertOwner(ownerData, logger); + const vehicleid = await findExistingVehicle(shopId, vehicleData.v_vin, logger); - // nested relationships - vehicle: { data: vehicleData }, + // Build job input + const jobInput = { + shopid: shopId, + ownerid, + ro_number: refClaimNum, + ciecaid, + cieca_ttl, + cat_no, + category, + class: classType, + parts_tax_rates, + clm_no, + status: status || defaultStatus, + clm_total: cieca_ttl, + policy_no, + ded_amt, + comment, + date_exported, + asgn_no, + asgn_type, + asgn_date, + scheduled_in, + scheduled_completion, + ...ownerData, // Inline owner data + ...estimatorData, + ...adjusterData, + ...repairFacilityData, + // Inline vehicle data + v_vin: vehicleData.v_vin, + v_model_yr: vehicleData.v_model_yr, + v_model_desc: vehicleData.v_model_desc, + v_make_desc: vehicleData.v_make_desc, + v_color: vehicleData.v_color, + plate_no: vehicleData.plate_no, + plate_st: vehicleData.plate_st, + ...(vehicleid ? { vehicleid } : { vehicle: { data: vehicleData } }), joblines: { data: joblinesData } }; + // Insert job const { insert_jobs_one: newJob } = await client.request(INSERT_JOB_WITH_LINES, { job: jobInput }); - logger.log("parts-job-created", "info", newJob.id, null); return res.status(200).json({ success: true, jobId: newJob.id }); From 01185b307360597f7b09b8f20dc54895ab41019b Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Tue, 24 Jun 2025 16:22:07 -0400 Subject: [PATCH 13/98] feature/IO-3182-Phone-Number-Consent - Checkpoint --- ...rtsManagementVehicleDamageEstimateAddRq.js | 99 +++++++++++++++++-- 1 file changed, 93 insertions(+), 6 deletions(-) diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index c163a51da..ba9ac2aa2 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -238,6 +238,75 @@ const extractRepairFacilityData = (rq) => { }; }; +/** + * Extracts loss information from the XML request. + * @param rq + * @returns {{loss_dt: (*|null), reported_dt: (*|null), loss_type_code: (*|null), loss_type_desc: (*|null)}} + */ +const extractLossInfo = (rq) => { + const loss = rq.ClaimInfo?.LossInfo?.Facts || {}; + const custom = rq.ClaimInfo?.CustomElement || {}; + return { + loss_date: loss.LossDateTime || null, + loss_type: custom.LossTypeCode || null, + loss_desc: custom.LossTypeDesc || null + }; +}; + +/** + * Extracts insurance data from the XML request. + * @param rq + * @returns {{insd_ln: (*|null), insd_fn: (string|null), insd_title: (*|null), insd_co_nm: (*|string|null), insd_addr1: (*|null), insd_addr2: (*|null), insd_city: (*|null), insd_st: (*|null), insd_zip: (*|null), insd_ctry: (*|null), insd_ph1, insd_ph1x, insd_ph2, insd_ph2x, insd_fax, insd_faxx, insd_ea}} + */ +const extractInsuranceData = (rq) => { + const insuredParty = rq.AdminInfo?.Insured?.Party || {}; + const insuredPerson = insuredParty.PersonInfo || {}; + const insuredComms = Array.isArray(insuredParty.ContactInfo?.Communications) + ? insuredParty.ContactInfo.Communications + : [insuredParty.ContactInfo?.Communications || {}]; + const insuredAddress = insuredPerson.Communications?.Address || {}; + + const insurerParty = rq.AdminInfo?.InsuranceCompany?.Party || {}; + + let insd_ph1, insd_ph1x, insd_ph2, insd_ph2x, insd_fax, insd_faxx, insd_ea; + + for (const c of insuredComms) { + if (c.CommQualifier === "CP") { + insd_ph1 = c.CommPhone; + insd_ph1x = c.CommPhoneExt; + } + if (c.CommQualifier === "WP") { + insd_ph2 = c.CommPhone; + insd_ph2x = c.CommPhoneExt; + } + if (c.CommQualifier === "FX") { + insd_fax = c.CommPhone; + insd_faxx = c.CommPhoneExt; + } + if (c.CommQualifier === "EM") insd_ea = c.CommEmail; + } + + return { + insd_ln: insuredPerson.PersonName?.LastName || null, + insd_fn: insuredPerson.PersonName?.FirstName || null, + insd_title: insuredPerson.PersonName?.Title || null, + insd_co_nm: insurerParty.OrgInfo?.CompanyName || insuredParty.OrgInfo?.CompanyName || null, + insd_addr1: insuredAddress.Address1 || null, + insd_addr2: insuredAddress.Address2 || null, + insd_city: insuredAddress.City || null, + insd_st: insuredAddress.StateProvince || null, + insd_zip: insuredAddress.PostalCode || null, + insd_ctry: insuredAddress.Country || null, + insd_ph1, + insd_ph1x, + insd_ph2, + insd_ph2x, + insd_fax, + insd_faxx, + insd_ea + }; +}; + /** * Extracts vehicle data from the XML request. * @param {object} rq - The VehicleDamageEstimateAddRq object. @@ -246,7 +315,8 @@ const extractRepairFacilityData = (rq) => { */ const extractVehicleData = (rq, shopId) => { const desc = rq.VehicleInfo?.VehicleDesc || {}; - + const exterior = rq.VehicleInfo?.Paint?.Exterior || {}; + const interior = rq.VehicleInfo?.Paint?.Interior || {}; return { shopid: shopId, v_vin: rq.VehicleInfo?.VINInfo?.VIN?.VINNum || null, @@ -255,12 +325,25 @@ const extractVehicleData = (rq, shopId) => { v_model_yr: desc.ModelYear || null, v_make_desc: desc.MakeDesc || null, v_model_desc: desc.ModelName || null, - v_color: rq.VehicleInfo?.Paint?.Exterior?.ColorName || null, + v_color: exterior.Color?.ColorName || null, v_bstyle: desc.BodyStyle || null, v_engine: desc.EngineDesc || null, v_options: desc.SubModelDesc || null, v_type: desc.FuelType || null, - v_cond: rq.VehicleInfo?.Condition?.DrivableInd + v_cond: rq.VehicleInfo?.Condition?.DrivableInd, + v_trimcode: desc.TrimCode || null, + v_tone: exterior.Tone || null, + v_stage: exterior.RefinishStage || rq.VehicleInfo?.Paint?.RefinishStage || null, + v_prod_dt: desc.ProductionDate || null, + v_paint_codes: Array.isArray(exterior.PaintCodeInfo) + ? exterior.PaintCodeInfo.map((p) => p.PaintCode).join(",") + : exterior.PaintCode || null, + v_mldgcode: desc.MldgCode || null, + v_makecode: desc.MakeCode || null, + trim_color: interior.ColorName || desc.TrimColor || null, + db_v_code: desc.DatabaseCode || null, + v_model_num: desc.ModelNum || null, + v_odo: desc.OdometerInfo?.OdometerReading || null }; }; @@ -395,7 +478,9 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const adjusterData = extractAdjusterData(rq); const repairFacilityData = extractRepairFacilityData(rq); const vehicleData = extractVehicleData(rq, shopId); + const lossInfo = extractLossInfo(rq); const joblinesData = extractJobLines(rq); + const insuranceData = extractInsuranceData(rq); // Find or create relationships const ownerid = await insertOwner(ownerData, logger); @@ -424,10 +509,12 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { asgn_date, scheduled_in, scheduled_completion, + ...insuranceData, // Inline insurance data + ...lossInfo, // Inline loss information ...ownerData, // Inline owner data - ...estimatorData, - ...adjusterData, - ...repairFacilityData, + ...estimatorData, // Inline estimator data + ...adjusterData, // Inline adjuster data + ...repairFacilityData, // Inline repair facility data // Inline vehicle data v_vin: vehicleData.v_vin, v_model_yr: vehicleData.v_model_yr, From 0e1ec83fcdc9cbda5c0fc7991bda6cd06d4c0ee5 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Wed, 25 Jun 2025 08:15:37 -0700 Subject: [PATCH 14/98] IO-3255 Fix breadcrumb path. --- .../src/components/breadcrumbs/breadcrumbs.component.jsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/src/components/breadcrumbs/breadcrumbs.component.jsx b/client/src/components/breadcrumbs/breadcrumbs.component.jsx index 93a9d0192..f90af8a11 100644 --- a/client/src/components/breadcrumbs/breadcrumbs.component.jsx +++ b/client/src/components/breadcrumbs/breadcrumbs.component.jsx @@ -5,7 +5,7 @@ import { connect } from "react-redux"; import { Link } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import { selectBreadcrumbs } from "../../redux/application/application.selectors"; -import { selectBodyshop } from "../../redux/user/user.selectors"; +import { selectBodyshop, selectPartsManagementOnly } from "../../redux/user/user.selectors"; import GlobalSearch from "../global-search/global-search.component"; import GlobalSearchOs from "../global-search/global-search-os.component"; import "./breadcrumbs.styles.scss"; @@ -13,10 +13,11 @@ import { useSplitTreatments } from "@splitsoftware/splitio-react"; const mapStateToProps = createStructuredSelector({ breadcrumbs: selectBreadcrumbs, - bodyshop: selectBodyshop + bodyshop: selectBodyshop, + partsManagementOnly: selectPartsManagementOnly }); -export function BreadCrumbs({ breadcrumbs, bodyshop }) { +export function BreadCrumbs({ breadcrumbs, bodyshop, partsManagementOnly }) { const { treatments: { OpenSearch } } = useSplitTreatments({ @@ -34,7 +35,7 @@ export function BreadCrumbs({ breadcrumbs, bodyshop }) { { key: "home", title: ( - + {(bodyshop && bodyshop.shopname && `(${bodyshop.shopname})`) || ""} ) From 8de92403ee08e12ccf54e898c957e1b5ed866bb1 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 27 Jun 2025 13:01:18 -0400 Subject: [PATCH 15/98] feature/IO-3255-simplified-parts-management - Checkpoint --- client/package-lock.json | 128 ++--- client/package.json | 8 +- .../simplified-parts.page.component.jsx | 3 +- package-lock.json | 444 +++++++++--------- package.json | 18 +- ...rtsManagementVehicleDamageEstimateAddRq.js | 95 +++- 6 files changed, 373 insertions(+), 323 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index b357aab33..d9f55d38a 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -21,11 +21,11 @@ "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.31.0", + "@sentry/react": "^9.32.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.1", + "antd": "^5.26.2", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -101,7 +101,7 @@ "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", "@vitejs/plugin-react": "^4.6.0", - "browserslist": "^4.25.0", + "browserslist": "^4.25.1", "browserslist-to-esbuild": "^2.1.1", "chalk": "^5.4.1", "eslint": "^8.57.1", @@ -116,7 +116,7 @@ "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", "vite": "^6.3.5", - "vite-plugin-babel": "^1.3.1", + "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", "vite-plugin-node-polyfills": "^0.23.0", "vite-plugin-pwa": "^1.0.0", @@ -3746,9 +3746,9 @@ } }, "node_modules/@rc-component/trigger": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.6.tgz", - "integrity": "sha512-/9zuTnWwhQ3S3WT1T8BubuFTT46kvnXgaERR9f4BTKyn61/wpf/BvbImzYBubzJibU707FxwbKszLlHjcLiv1Q==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.7.tgz", + "integrity": "sha512-Qggj4Z0AA2i5dJhzlfFSmg1Qrziu8dsdHOihROL5Kl18seO2Eh/ZaTYt2c8a/CyGaTChnFry7BEYew1+/fhSbA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.2", @@ -4466,50 +4466,50 @@ "license": "MIT" }, "node_modules/@sentry-internal/browser-utils": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.31.0.tgz", - "integrity": "sha512-rviu/jUmeQbY4rSO8l4pubOtRIhFtH5Gu/ryRNMTlpJRdomp4uxddqthHUDH5g6xCXZsMTyJEIdx0aTqbgr/GQ==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.32.0.tgz", + "integrity": "sha512-mVWdruSWXF+2WgS24jwLhWFyC/nDQbKXseLR8paU9LGSnVtlBlQseIx1GrANbJrhBxiEWSft4WiuxU34wPsbXg==", "license": "MIT", "dependencies": { - "@sentry/core": "9.31.0" + "@sentry/core": "9.32.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/feedback": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.31.0.tgz", - "integrity": "sha512-Ygi/8UZ7p2B4DhXQjZDtOc45vNUHkfk2XETBTBGkByEQkE8vygzSiKhgRcnVpzwq+8xKFMRy+PxvpcCo+PNQew==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.32.0.tgz", + "integrity": "sha512-OaXaovXqlhN1sG2wtJMhxMEjyeuK7RwY57o96LgKE0bWM//Fs9WWCOkGa+7l8TOf0+0ib7gfhJZlpN0hlqOgRw==", "license": "MIT", "dependencies": { - "@sentry/core": "9.31.0" + "@sentry/core": "9.32.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.31.0.tgz", - "integrity": "sha512-V5rvcO/xSj8JMw4ZnZT2cBYC+UOuIiZ2Flj4EoIurxMrTgowE1uMXUBA32EBfuB5/vQSJXB6W5uAudhk7LjBPQ==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.32.0.tgz", + "integrity": "sha512-mOHUKjUtHbEwshikrCQPM1ZqWAMUEcpEGashnXQp3KQivvbTxrExiNnt6XK5TjJyGvsI3A907Bp/HvEzgneYgQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.31.0", - "@sentry/core": "9.31.0" + "@sentry-internal/browser-utils": "9.32.0", + "@sentry/core": "9.32.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.31.0.tgz", - "integrity": "sha512-VGqfvQCIuXQZeecrBf8bd4sj8lYGzUA/2CffTAkad1nB1Onyz0Kzo54qLWemivCxA3ufHf6DCpNA3Loa/0ywFQ==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.32.0.tgz", + "integrity": "sha512-tu+coeTRpJxknmWPMJC2jqmIM5IsVoRn9gEDdkSrcPbgx/GwgE03fSJVBJL1tOEA8yRNIhZPMR86ORE7/7n2ow==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "9.31.0", - "@sentry/core": "9.31.0" + "@sentry-internal/replay": "9.32.0", + "@sentry/core": "9.32.0" }, "engines": { "node": ">=18" @@ -4525,16 +4525,16 @@ } }, "node_modules/@sentry/browser": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.31.0.tgz", - "integrity": "sha512-DzG72JJTqHzE0Qo2fHeHm3xgFs97InaSQStmTMxOA59yPqvAXbweNPcsgCNu1q76+jZyaJcoy1qOwahnLuEVDg==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.32.0.tgz", + "integrity": "sha512-BzPogpH87n+sC9VPfXaXkiKJtagLpIB87LGg1hSBURpwGx6Rt2ORmaVYgwwuuFZX8Hia727IIM7pbcbNfrXGRQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.31.0", - "@sentry-internal/feedback": "9.31.0", - "@sentry-internal/replay": "9.31.0", - "@sentry-internal/replay-canvas": "9.31.0", - "@sentry/core": "9.31.0" + "@sentry-internal/browser-utils": "9.32.0", + "@sentry-internal/feedback": "9.32.0", + "@sentry-internal/replay": "9.32.0", + "@sentry-internal/replay-canvas": "9.32.0", + "@sentry/core": "9.32.0" }, "engines": { "node": ">=18" @@ -4911,22 +4911,22 @@ } }, "node_modules/@sentry/core": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.31.0.tgz", - "integrity": "sha512-6JeoPGvBgT9m2YFIf2CrW+KrrOYzUqb9+Xwr/Dw25kPjVKy+WJjWqK8DKCNLgkBA22OCmSOmHuRwFR0YxGVdZQ==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.32.0.tgz", + "integrity": "sha512-1wAXMMmeY4Ny2MJBCuri3b4LMVPjqXdgbVgTxxipGW+gzPsjv+8+LCSnJAR/cRBr8JoXV+qGC2tE06rI1XDj3A==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@sentry/react": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.31.0.tgz", - "integrity": "sha512-cZT/AwRiawRED7pB4Ug6ZRbcWd92HQxOPc12KKe5ZUQFEc9jUqH6HqwzQUSMzkg86NrE9Hc6XXga+JZ3Q1Lzow==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.32.0.tgz", + "integrity": "sha512-4d13sA/e9oEEK9cB6DZxVNDLTw9Q2x0WzhKtit6jhFKv1ItQ61Uu+euBJLfy3yCzFGl7PJbfJViMt2bhqjkTuA==", "license": "MIT", "dependencies": { - "@sentry/browser": "9.31.0", - "@sentry/core": "9.31.0", + "@sentry/browser": "9.32.0", + "@sentry/core": "9.32.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -6120,9 +6120,9 @@ } }, "node_modules/antd": { - "version": "5.26.1", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.1.tgz", - "integrity": "sha512-CiLGZ2Ftld+fuoj+U3OL8uouuqUppqFJnW4O/4bOgSWzM9XsJGibpNtUa9QArhrZ5ndfnzlPP/4RVXUK/xfSvQ==", + "version": "5.26.2", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.2.tgz", + "integrity": "sha512-C8dBgwSzXfUS5ousUN+mfcaGFhEOd9wuyhvmw0lQnU9gukpRoFe1B0UKzvr6Z50QgapIl+s03nYlQJUghKqVjQ==", "license": "MIT", "dependencies": { "@ant-design/colors": "^7.2.1", @@ -6136,7 +6136,7 @@ "@rc-component/mutate-observer": "^1.1.0", "@rc-component/qrcode": "~1.0.0", "@rc-component/tour": "~1.15.1", - "@rc-component/trigger": "^2.2.6", + "@rc-component/trigger": "^2.2.7", "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.11", @@ -6164,7 +6164,7 @@ "rc-slider": "~11.1.8", "rc-steps": "~6.0.1", "rc-switch": "~4.1.0", - "rc-table": "~7.51.0", + "rc-table": "~7.51.1", "rc-tabs": "~15.6.1", "rc-textarea": "~1.10.0", "rc-tooltip": "~6.4.0", @@ -6998,9 +6998,9 @@ } }, "node_modules/browserslist": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", - "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", "funding": [ { "type": "opencollective", @@ -7017,8 +7017,8 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001718", - "electron-to-chromium": "^1.5.160", + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, @@ -7197,9 +7197,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001721", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz", - "integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==", + "version": "1.0.30001726", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", + "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", "funding": [ { "type": "opencollective", @@ -8361,9 +8361,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.165", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz", - "integrity": "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw==", + "version": "1.5.176", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.176.tgz", + "integrity": "sha512-2nDK9orkm7M9ZZkjO3PjbEd3VUulQLyg5T9O3enJdFvUg46Hzd4DUvTvAuEgbdHYXyFsiG4A5sO9IzToMH1cDg==", "license": "ISC" }, "node_modules/elliptic": { @@ -14138,9 +14138,9 @@ } }, "node_modules/rc-table": { - "version": "7.51.0", - "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.51.0.tgz", - "integrity": "sha512-7ZlvW6lB0IDKaSFInD6OfJsCepSJJtfsQv2PZLtzEeZd/PLzQnKliXPaoZqkqDdLdJ3jxE2x4sane4DjxcAg+g==", + "version": "7.51.1", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.51.1.tgz", + "integrity": "sha512-5iq15mTHhvC42TlBLRCoCBLoCmGlbRZAlyF21FonFnS/DIC8DeRqnmdyVREwt2CFbPceM0zSNdEeVfiGaqYsKw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.1", @@ -17625,14 +17625,14 @@ "license": "MIT" }, "node_modules/vite-plugin-babel": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/vite-plugin-babel/-/vite-plugin-babel-1.3.1.tgz", - "integrity": "sha512-ikAdgkYQS6ytr6KGmfIbEDES0gBMtw0tUtiwIe8/LEk/ndISFy6IR2MjQUMksirCtrWnqCrixbGKTw2ezOIMrA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/vite-plugin-babel/-/vite-plugin-babel-1.3.2.tgz", + "integrity": "sha512-mEld4OVyuNs5+ISN+U5XyTnNcDwln/s2oER2m0PQ32YYPqPR25E3mfnhAA/RkZJxPuwFkprKWV405aZArE6kzA==", "dev": true, "license": "MIT", "peerDependencies": { "@babel/core": "^7.0.0", - "vite": "^2.7.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + "vite": "^2.7.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "node_modules/vite-plugin-ejs": { diff --git a/client/package.json b/client/package.json index 67de920bf..14524131a 100644 --- a/client/package.json +++ b/client/package.json @@ -20,11 +20,11 @@ "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.31.0", + "@sentry/react": "^9.32.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.1", + "antd": "^5.26.2", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -141,7 +141,7 @@ "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", "@vitejs/plugin-react": "^4.6.0", - "browserslist": "^4.25.0", + "browserslist": "^4.25.1", "browserslist-to-esbuild": "^2.1.1", "chalk": "^5.4.1", "eslint": "^8.57.1", @@ -156,7 +156,7 @@ "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", "vite": "^6.3.5", - "vite-plugin-babel": "^1.3.1", + "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", "vite-plugin-node-polyfills": "^0.23.0", "vite-plugin-pwa": "^1.0.0", diff --git a/client/src/pages/simplified-parts/simplified-parts.page.component.jsx b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx index aa906834f..9603fd624 100644 --- a/client/src/pages/simplified-parts/simplified-parts.page.component.jsx +++ b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx @@ -14,11 +14,11 @@ import PrintCenterModalContainer from "../../components/print-center-modal/print import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-status.component.jsx"; import UpdateAlert from "../../components/update-alert/update-alert.component.jsx"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; -import { useSocket } from "../../contexts/SocketIO/useSocket.js"; import { addAlerts } from "../../redux/application/application.actions.js"; import { selectAlerts } from "../../redux/application/application.selectors.js"; import { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors.js"; import InstanceRenderManager from "../../utils/instanceRenderMgr.js"; + const SimplifiedPartsJobsPage = lazy(() => import("../simplified-parts-jobs/simplified-parts-jobs.page.jsx")); const SimplifiedPartsJobsDetailPage = lazy( () => import("../simplified-parts-jobs-detail/simplified-parts-jobs-detail.container.jsx") @@ -49,7 +49,6 @@ const mapDispatchToProps = (dispatch) => ({ export function SimplifiedPartsPage({ conflict, bodyshop, alerts, setAlerts }) { const { t } = useTranslation(); - const { socket, clientId } = useSocket(); const notification = useNotification(); // State to track displayed alerts diff --git a/package-lock.json b/package-lock.json index ac831e2ce..9014fd22d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,14 @@ "version": "0.2.0", "license": "UNLICENSED", "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.832.0", - "@aws-sdk/client-elasticache": "^3.830.0", - "@aws-sdk/client-s3": "^3.832.0", - "@aws-sdk/client-secrets-manager": "^3.830.0", - "@aws-sdk/client-ses": "^3.830.0", - "@aws-sdk/credential-provider-node": "^3.830.0", - "@aws-sdk/lib-storage": "^3.832.0", - "@aws-sdk/s3-request-presigner": "^3.832.0", + "@aws-sdk/client-cloudwatch-logs": "^3.835.0", + "@aws-sdk/client-elasticache": "^3.835.0", + "@aws-sdk/client-s3": "^3.837.0", + "@aws-sdk/client-secrets-manager": "^3.835.0", + "@aws-sdk/client-ses": "^3.835.0", + "@aws-sdk/credential-provider-node": "^3.835.0", + "@aws-sdk/lib-storage": "^3.837.0", + "@aws-sdk/s3-request-presigner": "^3.837.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -73,7 +73,7 @@ "globals": "^15.15.0", "mock-require": "^3.0.3", "p-limit": "^3.1.0", - "prettier": "^3.6.0", + "prettier": "^3.6.1", "supertest": "^7.1.1", "vitest": "^3.2.4" }, @@ -285,24 +285,24 @@ } }, "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.832.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.832.0.tgz", - "integrity": "sha512-Xpu1HKMafA9j7j/ttvKYcv0a4XRFCOBQFjKvsZTrKeGZoVzoEP+IKBfy8+pGI3zLZEm5N6J5d1ifXbZ+9F0icA==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.835.0.tgz", + "integrity": "sha512-lR08TngWAszUUEW1utaPfLLbDJF5BQVBDclvZF0ke1a4C0o3nU2HyoWy/A7fQJEOXGfiegABdqtbi9w3UHjibA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.830.0", + "@aws-sdk/core": "3.835.0", + "@aws-sdk/credential-provider-node": "3.835.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", + "@aws-sdk/middleware-user-agent": "3.835.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", + "@aws-sdk/util-user-agent-node": "3.835.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/eventstream-serde-browser": "^4.0.4", @@ -312,24 +312,24 @@ "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", + "@smithy/middleware-endpoint": "^4.1.12", + "@smithy/middleware-retry": "^4.1.13", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", + "@smithy/util-defaults-mode-browser": "^4.0.20", + "@smithy/util-defaults-mode-node": "^4.0.20", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", + "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", "@types/uuid": "^9.0.1", "tslib": "^2.6.2", @@ -353,48 +353,48 @@ } }, "node_modules/@aws-sdk/client-elasticache": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.830.0.tgz", - "integrity": "sha512-ln7OISYRUasEL54B0+UEeJLISd3vG2zkdRCCIEVUzh7SOGiHADgCaQAk6WFiGAy4F9uGUWiI5qDkvddTBZT3tw==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.835.0.tgz", + "integrity": "sha512-R3tSQ0VXOtfe4cMFXmtxbfXF6UyBEb99eY4+KBSO9V79wQw5iQGX/jrruWRgSo9r6sxz68kXqkGuxgKOg+D8VQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.830.0", + "@aws-sdk/core": "3.835.0", + "@aws-sdk/credential-provider-node": "3.835.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", + "@aws-sdk/middleware-user-agent": "3.835.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", + "@aws-sdk/util-user-agent-node": "3.835.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", + "@smithy/middleware-endpoint": "^4.1.12", + "@smithy/middleware-retry": "^4.1.13", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", + "@smithy/util-defaults-mode-browser": "^4.0.20", + "@smithy/util-defaults-mode-node": "^4.0.20", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", + "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", "@smithy/util-waiter": "^4.0.5", "tslib": "^2.6.2" @@ -404,32 +404,32 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.832.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.832.0.tgz", - "integrity": "sha512-S+md1zCe71SEuaRDuLHq4mzhYYkVxR1ENa8NwrgInfYoC4xo8/pESoR6i0ZZpcLs0Jw4EyVInWYs4GgDHW70qQ==", + "version": "3.837.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.837.0.tgz", + "integrity": "sha512-sBjPPG30HIfNwpzWuajCDf7agb4YAxPFFpsp3kwgptJF8PEi0HzQg64bskquMzjqLC2tXsn5rKtDVpQOvs29MQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.830.0", + "@aws-sdk/core": "3.835.0", + "@aws-sdk/credential-provider-node": "3.835.0", "@aws-sdk/middleware-bucket-endpoint": "3.830.0", "@aws-sdk/middleware-expect-continue": "3.821.0", - "@aws-sdk/middleware-flexible-checksums": "3.826.0", + "@aws-sdk/middleware-flexible-checksums": "3.835.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-location-constraint": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-sdk-s3": "3.826.0", + "@aws-sdk/middleware-sdk-s3": "3.835.0", "@aws-sdk/middleware-ssec": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", + "@aws-sdk/middleware-user-agent": "3.835.0", "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/signature-v4-multi-region": "3.826.0", + "@aws-sdk/signature-v4-multi-region": "3.835.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", + "@aws-sdk/util-user-agent-node": "3.835.0", "@aws-sdk/xml-builder": "3.821.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", @@ -443,24 +443,24 @@ "@smithy/invalid-dependency": "^4.0.4", "@smithy/md5-js": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", + "@smithy/middleware-endpoint": "^4.1.12", + "@smithy/middleware-retry": "^4.1.13", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", + "@smithy/util-defaults-mode-browser": "^4.0.20", + "@smithy/util-defaults-mode-node": "^4.0.20", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", + "@smithy/util-retry": "^4.0.6", "@smithy/util-stream": "^4.2.2", "@smithy/util-utf8": "^4.0.0", "@smithy/util-waiter": "^4.0.5", @@ -486,48 +486,48 @@ } }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.830.0.tgz", - "integrity": "sha512-St2EK5i91vwv9LmDUmWevZYl+Y/TYRP/AHm7gxZm1LkEf1VEjkSizUMm91JOnH6y+0Clok9mqe6jZ/XossMXlw==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.835.0.tgz", + "integrity": "sha512-w8xIFhxP54kRdmTuRjxOAgNU7MCSgVieXx5pUxMD6B92dpqDTjnVFgTDX8fpUFZSrSwe5dOCiHEDKZsV20YNaQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.830.0", + "@aws-sdk/core": "3.835.0", + "@aws-sdk/credential-provider-node": "3.835.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", + "@aws-sdk/middleware-user-agent": "3.835.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", + "@aws-sdk/util-user-agent-node": "3.835.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", + "@smithy/middleware-endpoint": "^4.1.12", + "@smithy/middleware-retry": "^4.1.13", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", + "@smithy/util-defaults-mode-browser": "^4.0.20", + "@smithy/util-defaults-mode-node": "^4.0.20", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", + "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", "@types/uuid": "^9.0.1", "tslib": "^2.6.2", @@ -551,48 +551,48 @@ } }, "node_modules/@aws-sdk/client-ses": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.830.0.tgz", - "integrity": "sha512-Y2XaJkqHJ7qM4cpCw3YS96fMZgT44mP3HLP+9dU0ct29L+iwf3zhigJGQzakieMdJfuTFZe7Vi6s1RbcWv5v5w==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.835.0.tgz", + "integrity": "sha512-Eugl8TqnvNWs2i38XVXwiLKWIreRdiOrIaf2lCPgowKZqw6yvLG6+Yc3yABzZZ5bnUZdDHt1pYfIMUbSXLGdAw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.830.0", + "@aws-sdk/core": "3.835.0", + "@aws-sdk/credential-provider-node": "3.835.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", + "@aws-sdk/middleware-user-agent": "3.835.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", + "@aws-sdk/util-user-agent-node": "3.835.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", + "@smithy/middleware-endpoint": "^4.1.12", + "@smithy/middleware-retry": "^4.1.13", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", + "@smithy/util-defaults-mode-browser": "^4.0.20", + "@smithy/util-defaults-mode-node": "^4.0.20", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", + "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", "@smithy/util-waiter": "^4.0.5", "tslib": "^2.6.2" @@ -602,47 +602,47 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", - "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.835.0.tgz", + "integrity": "sha512-4J19IcBKU5vL8yw/YWEvbwEGcmCli0rpRyxG53v0K5/3weVPxVBbKfkWcjWVQ4qdxNz2uInfbTde4BRBFxWllQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", + "@aws-sdk/core": "3.835.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", + "@aws-sdk/middleware-user-agent": "3.835.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", + "@aws-sdk/util-user-agent-node": "3.835.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", + "@smithy/middleware-endpoint": "^4.1.12", + "@smithy/middleware-retry": "^4.1.13", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", + "@smithy/util-defaults-mode-browser": "^4.0.20", + "@smithy/util-defaults-mode-node": "^4.0.20", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", + "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -651,9 +651,9 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", - "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.835.0.tgz", + "integrity": "sha512-7mnf4xbaLI8rkDa+w6fUU48dG6yDuOgLXEPe4Ut3SbMp1ceJBPMozNHbCwkiyHk3HpxZYf8eVy0wXhJMrxZq5w==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.821.0", @@ -663,7 +663,7 @@ "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", @@ -677,12 +677,12 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.826.0.tgz", - "integrity": "sha512-DK3pQY8+iKK3MGDdC3uOZQ2psU01obaKlTYhEwNu4VWzgwQL4Vi3sWj4xSWGEK41vqZxiRLq6fOq7ysRI+qEZA==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.835.0.tgz", + "integrity": "sha512-U9LFWe7+ephNyekpUbzT7o6SmJTmn6xkrPkE0D7pbLojnPVi/8SZKyjtgQGIsAv+2kFkOCqMOIYUKd/0pE7uew==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", + "@aws-sdk/core": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -693,18 +693,18 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.826.0.tgz", - "integrity": "sha512-N+IVZBh+yx/9GbMZTKO/gErBi/FYZQtcFRItoLbY+6WU+0cSWyZYfkoeOxHmQV3iX9k65oljERIWUmL9x6OSQg==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.835.0.tgz", + "integrity": "sha512-jCdNEsQklil7frDm/BuVKl4ubVoQHRbV6fnkOjmxAJz0/v7cR8JP0jBGlqKKzh3ROh5/vo1/5VUZbCTLpc9dSg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", + "@aws-sdk/core": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/node-http-handler": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" @@ -714,18 +714,18 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", - "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.835.0.tgz", + "integrity": "sha512-nqF6rYRAnJedmvDfrfKygzyeADcduDvtvn7GlbQQbXKeR2l7KnCdhuxHa0FALLvspkHiBx7NtInmvnd5IMuWsw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-env": "3.826.0", - "@aws-sdk/credential-provider-http": "3.826.0", - "@aws-sdk/credential-provider-process": "3.826.0", - "@aws-sdk/credential-provider-sso": "3.830.0", - "@aws-sdk/credential-provider-web-identity": "3.830.0", - "@aws-sdk/nested-clients": "3.830.0", + "@aws-sdk/core": "3.835.0", + "@aws-sdk/credential-provider-env": "3.835.0", + "@aws-sdk/credential-provider-http": "3.835.0", + "@aws-sdk/credential-provider-process": "3.835.0", + "@aws-sdk/credential-provider-sso": "3.835.0", + "@aws-sdk/credential-provider-web-identity": "3.835.0", + "@aws-sdk/nested-clients": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -738,17 +738,17 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", - "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.835.0.tgz", + "integrity": "sha512-77B8elyZlaEd7vDYyCnYtVLuagIBwuJ0AQ98/36JMGrYX7TT8UVAhiDAfVe0NdUOMORvDNFfzL06VBm7wittYw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.826.0", - "@aws-sdk/credential-provider-http": "3.826.0", - "@aws-sdk/credential-provider-ini": "3.830.0", - "@aws-sdk/credential-provider-process": "3.826.0", - "@aws-sdk/credential-provider-sso": "3.830.0", - "@aws-sdk/credential-provider-web-identity": "3.830.0", + "@aws-sdk/credential-provider-env": "3.835.0", + "@aws-sdk/credential-provider-http": "3.835.0", + "@aws-sdk/credential-provider-ini": "3.835.0", + "@aws-sdk/credential-provider-process": "3.835.0", + "@aws-sdk/credential-provider-sso": "3.835.0", + "@aws-sdk/credential-provider-web-identity": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -761,12 +761,12 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.826.0.tgz", - "integrity": "sha512-kURrc4amu3NLtw1yZw7EoLNEVhmOMRUTs+chaNcmS+ERm3yK0nKjaJzmKahmwlTQTSl3wJ8jjK7x962VPo+zWw==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.835.0.tgz", + "integrity": "sha512-qXkTt5pAhSi2Mp9GdgceZZFo/cFYrA735efqi/Re/nf0lpqBp8mRM8xv+iAaPHV4Q10q0DlkbEidT1DhxdT/+w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", + "@aws-sdk/core": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -778,14 +778,14 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", - "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.835.0.tgz", + "integrity": "sha512-jAiEMryaPFXayYGszrc7NcgZA/zrrE3QvvvUBh/Udasg+9Qp5ZELdJCm/p98twNyY9n5i6Ex6VgvdxZ7+iEheQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.830.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/token-providers": "3.830.0", + "@aws-sdk/client-sso": "3.835.0", + "@aws-sdk/core": "3.835.0", + "@aws-sdk/token-providers": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -797,13 +797,13 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", - "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.835.0.tgz", + "integrity": "sha512-zfleEFXDLlcJ7cyfS4xSyCRpd8SVlYZfH3rp0pg2vPYKbnmXVE0r+gPIYXl4L+Yz4A2tizYl63nKCNdtbxadog==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/nested-clients": "3.830.0", + "@aws-sdk/core": "3.835.0", + "@aws-sdk/nested-clients": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -814,14 +814,14 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.832.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.832.0.tgz", - "integrity": "sha512-NM+q0WD8TCreo+tvKy0AZytHQQC19zXVG8iapDhafLNs1W72zAQ659pTfVzsC00Zvwtsp0LI/b2FWTjkjTAAdA==", + "version": "3.837.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.837.0.tgz", + "integrity": "sha512-V7NkOw8bX1HdRTWSy+pMCpHQgSaUh/l1fQIx63anu4TORe18pkLkos0x5YnPJ+o2ksbCVtokDuOG1jGdVM0NPg==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/smithy-client": "^4.4.3", + "@smithy/middleware-endpoint": "^4.1.12", + "@smithy/smithy-client": "^4.4.4", "buffer": "5.6.0", "events": "3.3.0", "stream-browserify": "3.0.0", @@ -831,7 +831,7 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.832.0" + "@aws-sdk/client-s3": "^3.837.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { @@ -868,15 +868,15 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.826.0.tgz", - "integrity": "sha512-Fz9w8CFYPfSlHEB6feSsi06hdS+s+FB8k5pO4L7IV0tUa78mlhxF/VNlAJaVWYyOkZXl4HPH2K48aapACSQOXw==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.835.0.tgz", + "integrity": "sha512-9ezorQYlr5cQY28zWAReFhNKUTaXsi3TMvXIagMRrSeWtQ7R6TCYnt91xzHRCmFR2kp3zLI+dfoeH+wF3iCKUw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "3.826.0", + "@aws-sdk/core": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/is-array-buffer": "^4.0.0", "@smithy/node-config-provider": "^4.1.3", @@ -950,19 +950,19 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.826.0.tgz", - "integrity": "sha512-8F0qWaYKfvD/de1AKccXuigM+gb/IZSncCqxdnFWqd+TFzo9qI9Hh+TpUhWOMYSgxsMsYQ8ipmLzlD/lDhjrmA==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.835.0.tgz", + "integrity": "sha512-oPebxpVf9smInHhevHh3APFZagGU+4RPwXEWv9YtYapFvsMq+8QXFvOfxfVZ/mwpe0JVG7EiJzL9/9Kobmts8Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", + "@aws-sdk/core": "3.835.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-arn-parser": "3.804.0", "@smithy/core": "^3.5.3", "@smithy/node-config-provider": "^4.1.3", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.4", @@ -989,12 +989,12 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", - "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.835.0.tgz", + "integrity": "sha512-2gmAYygeE/gzhyF2XlkcbMLYFTbNfV61n+iCFa/ZofJHXYE+RxSyl5g4kujLEs7bVZHmjQZJXhprVSkGccq3/w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", + "@aws-sdk/core": "3.835.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-endpoints": "3.828.0", "@smithy/core": "^3.5.3", @@ -1007,47 +1007,47 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", - "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.835.0.tgz", + "integrity": "sha512-UtmOO0U5QkicjCEv+B32qqRAnS7o2ZkZhC+i3ccH1h3fsfaBshpuuNBwOYAzRCRBeKW5fw3ANFrV/+2FTp4jWg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", + "@aws-sdk/core": "3.835.0", "@aws-sdk/middleware-host-header": "3.821.0", "@aws-sdk/middleware-logger": "3.821.0", "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", + "@aws-sdk/middleware-user-agent": "3.835.0", "@aws-sdk/region-config-resolver": "3.821.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-endpoints": "3.828.0", "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", + "@aws-sdk/util-user-agent-node": "3.835.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.5.3", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", + "@smithy/middleware-endpoint": "^4.1.12", + "@smithy/middleware-retry": "^4.1.13", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", + "@smithy/util-defaults-mode-browser": "^4.0.20", + "@smithy/util-defaults-mode-node": "^4.0.20", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", + "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -1073,17 +1073,17 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.832.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.832.0.tgz", - "integrity": "sha512-zXuwfaAYu99LUF7/6iBr3UlKCMaMImBwfmLXJQlvtE3ebrERXQuISME9Vjd2oG+hJ6XcX6RJqkeIvZBytMzvRw==", + "version": "3.837.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.837.0.tgz", + "integrity": "sha512-h/D/cqeciBPGFSHIHRQm0q/CDvToV4rUoPef3tWzYtfoKzqfYaqRO175FnDv/4XgOYpdoqv6q36bx8KueVQ62w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/signature-v4-multi-region": "3.826.0", + "@aws-sdk/signature-v4-multi-region": "3.835.0", "@aws-sdk/types": "3.821.0", "@aws-sdk/util-format-url": "3.821.0", - "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/middleware-endpoint": "^4.1.12", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.4", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, @@ -1092,12 +1092,12 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.826.0.tgz", - "integrity": "sha512-3fEi/zy6tpMzomYosksGtu7jZqGFcdBXoL7YRsG7OEeQzBbOW9B+fVaQZ4jnsViSjzA/yKydLahMrfPnt+iaxg==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.835.0.tgz", + "integrity": "sha512-rEtJH4dIwJYlXXe5rIH+uTCQmd2VIjuaoHlDY3Dr4nxF6po6U7vKsLfybIU2tgflGVqoqYQnXsfW/kj/Rh+/ow==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.826.0", + "@aws-sdk/middleware-sdk-s3": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", @@ -1109,13 +1109,13 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", - "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.835.0.tgz", + "integrity": "sha512-zN1P3BE+Rv7w7q/CDA8VCQox6SE9QTn0vDtQ47AHA3eXZQQgYzBqgoLgJxR9rKKBIRGZqInJa/VRskLL95VliQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/nested-clients": "3.830.0", + "@aws-sdk/core": "3.835.0", + "@aws-sdk/nested-clients": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -1206,12 +1206,12 @@ } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", - "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", + "version": "3.835.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.835.0.tgz", + "integrity": "sha512-gY63QZ4W5w9JYHYuqvUxiVGpn7IbCt1ODPQB0ZZwGGr3WRmK+yyZxCtFjbYhEQDQLgTWpf8YgVxgQLv2ps0PJg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.828.0", + "@aws-sdk/middleware-user-agent": "3.835.0", "@aws-sdk/types": "3.821.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -2916,9 +2916,9 @@ } }, "node_modules/@smithy/core": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.5.3.tgz", - "integrity": "sha512-xa5byV9fEguZNofCclv6v9ra0FYh5FATQW/da7FQUVTic94DfrN/NvmKZjrMyzbpqfot9ZjBaO8U1UeTbmSLuA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.6.0.tgz", + "integrity": "sha512-Pgvfb+TQ4wUNLyHzvgCP4aYZMh16y7GcfF59oirRHcgGgkH1e/s9C0nv/v3WP+Quymyr5je71HeFQCwh+44XLg==", "license": "Apache-2.0", "dependencies": { "@smithy/middleware-serde": "^4.0.8", @@ -3135,12 +3135,12 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.11.tgz", - "integrity": "sha512-zDogwtRLzKl58lVS8wPcARevFZNBOOqnmzWWxVe9XiaXU2CADFjvJ9XfNibgkOWs08sxLuSr81NrpY4mgp9OwQ==", + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.13.tgz", + "integrity": "sha512-xg3EHV/Q5ZdAO5b0UiIMj3RIOCobuS40pBBODguUDVdko6YK6QIzCVRrHTogVuEKglBWqWenRnZ71iZnLL3ZAQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/middleware-serde": "^4.0.8", "@smithy/node-config-provider": "^4.1.3", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -3154,18 +3154,18 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.12.tgz", - "integrity": "sha512-wvIH70c4e91NtRxdaLZF+mbLZ/HcC6yg7ySKUiufL6ESp6zJUSnJucZ309AvG9nqCFHSRB5I6T3Ez1Q9wCh0Ww==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.14.tgz", + "integrity": "sha512-eoXaLlDGpKvdmvt+YBfRXE7HmIEtFF+DJCbTPwuLunP0YUnrydl+C4tS+vEM0+nyxXrX3PSUFqC+lP1+EHB1Tw==", "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.1.3", "@smithy/protocol-http": "^5.1.2", - "@smithy/service-error-classification": "^4.0.5", - "@smithy/smithy-client": "^4.4.3", + "@smithy/service-error-classification": "^4.0.6", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", + "@smithy/util-retry": "^4.0.6", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -3298,9 +3298,9 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.5.tgz", - "integrity": "sha512-LvcfhrnCBvCmTee81pRlh1F39yTS/+kYleVeLCwNtkY8wtGg8V/ca9rbZZvYIl8OjlMtL6KIjaiL/lgVqHD2nA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.6.tgz", + "integrity": "sha512-RRoTDL//7xi4tn5FrN2NzH17jbgmnKidUqd4KvquT0954/i6CXXkh1884jBiunq24g9cGtPBEXlU40W6EpNOOg==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.3.1" @@ -3342,13 +3342,13 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.3.tgz", - "integrity": "sha512-xxzNYgA0HD6ETCe5QJubsxP0hQH3QK3kbpJz3QrosBCuIWyEXLR/CO5hFb2OeawEKUxMNhz3a1nuJNN2np2RMA==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.5.tgz", + "integrity": "sha512-+lynZjGuUFJaMdDYSTMnP/uPBBXXukVfrJlP+1U/Dp5SFTEI++w6NMga8DjOENxecOF71V9Z2DllaVDYRnGlkg==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.5.3", - "@smithy/middleware-endpoint": "^4.1.11", + "@smithy/core": "^3.6.0", + "@smithy/middleware-endpoint": "^4.1.13", "@smithy/middleware-stack": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", @@ -3449,13 +3449,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.19", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.19.tgz", - "integrity": "sha512-mvLMh87xSmQrV5XqnUYEPoiFFeEGYeAKIDDKdhE2ahqitm8OHM3aSvhqL6rrK6wm1brIk90JhxDf5lf2hbrLbQ==", + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.21.tgz", + "integrity": "sha512-wM0jhTytgXu3wzJoIqpbBAG5U6BwiubZ6QKzSbP7/VbmF1v96xlAbX2Am/mz0Zep0NLvLh84JT0tuZnk3wmYQA==", "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.0.4", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "bowser": "^2.11.0", "tslib": "^2.6.2" @@ -3465,16 +3465,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.19", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.19.tgz", - "integrity": "sha512-8tYnx+LUfj6m+zkUUIrIQJxPM1xVxfRBvoGHua7R/i6qAxOMjqR6CpEpDwKoIs1o0+hOjGvkKE23CafKL0vJ9w==", + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.21.tgz", + "integrity": "sha512-/F34zkoU0GzpUgLJydHY8Rxu9lBn8xQC/s/0M0U9lLBkYbA1htaAFjWYJzpzsbXPuri5D1H8gjp2jBum05qBrA==", "license": "Apache-2.0", "dependencies": { "@smithy/config-resolver": "^4.1.4", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", - "@smithy/smithy-client": "^4.4.3", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, @@ -3522,12 +3522,12 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.5.tgz", - "integrity": "sha512-V7MSjVDTlEt/plmOFBn1762Dyu5uqMrV2Pl2X0dYk4XvWfdWJNe9Bs5Bzb56wkCuiWjSfClVMGcsuKrGj7S/yg==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.6.tgz", + "integrity": "sha512-+YekoF2CaSMv6zKrA6iI/N9yva3Gzn4L6n35Luydweu5MMPYpiGZlWqehPHDHyNbnyaYlz/WJyYAZnC+loBDZg==", "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.0.5", + "@smithy/service-error-classification": "^4.0.6", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, @@ -9826,9 +9826,9 @@ } }, "node_modules/prettier": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.0.tgz", - "integrity": "sha512-ujSB9uXHJKzM/2GBuE0hBOUgC77CN3Bnpqa+g80bkv3T3A93wL/xlzDATHhnhkzifz/UE2SNOvmbTz5hSkDlHw==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.1.tgz", + "integrity": "sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A==", "dev": true, "license": "MIT", "bin": { diff --git a/package.json b/package.json index 199ae1f76..5155066ff 100644 --- a/package.json +++ b/package.json @@ -16,14 +16,14 @@ "job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js" }, "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.832.0", - "@aws-sdk/client-elasticache": "^3.830.0", - "@aws-sdk/client-s3": "^3.832.0", - "@aws-sdk/client-secrets-manager": "^3.830.0", - "@aws-sdk/client-ses": "^3.830.0", - "@aws-sdk/credential-provider-node": "^3.830.0", - "@aws-sdk/lib-storage": "^3.832.0", - "@aws-sdk/s3-request-presigner": "^3.832.0", + "@aws-sdk/client-cloudwatch-logs": "^3.835.0", + "@aws-sdk/client-elasticache": "^3.835.0", + "@aws-sdk/client-s3": "^3.837.0", + "@aws-sdk/client-secrets-manager": "^3.835.0", + "@aws-sdk/client-ses": "^3.835.0", + "@aws-sdk/credential-provider-node": "^3.835.0", + "@aws-sdk/lib-storage": "^3.837.0", + "@aws-sdk/s3-request-presigner": "^3.837.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -80,7 +80,7 @@ "globals": "^15.15.0", "mock-require": "^3.0.3", "p-limit": "^3.1.0", - "prettier": "^3.6.0", + "prettier": "^3.6.1", "supertest": "^7.1.1", "vitest": "^3.2.4" } diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index ba9ac2aa2..1ab8e4e64 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -55,6 +55,34 @@ const parseXml = async (xml, logger) => { } }; +/** + * Recursively strip `xml2js`-style { _: 'value', $: { ... } } nodes into plain strings. + * @param {*} obj - Parsed XML object + * @returns {*} Normalized object + */ +const normalizeXmlObject = (obj) => { + if (Array.isArray(obj)) { + return obj.map(normalizeXmlObject); + } + + if (typeof obj === "object" && obj !== null) { + if (Object.keys(obj).length === 2 && "_" in obj && "$" in obj) { + return normalizeXmlObject(obj._); // unwrap {_:"value",$:{...}} to just "value" + } + if (Object.keys(obj).length === 1 && "_" in obj) { + return normalizeXmlObject(obj._); // unwrap {_:"value"} + } + + const normalized = {}; + for (const key in obj) { + normalized[key] = normalizeXmlObject(obj[key]); + } + return normalized; + } + + return obj; +}; + /** * Fetches the default order status for a bodyshop. * @param {string} shopId - The bodyshop UUID. @@ -81,7 +109,17 @@ const extractPartsTaxRates = (profile = {}) => { const partsTaxRates = {}; for (const code of KNOWN_PART_RATE_TYPES) { - const rateInfo = rateInfos.find((r) => (r?.RateType || "").toUpperCase() === code); + const rateInfo = rateInfos.find((r) => { + const rateType = + typeof r?.RateType === "string" + ? r.RateType + : typeof r?.RateType === "object" && r?.RateType._ // xml2js sometimes uses _ for text content + ? r.RateType._ + : ""; + + return rateType.toUpperCase() === code; + }); + if (!rateInfo) { partsTaxRates[code] = {}; continue; @@ -111,7 +149,6 @@ const extractPartsTaxRates = (profile = {}) => { return partsTaxRates; }; - /** * Extracts job-related data from the XML request. * @param {object} rq - The VehicleDamageEstimateAddRq object. @@ -151,31 +188,44 @@ const extractJobData = (rq) => { * @param {string} shopId - The bodyshop UUID. * @returns {object} Owner data for insertion and inline use. */ +/** + * Extracts owner data from the XML request. + * Falls back to Claimant if Owner is missing. + * @param {object} rq - The VehicleDamageEstimateAddRq object. + * @param {string} shopId - The bodyshop UUID. + * @returns {object} Owner data for insertion and inline use. + */ const extractOwnerData = (rq, shopId) => { - const ownerParty = rq.AdminInfo?.Owner?.Party || {}; - const adr = ownerParty.PersonInfo?.Communications?.Address || {}; + // Prefer Owner, fallback to Claimant + const ownerOrClaimant = rq.AdminInfo?.Owner?.Party || rq.AdminInfo?.Claimant?.Party || {}; + + const personInfo = ownerOrClaimant.PersonInfo || {}; + const personName = personInfo.PersonName || {}; + const address = personInfo.Communications?.Address || {}; + let ownr_ph1, ownr_ph2, ownr_ea; - (Array.isArray(ownerParty.ContactInfo?.Communications) - ? ownerParty.ContactInfo.Communications - : [ownerParty.ContactInfo?.Communications || {}] - ).forEach((c) => { + const comms = Array.isArray(ownerOrClaimant.ContactInfo?.Communications) + ? ownerOrClaimant.ContactInfo.Communications + : [ownerOrClaimant.ContactInfo?.Communications || {}]; + + for (const c of comms) { if (c.CommQualifier === "CP") ownr_ph1 = c.CommPhone; if (c.CommQualifier === "WP") ownr_ph2 = c.CommPhone; if (c.CommQualifier === "EM") ownr_ea = c.CommEmail; - }); + } return { shopid: shopId, - ownr_fn: ownerParty.PersonInfo?.PersonName?.FirstName || null, - ownr_ln: ownerParty.PersonInfo?.PersonName?.LastName || null, - ownr_co_nm: ownerParty.OrgInfo?.CompanyName || null, - ownr_addr1: adr.Address1 || null, - ownr_addr2: adr.Address2 || null, - ownr_city: adr.City || null, - ownr_st: adr.StateProvince || null, - ownr_zip: adr.PostalCode || null, - ownr_ctry: adr.Country || null, + ownr_fn: personName.FirstName || null, + ownr_ln: personName.LastName || null, + ownr_co_nm: ownerOrClaimant.OrgInfo?.CompanyName || null, + ownr_addr1: address.Address1 || null, + ownr_addr2: address.Address2 || null, + ownr_city: address.City || null, + ownr_st: address.StateProvince || null, + ownr_zip: address.PostalCode || null, + ownr_ctry: address.Country || null, ownr_ph1, ownr_ph2, ownr_ea @@ -341,9 +391,9 @@ const extractVehicleData = (rq, shopId) => { v_mldgcode: desc.MldgCode || null, v_makecode: desc.MakeCode || null, trim_color: interior.ColorName || desc.TrimColor || null, - db_v_code: desc.DatabaseCode || null, - v_model_num: desc.ModelNum || null, - v_odo: desc.OdometerInfo?.OdometerReading || null + db_v_code: desc.DatabaseCode || null + // v_model_num: desc.ModelNum || null + // v_odo: desc.OdometerInfo?.OdometerReading || null }; }; @@ -436,7 +486,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { try { // Parse XML const payload = await parseXml(req.body, logger); - const rq = payload.VehicleDamageEstimateAddRq; + const rq = normalizeXmlObject(payload.VehicleDamageEstimateAddRq); if (!rq) { logger.log("parts-missing-root", "error"); return res.status(400).send("Missing "); @@ -534,6 +584,7 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { return res.status(200).json({ success: true, jobId: newJob.id }); } catch (err) { logger.log("parts-route-error", "error", null, null, { error: err }); + console.dir({ err }); return res.status(err.status || 500).json({ error: err.message || "Internal error" }); } }; From 646c42b8c76900a4ff178956c47cdb67960f2388 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 27 Jun 2025 13:48:49 -0400 Subject: [PATCH 16/98] feature/IO-3255-simplified-parts-management - Checkpoint --- .../partsManagement.queries.js | 69 ++++++++++++++- ...rtsManagementVehicleDamageEstimateAddRq.js | 83 ++++++++++++++++++- 2 files changed, 150 insertions(+), 2 deletions(-) diff --git a/server/integrations/partsManagement/partsManagement.queries.js b/server/integrations/partsManagement/partsManagement.queries.js index 45a88ad58..e0ba6088c 100644 --- a/server/integrations/partsManagement/partsManagement.queries.js +++ b/server/integrations/partsManagement/partsManagement.queries.js @@ -32,9 +32,76 @@ const INSERT_JOB_WITH_LINES = ` } `; +const GET_JOB_BY_CLAIM = ` + query GetJobByClaim($shopid: uuid!, $clm_no: String!) { + jobs( + where: { shopid: { _eq: $shopid }, clm_no: { _eq: $clm_no } } + order_by: { created_at: desc } + limit: 1 + ) { + id + } + } +`; + +const UPDATE_JOB_BY_ID = ` + mutation UpdateJobById($id: uuid!, $job: jobs_set_input!) { + update_jobs_by_pk(pk_columns: { id: $id }, _set: $job) { + id + } + } +`; + +const UPSERT_JOBLINES = ` + mutation UpsertJoblines($joblines: [joblines_insert_input!]!) { + insert_joblines( + objects: $joblines + on_conflict: { + constraint: joblines_jobid_line_no_unq_seq_key + update_columns: [ + status + line_desc + part_type + part_qty + oem_partno + db_price + act_price + mod_lbr_ty + mod_lb_hrs + lbr_op + lbr_amt + notes + ] + } + ) { + affected_rows + } + } +`; +const DELETE_JOBLINES_BY_JOBID = ` + mutation DeleteJoblinesByJobId($jobid: uuid!) { + delete_joblines(where: { jobid: { _eq: $jobid } }) { + affected_rows + } + } +`; + +const INSERT_JOBLINES = ` + mutation InsertJoblines($joblines: [joblines_insert_input!]!) { + insert_joblines(objects: $joblines) { + affected_rows + } + } +`; + module.exports = { GET_BODYSHOP_STATUS, GET_VEHICLE_BY_SHOP_VIN, INSERT_OWNER, - INSERT_JOB_WITH_LINES + INSERT_JOB_WITH_LINES, + GET_JOB_BY_CLAIM, + UPDATE_JOB_BY_ID, + DELETE_JOBLINES_BY_JOBID, + UPSERT_JOBLINES, + INSERT_JOBLINES }; diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index 1ab8e4e64..ea3803725 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -9,7 +9,11 @@ const { GET_BODYSHOP_STATUS, GET_VEHICLE_BY_SHOP_VIN, INSERT_OWNER, - INSERT_JOB_WITH_LINES + INSERT_JOB_WITH_LINES, + GET_JOB_BY_CLAIM, + UPDATE_JOB_BY_ID, + INSERT_JOBLINES, + DELETE_JOBLINES_BY_JOBID } = require("./partsManagement.queries"); // Defaults @@ -436,6 +440,18 @@ const extractJobLines = (rq) => { }); }; +/** + * Checks if the request is a supplement or a document portion delta. + * TODO: This is a temporary check, should be replaced with a proper field in the XML. + * @param rq + * @returns {boolean} + */ +const isSupplement = (rq) => { + const docStatus = rq.DocumentInfo?.DocumentStatus; + const historyType = rq.RepairTotalsHistory?.HistoryTotalType; + return docStatus === "S" || historyType === "DocumentPortionDelta"; +}; + /** * Finds an existing vehicle by shopId and VIN. * @param {string} shopId - The bodyshop UUID. @@ -458,6 +474,26 @@ const findExistingVehicle = async (shopId, v_vin, logger) => { return null; }; +/** + * Finds an existing job by shopid and claim number. + * @param shopid + * @param clm_no + * @param logger + * @returns {Promise<*|null>} + */ +const findExistingJob = async (shopid, clm_no, logger) => { + try { + const { jobs } = await client.request(GET_JOB_BY_CLAIM, { + shopid, + clm_no + }); + return jobs?.[0] || null; + } catch (err) { + logger.log("parts-job-fetch-failed", "warn", null, null, { error: err }); + return null; + } +}; + /** * Inserts an owner and returns the owner ID. * @param {object} ownerInput - The owner data to insert. @@ -532,6 +568,21 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const joblinesData = extractJobLines(rq); const insuranceData = extractInsuranceData(rq); + // Uncomment for debugging + // console.dir( + // { + // joblinesData, + // lossInfo, + // insuranceData, + // vehicleData, + // ownerData, + // adjusterData, + // repairFacilityData, + // estimatorData + // }, + // { depth: null } + // ); + // Find or create relationships const ownerid = await insertOwner(ownerData, logger); const vehicleid = await findExistingVehicle(shopId, vehicleData.v_vin, logger); @@ -577,6 +628,36 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { joblines: { data: joblinesData } }; + // Check if this is a supplement or document portion delta. + if (isSupplement(rq)) { + console.log("----------------------IS SUPPLEMENT----------------------"); + const existingJob = await findExistingJob(shopId, clm_no, logger); + if (existingJob) { + const { joblines, ...jobWithoutLines } = jobInput; + + await client.request(UPDATE_JOB_BY_ID, { + id: existingJob.id, + job: jobWithoutLines + }); + + await client.request(DELETE_JOBLINES_BY_JOBID, { + jobid: existingJob.id + }); + + if (joblines?.data?.length) { + const joblinesWithJobId = joblines.data.map((line) => ({ + ...line, + jobid: existingJob.id + })); + + await client.request(INSERT_JOBLINES, { joblines: joblinesWithJobId }); + } + + logger.log("parts-job-updated", "info", existingJob.id); + return res.status(200).json({ success: true, jobId: existingJob.id }); + } + } + // Insert job const { insert_jobs_one: newJob } = await client.request(INSERT_JOB_WITH_LINES, { job: jobInput }); logger.log("parts-job-created", "info", newJob.id, null); From 6496f6c414113fea5e91f36cfc1bdc8e07db0e92 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Thu, 3 Jul 2025 11:52:01 -0400 Subject: [PATCH 17/98] feature/IO-3255-simplified-parts-management - Bump deps --- client/package-lock.json | 218 ++++++------ client/package.json | 24 +- package-lock.json | 724 +++++++++++++++++++-------------------- package.json | 28 +- 4 files changed, 497 insertions(+), 497 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index d9f55d38a..b672a0c37 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -13,19 +13,19 @@ "@apollo/client": "^3.13.6", "@emotion/is-prop-valid": "^1.3.1", "@fingerprintjs/fingerprintjs": "^4.6.1", - "@firebase/analytics": "^0.10.16", - "@firebase/app": "^0.13.1", - "@firebase/auth": "^1.10.7", - "@firebase/firestore": "^4.7.17", - "@firebase/messaging": "^0.12.21", + "@firebase/analytics": "^0.10.17", + "@firebase/app": "^0.13.2", + "@firebase/auth": "^1.10.8", + "@firebase/firestore": "^4.8.0", + "@firebase/messaging": "^0.12.22", "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.32.0", + "@sentry/react": "^9.34.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.2", + "antd": "^5.26.3", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -91,11 +91,11 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.45.1", + "@dotenvx/dotenvx": "^1.45.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", - "@eslint/js": "^9.29.0", - "@playwright/test": "^1.53.1", + "@eslint/js": "^9.30.1", + "@playwright/test": "^1.53.2", "@sentry/webpack-plugin": "^3.5.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", @@ -111,7 +111,7 @@ "jsdom": "^26.0.0", "memfs": "^4.17.2", "os-browserify": "^0.3.0", - "playwright": "^1.53.1", + "playwright": "^1.53.2", "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", @@ -119,7 +119,7 @@ "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", "vite-plugin-node-polyfills": "^0.23.0", - "vite-plugin-pwa": "^1.0.0", + "vite-plugin-pwa": "^1.0.1", "vite-plugin-style-import": "^2.0.0", "vitest": "^3.2.4", "workbox-window": "^7.3.0" @@ -2585,9 +2585,9 @@ } }, "node_modules/@dotenvx/dotenvx": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.45.1.tgz", - "integrity": "sha512-wKHPD+/NMMJVBPg3i98uD9jsURDy+Ck6RQRiWf39TlOAzC+Ge1FkmDk3sgeljYZxA3qF6E7SJmvRqC70XQuuVA==", + "version": "1.45.2", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.45.2.tgz", + "integrity": "sha512-dljVOZTZhwF3G6E1ifDviOOF/vdHqf37xHVWYzNWW+Zk8Mm8KSJiKvWnFze1KknuWUPNb1jDL53I1f8XXKHEYg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2910,9 +2910,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", - "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", + "version": "9.30.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.1.tgz", + "integrity": "sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==", "dev": true, "license": "MIT", "engines": { @@ -2932,15 +2932,15 @@ } }, "node_modules/@firebase/analytics": { - "version": "0.10.16", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.16.tgz", - "integrity": "sha512-cMtp19He7Fd6uaj/nDEul+8JwvJsN8aRSJyuA1QN3QrKvfDDp+efjVurJO61sJpkVftw9O9nNMdhFbRcTmTfRQ==", + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.17.tgz", + "integrity": "sha512-n5vfBbvzduMou/2cqsnKrIes4auaBjdhg8QNA2ZQZ59QgtO2QiwBaXQZQE4O4sgB0Ds1tvLgUUkY+pwzu6/xEg==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.17", - "@firebase/installations": "0.6.17", + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.0", + "@firebase/util": "1.12.1", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2948,14 +2948,14 @@ } }, "node_modules/@firebase/app": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.1.tgz", - "integrity": "sha512-0O33PKrXLoIWkoOO5ByFaLjZehBctSYWnb+xJkIdx2SKP/K9l1UPFXPwASyrOIqyY3ws+7orF/1j7wI5EKzPYQ==", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.13.2.tgz", + "integrity": "sha512-jwtMmJa1BXXDCiDx1vC6SFN/+HfYG53UkfJa6qeN5ogvOunzbFDO3wISZy5n9xgYFUrEP6M7e8EG++riHNTv9w==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.17", + "@firebase/component": "0.6.18", "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.0", + "@firebase/util": "1.12.1", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -2964,14 +2964,14 @@ } }, "node_modules/@firebase/auth": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.7.tgz", - "integrity": "sha512-77o0aBKCfchdL1gkahARdawHyYefh+wRYn7o60tbwW6bfJNq2idbrRb3WSYCT4yBKWL0+9kKdwxBHPZ6DEiB+g==", + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.10.8.tgz", + "integrity": "sha512-GpuTz5ap8zumr/ocnPY57ZanX02COsXloY6Y/2LYPAuXYiaJRf6BAGDEdRq1BMjP93kqQnKNuKZUTMZbQ8MNYA==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.17", + "@firebase/component": "0.6.18", "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.0", + "@firebase/util": "1.12.1", "tslib": "^2.1.0" }, "engines": { @@ -2988,12 +2988,12 @@ } }, "node_modules/@firebase/component": { - "version": "0.6.17", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.17.tgz", - "integrity": "sha512-M6DOg7OySrKEFS8kxA3MU5/xc37fiOpKPMz6cTsMUcsuKB6CiZxxNAvgFta8HGRgEpZbi8WjGIj6Uf+TpOhyzg==", + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.18.tgz", + "integrity": "sha512-n28kPCkE2dL2U28fSxZJjzPPVpKsQminJ6NrzcKXAI0E/lYC8YhfwpyllScqVEvAI3J2QgJZWYgrX+1qGI+SQQ==", "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.12.0", + "@firebase/util": "1.12.1", "tslib": "^2.1.0" }, "engines": { @@ -3001,14 +3001,14 @@ } }, "node_modules/@firebase/firestore": { - "version": "4.7.17", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.17.tgz", - "integrity": "sha512-YhXWA7HlSnekExhZ5u4i0e+kpPxsh/qMrzeNDgsAva71JXK8OOuOx+yLyYBFhmu3Hr5JJDO2fsZA/wrWoQYHDg==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.8.0.tgz", + "integrity": "sha512-QSRk+Q1/CaabKyqn3C32KSFiOdZpSqI9rpLK5BHPcooElumOBooPFa6YkDdiT+/KhJtel36LdAacha9BptMj2A==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.17", + "@firebase/component": "0.6.18", "@firebase/logger": "0.4.4", - "@firebase/util": "1.12.0", + "@firebase/util": "1.12.1", "@firebase/webchannel-wrapper": "1.0.3", "@grpc/grpc-js": "~1.9.0", "@grpc/proto-loader": "^0.7.8", @@ -3022,13 +3022,13 @@ } }, "node_modules/@firebase/installations": { - "version": "0.6.17", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.17.tgz", - "integrity": "sha512-zfhqCNJZRe12KyADtRrtOj+SeSbD1H/K8J24oQAJVv/u02eQajEGlhZtcx9Qk7vhGWF5z9dvIygVDYqLL4o1XQ==", + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.18.tgz", + "integrity": "sha512-NQ86uGAcvO8nBRwVltRL9QQ4Reidc/3whdAasgeWCPIcrhOKDuNpAALa6eCVryLnK14ua2DqekCOX5uC9XbU/A==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.17", - "@firebase/util": "1.12.0", + "@firebase/component": "0.6.18", + "@firebase/util": "1.12.1", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -3049,15 +3049,15 @@ } }, "node_modules/@firebase/messaging": { - "version": "0.12.21", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.21.tgz", - "integrity": "sha512-bYJ2Evj167Z+lJ1ach6UglXz5dUKY1zrJZd15GagBUJSR7d9KfiM1W8dsyL0lDxcmhmA/sLaBYAAhF1uilwN0g==", + "version": "0.12.22", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.22.tgz", + "integrity": "sha512-GJcrPLc+Hu7nk+XQ70Okt3M1u1eRr2ZvpMbzbc54oTPJZySHcX9ccZGVFcsZbSZ6o1uqumm8Oc7OFkD3Rn1/og==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.17", - "@firebase/installations": "0.6.17", + "@firebase/component": "0.6.18", + "@firebase/installations": "0.6.18", "@firebase/messaging-interop-types": "0.2.3", - "@firebase/util": "1.12.0", + "@firebase/util": "1.12.1", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -3072,9 +3072,9 @@ "license": "Apache-2.0" }, "node_modules/@firebase/util": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.0.tgz", - "integrity": "sha512-Z4rK23xBCwgKDqmzGVMef+Vb4xso2j5Q8OG0vVL4m4fA5ZjPMYQazu8OJJC3vtQRC3SQ/Pgx/6TPNVsCd70QRw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.12.1.tgz", + "integrity": "sha512-zGlBn/9Dnya5ta9bX/fgEoNC3Cp8s6h+uYPYaDieZsFOAdHP/ExzQ/eaDgxD3GOROdPkLKpvKY0iIzr9adle0w==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -3516,13 +3516,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.53.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.1.tgz", - "integrity": "sha512-Z4c23LHV0muZ8hfv4jw6HngPJkbbtZxTkxPNIg7cJcTc9C28N/p2q7g3JZS2SiKBBHJ3uM1dgDye66bB7LEk5w==", + "version": "1.53.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz", + "integrity": "sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.53.1" + "playwright": "1.53.2" }, "bin": { "playwright": "cli.js" @@ -4466,50 +4466,50 @@ "license": "MIT" }, "node_modules/@sentry-internal/browser-utils": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.32.0.tgz", - "integrity": "sha512-mVWdruSWXF+2WgS24jwLhWFyC/nDQbKXseLR8paU9LGSnVtlBlQseIx1GrANbJrhBxiEWSft4WiuxU34wPsbXg==", + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.34.0.tgz", + "integrity": "sha512-pXVznvP4CROejYtk6y7UQvPTieWz2vXjukGlO45fsnQa9nNo30lkQh3Ws2HZw2YbTxYZQYx75FBDezwKl2q0hQ==", "license": "MIT", "dependencies": { - "@sentry/core": "9.32.0" + "@sentry/core": "9.34.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/feedback": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.32.0.tgz", - "integrity": "sha512-OaXaovXqlhN1sG2wtJMhxMEjyeuK7RwY57o96LgKE0bWM//Fs9WWCOkGa+7l8TOf0+0ib7gfhJZlpN0hlqOgRw==", + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.34.0.tgz", + "integrity": "sha512-HT/EBRl1DR8XqlJk2wFNPJFcnIzNcEDjmW7C/o7K0GeP5jcSH0dKpcH7ykz2bi46gMRPrkO5EK2eXGK81KYI3g==", "license": "MIT", "dependencies": { - "@sentry/core": "9.32.0" + "@sentry/core": "9.34.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.32.0.tgz", - "integrity": "sha512-mOHUKjUtHbEwshikrCQPM1ZqWAMUEcpEGashnXQp3KQivvbTxrExiNnt6XK5TjJyGvsI3A907Bp/HvEzgneYgQ==", + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.34.0.tgz", + "integrity": "sha512-joYSqWltmpkcqI8Gg8jwFtPv0F01whmuQfNGoGaL7Z6B/xO1vvkqEudrg1tmswUHhqtYpZYaEaCvrmv0sPGCfA==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.32.0", - "@sentry/core": "9.32.0" + "@sentry-internal/browser-utils": "9.34.0", + "@sentry/core": "9.34.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.32.0.tgz", - "integrity": "sha512-tu+coeTRpJxknmWPMJC2jqmIM5IsVoRn9gEDdkSrcPbgx/GwgE03fSJVBJL1tOEA8yRNIhZPMR86ORE7/7n2ow==", + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.34.0.tgz", + "integrity": "sha512-GCtqMFk9WwrU3JNz1tlCFAhzmNfgZhLRaS0cLzoTuxPbG3CC2VUIWYEOw7+AdCJZGm8ElTMxu+BkChgGb8qthQ==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "9.32.0", - "@sentry/core": "9.32.0" + "@sentry-internal/replay": "9.34.0", + "@sentry/core": "9.34.0" }, "engines": { "node": ">=18" @@ -4525,16 +4525,16 @@ } }, "node_modules/@sentry/browser": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.32.0.tgz", - "integrity": "sha512-BzPogpH87n+sC9VPfXaXkiKJtagLpIB87LGg1hSBURpwGx6Rt2ORmaVYgwwuuFZX8Hia727IIM7pbcbNfrXGRQ==", + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.34.0.tgz", + "integrity": "sha512-6oJxU7JEA/RCgMTVlHXT54U9d0DWg61GgzyLTM+FUa8OUrAoK/t+CZGSMc/13nYN8xs7vcpiORdRx0ogch9zGw==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.32.0", - "@sentry-internal/feedback": "9.32.0", - "@sentry-internal/replay": "9.32.0", - "@sentry-internal/replay-canvas": "9.32.0", - "@sentry/core": "9.32.0" + "@sentry-internal/browser-utils": "9.34.0", + "@sentry-internal/feedback": "9.34.0", + "@sentry-internal/replay": "9.34.0", + "@sentry-internal/replay-canvas": "9.34.0", + "@sentry/core": "9.34.0" }, "engines": { "node": ">=18" @@ -4911,22 +4911,22 @@ } }, "node_modules/@sentry/core": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.32.0.tgz", - "integrity": "sha512-1wAXMMmeY4Ny2MJBCuri3b4LMVPjqXdgbVgTxxipGW+gzPsjv+8+LCSnJAR/cRBr8JoXV+qGC2tE06rI1XDj3A==", + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.34.0.tgz", + "integrity": "sha512-M/zikVaE3KLkhCFDyrHB35sF7pVkB2RPy07BcRsdFsSsdpjoG+Zq2Sxth2tMTbjd0x9Vtb/X6LVjyCj9GSEvVg==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@sentry/react": { - "version": "9.32.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.32.0.tgz", - "integrity": "sha512-4d13sA/e9oEEK9cB6DZxVNDLTw9Q2x0WzhKtit6jhFKv1ItQ61Uu+euBJLfy3yCzFGl7PJbfJViMt2bhqjkTuA==", + "version": "9.34.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.34.0.tgz", + "integrity": "sha512-xrai0g8qBS0AyiAytHlrBiTPu1zG7DNNh4GodAkHcd1j2iVti2c+AR7KgUY7UrsrjXd8Fpy7c+qo+5DnHLpulw==", "license": "MIT", "dependencies": { - "@sentry/browser": "9.32.0", - "@sentry/core": "9.32.0", + "@sentry/browser": "9.34.0", + "@sentry/core": "9.34.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -6120,9 +6120,9 @@ } }, "node_modules/antd": { - "version": "5.26.2", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.2.tgz", - "integrity": "sha512-C8dBgwSzXfUS5ousUN+mfcaGFhEOd9wuyhvmw0lQnU9gukpRoFe1B0UKzvr6Z50QgapIl+s03nYlQJUghKqVjQ==", + "version": "5.26.3", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.3.tgz", + "integrity": "sha512-M/s9Q39h/+G7AWnS6fbNxmAI9waTH4ti022GVEXBLq2j810V1wJ3UOQps13nEilzDNcyxnFN/EIbqIgS7wSYaA==", "license": "MIT", "dependencies": { "@ant-design/colors": "^7.2.1", @@ -13337,13 +13337,13 @@ } }, "node_modules/playwright": { - "version": "1.53.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.1.tgz", - "integrity": "sha512-LJ13YLr/ocweuwxyGf1XNFWIU4M2zUSo149Qbp+A4cpwDjsxRPj7k6H25LBrEHiEwxvRbD8HdwvQmRMSvquhYw==", + "version": "1.53.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.2.tgz", + "integrity": "sha512-6K/qQxVFuVQhRQhFsVZ9fGeatxirtrpPgxzBYWyZLEXJzqYwuL4fuNmfOfD5et1tJE4GScKyPNeLhZeRwuTU3A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.53.1" + "playwright-core": "1.53.2" }, "bin": { "playwright": "cli.js" @@ -13356,9 +13356,9 @@ } }, "node_modules/playwright-core": { - "version": "1.53.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.1.tgz", - "integrity": "sha512-Z46Oq7tLAyT0lGoFx4DOuB1IA9D1TPj0QkYxpPVUnGDqHHvDpCftu1J2hM2PiWsNMoZh8+LQaarAWcDfPBc6zg==", + "version": "1.53.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.2.tgz", + "integrity": "sha512-ox/OytMy+2w1jcYEYlOo1Hhp8hZkLCximMTUTMBXjGUA1KoFfiSZ+DU+3a739jsPY0yoKH2TFy9S2fsJas8yAw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -17697,9 +17697,9 @@ } }, "node_modules/vite-plugin-pwa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.0.0.tgz", - "integrity": "sha512-X77jo0AOd5OcxmWj3WnVti8n7Kw2tBgV1c8MCXFclrSlDV23ePzv2eTDIALXI2Qo6nJ5pZJeZAuX0AawvRfoeA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.0.1.tgz", + "integrity": "sha512-STyUomQbydj7vGamtgQYIJI0YsUZ3T4pJLGBQDQPhzMse6aGSncmEN21OV35PrFsmCvmtiH+Nu1JS1ke4RqBjQ==", "dev": true, "license": "MIT", "dependencies": { @@ -17717,7 +17717,7 @@ }, "peerDependencies": { "@vite-pwa/assets-generator": "^1.0.0", - "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "workbox-build": "^7.3.0", "workbox-window": "^7.3.0" }, diff --git a/client/package.json b/client/package.json index 14524131a..206dd44f4 100644 --- a/client/package.json +++ b/client/package.json @@ -12,19 +12,19 @@ "@apollo/client": "^3.13.6", "@emotion/is-prop-valid": "^1.3.1", "@fingerprintjs/fingerprintjs": "^4.6.1", - "@firebase/analytics": "^0.10.16", - "@firebase/app": "^0.13.1", - "@firebase/auth": "^1.10.7", - "@firebase/firestore": "^4.7.17", - "@firebase/messaging": "^0.12.21", + "@firebase/analytics": "^0.10.17", + "@firebase/app": "^0.13.2", + "@firebase/auth": "^1.10.8", + "@firebase/firestore": "^4.8.0", + "@firebase/messaging": "^0.12.22", "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.32.0", + "@sentry/react": "^9.34.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.2", + "antd": "^5.26.3", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -131,11 +131,11 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.45.1", + "@dotenvx/dotenvx": "^1.45.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", - "@eslint/js": "^9.29.0", - "@playwright/test": "^1.53.1", + "@eslint/js": "^9.30.1", + "@playwright/test": "^1.53.2", "@sentry/webpack-plugin": "^3.5.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", @@ -151,7 +151,7 @@ "jsdom": "^26.0.0", "memfs": "^4.17.2", "os-browserify": "^0.3.0", - "playwright": "^1.53.1", + "playwright": "^1.53.2", "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", @@ -159,7 +159,7 @@ "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", "vite-plugin-node-polyfills": "^0.23.0", - "vite-plugin-pwa": "^1.0.0", + "vite-plugin-pwa": "^1.0.1", "vite-plugin-style-import": "^2.0.0", "vitest": "^3.2.4", "workbox-window": "^7.3.0" diff --git a/package-lock.json b/package-lock.json index 9014fd22d..07f637473 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,14 @@ "version": "0.2.0", "license": "UNLICENSED", "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.835.0", - "@aws-sdk/client-elasticache": "^3.835.0", - "@aws-sdk/client-s3": "^3.837.0", - "@aws-sdk/client-secrets-manager": "^3.835.0", - "@aws-sdk/client-ses": "^3.835.0", - "@aws-sdk/credential-provider-node": "^3.835.0", - "@aws-sdk/lib-storage": "^3.837.0", - "@aws-sdk/s3-request-presigner": "^3.837.0", + "@aws-sdk/client-cloudwatch-logs": "^3.840.0", + "@aws-sdk/client-elasticache": "^3.840.0", + "@aws-sdk/client-s3": "^3.842.0", + "@aws-sdk/client-secrets-manager": "^3.840.0", + "@aws-sdk/client-ses": "^3.840.0", + "@aws-sdk/credential-provider-node": "^3.840.0", + "@aws-sdk/lib-storage": "^3.842.0", + "@aws-sdk/s3-request-presigner": "^3.842.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -24,14 +24,14 @@ "aws4": "^1.13.2", "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.56.0", + "bullmq": "^5.56.1", "chart.js": "^4.5.0", "cloudinary": "^2.7.0", "compression": "^1.8.0", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.56.0", + "dd-trace": "^5.57.1", "dinero.js": "^1.9.1", "dotenv": "^16.4.5", "express": "^4.21.1", @@ -58,7 +58,7 @@ "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "ssh2-sftp-client": "^11.0.0", - "twilio": "^5.7.1", + "twilio": "^5.7.2", "uuid": "^11.1.0", "winston": "^3.17.0", "winston-cloudwatch": "^6.3.0", @@ -67,13 +67,13 @@ "yazl": "^3.3.1" }, "devDependencies": { - "@eslint/js": "^9.29.0", - "eslint": "^9.29.0", + "@eslint/js": "^9.30.1", + "eslint": "^9.30.1", "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "mock-require": "^3.0.3", "p-limit": "^3.1.0", - "prettier": "^3.6.1", + "prettier": "^3.6.2", "supertest": "^7.1.1", "vitest": "^3.2.4" }, @@ -285,26 +285,26 @@ } }, "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.835.0.tgz", - "integrity": "sha512-lR08TngWAszUUEW1utaPfLLbDJF5BQVBDclvZF0ke1a4C0o3nU2HyoWy/A7fQJEOXGfiegABdqtbi9w3UHjibA==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.840.0.tgz", + "integrity": "sha512-fLVyIpED/dSNoGadJdA/3Tv7iVgeuQmr20lWvIaGzKheZPziEmNqH7w8YsbQZoazsTiU6BfLgNSFhFwOmfFvhA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.835.0", - "@aws-sdk/credential-provider-node": "3.835.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.835.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.835.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/credential-provider-node": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/eventstream-serde-browser": "^4.0.4", "@smithy/eventstream-serde-config-resolver": "^4.1.2", "@smithy/eventstream-serde-node": "^4.0.4", @@ -312,21 +312,21 @@ "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.12", - "@smithy/middleware-retry": "^4.1.13", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.20", - "@smithy/util-defaults-mode-node": "^4.0.20", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.6", @@ -353,50 +353,50 @@ } }, "node_modules/@aws-sdk/client-elasticache": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.835.0.tgz", - "integrity": "sha512-R3tSQ0VXOtfe4cMFXmtxbfXF6UyBEb99eY4+KBSO9V79wQw5iQGX/jrruWRgSo9r6sxz68kXqkGuxgKOg+D8VQ==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.840.0.tgz", + "integrity": "sha512-qVs5bMm2bM3qcsMTv3a5Tg07v8jLt3dbGumysGWUg2mudZBM4L6CxRn4rvCIn5MFPNArvO1QeiFc7l+ZLNj03g==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.835.0", - "@aws-sdk/credential-provider-node": "3.835.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.835.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.835.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/credential-provider-node": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.12", - "@smithy/middleware-retry": "^4.1.13", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.20", - "@smithy/util-defaults-mode-node": "^4.0.20", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", - "@smithy/util-waiter": "^4.0.5", + "@smithy/util-waiter": "^4.0.6", "tslib": "^2.6.2" }, "engines": { @@ -404,35 +404,35 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.837.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.837.0.tgz", - "integrity": "sha512-sBjPPG30HIfNwpzWuajCDf7agb4YAxPFFpsp3kwgptJF8PEi0HzQg64bskquMzjqLC2tXsn5rKtDVpQOvs29MQ==", + "version": "3.842.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.842.0.tgz", + "integrity": "sha512-T5Rh72Rcq1xIaM8KkTr1Wpr7/WPCYO++KrM+/Em0rq2jxpjMMhj77ITpgH7eEmNxWmwIndTwqpgfmbpNfk7Gbw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.835.0", - "@aws-sdk/credential-provider-node": "3.835.0", - "@aws-sdk/middleware-bucket-endpoint": "3.830.0", - "@aws-sdk/middleware-expect-continue": "3.821.0", - "@aws-sdk/middleware-flexible-checksums": "3.835.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-location-constraint": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-sdk-s3": "3.835.0", - "@aws-sdk/middleware-ssec": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.835.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/signature-v4-multi-region": "3.835.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.835.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/credential-provider-node": "3.840.0", + "@aws-sdk/middleware-bucket-endpoint": "3.840.0", + "@aws-sdk/middleware-expect-continue": "3.840.0", + "@aws-sdk/middleware-flexible-checksums": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-location-constraint": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-sdk-s3": "3.840.0", + "@aws-sdk/middleware-ssec": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/signature-v4-multi-region": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", "@aws-sdk/xml-builder": "3.821.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/eventstream-serde-browser": "^4.0.4", "@smithy/eventstream-serde-config-resolver": "^4.1.2", "@smithy/eventstream-serde-node": "^4.0.4", @@ -443,27 +443,27 @@ "@smithy/invalid-dependency": "^4.0.4", "@smithy/md5-js": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.12", - "@smithy/middleware-retry": "^4.1.13", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.20", - "@smithy/util-defaults-mode-node": "^4.0.20", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.6", "@smithy/util-stream": "^4.2.2", "@smithy/util-utf8": "^4.0.0", - "@smithy/util-waiter": "^4.0.5", + "@smithy/util-waiter": "^4.0.6", "@types/uuid": "^9.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" @@ -486,45 +486,45 @@ } }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.835.0.tgz", - "integrity": "sha512-w8xIFhxP54kRdmTuRjxOAgNU7MCSgVieXx5pUxMD6B92dpqDTjnVFgTDX8fpUFZSrSwe5dOCiHEDKZsV20YNaQ==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.840.0.tgz", + "integrity": "sha512-oUcoZT4YJc/WUoxydfzSE3o89dBvdzan75XOLXg3JVg64os4ao8SUkIphR3YXmjmHz8qwaVNXVF4MpR3IxGPCg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.835.0", - "@aws-sdk/credential-provider-node": "3.835.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.835.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.835.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/credential-provider-node": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.12", - "@smithy/middleware-retry": "^4.1.13", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.20", - "@smithy/util-defaults-mode-node": "^4.0.20", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.6", @@ -551,50 +551,50 @@ } }, "node_modules/@aws-sdk/client-ses": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.835.0.tgz", - "integrity": "sha512-Eugl8TqnvNWs2i38XVXwiLKWIreRdiOrIaf2lCPgowKZqw6yvLG6+Yc3yABzZZ5bnUZdDHt1pYfIMUbSXLGdAw==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.840.0.tgz", + "integrity": "sha512-RTIVFrAGDAOJ0xWFgCf9q0y1QrfPOCn1O6fKfjqwGig0XjwQH/YbxwC6wfV24/JAPrt2qRjkSU6SvBSVcHp9+w==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.835.0", - "@aws-sdk/credential-provider-node": "3.835.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.835.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.835.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/credential-provider-node": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.12", - "@smithy/middleware-retry": "^4.1.13", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.20", - "@smithy/util-defaults-mode-node": "^4.0.20", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.6", "@smithy/util-utf8": "^4.0.0", - "@smithy/util-waiter": "^4.0.5", + "@smithy/util-waiter": "^4.0.6", "tslib": "^2.6.2" }, "engines": { @@ -602,44 +602,44 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.835.0.tgz", - "integrity": "sha512-4J19IcBKU5vL8yw/YWEvbwEGcmCli0rpRyxG53v0K5/3weVPxVBbKfkWcjWVQ4qdxNz2uInfbTde4BRBFxWllQ==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.840.0.tgz", + "integrity": "sha512-3Zp+FWN2hhmKdpS0Ragi5V2ZPsZNScE3jlbgoJjzjI/roHZqO+e3/+XFN4TlM0DsPKYJNp+1TAjmhxN6rOnfYA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.835.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.835.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.835.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.12", - "@smithy/middleware-retry": "^4.1.13", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.20", - "@smithy/util-defaults-mode-node": "^4.0.20", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.6", @@ -651,19 +651,19 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.835.0.tgz", - "integrity": "sha512-7mnf4xbaLI8rkDa+w6fUU48dG6yDuOgLXEPe4Ut3SbMp1ceJBPMozNHbCwkiyHk3HpxZYf8eVy0wXhJMrxZq5w==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.840.0.tgz", + "integrity": "sha512-x3Zgb39tF1h2XpU+yA4OAAQlW6LVEfXNlSedSYJ7HGKXqA/E9h3rWQVpYfhXXVVsLdYXdNw5KBUkoAoruoZSZA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@aws-sdk/xml-builder": "3.821.0", - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", @@ -677,13 +677,13 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.835.0.tgz", - "integrity": "sha512-U9LFWe7+ephNyekpUbzT7o6SmJTmn6xkrPkE0D7pbLojnPVi/8SZKyjtgQGIsAv+2kFkOCqMOIYUKd/0pE7uew==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.840.0.tgz", + "integrity": "sha512-EzF6VcJK7XvQ/G15AVEfJzN2mNXU8fcVpXo4bRyr1S6t2q5zx6UPH/XjDbn18xyUmOq01t+r8gG+TmHEVo18fA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -693,18 +693,18 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.835.0.tgz", - "integrity": "sha512-jCdNEsQklil7frDm/BuVKl4ubVoQHRbV6fnkOjmxAJz0/v7cR8JP0jBGlqKKzh3ROh5/vo1/5VUZbCTLpc9dSg==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.840.0.tgz", + "integrity": "sha512-wbnUiPGLVea6mXbUh04fu+VJmGkQvmToPeTYdHE8eRZq3NRDi3t3WltT+jArLBKD/4NppRpMjf2ju4coMCz91g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/node-http-handler": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/util-stream": "^4.2.2", "tslib": "^2.6.2" @@ -714,19 +714,19 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.835.0.tgz", - "integrity": "sha512-nqF6rYRAnJedmvDfrfKygzyeADcduDvtvn7GlbQQbXKeR2l7KnCdhuxHa0FALLvspkHiBx7NtInmvnd5IMuWsw==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.840.0.tgz", + "integrity": "sha512-7F290BsWydShHb+7InXd+IjJc3mlEIm9I0R57F/Pjl1xZB69MdkhVGCnuETWoBt4g53ktJd6NEjzm/iAhFXFmw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.835.0", - "@aws-sdk/credential-provider-env": "3.835.0", - "@aws-sdk/credential-provider-http": "3.835.0", - "@aws-sdk/credential-provider-process": "3.835.0", - "@aws-sdk/credential-provider-sso": "3.835.0", - "@aws-sdk/credential-provider-web-identity": "3.835.0", - "@aws-sdk/nested-clients": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/credential-provider-env": "3.840.0", + "@aws-sdk/credential-provider-http": "3.840.0", + "@aws-sdk/credential-provider-process": "3.840.0", + "@aws-sdk/credential-provider-sso": "3.840.0", + "@aws-sdk/credential-provider-web-identity": "3.840.0", + "@aws-sdk/nested-clients": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -738,18 +738,18 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.835.0.tgz", - "integrity": "sha512-77B8elyZlaEd7vDYyCnYtVLuagIBwuJ0AQ98/36JMGrYX7TT8UVAhiDAfVe0NdUOMORvDNFfzL06VBm7wittYw==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.840.0.tgz", + "integrity": "sha512-KufP8JnxA31wxklLm63evUPSFApGcH8X86z3mv9SRbpCm5ycgWIGVCTXpTOdgq6rPZrwT9pftzv2/b4mV/9clg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.835.0", - "@aws-sdk/credential-provider-http": "3.835.0", - "@aws-sdk/credential-provider-ini": "3.835.0", - "@aws-sdk/credential-provider-process": "3.835.0", - "@aws-sdk/credential-provider-sso": "3.835.0", - "@aws-sdk/credential-provider-web-identity": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/credential-provider-env": "3.840.0", + "@aws-sdk/credential-provider-http": "3.840.0", + "@aws-sdk/credential-provider-ini": "3.840.0", + "@aws-sdk/credential-provider-process": "3.840.0", + "@aws-sdk/credential-provider-sso": "3.840.0", + "@aws-sdk/credential-provider-web-identity": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -761,13 +761,13 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.835.0.tgz", - "integrity": "sha512-qXkTt5pAhSi2Mp9GdgceZZFo/cFYrA735efqi/Re/nf0lpqBp8mRM8xv+iAaPHV4Q10q0DlkbEidT1DhxdT/+w==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.840.0.tgz", + "integrity": "sha512-HkDQWHy8tCI4A0Ps2NVtuVYMv9cB4y/IuD/TdOsqeRIAT12h8jDb98BwQPNLAImAOwOWzZJ8Cu0xtSpX7CQhMw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", "@smithy/types": "^4.3.1", @@ -778,15 +778,15 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.835.0.tgz", - "integrity": "sha512-jAiEMryaPFXayYGszrc7NcgZA/zrrE3QvvvUBh/Udasg+9Qp5ZELdJCm/p98twNyY9n5i6Ex6VgvdxZ7+iEheQ==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.840.0.tgz", + "integrity": "sha512-2qgdtdd6R0Z1y0KL8gzzwFUGmhBHSUx4zy85L2XV1CXhpRNwV71SVWJqLDVV5RVWVf9mg50Pm3AWrUC0xb0pcA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.835.0", - "@aws-sdk/core": "3.835.0", - "@aws-sdk/token-providers": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/client-sso": "3.840.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/token-providers": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", "@smithy/types": "^4.3.1", @@ -797,14 +797,14 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.835.0.tgz", - "integrity": "sha512-zfleEFXDLlcJ7cyfS4xSyCRpd8SVlYZfH3rp0pg2vPYKbnmXVE0r+gPIYXl4L+Yz4A2tizYl63nKCNdtbxadog==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.840.0.tgz", + "integrity": "sha512-dpEeVXG8uNZSmVXReE4WP0lwoioX2gstk4RnUgrdUE3YaPq8A+hJiVAyc3h+cjDeIqfbsQbZm9qFetKC2LF9dQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.835.0", - "@aws-sdk/nested-clients": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/nested-clients": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -814,14 +814,14 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.837.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.837.0.tgz", - "integrity": "sha512-V7NkOw8bX1HdRTWSy+pMCpHQgSaUh/l1fQIx63anu4TORe18pkLkos0x5YnPJ+o2ksbCVtokDuOG1jGdVM0NPg==", + "version": "3.842.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.842.0.tgz", + "integrity": "sha512-QRWu+/I6Sgy4Kj2gq9srdw0/YSDiybSiMiQMUgcw4iI4mgWUcEwRPw7rGUFRWwdZUAhYGUv1T37Ydz2GXDFnJQ==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.12", - "@smithy/smithy-client": "^4.4.4", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/smithy-client": "^4.4.5", "buffer": "5.6.0", "events": "3.3.0", "stream-browserify": "3.0.0", @@ -831,16 +831,16 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.837.0" + "@aws-sdk/client-s3": "^3.842.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.830.0.tgz", - "integrity": "sha512-ElVeCReZSH5Ds+/pkL5ebneJjuo8f49e9JXV1cYizuH0OAOQfYaBU9+M+7+rn61pTttOFE8W//qKzrXBBJhfMg==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.840.0.tgz", + "integrity": "sha512-+gkQNtPwcSMmlwBHFd4saVVS11In6ID1HczNzpM3MXKXRBfSlbZJbCt6wN//AZ8HMklZEik4tcEOG0qa9UY8SQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@aws-sdk/util-arn-parser": "3.804.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/protocol-http": "^5.1.2", @@ -853,12 +853,12 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.821.0.tgz", - "integrity": "sha512-zAOoSZKe1njOrtynvK6ZORU57YGv5I7KP4+rwOvUN3ZhJbQ7QPf8gKtFUCYAPRMegaXCKF/ADPtDZBAmM+zZ9g==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.840.0.tgz", + "integrity": "sha512-iJg2r6FKsKKvdiU4oCOuCf7Ro/YE0Q2BT/QyEZN3/Rt8Nr4SAZiQOlcBXOCpGvuIKOEAhvDOUnW3aDHL01PdVw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -868,16 +868,16 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.835.0.tgz", - "integrity": "sha512-9ezorQYlr5cQY28zWAReFhNKUTaXsi3TMvXIagMRrSeWtQ7R6TCYnt91xzHRCmFR2kp3zLI+dfoeH+wF3iCKUw==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.840.0.tgz", + "integrity": "sha512-Kg/o2G6o72sdoRH0J+avdcf668gM1bp6O4VeEXpXwUj/urQnV5qiB2q1EYT110INHUKWOLXPND3sQAqh6sTqHw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/is-array-buffer": "^4.0.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/protocol-http": "^5.1.2", @@ -892,12 +892,12 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.821.0.tgz", - "integrity": "sha512-xSMR+sopSeWGx5/4pAGhhfMvGBHioVBbqGvDs6pG64xfNwM5vq5s5v6D04e2i+uSTj4qGa71dLUs5I0UzAK3sw==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.840.0.tgz", + "integrity": "sha512-ub+hXJAbAje94+Ya6c6eL7sYujoE8D4Bumu1NUI8TXjUhVVn0HzVWQjpRLshdLsUp1AW7XyeJaxyajRaJQ8+Xg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -907,12 +907,12 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.821.0.tgz", - "integrity": "sha512-sKrm80k0t3R0on8aA/WhWFoMaAl4yvdk+riotmMElLUpcMcRXAd1+600uFVrxJqZdbrKQ0mjX0PjT68DlkYXLg==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.840.0.tgz", + "integrity": "sha512-KVLD0u0YMF3aQkVF8bdyHAGWSUY6N1Du89htTLgqCcIhSxxAJ9qifrosVZ9jkAzqRW99hcufyt2LylcVU2yoKQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, @@ -921,12 +921,12 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.821.0.tgz", - "integrity": "sha512-0cvI0ipf2tGx7fXYEEN5fBeZDz2RnHyb9xftSgUsEq7NBxjV0yTZfLJw6Za5rjE6snC80dRN8+bTNR1tuG89zA==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.840.0.tgz", + "integrity": "sha512-lSV8FvjpdllpGaRspywss4CtXV8M7NNNH+2/j86vMH+YCOZ6fu2T/TyFd/tHwZ92vDfHctWkRbQxg0bagqwovA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, @@ -935,12 +935,12 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.821.0.tgz", - "integrity": "sha512-efmaifbhBoqKG3bAoEfDdcM8hn1psF+4qa7ykWuYmfmah59JBeqHLfz5W9m9JoTwoKPkFcVLWZxnyZzAnVBOIg==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.840.0.tgz", + "integrity": "sha512-Gu7lGDyfddyhIkj1Z1JtrY5NHb5+x/CRiB87GjaSrKxkDaydtX2CU977JIABtt69l9wLbcGDIQ+W0uJ5xPof7g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -950,19 +950,19 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.835.0.tgz", - "integrity": "sha512-oPebxpVf9smInHhevHh3APFZagGU+4RPwXEWv9YtYapFvsMq+8QXFvOfxfVZ/mwpe0JVG7EiJzL9/9Kobmts8Q==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.840.0.tgz", + "integrity": "sha512-rOUji7CayWN3O09zvvgLzDVQe0HiJdZkxoTS6vzOS3WbbdT7joGdVtAJHtn+x776QT3hHzbKU5gnfhel0o6gQA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", "@aws-sdk/util-arn-parser": "3.804.0", - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.4", @@ -975,12 +975,12 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.821.0.tgz", - "integrity": "sha512-YYi1Hhr2AYiU/24cQc8HIB+SWbQo6FBkMYojVuz/zgrtkFmALxENGF/21OPg7f/QWd+eadZJRxCjmRwh5F2Cxg==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.840.0.tgz", + "integrity": "sha512-CBZP9t1QbjDFGOrtnUEHL1oAvmnCUUm7p0aPNbIdSzNtH42TNKjPRN3TuEIJDGjkrqpL3MXyDSmNayDcw/XW7Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, @@ -989,15 +989,15 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.835.0.tgz", - "integrity": "sha512-2gmAYygeE/gzhyF2XlkcbMLYFTbNfV61n+iCFa/ZofJHXYE+RxSyl5g4kujLEs7bVZHmjQZJXhprVSkGccq3/w==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.840.0.tgz", + "integrity": "sha512-hiiMf7BP5ZkAFAvWRcK67Mw/g55ar7OCrvrynC92hunx/xhMkrgSLM0EXIZ1oTn3uql9kH/qqGF0nqsK6K555A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.835.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@smithy/core": "^3.5.3", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@smithy/core": "^3.6.0", "@smithy/protocol-http": "^5.1.2", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -1007,44 +1007,44 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.835.0.tgz", - "integrity": "sha512-UtmOO0U5QkicjCEv+B32qqRAnS7o2ZkZhC+i3ccH1h3fsfaBshpuuNBwOYAzRCRBeKW5fw3ANFrV/+2FTp4jWg==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.840.0.tgz", + "integrity": "sha512-LXYYo9+n4hRqnRSIMXLBb+BLz+cEmjMtTudwK1BF6Bn2RfdDv29KuyeDRrPCS3TwKl7ZKmXUmE9n5UuHAPfBpA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.835.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.835.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.835.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/middleware-host-header": "3.840.0", + "@aws-sdk/middleware-logger": "3.840.0", + "@aws-sdk/middleware-recursion-detection": "3.840.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/region-config-resolver": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-endpoints": "3.840.0", + "@aws-sdk/util-user-agent-browser": "3.840.0", + "@aws-sdk/util-user-agent-node": "3.840.0", "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", + "@smithy/core": "^3.6.0", "@smithy/fetch-http-handler": "^5.0.4", "@smithy/hash-node": "^4.0.4", "@smithy/invalid-dependency": "^4.0.4", "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.12", - "@smithy/middleware-retry": "^4.1.13", + "@smithy/middleware-endpoint": "^4.1.13", + "@smithy/middleware-retry": "^4.1.14", "@smithy/middleware-serde": "^4.0.8", "@smithy/middleware-stack": "^4.0.4", "@smithy/node-config-provider": "^4.1.3", "@smithy/node-http-handler": "^4.0.6", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "@smithy/url-parser": "^4.0.4", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.20", - "@smithy/util-defaults-mode-node": "^4.0.20", + "@smithy/util-defaults-mode-browser": "^4.0.21", + "@smithy/util-defaults-mode-node": "^4.0.21", "@smithy/util-endpoints": "^3.0.6", "@smithy/util-middleware": "^4.0.4", "@smithy/util-retry": "^4.0.6", @@ -1056,12 +1056,12 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.821.0.tgz", - "integrity": "sha512-t8og+lRCIIy5nlId0bScNpCkif8sc0LhmtaKsbm0ZPm3sCa/WhCbSZibjbZ28FNjVCV+p0D9RYZx0VDDbtWyjw==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.840.0.tgz", + "integrity": "sha512-Qjnxd/yDv9KpIMWr90ZDPtRj0v75AqGC92Lm9+oHXZ8p1MjG5JE2CW0HL8JRgK9iKzgKBL7pPQRXI8FkvEVfrA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", "@smithy/util-config-provider": "^4.0.0", @@ -1073,17 +1073,17 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.837.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.837.0.tgz", - "integrity": "sha512-h/D/cqeciBPGFSHIHRQm0q/CDvToV4rUoPef3tWzYtfoKzqfYaqRO175FnDv/4XgOYpdoqv6q36bx8KueVQ62w==", + "version": "3.842.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.842.0.tgz", + "integrity": "sha512-daS69IJ20X+BzsiEtj3XuyyM765iFOdZ648lrptHncQHRWdpzahk67/nP/SKYhWvnNrQ4pw2vYlVxpOs9vl1yg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/signature-v4-multi-region": "3.835.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-format-url": "3.821.0", - "@smithy/middleware-endpoint": "^4.1.12", + "@aws-sdk/signature-v4-multi-region": "3.840.0", + "@aws-sdk/types": "3.840.0", + "@aws-sdk/util-format-url": "3.840.0", + "@smithy/middleware-endpoint": "^4.1.13", "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.4", + "@smithy/smithy-client": "^4.4.5", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" }, @@ -1092,13 +1092,13 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.835.0.tgz", - "integrity": "sha512-rEtJH4dIwJYlXXe5rIH+uTCQmd2VIjuaoHlDY3Dr4nxF6po6U7vKsLfybIU2tgflGVqoqYQnXsfW/kj/Rh+/ow==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.840.0.tgz", + "integrity": "sha512-8AoVgHrkSfhvGPtwx23hIUO4MmMnux2pjnso1lrLZGqxfElM6jm2w4jTNLlNXk8uKHGyX89HaAIuT0lL6dJj9g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/middleware-sdk-s3": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", "@smithy/types": "^4.3.1", @@ -1109,14 +1109,14 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.835.0.tgz", - "integrity": "sha512-zN1P3BE+Rv7w7q/CDA8VCQox6SE9QTn0vDtQ47AHA3eXZQQgYzBqgoLgJxR9rKKBIRGZqInJa/VRskLL95VliQ==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.840.0.tgz", + "integrity": "sha512-6BuTOLTXvmgwjK7ve7aTg9JaWFdM5UoMolLVPMyh3wTv9Ufalh8oklxYHUBIxsKkBGO2WiHXytveuxH6tAgTYg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.835.0", - "@aws-sdk/nested-clients": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/core": "3.840.0", + "@aws-sdk/nested-clients": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", "@smithy/types": "^4.3.1", @@ -1127,9 +1127,9 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.821.0.tgz", - "integrity": "sha512-Znroqdai1a90TlxGaJ+FK1lwC0fHpo97Xjsp5UKGR5JODYm7f9+/fF17ebO1KdoBr/Rm0UIFiF5VmI8ts9F1eA==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.840.0.tgz", + "integrity": "sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.3.1", @@ -1152,12 +1152,12 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", - "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.840.0.tgz", + "integrity": "sha512-eqE9ROdg/Kk0rj3poutyRCFauPDXIf/WSvCqFiRDDVi6QOnCv/M0g2XW8/jSvkJlOyaXkNCptapIp6BeeFFGYw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/types": "^4.3.1", "@smithy/util-endpoints": "^3.0.6", "tslib": "^2.6.2" @@ -1167,12 +1167,12 @@ } }, "node_modules/@aws-sdk/util-format-url": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.821.0.tgz", - "integrity": "sha512-h+xqmPToxDrZ0a7rxE1a8Oh4zpWfZe9oiQUphGtfiGFA6j75UiURH5J3MmGHa/G4t15I3iLLbYtUXxvb1i7evg==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.840.0.tgz", + "integrity": "sha512-VB1PWyI1TQPiPvg4w7tgUGGQER1xxXPNUqfh3baxUSFi1Oh8wHrDnFywkxLm3NMmgDmnLnSZ5Q326qAoyqKLSg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/querystring-builder": "^4.0.4", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -1194,25 +1194,25 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.821.0.tgz", - "integrity": "sha512-irWZHyM0Jr1xhC+38OuZ7JB6OXMLPZlj48thElpsO1ZSLRkLZx5+I7VV6k3sp2yZ7BYbKz/G2ojSv4wdm7XTLw==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.840.0.tgz", + "integrity": "sha512-JdyZM3EhhL4PqwFpttZu1afDpPJCCc3eyZOLi+srpX11LsGj6sThf47TYQN75HT1CarZ7cCdQHGzP2uy3/xHfQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", + "@aws-sdk/types": "3.840.0", "@smithy/types": "^4.3.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.835.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.835.0.tgz", - "integrity": "sha512-gY63QZ4W5w9JYHYuqvUxiVGpn7IbCt1ODPQB0ZZwGGr3WRmK+yyZxCtFjbYhEQDQLgTWpf8YgVxgQLv2ps0PJg==", + "version": "3.840.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.840.0.tgz", + "integrity": "sha512-Fy5JUEDQU1tPm2Yw/YqRYYc27W5+QD/J4mYvQvdWjUGZLB5q3eLFMGD35Uc28ZFoGMufPr4OCxK/bRfWROBRHQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.835.0", - "@aws-sdk/types": "3.821.0", + "@aws-sdk/middleware-user-agent": "3.840.0", + "@aws-sdk/types": "3.840.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", "tslib": "^2.6.2" @@ -1263,9 +1263,9 @@ } }, "node_modules/@datadog/libdatadog": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@datadog/libdatadog/-/libdatadog-0.6.0.tgz", - "integrity": "sha512-Ldu+U59LUnejtd7ceXMKJCAFZeYpNdTEEXr8PISY9HFXMa4DOwepcWMaJAAqCPU7LINJeivVwvSD1Pm14VZy7w==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@datadog/libdatadog/-/libdatadog-0.7.0.tgz", + "integrity": "sha512-VVZLspzQcfEU47gmGCVoRkngn7RgFRR4CHjw4YaX8eWT+xz4Q4l6PvA45b7CMk9nlt3MNN5MtGdYttYMIpo6Sg==", "license": "Apache-2.0" }, "node_modules/@datadog/native-appsec": { @@ -1306,9 +1306,9 @@ } }, "node_modules/@datadog/pprof": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.8.2.tgz", - "integrity": "sha512-M+bO4v4TaxYK6k2qJBxnhf7Vh25Wode64y4LfxzGs5kLTFr8eFTp6HJai3/af7U5gjTHX/4s+CHv2bxja97pbw==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.9.0.tgz", + "integrity": "sha512-7KretVkHUANWe31u9cGJpxmUkyrXsCD+fmlZQUz/zk9mtQNC4uBIKX53VUFfrVj/bxAhEEIPw5XTYiMc5RJLsw==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -1822,9 +1822,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz", - "integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1837,9 +1837,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", - "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", + "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1897,9 +1897,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", - "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", + "version": "9.30.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.1.tgz", + "integrity": "sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==", "dev": true, "license": "MIT", "engines": { @@ -3580,9 +3580,9 @@ } }, "node_modules/@smithy/util-waiter": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.0.5.tgz", - "integrity": "sha512-4QvC49HTteI1gfemu0I1syWovJgPvGn7CVUoN9ZFkdvr/cCFkrEL7qNCdx/2eICqDWEGnnr68oMdSIPCLAriSQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.0.6.tgz", + "integrity": "sha512-slcr1wdRbX7NFphXZOxtxRNA7hXAAtJAXJDE/wdoMAos27SIquVCKiSqfB6/28YzQ8FCsB5NKkhdM5gMADbqxg==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.0.4", @@ -4675,9 +4675,9 @@ } }, "node_modules/bullmq": { - "version": "5.56.0", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.56.0.tgz", - "integrity": "sha512-j5ct2tdc9M8PKcjhJw+euO24BsO1wXBAkNGXYI1R1qvh7FvRldZ5wtLixLWqQ4/crafj0Vrwi+y1kXFXMwBJFA==", + "version": "5.56.1", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.56.1.tgz", + "integrity": "sha512-HmX53sf24bbDj5NVrDLDEjy8OSDmbGMESfvFhVK8NpHsA4WlAdKxPDf7c5b9RZf5wZGHyAd2XhWSkE9dmNPYww==", "license": "MIT", "dependencies": { "cron-parser": "^4.9.0", @@ -5514,30 +5514,30 @@ } }, "node_modules/dd-trace": { - "version": "5.56.0", - "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.56.0.tgz", - "integrity": "sha512-1GiAh1UATmn8uZxk+nqZAdfJppiOq4kxJKiozMNvupffbcbAuDj5qnfYF9Hz3oqsk+Jtt2oheQeR05c4JRshXw==", + "version": "5.57.1", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.57.1.tgz", + "integrity": "sha512-dT8xe4iGC+AH4B19S9dQX4NBUssqb+oGnWGMIBdm8+GWY+nVV7x3FQ3cUjjdWwAKJpRY83DJ+U5w3rVEn31a9A==", "hasInstallScript": true, "license": "(Apache-2.0 OR BSD-3-Clause)", "dependencies": { - "@datadog/libdatadog": "^0.6.0", + "@datadog/libdatadog": "0.7.0", "@datadog/native-appsec": "8.5.2", "@datadog/native-iast-taint-tracking": "4.0.0", - "@datadog/native-metrics": "^3.1.1", - "@datadog/pprof": "5.8.2", - "@datadog/sketches-js": "^2.1.1", + "@datadog/native-metrics": "3.1.1", + "@datadog/pprof": "5.9.0", + "@datadog/sketches-js": "2.1.1", "@datadog/wasm-js-rewriter": "4.0.1", "@isaacs/ttlcache": "^1.4.1", - "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/api": "1.8.0", "@opentelemetry/core": "^1.14.0", "crypto-randomuuid": "^1.0.0", - "dc-polyfill": "0.1.9", + "dc-polyfill": "^0.1.9", "ignore": "^5.2.4", - "import-in-the-middle": "1.14.0", - "istanbul-lib-coverage": "3.2.2", + "import-in-the-middle": "^1.14.2", + "istanbul-lib-coverage": "^3.2.2", "jest-docblock": "^29.7.0", "koalas": "^1.0.2", - "limiter": "1.1.5", + "limiter": "^1.1.5", "lodash.sortby": "^4.7.0", "lru-cache": "^7.18.3", "module-details-from-path": "^1.0.4", @@ -6289,19 +6289,19 @@ } }, "node_modules/eslint": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz", - "integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==", + "version": "9.30.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.30.1.tgz", + "integrity": "sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.1", - "@eslint/config-helpers": "^0.2.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.0", "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.29.0", + "@eslint/js": "9.30.1", "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -7740,9 +7740,9 @@ } }, "node_modules/import-in-the-middle": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.14.0.tgz", - "integrity": "sha512-g5zLT0HaztRJWysayWYiUq/7E5H825QIiecMD2pI5QO7Wzr847l6GDvPvmZaDIdrDtS2w7qRczywxiK6SL5vRw==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.14.2.tgz", + "integrity": "sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==", "license": "Apache-2.0", "dependencies": { "acorn": "^8.14.0", @@ -9826,9 +9826,9 @@ } }, "node_modules/prettier": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.1.tgz", - "integrity": "sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", "bin": { @@ -11866,9 +11866,9 @@ "license": "Unlicense" }, "node_modules/twilio": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.7.1.tgz", - "integrity": "sha512-BcoVK6FR580HRX94z2u3b+foHkvFj39DDzLU4Xv+N/7ejDIGgQdrtg7CgRqIT04UNs98HJAvjuAOzkYetI6ExQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.7.2.tgz", + "integrity": "sha512-WNqB6OSdoWU7xtIodcoLjauxO5Uqd90B9YS525hEjKN+dVmN/UqibonChhDbUo1q3mDjtKPfuGvlUYRSrXOPfg==", "license": "MIT", "dependencies": { "axios": "^1.8.3", diff --git a/package.json b/package.json index 5155066ff..1346aa3e4 100644 --- a/package.json +++ b/package.json @@ -16,14 +16,14 @@ "job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js" }, "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.835.0", - "@aws-sdk/client-elasticache": "^3.835.0", - "@aws-sdk/client-s3": "^3.837.0", - "@aws-sdk/client-secrets-manager": "^3.835.0", - "@aws-sdk/client-ses": "^3.835.0", - "@aws-sdk/credential-provider-node": "^3.835.0", - "@aws-sdk/lib-storage": "^3.837.0", - "@aws-sdk/s3-request-presigner": "^3.837.0", + "@aws-sdk/client-cloudwatch-logs": "^3.840.0", + "@aws-sdk/client-elasticache": "^3.840.0", + "@aws-sdk/client-s3": "^3.842.0", + "@aws-sdk/client-secrets-manager": "^3.840.0", + "@aws-sdk/client-ses": "^3.840.0", + "@aws-sdk/credential-provider-node": "^3.840.0", + "@aws-sdk/lib-storage": "^3.842.0", + "@aws-sdk/s3-request-presigner": "^3.842.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", @@ -31,14 +31,14 @@ "aws4": "^1.13.2", "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.56.0", + "bullmq": "^5.56.1", "chart.js": "^4.5.0", "cloudinary": "^2.7.0", "compression": "^1.8.0", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.56.0", + "dd-trace": "^5.57.1", "dinero.js": "^1.9.1", "dotenv": "^16.4.5", "express": "^4.21.1", @@ -65,7 +65,7 @@ "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "ssh2-sftp-client": "^11.0.0", - "twilio": "^5.7.1", + "twilio": "^5.7.2", "uuid": "^11.1.0", "winston": "^3.17.0", "winston-cloudwatch": "^6.3.0", @@ -74,13 +74,13 @@ "yazl": "^3.3.1" }, "devDependencies": { - "@eslint/js": "^9.29.0", - "eslint": "^9.29.0", + "@eslint/js": "^9.30.1", + "eslint": "^9.30.1", "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "mock-require": "^3.0.3", "p-limit": "^3.1.0", - "prettier": "^3.6.1", + "prettier": "^3.6.2", "supertest": "^7.1.1", "vitest": "^3.2.4" } From 5fa58e5013d9dab2c9a0ad64ac96ad41ab6592e7 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Thu, 3 Jul 2025 12:00:21 -0400 Subject: [PATCH 18/98] feature/IO-3255-simplified-parts-management - Front End Cleanup --- ...s-document-imgproxy-gallery.download.component.jsx | 1 - client/src/pages/manage/manage.page.component.jsx | 11 +---------- .../simplified-parts-jobs-detail.component.jsx | 10 ++-------- client/src/redux/user/user.selectors.js | 6 +----- 4 files changed, 4 insertions(+), 24 deletions(-) diff --git a/client/src/components/jobs-documents-imgproxy-gallery/jobs-document-imgproxy-gallery.download.component.jsx b/client/src/components/jobs-documents-imgproxy-gallery/jobs-document-imgproxy-gallery.download.component.jsx index 65140d6b0..50716982b 100644 --- a/client/src/components/jobs-documents-imgproxy-gallery/jobs-document-imgproxy-gallery.download.component.jsx +++ b/client/src/components/jobs-documents-imgproxy-gallery/jobs-document-imgproxy-gallery.download.component.jsx @@ -3,7 +3,6 @@ import axios from "axios"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; -import cleanAxios from "../../utils/CleanAxios"; import formatBytes from "../../utils/formatbytes"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx index 10676cfc5..fabc8bbf7 100644 --- a/client/src/pages/manage/manage.page.component.jsx +++ b/client/src/pages/manage/manage.page.component.jsx @@ -22,7 +22,6 @@ import PrintCenterModalContainer from "../../components/print-center-modal/print import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-status.component"; import UpdateAlert from "../../components/update-alert/update-alert.component"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; -import { useSocket } from "../../contexts/SocketIO/useSocket.js"; import { addAlerts } from "../../redux/application/application.actions.js"; import { selectAlerts } from "../../redux/application/application.selectors.js"; import { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors"; @@ -102,7 +101,7 @@ const MyTasksPage = lazy(() => import("../tasks/myTasksPageContainer.jsx")); const AllTasksPage = lazy(() => import("../tasks/allTasksPageContainer.jsx")); const TaskUpsertModalContainer = lazy(() => import("../../components/task-upsert-modal/task-upsert-modal.container")); -const { Content, Footer } = Layout; +const { Content } = Layout; const mapStateToProps = createStructuredSelector({ conflict: selectInstanceConflict, @@ -122,7 +121,6 @@ const mapDispatchToProps = (dispatch) => ({ export function Manage({ conflict, bodyshop, alerts, setAlerts }) { const { t } = useTranslation(); const [chatVisible] = useState(false); - const { socket, clientId } = useSocket(); const notification = useNotification(); // State to track displayed alerts @@ -636,13 +634,6 @@ export function Manage({ conflict, bodyshop, alerts, setAlerts }) { else if (bodyshop && bodyshop.sub_status !== "active") PageContent = ; else PageContent = AppRouteTable; - const broadcastMessage = () => { - if (socket && bodyshop && bodyshop.id) { - console.log(`Broadcasting message to bodyshop ${bodyshop.id}:`); - socket.emit("broadcast-to-bodyshop", bodyshop.id, `Hello from ${clientId}`); - } - }; - return ( <> diff --git a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx index 4b5cca325..c19e011d0 100644 --- a/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx +++ b/client/src/pages/simplified-parts-jobs-detail/simplified-parts-jobs-detail.component.jsx @@ -16,8 +16,6 @@ import JobsChangeStatus from "../../components/jobs-change-status/jobs-change-st import JobsDetailHeaderActions from "../../components/jobs-detail-header-actions/jobs-detail-header-actions.component.jsx"; import JobsDetailHeader from "../../components/jobs-detail-header/jobs-detail-header.component.jsx"; import JobsDetailPliContainer from "../../components/jobs-detail-pli/jobs-detail-pli.container.jsx"; -import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; -import { useSocket } from "../../contexts/SocketIO/useSocket.js"; import { QUERY_PARTS_BILLS_BY_JOBID } from "../../graphql/bills.queries.js"; import { insertAuditTrail } from "../../redux/application/application.actions.js"; import { selectJobReadOnly } from "../../redux/application/application.selectors.js"; @@ -60,18 +58,14 @@ export function SimplifiedPartsJobDetailComponent({ const { t } = useTranslation(); const [form] = Form.useForm(); const history = useNavigate(); - const [loading, setLoading] = useState(false); + const [loading] = useState(false); const search = queryString.parse(useLocation().search); - const formItemLayout = { - layout: "vertical" - }; + const billsQuery = useQuery(QUERY_PARTS_BILLS_BY_JOBID, { variables: { jobid: job.id }, fetchPolicy: "network-only", nextFetchPolicy: "network-only" }); - const notification = useNotification(); - const { scenarioNotificationsOn } = useSocket(); useEffect(() => { //form.setFieldsValue(transormJobToForm(job)); diff --git a/client/src/redux/user/user.selectors.js b/client/src/redux/user/user.selectors.js index b08b12931..f0a54ff68 100644 --- a/client/src/redux/user/user.selectors.js +++ b/client/src/redux/user/user.selectors.js @@ -1,4 +1,3 @@ -import { create } from "lodash"; import { createSelector } from "reselect"; const selectUser = (state) => state.user; @@ -18,7 +17,4 @@ export const selectAuthLevel = createSelector([selectUser], (user) => user.authL export const selectLoginLoading = createSelector([selectUser], (user) => user.loginLoading); export const selectCurrentEula = createSelector([selectUser], (user) => user.currentEula); -export const selectPartsManagementOnly = createSelector( - [selectUser], - (user) => user.partsManagementOnly -); \ No newline at end of file +export const selectPartsManagementOnly = createSelector([selectUser], (user) => user.partsManagementOnly); From 94b154a4ac712def0b1f620608902fadd06e4058 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Thu, 3 Jul 2025 14:05:35 -0400 Subject: [PATCH 19/98] feature/IO-3255-simplified-parts-management - Checkpoint / Meeting changes --- client/src/redux/user/user.sagas.js | 17 +-- .../partsManagementProvisioning.js | 29 +++-- ...rtsManagementVehicleDamageEstimateAddRq.js | 123 +++++------------- .../integrations/partsManagement/swagger.yaml | 6 + 4 files changed, 70 insertions(+), 105 deletions(-) diff --git a/client/src/redux/user/user.sagas.js b/client/src/redux/user/user.sagas.js index 649551ff6..2c84e1ee7 100644 --- a/client/src/redux/user/user.sagas.js +++ b/client/src/redux/user/user.sagas.js @@ -345,13 +345,13 @@ export function* SetAuthLevelFromShopDetails({ payload }) { payload.features?.allAccess === true ? window.$crisp.push(["set", "session:segments", [["allAccess"]]]) : (() => { - const featureKeys = Object.keys(payload.features).filter( - (key) => - payload.features[key] === true || - (typeof payload.features[key] === "string" && !isNaN(Date.parse(payload.features[key]))) - ); - window.$crisp.push(["set", "session:segments", [["basic", ...featureKeys]]]); - })(); + const featureKeys = Object.keys(payload.features).filter( + (key) => + payload.features[key] === true || + (typeof payload.features[key] === "string" && !isNaN(Date.parse(payload.features[key]))) + ); + window.$crisp.push(["set", "session:segments", [["basic", ...featureKeys]]]); + })(); InstanceRenderManager({ executeFunction: true, @@ -361,8 +361,9 @@ export function* SetAuthLevelFromShopDetails({ payload }) { } }); - //Set whether it is for parts management only. + //Set whether it is for parts management only. + // TODO: This is a temp fix we do not want to do a check on true yield put(setPartsManagementOnly(true || payload.features.partsManagementOnly)); } catch (error) { console.warn("Couldnt find $crisp.", error.message); diff --git a/server/integrations/partsManagement/partsManagementProvisioning.js b/server/integrations/partsManagement/partsManagementProvisioning.js index 4fe5970e9..8c8d2a394 100644 --- a/server/integrations/partsManagement/partsManagementProvisioning.js +++ b/server/integrations/partsManagement/partsManagementProvisioning.js @@ -32,12 +32,17 @@ const ensureEmailNotRegistered = async (email) => { }; /** - * Creates a new Firebase user with the provided email. + * Creates a new Firebase user with the provided email and optional password. * @param email + * @param password * @returns {Promise} */ -const createFirebaseUser = async (email) => { - return admin.auth().createUser({ email }); +const createFirebaseUser = async (email, password = null) => { + const userData = { email }; + if (password) { + userData.password = password; + } + return admin.auth().createUser(userData); }; /** @@ -158,7 +163,7 @@ const partsManagementProvisioning = async (req, res) => { const p = { ...req.body, userEmail: req.body.userEmail?.toLowerCase() }; try { - // Validate inputs + // Validate inputs await ensureEmailNotRegistered(p.userEmail); requireFields(p, [ "external_shop_id", @@ -179,7 +184,7 @@ const partsManagementProvisioning = async (req, res) => { ioadmin: true }); - // Create shop + // Create shop const shopInput = { shopname: p.shopname, address1: p.address1, @@ -198,6 +203,9 @@ const partsManagementProvisioning = async (req, res) => { height: "", headerMargin: DefaultNewShop.logo_img_path.headerMargin }, + features: { + partsManagementOnly: true // This is a parts management only shop + }, md_ro_statuses: DefaultNewShop.md_ro_statuses, vendors: { data: p.vendors.map((v) => ({ @@ -221,9 +229,12 @@ const partsManagementProvisioning = async (req, res) => { }; const newShopId = await insertBodyshop(shopInput); - // Create user + association - const userRecord = await createFirebaseUser(p.userEmail); - const resetLink = await generateResetLink(p.userEmail); + // Create user + association + const userRecord = await createFirebaseUser(p.userEmail, p.userPassword); + let resetLink = null; + if (!p.userPassword) { + resetLink = await generateResetLink(p.userEmail); + } const createdUser = await insertUserAssociation(userRecord.uid, p.userEmail, newShopId); return res.status(200).json({ @@ -231,7 +242,7 @@ const partsManagementProvisioning = async (req, res) => { user: { id: createdUser.id, email: createdUser.email, - resetLink + resetLink: resetLink || undefined // Only include resetLink if it exists } }); } catch (err) { diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js index ea3803725..547b4739f 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js @@ -9,11 +9,7 @@ const { GET_BODYSHOP_STATUS, GET_VEHICLE_BY_SHOP_VIN, INSERT_OWNER, - INSERT_JOB_WITH_LINES, - GET_JOB_BY_CLAIM, - UPDATE_JOB_BY_ID, - INSERT_JOBLINES, - DELETE_JOBLINES_BY_JOBID + INSERT_JOB_WITH_LINES } = require("./partsManagement.queries"); // Defaults @@ -177,12 +173,28 @@ const extractJobData = (rq) => { asgn_no: asgn.AssignmentNumber || null, asgn_type: asgn.AssignmentType || null, asgn_date: asgn.AssignmentDate || null, + // asgn_created: asgn.CreateDateTime || null, scheduled_in: ev.RepairEvent?.RequestedPickUpDateTime || null, scheduled_completion: ev.RepairEvent?.TargetCompletionDateTime || null, clm_no: ci.ClaimNum || null, status: ci.ClaimStatus || null, policy_no: ci.PolicyInfo?.PolicyNum || null, ded_amt: parseFloat(ci.PolicyInfo?.CoverageInfo?.Coverage?.DeductibleInfo?.DeductibleAmt || 0) + // document_id: doc.DocumentID || null, + // bms_version: doc.BMSVer || null, + // reference_info: + // doc.ReferenceInfo?.OtherReferenceInfo?.map((ref) => ({ + // name: ref.OtherReferenceName, + // number: ref.OtherRefNum + // })) || [], + // currency_info: doc.CurrencyInfo + // ? { + // code: doc.CurrencyInfo.CurCode, + // base_code: doc.CurrencyInfo.BaseCurCode, + // rate: parseFloat(doc.CurrencyInfo.CurRate || 0), + // rule: doc.CurrencyInfo.CurConvertRule + // } + // : null }; }; @@ -200,14 +212,12 @@ const extractJobData = (rq) => { * @returns {object} Owner data for insertion and inline use. */ const extractOwnerData = (rq, shopId) => { - // Prefer Owner, fallback to Claimant const ownerOrClaimant = rq.AdminInfo?.Owner?.Party || rq.AdminInfo?.Claimant?.Party || {}; - const personInfo = ownerOrClaimant.PersonInfo || {}; const personName = personInfo.PersonName || {}; const address = personInfo.Communications?.Address || {}; - let ownr_ph1, ownr_ph2, ownr_ea; + let ownr_ph1, ownr_ph2, ownr_ea, ownr_alt_ph; const comms = Array.isArray(ownerOrClaimant.ContactInfo?.Communications) ? ownerOrClaimant.ContactInfo.Communications @@ -217,6 +227,7 @@ const extractOwnerData = (rq, shopId) => { if (c.CommQualifier === "CP") ownr_ph1 = c.CommPhone; if (c.CommQualifier === "WP") ownr_ph2 = c.CommPhone; if (c.CommQualifier === "EM") ownr_ea = c.CommEmail; + if (c.CommQualifier === "AL") ownr_alt_ph = c.CommPhone; } return { @@ -232,7 +243,11 @@ const extractOwnerData = (rq, shopId) => { ownr_ctry: address.Country || null, ownr_ph1, ownr_ph2, - ownr_ea + ownr_ea, + ownr_alt_ph + // ownr_id_qualifier: ownerOrClaimant.IDInfo?.IDQualifierCode || null // New + // ownr_id_num: ownerOrClaimant.IDInfo?.IDNum || null, // New + // ownr_preferred_contact: ownerOrClaimant.PreferredContactMethod || null // New }; }; @@ -304,13 +319,19 @@ const extractLossInfo = (rq) => { loss_date: loss.LossDateTime || null, loss_type: custom.LossTypeCode || null, loss_desc: custom.LossTypeDesc || null + // primary_poi: loss.PrimaryPOI?.POICode || null, + // secondary_poi: loss.SecondaryPOI?.POICode || null, + // damage_memo: loss.DamageMemo || null, //(maybe ins_memo) + // total_loss_ind: rq.ClaimInfo?.LossInfo?.TotalLossInd || null // New }; }; /** * Extracts insurance data from the XML request. * @param rq - * @returns {{insd_ln: (*|null), insd_fn: (string|null), insd_title: (*|null), insd_co_nm: (*|string|null), insd_addr1: (*|null), insd_addr2: (*|null), insd_city: (*|null), insd_st: (*|null), insd_zip: (*|null), insd_ctry: (*|null), insd_ph1, insd_ph1x, insd_ph2, insd_ph2x, insd_fax, insd_faxx, insd_ea}} + * @returns {{insd_ln: (*|null), insd_fn: (string|null), insd_title: (*|null), insd_co_nm: (*|string|null), insd_addr1: + * (*|null), insd_addr2: (*|null), insd_city: (*|null), insd_st: (*|null), insd_zip: (*|null), insd_ctry: (*|null), + * insd_ph1, insd_ph1x, insd_ph2, insd_ph2x, insd_fax, insd_faxx, insd_ea}} */ const extractInsuranceData = (rq) => { const insuredParty = rq.AdminInfo?.Insured?.Party || {}; @@ -424,7 +445,10 @@ const extractJobLines = (rq) => { mod_lb_hrs: parseFloat(line.LaborInfo?.LaborHours || 0), lbr_op: line.LaborInfo?.LaborOperation || null, lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), - notes: line.LineMemo || null + notes: line.LineMemo || null, + manual_line: line.ManualLineInd || null + // taxable_ind: line.PartInfo?.TaxableInd || null, + // automated_entry: line.AutomatedEntry || null }; // TODO: Commented out as not clear if needed for version 1, this only applies to Imex and not rome on the front @@ -440,18 +464,6 @@ const extractJobLines = (rq) => { }); }; -/** - * Checks if the request is a supplement or a document portion delta. - * TODO: This is a temporary check, should be replaced with a proper field in the XML. - * @param rq - * @returns {boolean} - */ -const isSupplement = (rq) => { - const docStatus = rq.DocumentInfo?.DocumentStatus; - const historyType = rq.RepairTotalsHistory?.HistoryTotalType; - return docStatus === "S" || historyType === "DocumentPortionDelta"; -}; - /** * Finds an existing vehicle by shopId and VIN. * @param {string} shopId - The bodyshop UUID. @@ -474,26 +486,6 @@ const findExistingVehicle = async (shopId, v_vin, logger) => { return null; }; -/** - * Finds an existing job by shopid and claim number. - * @param shopid - * @param clm_no - * @param logger - * @returns {Promise<*|null>} - */ -const findExistingJob = async (shopid, clm_no, logger) => { - try { - const { jobs } = await client.request(GET_JOB_BY_CLAIM, { - shopid, - clm_no - }); - return jobs?.[0] || null; - } catch (err) { - logger.log("parts-job-fetch-failed", "warn", null, null, { error: err }); - return null; - } -}; - /** * Inserts an owner and returns the owner ID. * @param {object} ownerInput - The owner data to insert. @@ -568,21 +560,6 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { const joblinesData = extractJobLines(rq); const insuranceData = extractInsuranceData(rq); - // Uncomment for debugging - // console.dir( - // { - // joblinesData, - // lossInfo, - // insuranceData, - // vehicleData, - // ownerData, - // adjusterData, - // repairFacilityData, - // estimatorData - // }, - // { depth: null } - // ); - // Find or create relationships const ownerid = await insertOwner(ownerData, logger); const vehicleid = await findExistingVehicle(shopId, vehicleData.v_vin, logger); @@ -628,36 +605,6 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { joblines: { data: joblinesData } }; - // Check if this is a supplement or document portion delta. - if (isSupplement(rq)) { - console.log("----------------------IS SUPPLEMENT----------------------"); - const existingJob = await findExistingJob(shopId, clm_no, logger); - if (existingJob) { - const { joblines, ...jobWithoutLines } = jobInput; - - await client.request(UPDATE_JOB_BY_ID, { - id: existingJob.id, - job: jobWithoutLines - }); - - await client.request(DELETE_JOBLINES_BY_JOBID, { - jobid: existingJob.id - }); - - if (joblines?.data?.length) { - const joblinesWithJobId = joblines.data.map((line) => ({ - ...line, - jobid: existingJob.id - })); - - await client.request(INSERT_JOBLINES, { joblines: joblinesWithJobId }); - } - - logger.log("parts-job-updated", "info", existingJob.id); - return res.status(200).json({ success: true, jobId: existingJob.id }); - } - } - // Insert job const { insert_jobs_one: newJob } = await client.request(INSERT_JOB_WITH_LINES, { job: jobInput }); logger.log("parts-job-created", "info", newJob.id, null); diff --git a/server/integrations/partsManagement/swagger.yaml b/server/integrations/partsManagement/swagger.yaml index 40e28e9b5..03987f0f0 100644 --- a/server/integrations/partsManagement/swagger.yaml +++ b/server/integrations/partsManagement/swagger.yaml @@ -54,6 +54,10 @@ paths: userEmail: type: string format: email + userPassword: + type: string + description: Optional password for the new user. If provided, the password is set directly, and no password reset link is sent. Must be at least 6 characters. + nullable: true logoUrl: type: string format: uri @@ -140,6 +144,8 @@ paths: resetLink: type: string format: uri + nullable: true + description: Password reset link for the user. Only included if userPassword is not provided in the request. '400': description: Bad request (missing or invalid fields) content: From 8bc6bea4b2c46916bc4703e798b6d89ac3329a9b Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 7 Jul 2025 12:14:23 -0400 Subject: [PATCH 20/98] feature/IO-3255-simplified-parts-management - Bump deps, add Change Request --- client/package-lock.json | 104 ++++++++--------- client/package.json | 10 +- .../partsManagement/partsManagementUtils.js | 54 +++++++++ ...sampleBody.vehicleDamageEstimateAddRq.xml} | 0 ...AddRq.js => vehicleDamageEstimateAddRq.js} | 55 +-------- .../vehicleDamageEstimateChgRq.js | 106 ++++++++++++++++++ server/routes/intergrationRoutes.js | 26 ++++- 7 files changed, 242 insertions(+), 113 deletions(-) create mode 100644 server/integrations/partsManagement/partsManagementUtils.js rename server/integrations/partsManagement/{sampleBody.xml => sampleBody.vehicleDamageEstimateAddRq.xml} (100%) rename server/integrations/partsManagement/{partsManagementVehicleDamageEstimateAddRq.js => vehicleDamageEstimateAddRq.js} (92%) create mode 100644 server/integrations/partsManagement/vehicleDamageEstimateChgRq.js diff --git a/client/package-lock.json b/client/package-lock.json index b672a0c37..9e3a2cfd9 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -21,11 +21,11 @@ "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.34.0", + "@sentry/react": "^9.35.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.3", + "antd": "^5.26.4", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -50,7 +50,7 @@ "object-hash": "^3.0.0", "phone": "^3.1.62", "prop-types": "^15.8.1", - "query-string": "^9.2.1", + "query-string": "^9.2.2", "raf-schd": "^4.0.3", "react": "^18.3.1", "react-big-calendar": "^1.19.4", @@ -60,7 +60,7 @@ "react-drag-listview": "^2.0.0", "react-grid-gallery": "^1.0.1", "react-grid-layout": "1.3.4", - "react-i18next": "^15.5.3", + "react-i18next": "^15.6.0", "react-icons": "^5.5.0", "react-image-lightbox": "^5.1.4", "react-markdown": "^10.1.0", @@ -118,7 +118,7 @@ "vite": "^6.3.5", "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", - "vite-plugin-node-polyfills": "^0.23.0", + "vite-plugin-node-polyfills": "^0.24.0", "vite-plugin-pwa": "^1.0.1", "vite-plugin-style-import": "^2.0.0", "vitest": "^3.2.4", @@ -4466,50 +4466,50 @@ "license": "MIT" }, "node_modules/@sentry-internal/browser-utils": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.34.0.tgz", - "integrity": "sha512-pXVznvP4CROejYtk6y7UQvPTieWz2vXjukGlO45fsnQa9nNo30lkQh3Ws2HZw2YbTxYZQYx75FBDezwKl2q0hQ==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.35.0.tgz", + "integrity": "sha512-75/zOArDQ4ASgndKGQo0m0v8P921eq/Q/sJvR14NopzwuwAchBhjziixWCwxKgvoA20eg3OGwMIkzztxmdp2Tw==", "license": "MIT", "dependencies": { - "@sentry/core": "9.34.0" + "@sentry/core": "9.35.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/feedback": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.34.0.tgz", - "integrity": "sha512-HT/EBRl1DR8XqlJk2wFNPJFcnIzNcEDjmW7C/o7K0GeP5jcSH0dKpcH7ykz2bi46gMRPrkO5EK2eXGK81KYI3g==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.35.0.tgz", + "integrity": "sha512-IKaZWUmqqqLucuJ5EGgwdrBdvP3l3STXvgKsLmW2l+s9WYbvfPPHukZhUULYRsXleQKXnOuz44WQmwNeZYQutw==", "license": "MIT", "dependencies": { - "@sentry/core": "9.34.0" + "@sentry/core": "9.35.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.34.0.tgz", - "integrity": "sha512-joYSqWltmpkcqI8Gg8jwFtPv0F01whmuQfNGoGaL7Z6B/xO1vvkqEudrg1tmswUHhqtYpZYaEaCvrmv0sPGCfA==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.35.0.tgz", + "integrity": "sha512-veGNAXeHXULzkGPudMg5iFqkW4wFD/qVbQSr+s0q3+IZ7vJ+Eql+eBDZEKrfKYIBdNOf5POr+KaEBMpMGCbEkQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.34.0", - "@sentry/core": "9.34.0" + "@sentry-internal/browser-utils": "9.35.0", + "@sentry/core": "9.35.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.34.0.tgz", - "integrity": "sha512-GCtqMFk9WwrU3JNz1tlCFAhzmNfgZhLRaS0cLzoTuxPbG3CC2VUIWYEOw7+AdCJZGm8ElTMxu+BkChgGb8qthQ==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.35.0.tgz", + "integrity": "sha512-nXxrEIkpn+FBxYsD4JPQStEGQWF0j0Rs0LoCyuB1e2QeEg6Pipqg4DIjWDjZyeUAsdoaUsIRhWbMK5OBWUuudw==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "9.34.0", - "@sentry/core": "9.34.0" + "@sentry-internal/replay": "9.35.0", + "@sentry/core": "9.35.0" }, "engines": { "node": ">=18" @@ -4525,16 +4525,16 @@ } }, "node_modules/@sentry/browser": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.34.0.tgz", - "integrity": "sha512-6oJxU7JEA/RCgMTVlHXT54U9d0DWg61GgzyLTM+FUa8OUrAoK/t+CZGSMc/13nYN8xs7vcpiORdRx0ogch9zGw==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.35.0.tgz", + "integrity": "sha512-m1fRwMa1vik6VFAAz6RlJUUU+0+Uo+QIKJWWOx9calb11Zt4wIg9wvox7TOgMd8KPt3sefPXIPM38A+uixyXYw==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.34.0", - "@sentry-internal/feedback": "9.34.0", - "@sentry-internal/replay": "9.34.0", - "@sentry-internal/replay-canvas": "9.34.0", - "@sentry/core": "9.34.0" + "@sentry-internal/browser-utils": "9.35.0", + "@sentry-internal/feedback": "9.35.0", + "@sentry-internal/replay": "9.35.0", + "@sentry-internal/replay-canvas": "9.35.0", + "@sentry/core": "9.35.0" }, "engines": { "node": ">=18" @@ -4911,22 +4911,22 @@ } }, "node_modules/@sentry/core": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.34.0.tgz", - "integrity": "sha512-M/zikVaE3KLkhCFDyrHB35sF7pVkB2RPy07BcRsdFsSsdpjoG+Zq2Sxth2tMTbjd0x9Vtb/X6LVjyCj9GSEvVg==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.35.0.tgz", + "integrity": "sha512-bdAtzVQZ/wn4L/m8r2OUCCG/NWr0Q8dyZDwdwvINJaMbyhDRUdQh/MWjrz+id/3JoOL1LigAyTV1h4FJDGuwUQ==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@sentry/react": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.34.0.tgz", - "integrity": "sha512-xrai0g8qBS0AyiAytHlrBiTPu1zG7DNNh4GodAkHcd1j2iVti2c+AR7KgUY7UrsrjXd8Fpy7c+qo+5DnHLpulw==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.35.0.tgz", + "integrity": "sha512-zoLcucRYhSLKGYJ0b06MBVF+s3DvLK3YY651sf9boV071tWZs6Q8FDDD3E+pgw8t+ngL+6kB989Ns2HhyLyYIQ==", "license": "MIT", "dependencies": { - "@sentry/browser": "9.34.0", - "@sentry/core": "9.34.0", + "@sentry/browser": "9.35.0", + "@sentry/core": "9.35.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -6120,9 +6120,9 @@ } }, "node_modules/antd": { - "version": "5.26.3", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.3.tgz", - "integrity": "sha512-M/s9Q39h/+G7AWnS6fbNxmAI9waTH4ti022GVEXBLq2j810V1wJ3UOQps13nEilzDNcyxnFN/EIbqIgS7wSYaA==", + "version": "5.26.4", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.4.tgz", + "integrity": "sha512-e1EnOvEkvvqcQ18dxfzChBJyJACyih13WpNf2OtnP9z2POh/SF0fXL+ynUemT1zfr+p+P1po/tmHXaMc5PMghg==", "license": "MIT", "dependencies": { "@ant-design/colors": "^7.2.1", @@ -13610,9 +13610,9 @@ } }, "node_modules/query-string": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-9.2.1.tgz", - "integrity": "sha512-3jTGGLRzlhu/1ws2zlr4Q+GVMLCQTLFOj8CMX5x44cdZG9FQE07x2mQhaNxaKVPNmIDu0mvJ/cEwtY7Pim7hqA==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-9.2.2.tgz", + "integrity": "sha512-pDSIZJ9sFuOp6VnD+5IkakSVf+rICAuuU88Hcsr6AKL0QtxSIfVuKiVP2oahFI7tk3CRSexwV+Ya6MOoTxzg9g==", "license": "MIT", "dependencies": { "decode-uri-component": "^0.4.1", @@ -14441,9 +14441,9 @@ } }, "node_modules/react-i18next": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.5.3.tgz", - "integrity": "sha512-ypYmOKOnjqPEJZO4m1BI0kS8kWqkBNsKYyhVUfij0gvjy9xJNoG/VcGkxq5dRlVwzmrmY1BQMAmpbbUBLwC4Kw==", + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.6.0.tgz", + "integrity": "sha512-W135dB0rDfiFmbMipC17nOhGdttO5mzH8BivY+2ybsQBbXvxWIwl3cmeH3T9d+YPBSJu/ouyJKFJTtkK7rJofw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.27.6", @@ -17680,9 +17680,9 @@ } }, "node_modules/vite-plugin-node-polyfills": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.23.0.tgz", - "integrity": "sha512-4n+Ys+2bKHQohPBKigFlndwWQ5fFKwaGY6muNDMTb0fSQLyBzS+jjUNRZG9sKF0S/Go4ApG6LFnUGopjkILg3w==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.24.0.tgz", + "integrity": "sha512-GA9QKLH+vIM8NPaGA+o2t8PDfFUl32J8rUp1zQfMKVJQiNkOX4unE51tR6ppl6iKw5yOrDAdSH7r/UIFLCVhLw==", "dev": true, "license": "MIT", "dependencies": { @@ -17693,7 +17693,7 @@ "url": "https://github.com/sponsors/davidmyersdev" }, "peerDependencies": { - "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "node_modules/vite-plugin-pwa": { diff --git a/client/package.json b/client/package.json index 206dd44f4..732de4277 100644 --- a/client/package.json +++ b/client/package.json @@ -20,11 +20,11 @@ "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.46.0", - "@sentry/react": "^9.34.0", + "@sentry/react": "^9.35.0", "@sentry/vite-plugin": "^3.5.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.3", + "antd": "^5.26.4", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -49,7 +49,7 @@ "object-hash": "^3.0.0", "phone": "^3.1.62", "prop-types": "^15.8.1", - "query-string": "^9.2.1", + "query-string": "^9.2.2", "raf-schd": "^4.0.3", "react": "^18.3.1", "react-big-calendar": "^1.19.4", @@ -59,7 +59,7 @@ "react-drag-listview": "^2.0.0", "react-grid-gallery": "^1.0.1", "react-grid-layout": "1.3.4", - "react-i18next": "^15.5.3", + "react-i18next": "^15.6.0", "react-icons": "^5.5.0", "react-image-lightbox": "^5.1.4", "react-markdown": "^10.1.0", @@ -158,7 +158,7 @@ "vite": "^6.3.5", "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", - "vite-plugin-node-polyfills": "^0.23.0", + "vite-plugin-node-polyfills": "^0.24.0", "vite-plugin-pwa": "^1.0.1", "vite-plugin-style-import": "^2.0.0", "vitest": "^3.2.4", diff --git a/server/integrations/partsManagement/partsManagementUtils.js b/server/integrations/partsManagement/partsManagementUtils.js new file mode 100644 index 000000000..b1b68b557 --- /dev/null +++ b/server/integrations/partsManagement/partsManagementUtils.js @@ -0,0 +1,54 @@ +const xml2js = require("xml2js"); + +/** + * Parses XML string into a JavaScript object. + * @param {string} xml - The XML string to parse. + * @param {object} logger - The logger instance. + * @returns {Promise} The parsed XML object. + * @throws {Error} If XML parsing fails. + */ +const parseXml = async (xml, logger) => { + try { + return await xml2js.parseStringPromise(xml, { + explicitArray: false, + tagNameProcessors: [xml2js.processors.stripPrefix], + attrNameProcessors: [xml2js.processors.stripPrefix] + }); + } catch (err) { + logger.log("parts-xml-parse-error", "error", null, null, { error: err }); + throw new Error("Invalid XML"); + } +}; + +/** + * Recursively strip `xml2js`-style { _: 'value', $: { ... } } nodes into plain strings. + * @param {*} obj - Parsed XML object + * @returns {*} Normalized object + */ +const normalizeXmlObject = (obj) => { + if (Array.isArray(obj)) { + return obj.map(normalizeXmlObject); + } + + if (typeof obj === "object" && obj !== null) { + if (Object.keys(obj).length === 2 && "_" in obj && "$" in obj) { + return normalizeXmlObject(obj._); // unwrap {_:"value",$:{...}} to just "value" + } + if (Object.keys(obj).length === 1 && "_" in obj) { + return normalizeXmlObject(obj._); // unwrap {_:"value"} + } + + const normalized = {}; + for (const key in obj) { + normalized[key] = normalizeXmlObject(obj[key]); + } + return normalized; + } + + return obj; +}; + +module.exports = { + parseXml, + normalizeXmlObject +}; diff --git a/server/integrations/partsManagement/sampleBody.xml b/server/integrations/partsManagement/sampleBody.vehicleDamageEstimateAddRq.xml similarity index 100% rename from server/integrations/partsManagement/sampleBody.xml rename to server/integrations/partsManagement/sampleBody.vehicleDamageEstimateAddRq.xml diff --git a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/vehicleDamageEstimateAddRq.js similarity index 92% rename from server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js rename to server/integrations/partsManagement/vehicleDamageEstimateAddRq.js index 547b4739f..82bf09cc5 100644 --- a/server/integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/vehicleDamageEstimateAddRq.js @@ -1,8 +1,8 @@ // no-dd-sa:javascript-code-style/assignment-name // CamelCase is used for GraphQL and database fields. -const xml2js = require("xml2js"); const client = require("../../graphql-client/graphql-client").client; +const { parseXml, normalizeXmlObject } = require("./partsManagementUtils"); // GraphQL Queries and Mutations const { @@ -34,55 +34,6 @@ const KNOWN_PART_RATE_TYPES = [ "CCM", "CCDR" ]; - -/** - * Parses XML string into a JavaScript object. - * @param {string} xml - The XML string to parse. - * @param {object} logger - The logger instance. - * @returns {Promise} The parsed XML object. - * @throws {Error} If XML parsing fails. - */ -const parseXml = async (xml, logger) => { - try { - return await xml2js.parseStringPromise(xml, { - explicitArray: false, - tagNameProcessors: [xml2js.processors.stripPrefix], - attrNameProcessors: [xml2js.processors.stripPrefix] - }); - } catch (err) { - logger.log("parts-xml-parse-error", "error", null, null, { error: err }); - throw new Error("Invalid XML"); - } -}; - -/** - * Recursively strip `xml2js`-style { _: 'value', $: { ... } } nodes into plain strings. - * @param {*} obj - Parsed XML object - * @returns {*} Normalized object - */ -const normalizeXmlObject = (obj) => { - if (Array.isArray(obj)) { - return obj.map(normalizeXmlObject); - } - - if (typeof obj === "object" && obj !== null) { - if (Object.keys(obj).length === 2 && "_" in obj && "$" in obj) { - return normalizeXmlObject(obj._); // unwrap {_:"value",$:{...}} to just "value" - } - if (Object.keys(obj).length === 1 && "_" in obj) { - return normalizeXmlObject(obj._); // unwrap {_:"value"} - } - - const normalized = {}; - for (const key in obj) { - normalized[key] = normalizeXmlObject(obj[key]); - } - return normalized; - } - - return obj; -}; - /** * Fetches the default order status for a bodyshop. * @param {string} shopId - The bodyshop UUID. @@ -508,7 +459,7 @@ const insertOwner = async (ownerInput, logger) => { * @param {object} res - The HTTP response object. * @returns {Promise} */ -const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { +const vehicleDamageEstimateAddRq = async (req, res) => { const { logger } = req; try { @@ -617,4 +568,4 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => { } }; -module.exports = partsManagementVehicleDamageEstimateAddRq; +module.exports = vehicleDamageEstimateAddRq; diff --git a/server/integrations/partsManagement/vehicleDamageEstimateChgRq.js b/server/integrations/partsManagement/vehicleDamageEstimateChgRq.js new file mode 100644 index 000000000..a486bd24a --- /dev/null +++ b/server/integrations/partsManagement/vehicleDamageEstimateChgRq.js @@ -0,0 +1,106 @@ +// no-dd-sa:javascript-code-style/assignment-name +// Handler for VehicleDamageEstimateChgRq + +const client = require("../../graphql-client/graphql-client").client; +const { parseXml, normalizeXmlObject } = require("./partsManagementUtils"); + +const { + GET_JOB_BY_CLAIM_OR_DOCID, + UPDATE_JOB_BY_PK, + UPSERT_JOBLINES, + DELETE_JOBLINES_BY_IDS +} = require("./partsManagement.queries"); + +const findJob = async (claimNum, documentId, logger) => { + try { + const { jobs } = await client.request(GET_JOB_BY_CLAIM_OR_DOCID, { claimNum, documentId }); + return jobs?.[0] || null; + } catch (err) { + logger.log("parts-job-lookup-failed", "error", null, null, { error: err }); + return null; + } +}; + +const extractUpdatedJobData = (rq) => { + const doc = rq.DocumentInfo || {}; + const claim = rq.ClaimInfo || {}; + + return { + comment: doc.Comment || null, + clm_no: claim.ClaimNum || null, + status: claim.ClaimStatus || null, + policy_no: claim.PolicyInfo?.PolicyNum || null + }; +}; + +const extractUpdatedJobLines = (addsChgs = {}) => { + const lines = Array.isArray(addsChgs.DamageLineInfo) ? addsChgs.DamageLineInfo : [addsChgs.DamageLineInfo || []]; + + return lines.map((line) => ({ + line_no: parseInt(line.LineNum, 10), + unq_seq: parseInt(line.UniqueSequenceNum, 10), + status: line.LineStatusCode || null, + line_desc: line.LineDesc || null, + part_type: line.PartInfo?.PartType || null, + part_qty: parseFloat(line.PartInfo?.Quantity || 0), + oem_partno: line.PartInfo?.OEMPartNum || null, + db_price: parseFloat(line.PartInfo?.PartPrice || 0), + act_price: parseFloat(line.PartInfo?.PartPrice || 0), + mod_lbr_ty: line.LaborInfo?.LaborType || null, + mod_lb_hrs: parseFloat(line.LaborInfo?.LaborHours || 0), + lbr_op: line.LaborInfo?.LaborOperation || null, + lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), + notes: line.LineMemo || null, + manual_line: line.ManualLineInd || null + })); +}; + +const extractDeletions = (deletions = {}) => { + const lines = Array.isArray(deletions.DamageLineInfo) ? deletions.DamageLineInfo : [deletions.DamageLineInfo || []]; + + return lines.map((line) => parseInt(line.UniqueSequenceNum, 10)).filter((id) => !isNaN(id)); +}; + +const partsManagementVehicleDamageEstimateChgRq = async (req, res) => { + const { logger } = req; + + try { + const payload = await parseXml(req.body, logger); + const rq = normalizeXmlObject(payload.VehicleDamageEstimateChgRq); + if (!rq) return res.status(400).send("Missing "); + + const shopId = rq.ShopID; + const claimNum = rq.ClaimInfo?.ClaimNum; + const documentId = rq.DocumentInfo?.DocumentID; + + if (!shopId || !claimNum) return res.status(400).send("Missing ShopID or ClaimNum"); + + const job = await findJob(claimNum, documentId, logger); + if (!job) return res.status(404).send("Job not found"); + + const updatedJobData = extractUpdatedJobData(rq); + const updatedLines = extractUpdatedJobLines(rq.AddsChgs); + const deletedLineIds = extractDeletions(rq.Deletions); + + await client.request(UPDATE_JOB_BY_PK, { id: job.id, changes: updatedJobData }); + + if (updatedLines.length > 0) { + await client.request(UPSERT_JOBLINES, { + jobid: job.id, + joblines: updatedLines + }); + } + + if (deletedLineIds.length > 0) { + await client.request(DELETE_JOBLINES_BY_IDS, { jobid: job.id, unqSeqs: deletedLineIds }); + } + + logger.log("parts-job-changed", "info", job.id, null); + return res.status(200).json({ success: true, jobId: job.id }); + } catch (err) { + logger.log("parts-chgrq-error", "error", null, null, { error: err }); + return res.status(err.status || 500).json({ error: err.message || "Internal error" }); + } +}; + +module.exports = partsManagementVehicleDamageEstimateChgRq; diff --git a/server/routes/intergrationRoutes.js b/server/routes/intergrationRoutes.js index 4af112a97..5914a2bde 100644 --- a/server/routes/intergrationRoutes.js +++ b/server/routes/intergrationRoutes.js @@ -1,6 +1,6 @@ const express = require("express"); const router = express.Router(); -const bodyParser = require("body-parser"); // Add body-parser dependency +const bodyParser = require("body-parser"); // Pull secrets from env const { VSSTA_INTEGRATION_SECRET, PARTS_MANAGEMENT_INTEGRATION_SECRET } = process.env; @@ -17,18 +17,36 @@ if (typeof VSSTA_INTEGRATION_SECRET === "string" && VSSTA_INTEGRATION_SECRET.len // Only load Parts Management routes if that secret is set if (typeof PARTS_MANAGEMENT_INTEGRATION_SECRET === "string" && PARTS_MANAGEMENT_INTEGRATION_SECRET.length > 0) { + const XML_BODY_LIMIT = "10mb"; // Set a limit for XML body size + const partsManagementProvisioning = require("../integrations/partsManagement/partsManagementProvisioning"); const partsManagementIntegrationMiddleware = require("../middleware/partsManagementIntegrationMiddleware"); - const partsManagementVehicleDamageEstimateAddRq = require("../integrations/partsManagement/partsManagementVehicleDamageEstimateAddRq"); + const partsManagementVehicleDamageEstimateAddRq = require("../integrations/partsManagement/vehicleDamageEstimateAddRq"); + const partsManagementVehicleDamageEstimateChqRq = require("../integrations/partsManagement/vehicleDamageEstimateChgRq"); - // Add XML parsing middleware for the VehicleDamageEstimateAddRq route + /** + * Route to handle Vehicle Damage Estimate Add Request + */ router.post( "/parts-management/VehicleDamageEstimateAddRq", - bodyParser.raw({ type: "application/xml", limit: "10mb" }), // Parse XML body + bodyParser.raw({ type: "application/xml", limit: XML_BODY_LIMIT }), // Parse XML body partsManagementIntegrationMiddleware, partsManagementVehicleDamageEstimateAddRq ); + /** + * Route to handle Vehicle Damage Estimate Change Request + */ + router.post( + "/parts-management/VehicleDamageEstimateChgRq", + bodyParser.raw({ type: "application/xml", limit: XML_BODY_LIMIT }), // Parse XML body + partsManagementIntegrationMiddleware, + partsManagementVehicleDamageEstimateChqRq + ); + + /** + * Route to handle Parts Management Provisioning + */ router.post("/parts-management/provision", partsManagementIntegrationMiddleware, partsManagementProvisioning); } else { console.warn("PARTS_MANAGEMENT_INTEGRATION_SECRET is not set — skipping /parts-management/provision route"); From bd2720f5343c80d233a2734b23b49da23eace45a Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 7 Jul 2025 13:09:55 -0400 Subject: [PATCH 21/98] feature/IO-3255-simplified-parts-management - Refactor / Working Change Request --- .../partsManagementProvisioning.js | 133 ++++-------------- .../vehicleDamageEstimateAddRq.js | 6 +- .../vehicleDamageEstimateChgRq.js | 27 ++-- .../partsManagement.queries.js | 111 +++++++++++---- server/routes/intergrationRoutes.js | 8 +- 5 files changed, 129 insertions(+), 156 deletions(-) rename server/integrations/partsManagement/{ => endpoints}/partsManagementProvisioning.js (59%) rename server/integrations/partsManagement/{ => endpoints}/vehicleDamageEstimateAddRq.js (99%) rename server/integrations/partsManagement/{ => endpoints}/vehicleDamageEstimateChgRq.js (79%) diff --git a/server/integrations/partsManagement/partsManagementProvisioning.js b/server/integrations/partsManagement/endpoints/partsManagementProvisioning.js similarity index 59% rename from server/integrations/partsManagement/partsManagementProvisioning.js rename to server/integrations/partsManagement/endpoints/partsManagementProvisioning.js index 8c8d2a394..797ce619d 100644 --- a/server/integrations/partsManagement/partsManagementProvisioning.js +++ b/server/integrations/partsManagement/endpoints/partsManagementProvisioning.js @@ -1,12 +1,15 @@ const admin = require("firebase-admin"); -const client = require("../../graphql-client/graphql-client").client; -const DefaultNewShop = require("./defaultNewShop.json"); +const client = require("../../../graphql-client/graphql-client").client; +const DefaultNewShop = require("../defaultNewShop.json"); + +const { + CHECK_EXTERNAL_SHOP_ID, + CREATE_SHOP, + DELETE_VENDORS_BY_SHOP, + DELETE_SHOP, + CREATE_USER +} = require("../partsManagement.queries"); -/** - * Ensures that the required fields are present in the payload. - * @param payload - * @param fields - */ const requireFields = (payload, fields) => { for (const field of fields) { if (!payload[field]) { @@ -15,11 +18,6 @@ const requireFields = (payload, fields) => { } }; -/** - * Ensures that the email is not already registered in Firebase. - * @param email - * @returns {Promise} - */ const ensureEmailNotRegistered = async (email) => { try { await admin.auth().getUserByEmail(email); @@ -31,113 +29,41 @@ const ensureEmailNotRegistered = async (email) => { } }; -/** - * Creates a new Firebase user with the provided email and optional password. - * @param email - * @param password - * @returns {Promise} - */ const createFirebaseUser = async (email, password = null) => { const userData = { email }; - if (password) { - userData.password = password; - } + if (password) userData.password = password; return admin.auth().createUser(userData); }; -/** - * Deletes a Firebase user by their UID. - * @param uid - * @returns {Promise} - */ const deleteFirebaseUser = async (uid) => { return admin.auth().deleteUser(uid); }; -/** - * Generates a password reset link for the given email. - * @param email - * @returns {Promise} - */ const generateResetLink = async (email) => { return admin.auth().generatePasswordResetLink(email); }; -/** - * Ensures that the external shop ID is unique in the database. - * @param externalId - * @returns {Promise} - */ const ensureExternalIdUnique = async (externalId) => { - const query = ` - query CHECK_KEY($key: String!) { - bodyshops(where: { external_shop_id: { _eq: $key } }) { - external_shop_id - } - }`; - const resp = await client.request(query, { key: externalId }); + const resp = await client.request(CHECK_EXTERNAL_SHOP_ID, { key: externalId }); if (resp.bodyshops.length) { throw { status: 400, message: `external_shop_id '${externalId}' is already in use.` }; } }; -/** - * Inserts a new bodyshop into the database. - * @param input - * @returns {Promise<*>} - */ const insertBodyshop = async (input) => { - const mutation = ` - mutation CREATE_SHOP($bs: bodyshops_insert_input!) { - insert_bodyshops_one(object: $bs) { id } - }`; - const resp = await client.request(mutation, { bs: input }); + const resp = await client.request(CREATE_SHOP, { bs: input }); return resp.insert_bodyshops_one.id; }; -/** - * Deletes all vendors associated with a specific shop ID. - * @param shopId - * @returns {Promise} - */ const deleteVendorsByShop = async (shopId) => { - const mutation = ` - mutation DELETE_VENDORS($shopId: uuid!) { - delete_vendors(where: { shopid: { _eq: $shopId } }) { - affected_rows - } - }`; - await client.request(mutation, { shopId }); + await client.request(DELETE_VENDORS_BY_SHOP, { shopId }); }; -/** - * Deletes a bodyshop by its ID. - * @param shopId - * @returns {Promise} - */ const deleteBodyshop = async (shopId) => { - const mutation = ` - mutation DELETE_SHOP($id: uuid!) { - delete_bodyshops_by_pk(id: $id) { id } - }`; - await client.request(mutation, { id: shopId }); + await client.request(DELETE_SHOP, { id: shopId }); }; -/** - * Inserts a new user association into the database. - * @param uid - * @param email - * @param shopId - * @returns {Promise<*>} - */ const insertUserAssociation = async (uid, email, shopId) => { - const mutation = ` - mutation CREATE_USER($u: users_insert_input!) { - insert_users_one(object: $u) { - id: authid - email - } - }`; const vars = { u: { email, @@ -148,22 +74,15 @@ const insertUserAssociation = async (uid, email, shopId) => { } } }; - const resp = await client.request(mutation, vars); + const resp = await client.request(CREATE_USER, vars); return resp.insert_users_one; }; -/** - * Handles the provisioning of a new parts management shop and user. - * @param req - * @param res - * @returns {Promise<*>} - */ const partsManagementProvisioning = async (req, res) => { const { logger } = req; const p = { ...req.body, userEmail: req.body.userEmail?.toLowerCase() }; try { - // Validate inputs await ensureEmailNotRegistered(p.userEmail); requireFields(p, [ "external_shop_id", @@ -184,7 +103,6 @@ const partsManagementProvisioning = async (req, res) => { ioadmin: true }); - // Create shop const shopInput = { shopname: p.shopname, address1: p.address1, @@ -204,7 +122,7 @@ const partsManagementProvisioning = async (req, res) => { headerMargin: DefaultNewShop.logo_img_path.headerMargin }, features: { - partsManagementOnly: true // This is a parts management only shop + partsManagementOnly: true }, md_ro_statuses: DefaultNewShop.md_ro_statuses, vendors: { @@ -227,14 +145,12 @@ const partsManagementProvisioning = async (req, res) => { })) } }; - const newShopId = await insertBodyshop(shopInput); - // Create user + association + const newShopId = await insertBodyshop(shopInput); const userRecord = await createFirebaseUser(p.userEmail, p.userPassword); let resetLink = null; - if (!p.userPassword) { - resetLink = await generateResetLink(p.userEmail); - } + if (!p.userPassword) resetLink = await generateResetLink(p.userEmail); + const createdUser = await insertUserAssociation(userRecord.uid, p.userEmail, newShopId); return res.status(200).json({ @@ -242,7 +158,7 @@ const partsManagementProvisioning = async (req, res) => { user: { id: createdUser.id, email: createdUser.email, - resetLink: resetLink || undefined // Only include resetLink if it exists + resetLink: resetLink || undefined } }); } catch (err) { @@ -251,18 +167,17 @@ const partsManagementProvisioning = async (req, res) => { detail: err.detail || err }); - // Cleanup on failure if (err.userRecord) { await deleteFirebaseUser(err.userRecord.uid).catch(() => { - // Ignore errors during user deletion cleanup + /* empty */ }); } if (err.newShopId) { await deleteVendorsByShop(err.newShopId).catch(() => { - // Ignore errors during vendor deletion cleanup + /* empty */ }); await deleteBodyshop(err.newShopId).catch(() => { - // Ignore errors during shop deletion cleanup + /* empty */ }); } diff --git a/server/integrations/partsManagement/vehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js similarity index 99% rename from server/integrations/partsManagement/vehicleDamageEstimateAddRq.js rename to server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js index 82bf09cc5..c0ff0fa34 100644 --- a/server/integrations/partsManagement/vehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js @@ -1,8 +1,8 @@ // no-dd-sa:javascript-code-style/assignment-name // CamelCase is used for GraphQL and database fields. -const client = require("../../graphql-client/graphql-client").client; -const { parseXml, normalizeXmlObject } = require("./partsManagementUtils"); +const client = require("../../../graphql-client/graphql-client").client; +const { parseXml, normalizeXmlObject } = require("../partsManagementUtils"); // GraphQL Queries and Mutations const { @@ -10,7 +10,7 @@ const { GET_VEHICLE_BY_SHOP_VIN, INSERT_OWNER, INSERT_JOB_WITH_LINES -} = require("./partsManagement.queries"); +} = require("../partsManagement.queries"); // Defaults const FALLBACK_DEFAULT_ORDER_STATUS = "OPEN"; diff --git a/server/integrations/partsManagement/vehicleDamageEstimateChgRq.js b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js similarity index 79% rename from server/integrations/partsManagement/vehicleDamageEstimateChgRq.js rename to server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js index a486bd24a..936a901da 100644 --- a/server/integrations/partsManagement/vehicleDamageEstimateChgRq.js +++ b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js @@ -1,19 +1,19 @@ // no-dd-sa:javascript-code-style/assignment-name // Handler for VehicleDamageEstimateChgRq -const client = require("../../graphql-client/graphql-client").client; -const { parseXml, normalizeXmlObject } = require("./partsManagementUtils"); +const client = require("../../../graphql-client/graphql-client").client; +const { parseXml, normalizeXmlObject } = require("../partsManagementUtils"); const { - GET_JOB_BY_CLAIM_OR_DOCID, - UPDATE_JOB_BY_PK, + GET_JOB_BY_CLAIM, + UPDATE_JOB_BY_ID, UPSERT_JOBLINES, DELETE_JOBLINES_BY_IDS -} = require("./partsManagement.queries"); +} = require("../partsManagement.queries"); -const findJob = async (claimNum, documentId, logger) => { +const findJob = async (shopId, claimNum, logger) => { try { - const { jobs } = await client.request(GET_JOB_BY_CLAIM_OR_DOCID, { claimNum, documentId }); + const { jobs } = await client.request(GET_JOB_BY_CLAIM, { shopid: shopId, clm_no: claimNum }); return jobs?.[0] || null; } catch (err) { logger.log("parts-job-lookup-failed", "error", null, null, { error: err }); @@ -33,10 +33,11 @@ const extractUpdatedJobData = (rq) => { }; }; -const extractUpdatedJobLines = (addsChgs = {}) => { +const extractUpdatedJobLines = (addsChgs = {}, jobId) => { const lines = Array.isArray(addsChgs.DamageLineInfo) ? addsChgs.DamageLineInfo : [addsChgs.DamageLineInfo || []]; return lines.map((line) => ({ + jobid: jobId, line_no: parseInt(line.LineNum, 10), unq_seq: parseInt(line.UniqueSequenceNum, 10), status: line.LineStatusCode || null, @@ -51,7 +52,7 @@ const extractUpdatedJobLines = (addsChgs = {}) => { lbr_op: line.LaborInfo?.LaborOperation || null, lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), notes: line.LineMemo || null, - manual_line: line.ManualLineInd || null + manual_line: line.ManualLineInd === "1" })); }; @@ -71,22 +72,20 @@ const partsManagementVehicleDamageEstimateChgRq = async (req, res) => { const shopId = rq.ShopID; const claimNum = rq.ClaimInfo?.ClaimNum; - const documentId = rq.DocumentInfo?.DocumentID; if (!shopId || !claimNum) return res.status(400).send("Missing ShopID or ClaimNum"); - const job = await findJob(claimNum, documentId, logger); + const job = await findJob(shopId, claimNum, logger); if (!job) return res.status(404).send("Job not found"); const updatedJobData = extractUpdatedJobData(rq); - const updatedLines = extractUpdatedJobLines(rq.AddsChgs); + const updatedLines = extractUpdatedJobLines(rq.AddsChgs, job.id); const deletedLineIds = extractDeletions(rq.Deletions); - await client.request(UPDATE_JOB_BY_PK, { id: job.id, changes: updatedJobData }); + await client.request(UPDATE_JOB_BY_ID, { id: job.id, job: updatedJobData }); if (updatedLines.length > 0) { await client.request(UPSERT_JOBLINES, { - jobid: job.id, joblines: updatedLines }); } diff --git a/server/integrations/partsManagement/partsManagement.queries.js b/server/integrations/partsManagement/partsManagement.queries.js index e0ba6088c..c56e82493 100644 --- a/server/integrations/partsManagement/partsManagement.queries.js +++ b/server/integrations/partsManagement/partsManagement.queries.js @@ -53,34 +53,50 @@ const UPDATE_JOB_BY_ID = ` `; const UPSERT_JOBLINES = ` - mutation UpsertJoblines($joblines: [joblines_insert_input!]!) { - insert_joblines( - objects: $joblines - on_conflict: { - constraint: joblines_jobid_line_no_unq_seq_key - update_columns: [ - status - line_desc - part_type - part_qty - oem_partno - db_price - act_price - mod_lbr_ty - mod_lb_hrs - lbr_op - lbr_amt - notes - ] - } - ) { +mutation UpsertJoblines($joblines: [joblines_insert_input!]!) { + insert_joblines( + objects: $joblines + on_conflict: { + constraint: joblines_pkey + update_columns: [ + jobid + status + line_desc + part_type + part_qty + oem_partno + db_price + act_price + mod_lbr_ty + mod_lb_hrs + lbr_op + lbr_amt + notes + manual_line + ] + } + ) { + affected_rows + } +} +`; + +const DELETE_JOBLINES_BY_JOBID = ` + mutation DeleteJoblinesByJobId($jobid: uuid!) { + delete_joblines(where: { jobid: { _eq: $jobid } }) { affected_rows } } `; -const DELETE_JOBLINES_BY_JOBID = ` - mutation DeleteJoblinesByJobId($jobid: uuid!) { - delete_joblines(where: { jobid: { _eq: $jobid } }) { + +const DELETE_JOBLINES_BY_IDS = ` + mutation DeleteJoblinesByIds($jobid: uuid!, $unqSeqs: [Int!]!) { + delete_joblines( + where: { + jobid: { _eq: $jobid }, + unq_seq: { _in: $unqSeqs } + } + ) { affected_rows } } @@ -94,6 +110,43 @@ const INSERT_JOBLINES = ` } `; +const CHECK_EXTERNAL_SHOP_ID = ` + query CHECK_KEY($key: String!) { + bodyshops(where: { external_shop_id: { _eq: $key } }) { + external_shop_id + } + } +`; + +const CREATE_SHOP = ` + mutation CREATE_SHOP($bs: bodyshops_insert_input!) { + insert_bodyshops_one(object: $bs) { id } + } +`; + +const DELETE_VENDORS_BY_SHOP = ` + mutation DELETE_VENDORS($shopId: uuid!) { + delete_vendors(where: { shopid: { _eq: $shopId } }) { + affected_rows + } + } +`; + +const DELETE_SHOP = ` + mutation DELETE_SHOP($id: uuid!) { + delete_bodyshops_by_pk(id: $id) { id } + } +`; + +const CREATE_USER = ` + mutation CREATE_USER($u: users_insert_input!) { + insert_users_one(object: $u) { + id: authid + email + } + } +`; + module.exports = { GET_BODYSHOP_STATUS, GET_VEHICLE_BY_SHOP_VIN, @@ -101,7 +154,13 @@ module.exports = { INSERT_JOB_WITH_LINES, GET_JOB_BY_CLAIM, UPDATE_JOB_BY_ID, - DELETE_JOBLINES_BY_JOBID, UPSERT_JOBLINES, - INSERT_JOBLINES + DELETE_JOBLINES_BY_JOBID, + DELETE_JOBLINES_BY_IDS, + INSERT_JOBLINES, + CHECK_EXTERNAL_SHOP_ID, + CREATE_SHOP, + DELETE_VENDORS_BY_SHOP, + DELETE_SHOP, + CREATE_USER }; diff --git a/server/routes/intergrationRoutes.js b/server/routes/intergrationRoutes.js index 5914a2bde..d51f46b58 100644 --- a/server/routes/intergrationRoutes.js +++ b/server/routes/intergrationRoutes.js @@ -19,10 +19,10 @@ if (typeof VSSTA_INTEGRATION_SECRET === "string" && VSSTA_INTEGRATION_SECRET.len if (typeof PARTS_MANAGEMENT_INTEGRATION_SECRET === "string" && PARTS_MANAGEMENT_INTEGRATION_SECRET.length > 0) { const XML_BODY_LIMIT = "10mb"; // Set a limit for XML body size - const partsManagementProvisioning = require("../integrations/partsManagement/partsManagementProvisioning"); + const partsManagementProvisioning = require("../integrations/partsManagement/endpoints/partsManagementProvisioning"); const partsManagementIntegrationMiddleware = require("../middleware/partsManagementIntegrationMiddleware"); - const partsManagementVehicleDamageEstimateAddRq = require("../integrations/partsManagement/vehicleDamageEstimateAddRq"); - const partsManagementVehicleDamageEstimateChqRq = require("../integrations/partsManagement/vehicleDamageEstimateChgRq"); + const partsManagementVehicleDamageEstimateAddRq = require("../integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq"); + const partsManagementVehicleDamageEstimateChqRq = require("../integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq"); /** * Route to handle Vehicle Damage Estimate Add Request @@ -38,7 +38,7 @@ if (typeof PARTS_MANAGEMENT_INTEGRATION_SECRET === "string" && PARTS_MANAGEMENT_ * Route to handle Vehicle Damage Estimate Change Request */ router.post( - "/parts-management/VehicleDamageEstimateChgRq", + "/parts-management/VehicleDamageEstimateChqRq", bodyParser.raw({ type: "application/xml", limit: XML_BODY_LIMIT }), // Parse XML body partsManagementIntegrationMiddleware, partsManagementVehicleDamageEstimateChqRq From c71026f22a935a201c10e3a7573877728e50aacd Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 7 Jul 2025 13:12:47 -0400 Subject: [PATCH 22/98] feature/IO-3255-simplified-parts-management - Sample data modified / added --- .../sampleBody.vehicleDamageEstimateAddRq.xml | 0 .../sampleBody.vehicleDamageEstimateChgRq.xml | 62 +++++++++++++++++++ 2 files changed, 62 insertions(+) rename server/integrations/partsManagement/{ => sampleData}/sampleBody.vehicleDamageEstimateAddRq.xml (100%) create mode 100644 server/integrations/partsManagement/sampleData/sampleBody.vehicleDamageEstimateChgRq.xml diff --git a/server/integrations/partsManagement/sampleBody.vehicleDamageEstimateAddRq.xml b/server/integrations/partsManagement/sampleData/sampleBody.vehicleDamageEstimateAddRq.xml similarity index 100% rename from server/integrations/partsManagement/sampleBody.vehicleDamageEstimateAddRq.xml rename to server/integrations/partsManagement/sampleData/sampleBody.vehicleDamageEstimateAddRq.xml diff --git a/server/integrations/partsManagement/sampleData/sampleBody.vehicleDamageEstimateChgRq.xml b/server/integrations/partsManagement/sampleData/sampleBody.vehicleDamageEstimateChgRq.xml new file mode 100644 index 000000000..ba8a242ad --- /dev/null +++ b/server/integrations/partsManagement/sampleData/sampleBody.vehicleDamageEstimateChgRq.xml @@ -0,0 +1,62 @@ + + + 71f8494c-89f0-43e0-8eb2-820b52d723bc + chg-0001-uuid + + + CLM123 + In Progress + + POL456 + + + + + Revised bumper labor hours and added notes + + + + + 1 + 1001 + 0 + Updated + Front Bumper + + PAA + 1 + 200.00 + OEM123 + 1 + + + LAB + OP1 + 3.0 + 300.00 + + Increased time due to hidden damage + + + + 4 + 1004 + 0 + Updated + Dent Repair Door + + LAD + OP3 + 2.0 + 200.00 + + Increased scope of repair + + + + + + 1003 + + + From 91cc12873e5cd4587412ca304c38bbe5b12a0aac Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 7 Jul 2025 13:19:19 -0400 Subject: [PATCH 23/98] feature/IO-3255-simplified-parts-management -Cleanup / Docblocks --- .../endpoints/partsManagementProvisioning.js | 59 +++++++++++++++++++ .../endpoints/vehicleDamageEstimateAddRq.js | 6 -- .../endpoints/vehicleDamageEstimateChgRq.js | 29 +++++++++ 3 files changed, 88 insertions(+), 6 deletions(-) diff --git a/server/integrations/partsManagement/endpoints/partsManagementProvisioning.js b/server/integrations/partsManagement/endpoints/partsManagementProvisioning.js index 797ce619d..8f319cc5b 100644 --- a/server/integrations/partsManagement/endpoints/partsManagementProvisioning.js +++ b/server/integrations/partsManagement/endpoints/partsManagementProvisioning.js @@ -10,6 +10,11 @@ const { CREATE_USER } = require("../partsManagement.queries"); +/** + * Checks if the required fields are present in the payload. + * @param payload + * @param fields + */ const requireFields = (payload, fields) => { for (const field of fields) { if (!payload[field]) { @@ -18,6 +23,11 @@ const requireFields = (payload, fields) => { } }; +/** + * Ensures that the provided email is not already registered in Firebase. + * @param email + * @returns {Promise} + */ const ensureEmailNotRegistered = async (email) => { try { await admin.auth().getUserByEmail(email); @@ -29,20 +39,41 @@ const ensureEmailNotRegistered = async (email) => { } }; +/** + * Creates a new Firebase user with the given email and optional password. + * @param email + * @param password + * @returns {Promise} + */ const createFirebaseUser = async (email, password = null) => { const userData = { email }; if (password) userData.password = password; return admin.auth().createUser(userData); }; +/** + * Deletes a Firebase user by UID. + * @param uid + * @returns {Promise} + */ const deleteFirebaseUser = async (uid) => { return admin.auth().deleteUser(uid); }; +/** + * Generates a password reset link for the given email. + * @param email + * @returns {Promise} + */ const generateResetLink = async (email) => { return admin.auth().generatePasswordResetLink(email); }; +/** + * Ensures that the provided external shop ID is unique. + * @param externalId + * @returns {Promise} + */ const ensureExternalIdUnique = async (externalId) => { const resp = await client.request(CHECK_EXTERNAL_SHOP_ID, { key: externalId }); if (resp.bodyshops.length) { @@ -50,19 +81,41 @@ const ensureExternalIdUnique = async (externalId) => { } }; +/** + * Inserts a new bodyshop into the database. + * @param input + * @returns {Promise<*>} + */ const insertBodyshop = async (input) => { const resp = await client.request(CREATE_SHOP, { bs: input }); return resp.insert_bodyshops_one.id; }; +/** + * Deletes all vendors associated with a shop. + * @param shopId + * @returns {Promise} + */ const deleteVendorsByShop = async (shopId) => { await client.request(DELETE_VENDORS_BY_SHOP, { shopId }); }; +/** + * Deletes a bodyshop from the database. + * @param shopId + * @returns {Promise} + */ const deleteBodyshop = async (shopId) => { await client.request(DELETE_SHOP, { id: shopId }); }; +/** + * Inserts a new user association into the database. + * @param uid + * @param email + * @param shopId + * @returns {Promise<*>} + */ const insertUserAssociation = async (uid, email, shopId) => { const vars = { u: { @@ -78,6 +131,12 @@ const insertUserAssociation = async (uid, email, shopId) => { return resp.insert_users_one; }; +/** + * Handles provisioning a new shop for parts management. + * @param req + * @param res + * @returns {Promise<*>} + */ const partsManagementProvisioning = async (req, res) => { const { logger } = req; const p = { ...req.body, userEmail: req.body.userEmail?.toLowerCase() }; diff --git a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js index c0ff0fa34..7617221f5 100644 --- a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js @@ -149,12 +149,6 @@ const extractJobData = (rq) => { }; }; -/** - * Extracts owner data from the XML request. - * @param {object} rq - The VehicleDamageEstimateAddRq object. - * @param {string} shopId - The bodyshop UUID. - * @returns {object} Owner data for insertion and inline use. - */ /** * Extracts owner data from the XML request. * Falls back to Claimant if Owner is missing. diff --git a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js index 936a901da..e9e6ea93f 100644 --- a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js +++ b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq.js @@ -11,6 +11,13 @@ const { DELETE_JOBLINES_BY_IDS } = require("../partsManagement.queries"); +/** + * Finds a job by shop ID and claim number. + * @param shopId + * @param claimNum + * @param logger + * @returns {Promise<*|null>} + */ const findJob = async (shopId, claimNum, logger) => { try { const { jobs } = await client.request(GET_JOB_BY_CLAIM, { shopid: shopId, clm_no: claimNum }); @@ -21,6 +28,11 @@ const findJob = async (shopId, claimNum, logger) => { } }; +/** + * Extracts updated job data from the request payload. + * @param rq + * @returns {{comment: (number|((comment: Comment, helper: postcss.Helpers) => (Promise | void))|string|null), clm_no: null, status: (*|null), policy_no: (*|null)}} + */ const extractUpdatedJobData = (rq) => { const doc = rq.DocumentInfo || {}; const claim = rq.ClaimInfo || {}; @@ -33,6 +45,12 @@ const extractUpdatedJobData = (rq) => { }; }; +/** + * Extracts updated job lines from the request payload. + * @param addsChgs + * @param jobId + * @returns {{jobid: *, line_no: number, unq_seq: number, status, line_desc, part_type, part_qty: number, oem_partno, db_price: number, act_price: number, mod_lbr_ty, mod_lb_hrs: number, lbr_op, lbr_amt: number, notes, manual_line: boolean}[]} + */ const extractUpdatedJobLines = (addsChgs = {}, jobId) => { const lines = Array.isArray(addsChgs.DamageLineInfo) ? addsChgs.DamageLineInfo : [addsChgs.DamageLineInfo || []]; @@ -56,12 +74,23 @@ const extractUpdatedJobLines = (addsChgs = {}, jobId) => { })); }; +/** + * Extracts deletion IDs from the deletions object. + * @param deletions + * @returns {number[]} + */ const extractDeletions = (deletions = {}) => { const lines = Array.isArray(deletions.DamageLineInfo) ? deletions.DamageLineInfo : [deletions.DamageLineInfo || []]; return lines.map((line) => parseInt(line.UniqueSequenceNum, 10)).filter((id) => !isNaN(id)); }; +/** + * Handles VehicleDamageEstimateChgRq requests. + * @param req + * @param res + * @returns {Promise<*>} + */ const partsManagementVehicleDamageEstimateChgRq = async (req, res) => { const { logger } = req; From 53a559b126aa0667fb741322798314e19ed0e781 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Thu, 17 Jul 2025 12:48:30 -0400 Subject: [PATCH 24/98] feature/IO-3255-simplified-parts-management - Checkpoint --- .gitignore | 2 ++ _reference/ragmate/local-rag-compose.yml | 10 ++++++++++ .../endpoints/vehicleDamageEstimateAddRq.js | 1 - 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 _reference/ragmate/local-rag-compose.yml diff --git a/.gitignore b/.gitignore index 9a2f7ecc1..3e33d8a2b 100644 --- a/.gitignore +++ b/.gitignore @@ -130,3 +130,5 @@ test-output.txt server/job/test/fixtures .github +_reference/ragmate/.ragmate.env +docker_data diff --git a/_reference/ragmate/local-rag-compose.yml b/_reference/ragmate/local-rag-compose.yml new file mode 100644 index 000000000..37a4af622 --- /dev/null +++ b/_reference/ragmate/local-rag-compose.yml @@ -0,0 +1,10 @@ +services: + ragmate: + image: ghcr.io/ragmate/ragmate:latest + ports: + - "11434:11434" + env_file: + - .ragmate.env + volumes: + - .:/project + - ./docker_data/ragmate:/apps/cache diff --git a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js index 7617221f5..cd67d8a71 100644 --- a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js @@ -557,7 +557,6 @@ const vehicleDamageEstimateAddRq = async (req, res) => { return res.status(200).json({ success: true, jobId: newJob.id }); } catch (err) { logger.log("parts-route-error", "error", null, null, { error: err }); - console.dir({ err }); return res.status(err.status || 500).json({ error: err.message || "Internal error" }); } }; From 7a1e7bd4f99038b7660a80e63231103aced36b5f Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Thu, 17 Jul 2025 13:31:02 -0400 Subject: [PATCH 25/98] feature/IO-3255-simplified-parts-management - Expand Joblines Parser, remove body-parser reference in favor of express.raw --- .../endpoints/vehicleDamageEstimateAddRq.js | 62 +++++++++++-------- server/routes/intergrationRoutes.js | 5 +- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js index cd67d8a71..1df1fda9b 100644 --- a/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js +++ b/server/integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq.js @@ -3,6 +3,7 @@ const client = require("../../../graphql-client/graphql-client").client; const { parseXml, normalizeXmlObject } = require("../partsManagementUtils"); +const { toArray } = require("lodash"); // GraphQL Queries and Mutations const { @@ -373,37 +374,48 @@ const extractVehicleData = (rq, shopId) => { * @returns {object[]} Array of job line objects. */ const extractJobLines = (rq) => { - const damageLines = Array.isArray(rq.DamageLineInfo) ? rq.DamageLineInfo : [rq.DamageLineInfo]; + const damageLines = toArray(rq.DamageLineInfo); + if (damageLines.length === 0) { + return []; // Or throw if required + } return damageLines.map((line) => { + const partInfo = line.PartInfo || {}; + const laborInfo = line.LaborInfo || {}; + const subletInfo = line.SubletInfo || {}; + + let jobLineType = "PART"; + if (Object.keys(subletInfo).length > 0) jobLineType = "SUBLET"; + else if (Object.keys(laborInfo).length > 0 && Object.keys(partInfo).length === 0) jobLineType = "LABOR"; + const jobLine = { - line_no: parseInt(line.LineNum, 10), - unq_seq: parseInt(line.UniqueSequenceNum, 10), + line_no: parseInt(line.LineNum || 0, 10), + unq_seq: parseInt(line.UniqueSequenceNum || 0, 10), status: line.LineStatusCode || null, - line_desc: line.LineDesc || null, - part_type: line.PartInfo?.PartType || null, - part_qty: parseFloat(line.PartInfo?.Quantity || 0), - oem_partno: line.PartInfo?.OEMPartNum || null, - db_price: parseFloat(line.PartInfo?.PartPrice || 0), - act_price: parseFloat(line.PartInfo?.PartPrice || 0), - mod_lbr_ty: line.LaborInfo?.LaborType || null, - mod_lb_hrs: parseFloat(line.LaborInfo?.LaborHours || 0), - lbr_op: line.LaborInfo?.LaborOperation || null, - lbr_amt: parseFloat(line.LaborInfo?.LaborAmt || 0), - notes: line.LineMemo || null, - manual_line: line.ManualLineInd || null - // taxable_ind: line.PartInfo?.TaxableInd || null, - // automated_entry: line.AutomatedEntry || null + line_desc: line.LineDesc || null + // line_type: jobLineType // New field for clarity }; - // TODO: Commented out as not clear if needed for version 1, this only applies to Imex and not rome on the front - // end - // if ((jobLine.part_type === "PASL" || jobLine.part_type === "PAS") && jobLine.lbr_op !== "OP11") { - // jobLine.tax_part = true; - // } - // if (line.db_ref === "900510") { - // jobLine.tax_part = true; - // } + if (jobLineType === "PART") { + jobLine.part_type = partInfo.PartType || null; + jobLine.part_qty = parseFloat(partInfo.Quantity || 0); + jobLine.oem_partno = partInfo.OEMPartNum || null; + jobLine.db_price = parseFloat(partInfo.PartPrice || 0); + jobLine.act_price = parseFloat(partInfo.PartPrice || 0); // Or NonOEM if selected + } else if (jobLineType === "SUBLET") { + jobLine.part_type = "SUB"; // Custom code for sublet + jobLine.part_qty = 1; // Default + jobLine.act_price = parseFloat(subletInfo.SubletAmount || 0); + jobLine.sublet_vendor = subletInfo.SubletVendorName || null; + jobLine.lbr_hrs = parseFloat(subletInfo.SubletLaborHours || 0); + } // Labor-only already handled + + jobLine.mod_lbr_ty = laborInfo.LaborType || null; + jobLine.mod_lb_hrs = parseFloat(laborInfo.LaborHours || 0); + jobLine.lbr_op = laborInfo.LaborOperation || null; + jobLine.lbr_amt = parseFloat(laborInfo.LaborAmt || 0); + jobLine.notes = line.LineMemo || null; + jobLine.manual_line = line.ManualLineInd || null; return jobLine; }); diff --git a/server/routes/intergrationRoutes.js b/server/routes/intergrationRoutes.js index d51f46b58..829809478 100644 --- a/server/routes/intergrationRoutes.js +++ b/server/routes/intergrationRoutes.js @@ -1,6 +1,5 @@ const express = require("express"); const router = express.Router(); -const bodyParser = require("body-parser"); // Pull secrets from env const { VSSTA_INTEGRATION_SECRET, PARTS_MANAGEMENT_INTEGRATION_SECRET } = process.env; @@ -29,7 +28,7 @@ if (typeof PARTS_MANAGEMENT_INTEGRATION_SECRET === "string" && PARTS_MANAGEMENT_ */ router.post( "/parts-management/VehicleDamageEstimateAddRq", - bodyParser.raw({ type: "application/xml", limit: XML_BODY_LIMIT }), // Parse XML body + express.raw({ type: "application/xml", limit: XML_BODY_LIMIT }), // Parse XML body partsManagementIntegrationMiddleware, partsManagementVehicleDamageEstimateAddRq ); @@ -39,7 +38,7 @@ if (typeof PARTS_MANAGEMENT_INTEGRATION_SECRET === "string" && PARTS_MANAGEMENT_ */ router.post( "/parts-management/VehicleDamageEstimateChqRq", - bodyParser.raw({ type: "application/xml", limit: XML_BODY_LIMIT }), // Parse XML body + express.raw({ type: "application/xml", limit: XML_BODY_LIMIT }), // Parse XML body partsManagementIntegrationMiddleware, partsManagementVehicleDamageEstimateChqRq ); From e8dec042bd5977449bad357d993b20b3c12c48e1 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 21 Jul 2025 13:04:30 -0400 Subject: [PATCH 26/98] feature/IO-3255-simplified-parts-management - Merge Master / Bump Packages --- client/package-lock.json | 24 ++++++++++++------------ client/package.json | 6 +++--- package-lock.json | 40 ++++++++++++++++++++-------------------- package.json | 8 ++++---- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 4338c24ee..e55811f94 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -25,7 +25,7 @@ "@sentry/vite-plugin": "^3.6.1", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.4", + "antd": "^5.26.6", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -48,7 +48,7 @@ "memoize-one": "^6.0.0", "normalize-url": "^8.0.2", "object-hash": "^3.0.0", - "phone": "^3.1.62", + "phone": "^3.1.66", "prop-types": "^15.8.1", "query-string": "^9.2.2", "raf-schd": "^4.0.3", @@ -91,7 +91,7 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.48.0", + "@dotenvx/dotenvx": "^1.48.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", "@eslint/js": "^9.31.0", @@ -2585,9 +2585,9 @@ } }, "node_modules/@dotenvx/dotenvx": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.48.0.tgz", - "integrity": "sha512-UrAKBvUYl8SwCyYa8U8lND4rkdPbd7uOPtCPeiObeg5B44yrdH2ioO0tLfsGAGoenLmf6IpN6be4eT4gXxyzjQ==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.48.2.tgz", + "integrity": "sha512-6ui++YMlQwXsP3p5wmwwxK79Xe6a4PLI64aN2mdbAf2154wrsLEhKNsAqk8QXyra/kBFKgdO3ssBzoIWaont8g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -5941,9 +5941,9 @@ } }, "node_modules/antd": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.5.tgz", - "integrity": "sha512-HB7Cr0tPZMMeAyDDH8KZU0aP8/uO51oasmflJhDBzaRRZmLT8Pyjtt8qS22Sc839glm8gpKQcaG0mln66Gt9Fg==", + "version": "5.26.6", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.6.tgz", + "integrity": "sha512-k8ipeT+UL2tP/x4jHTXElScAxsD94JgrIEeGHj80nNO4dL9hqcmaOUBpHo3ieCf6MFjhS7gLUthysQeP6e7DUg==", "license": "MIT", "dependencies": { "@ant-design/colors": "^7.2.1", @@ -13117,9 +13117,9 @@ "license": "MIT" }, "node_modules/phone": { - "version": "3.1.62", - "resolved": "https://registry.npmjs.org/phone/-/phone-3.1.62.tgz", - "integrity": "sha512-mxUdq2nULKg6ukgVr4GSF9/sQiAa6e3AJy2HNE3UJA+lqdEF+Cko2RhKHhZRHtFaLKuBLPptitIwjv0uHG+vhw==", + "version": "3.1.66", + "resolved": "https://registry.npmjs.org/phone/-/phone-3.1.66.tgz", + "integrity": "sha512-xElqlpBlI80ltMhcrjCi5vPYpczIlRi+HRg8Nx0ogvMAyNBKSz7OO7sqSWobhlTK4EEq27g9TL2V3TAPImqsYQ==", "license": "MIT", "engines": { "node": ">=12" diff --git a/client/package.json b/client/package.json index 460621c33..8e075fce3 100644 --- a/client/package.json +++ b/client/package.json @@ -24,7 +24,7 @@ "@sentry/vite-plugin": "^3.6.1", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.4", + "antd": "^5.26.6", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", @@ -47,7 +47,7 @@ "memoize-one": "^6.0.0", "normalize-url": "^8.0.2", "object-hash": "^3.0.0", - "phone": "^3.1.62", + "phone": "^3.1.66", "prop-types": "^15.8.1", "query-string": "^9.2.2", "raf-schd": "^4.0.3", @@ -131,7 +131,7 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.48.0", + "@dotenvx/dotenvx": "^1.48.2", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", "@eslint/js": "^9.31.0", diff --git a/package-lock.json b/package-lock.json index c9ac3747f..44fb54769 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.2.0", "license": "UNLICENSED", "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.848.0", + "@aws-sdk/client-cloudwatch-logs": "^3.849.0", "@aws-sdk/client-elasticache": "^3.848.0", "@aws-sdk/client-s3": "^3.848.0", "@aws-sdk/client-secrets-manager": "^3.848.0", @@ -24,14 +24,14 @@ "aws4": "^1.13.2", "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.56.4", + "bullmq": "^5.56.5", "chart.js": "^4.5.0", "cloudinary": "^2.7.0", "compression": "^1.8.1", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.59.0", + "dd-trace": "^5.60.0", "dinero.js": "^1.9.1", "dotenv": "^16.4.5", "express": "^4.21.1", @@ -49,7 +49,7 @@ "multer": "^1.4.5-lts.1", "node-persist": "^4.0.4", "nodemailer": "^6.10.0", - "phone": "^3.1.62", + "phone": "^3.1.66", "query-string": "7.1.3", "recursive-diff": "^1.0.9", "rimraf": "^6.0.1", @@ -285,9 +285,9 @@ } }, "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.848.0.tgz", - "integrity": "sha512-zb9wSTeqozISI3k9rDUCnScGslPHeAkZ6cID38Mt7JgI5QcozAGgqH7m8FWigfiu8/BGJlW/ndOQCXzWYtX8sw==", + "version": "3.849.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.849.0.tgz", + "integrity": "sha512-+11BgdFro0hV+ypIogNiRofvAGsVNZs1MxkX8fsjuGq6/uflLg3x6/RRmZCFl14Y/NAuGe3ojBp+8UCvBIf8Sg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -1300,9 +1300,9 @@ "license": "Apache-2.0" }, "node_modules/@datadog/native-appsec": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-10.0.0.tgz", - "integrity": "sha512-1veYkp5DRy3RnqFRQGGIfX6ON8UibIq6YOXa+oJ0n5TRQFd1v6qWPzfonO31W4rDJ5qjxNRV6lX33m8JfaYnag==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-10.0.1.tgz", + "integrity": "sha512-v60KOnQOAn6lcrFB8eHXfW5H227mk5tuj0CCqlk1FCZ5UxW8jjvXYV3cVjlQvSkwk55BN9jh6xa99QaX5WkqmQ==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -4056,9 +4056,9 @@ } }, "node_modules/bullmq": { - "version": "5.56.4", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.56.4.tgz", - "integrity": "sha512-5wSHd0oXs2jS6P+6tay/01Iz0cWRK8iYcscKtpS/GewEq0bJZwbkMZc77GJVOT9SP+UQuXA2y+pQTdCQJel7kQ==", + "version": "5.56.5", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.56.5.tgz", + "integrity": "sha512-nhcVxoE9Y0YUuNYtvaD+N0Bk2kqcU+rXzJwdQIr8i8qC/fxoghwUYb9a+CidTv24pi1eqstLnBoa8xkR/P7Mdw==", "license": "MIT", "dependencies": { "cron-parser": "^4.9.0", @@ -4895,14 +4895,14 @@ } }, "node_modules/dd-trace": { - "version": "5.59.0", - "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.59.0.tgz", - "integrity": "sha512-N0SG1N6WZKymzXvoZiQRMb9HcPWpyL7oA6Ws2yjb+RfD5xUrkWjdqZW5mT/MoIkmeh/3KPzoldDa6iu+LOeACg==", + "version": "5.60.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.60.0.tgz", + "integrity": "sha512-jMV/bQcGVKxWpMyXNg6p+qGWrXsUh6+GupLjeZvQYT2rGkG1W0DWUOaETmw1jGdiKMOHoyuo3ZKUnf1DM5AKIA==", "hasInstallScript": true, "license": "(Apache-2.0 OR BSD-3-Clause)", "dependencies": { "@datadog/libdatadog": "0.7.0", - "@datadog/native-appsec": "10.0.0", + "@datadog/native-appsec": "10.0.1", "@datadog/native-iast-taint-tracking": "4.0.0", "@datadog/native-metrics": "3.1.1", "@datadog/pprof": "5.9.0", @@ -9167,9 +9167,9 @@ } }, "node_modules/phone": { - "version": "3.1.62", - "resolved": "https://registry.npmjs.org/phone/-/phone-3.1.62.tgz", - "integrity": "sha512-mxUdq2nULKg6ukgVr4GSF9/sQiAa6e3AJy2HNE3UJA+lqdEF+Cko2RhKHhZRHtFaLKuBLPptitIwjv0uHG+vhw==", + "version": "3.1.66", + "resolved": "https://registry.npmjs.org/phone/-/phone-3.1.66.tgz", + "integrity": "sha512-xElqlpBlI80ltMhcrjCi5vPYpczIlRi+HRg8Nx0ogvMAyNBKSz7OO7sqSWobhlTK4EEq27g9TL2V3TAPImqsYQ==", "license": "MIT", "engines": { "node": ">=12" diff --git a/package.json b/package.json index 6a932c4b6..9b038bcca 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js" }, "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.848.0", + "@aws-sdk/client-cloudwatch-logs": "^3.849.0", "@aws-sdk/client-elasticache": "^3.848.0", "@aws-sdk/client-s3": "^3.848.0", "@aws-sdk/client-secrets-manager": "^3.848.0", @@ -31,14 +31,14 @@ "aws4": "^1.13.2", "axios": "^1.10.0", "better-queue": "^3.8.12", - "bullmq": "^5.56.4", + "bullmq": "^5.56.5", "chart.js": "^4.5.0", "cloudinary": "^2.7.0", "compression": "^1.8.1", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.59.0", + "dd-trace": "^5.60.0", "dinero.js": "^1.9.1", "dotenv": "^16.4.5", "express": "^4.21.1", @@ -56,7 +56,7 @@ "multer": "^1.4.5-lts.1", "node-persist": "^4.0.4", "nodemailer": "^6.10.0", - "phone": "^3.1.62", + "phone": "^3.1.66", "query-string": "7.1.3", "recursive-diff": "^1.0.9", "rimraf": "^6.0.1", From dfa457e3c6e029d6c8c84d65c86d38e6fe821634 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 21 Jul 2025 15:05:15 -0400 Subject: [PATCH 27/98] feature/IO-3255-simplified-parts-management -Checkpoint --- client/package-lock.json | 121 +++++++++++------- client/package.json | 10 +- .../sign-in-form/sign-in-form.component.jsx | 38 +++++- .../pages/manage/manage.page.component.jsx | 5 +- .../simplified-parts.page.component.jsx | 5 +- client/src/pages/tech/tech.page.component.jsx | 4 +- 6 files changed, 124 insertions(+), 59 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index e55811f94..5454ff712 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -22,7 +22,7 @@ "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.50.0", "@sentry/react": "^9.40.0", - "@sentry/vite-plugin": "^3.6.1", + "@sentry/vite-plugin": "^4.0.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", "antd": "^5.26.6", @@ -35,11 +35,11 @@ "dayjs": "^1.11.13", "dayjs-business-days2": "^1.3.0", "dinero.js": "^1.9.1", - "dotenv": "^16.4.7", + "dotenv": "^17.2.0", "env-cmd": "^10.1.0", "exifr": "^7.1.3", "graphql": "^16.11.0", - "i18next": "^24.2.3", + "i18next": "^25.3.2", "i18next-browser-languagedetector": "^8.2.0", "immutability-helper": "^3.1.1", "libphonenumber-js": "^1.12.10", @@ -96,7 +96,7 @@ "@emotion/react": "^11.14.0", "@eslint/js": "^9.31.0", "@playwright/test": "^1.54.1", - "@sentry/webpack-plugin": "^3.6.1", + "@sentry/webpack-plugin": "^4.0.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", @@ -115,7 +115,7 @@ "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", - "vite": "^6.3.5", + "vite": "^7.0.5", "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", "vite-plugin-node-polyfills": "^0.24.0", @@ -2608,6 +2608,19 @@ "url": "https://dotenvx.com" } }, + "node_modules/@dotenvx/dotenvx/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/@ecies/ciphers": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@ecies/ciphers/-/ciphers-0.2.3.tgz", @@ -4502,9 +4515,9 @@ } }, "node_modules/@sentry/babel-plugin-component-annotate": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-3.6.1.tgz", - "integrity": "sha512-zmvUa4RpzDG3LQJFpGCE8lniz8Rk1Wa6ZvvK+yEH+snZeaHHRbSnAQBMR607GOClP+euGHNO2YtaY4UAdNTYbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-4.0.0.tgz", + "integrity": "sha512-1sozj4esnQBhJ2QO4imiLMl1858StkLjUxFF1KxgX/X1uEL/QlW2MYL8CKzbLeACy1SkR9h4V8GXSZvCnci5Dw==", "license": "MIT", "engines": { "node": ">= 14" @@ -4527,13 +4540,13 @@ } }, "node_modules/@sentry/bundler-plugin-core": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-3.6.1.tgz", - "integrity": "sha512-/ubWjPwgLep84sUPzHfKL2Ns9mK9aQrEX4aBFztru7ygiJidKJTxYGtvjh4dL2M1aZ0WRQYp+7PF6+VKwdZXcQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-4.0.0.tgz", + "integrity": "sha512-dTdbcctT5MJUwdbttZm2zomO+ui1F062ZIkogHeHqlA938Fwd1+9JIJ328+XL4XdcUG2yiFAZBWUPW3bYwoN9A==", "license": "MIT", "dependencies": { "@babel/core": "^7.18.5", - "@sentry/babel-plugin-component-annotate": "3.6.1", + "@sentry/babel-plugin-component-annotate": "4.0.0", "@sentry/cli": "^2.49.0", "dotenv": "^16.3.1", "find-up": "^5.0.0", @@ -4545,6 +4558,18 @@ "node": ">= 14" } }, + "node_modules/@sentry/bundler-plugin-core/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/@sentry/cli": { "version": "2.50.0", "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.50.0.tgz", @@ -4758,12 +4783,12 @@ } }, "node_modules/@sentry/vite-plugin": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-3.6.1.tgz", - "integrity": "sha512-x8WMdv2K2HcGS2ezEUIEZXpT/fNeWQ9rsEeF0K9DfKXK8Z9lzRmCr6TVA6I9+yW39Is+1/0cv1Rsu0LhO7lHzg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-4.0.0.tgz", + "integrity": "sha512-JX5irzvyoOSKto0U0eXDqigsTXdXnPRQaAms/kcU6A6Bf+WaPfCTE5NrJWg6ZeLvi7GiPWch11OO+TB6ZN8RKA==", "license": "MIT", "dependencies": { - "@sentry/bundler-plugin-core": "3.6.1", + "@sentry/bundler-plugin-core": "4.0.0", "unplugin": "1.0.1" }, "engines": { @@ -4771,13 +4796,13 @@ } }, "node_modules/@sentry/webpack-plugin": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-3.6.1.tgz", - "integrity": "sha512-F2yqwbdxfCENMN5u4ih4WfOtGjW56/92DBC0bU6un7Ns/l2qd+wRONIvrF+58rl/VkCFfMlUtZTVoKGRyMRmHA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-4.0.0.tgz", + "integrity": "sha512-Uhfjqnuxv4eYIt0GbPAdlFPum3BtasNhQrO3OJuVQRYRq21En7ARKXISoOhZHMo4tRRiiv+3npKYmpzHTALbQg==", "dev": true, "license": "MIT", "dependencies": { - "@sentry/bundler-plugin-core": "3.6.1", + "@sentry/bundler-plugin-core": "4.0.0", "unplugin": "1.0.1", "uuid": "^9.0.0" }, @@ -8116,9 +8141,9 @@ } }, "node_modules/dotenv": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", - "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.0.tgz", + "integrity": "sha512-Q4sgBT60gzd0BB0lSyYD3xM4YxrXA9y4uBDof1JNYGzOXrQdQ6yX+7XIAqoFOGQFOTK1D3Hts5OllpxMDZFONQ==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -9317,9 +9342,9 @@ } }, "node_modules/fdir": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -10129,9 +10154,9 @@ } }, "node_modules/i18next": { - "version": "24.2.3", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.3.tgz", - "integrity": "sha512-lfbf80OzkocvX7nmZtu7nSTNbrTYR52sLWxPtlXX1zAhVw8WEnFk4puUkCR4B1dNQwbSpEHHHemcZu//7EcB7A==", + "version": "25.3.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.3.2.tgz", + "integrity": "sha512-JSnbZDxRVbphc5jiptxr3o2zocy5dEqpVm9qCGdJwRNO+9saUJS0/u4LnM/13C23fUEWxAylPqKU/NpMV/IjqA==", "funding": [ { "type": "individual", @@ -10148,7 +10173,7 @@ ], "license": "MIT", "dependencies": { - "@babel/runtime": "^7.26.10" + "@babel/runtime": "^7.27.6" }, "peerDependencies": { "typescript": "^5" @@ -17334,24 +17359,24 @@ } }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.5.tgz", + "integrity": "sha512-1mncVwJxy2C9ThLwz0+2GKZyEXuC3MyWtAAlNftlZZXZDP3AJt5FmwcMit/IGGaNZ8ZOB2BNO/HFUB+CpN0NQw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.4", + "fdir": "^6.4.6", "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" + "postcss": "^8.5.6", + "rollup": "^4.40.0", + "tinyglobby": "^0.2.14" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -17360,14 +17385,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", - "less": "*", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -17578,9 +17603,9 @@ } }, "node_modules/vite/node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -17598,7 +17623,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, diff --git a/client/package.json b/client/package.json index 8e075fce3..231212d89 100644 --- a/client/package.json +++ b/client/package.json @@ -21,7 +21,7 @@ "@reduxjs/toolkit": "^2.8.2", "@sentry/cli": "^2.50.0", "@sentry/react": "^9.40.0", - "@sentry/vite-plugin": "^3.6.1", + "@sentry/vite-plugin": "^4.0.0", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", "antd": "^5.26.6", @@ -34,11 +34,11 @@ "dayjs": "^1.11.13", "dayjs-business-days2": "^1.3.0", "dinero.js": "^1.9.1", - "dotenv": "^16.4.7", + "dotenv": "^17.2.0", "env-cmd": "^10.1.0", "exifr": "^7.1.3", "graphql": "^16.11.0", - "i18next": "^24.2.3", + "i18next": "^25.3.2", "i18next-browser-languagedetector": "^8.2.0", "immutability-helper": "^3.1.1", "libphonenumber-js": "^1.12.10", @@ -136,7 +136,7 @@ "@emotion/react": "^11.14.0", "@eslint/js": "^9.31.0", "@playwright/test": "^1.54.1", - "@sentry/webpack-plugin": "^3.6.1", + "@sentry/webpack-plugin": "^4.0.0", "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", @@ -155,7 +155,7 @@ "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", - "vite": "^6.3.5", + "vite": "^7.0.5", "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", "vite-plugin-node-polyfills": "^0.24.0", diff --git a/client/src/components/sign-in-form/sign-in-form.component.jsx b/client/src/components/sign-in-form/sign-in-form.component.jsx index d39128af4..1aa888c22 100644 --- a/client/src/components/sign-in-form/sign-in-form.component.jsx +++ b/client/src/components/sign-in-form/sign-in-form.component.jsx @@ -1,7 +1,7 @@ import { LockOutlined, UserOutlined } from "@ant-design/icons"; import { Button, Form, Input, Typography } from "antd"; import queryString from "query-string"; -import React, { useEffect } from "react"; +import { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { Link, useLocation, useNavigate } from "react-router-dom"; @@ -42,6 +42,42 @@ export function SignInComponent({ emailSignInStart, currentUser, signInError, se } }, [currentUser, redirect, navigate]); + // Add event listener for seamless login + useEffect(() => { + const handleSeamlessLogin = (event) => { + const { email, password, origin: requestOrigin } = event.detail || {}; + + // Validate input + if (!email || !password) { + window.parent.postMessage( + { type: "seamlessLoginResponse", status: "error", message: "Email and password are required" }, + requestOrigin || "*" // Use specific origin for security if known + ); + return; + } + + // Check if the user is already logged in + if (currentUser.authorized === true) { + console.log("User is already logged in, redirecting..."); + navigate(redirect || "/manage/"); + window.parent.postMessage({ type: "seamlessLoginResponse", status: "already_logged_in" }, requestOrigin || "*"); + return; + } + + // Proceed with sign-in if not logged in + emailSignInStart(email, password); + window.parent.postMessage({ type: "seamlessLoginResponse", status: "login_attempted" }, requestOrigin || "*"); + }; + + // Add event listener for custom seamless login event + window.addEventListener("seamlessLoginRequest", handleSeamlessLogin); + + // Cleanup to remove the event listener on unmount + return () => { + window.removeEventListener("seamlessLoginRequest", handleSeamlessLogin); + }; + }, [emailSignInStart, currentUser, navigate, redirect]); + return (
diff --git a/client/src/pages/manage/manage.page.component.jsx b/client/src/pages/manage/manage.page.component.jsx index fabc8bbf7..735f93161 100644 --- a/client/src/pages/manage/manage.page.component.jsx +++ b/client/src/pages/manage/manage.page.component.jsx @@ -18,7 +18,6 @@ import GlobalFooter from "../../components/global-footer/global-footer.component import HeaderContainer from "../../components/header/header.container"; import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component"; import PartnerPingComponent from "../../components/partner-ping/partner-ping.component"; -import PrintCenterModalContainer from "../../components/print-center-modal/print-center-modal.container"; import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-status.component"; import UpdateAlert from "../../components/update-alert/update-alert.component"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; @@ -27,6 +26,10 @@ import { selectAlerts } from "../../redux/application/application.selectors.js"; import { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors"; import InstanceRenderManager from "../../utils/instanceRenderMgr.js"; +const PrintCenterModalContainer = lazy( + () => import("../../components/print-center-modal/print-center-modal.container") +); + const JobsPage = lazy(() => import("../jobs/jobs.page")); const CardPaymentModalContainer = lazy( diff --git a/client/src/pages/simplified-parts/simplified-parts.page.component.jsx b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx index 9603fd624..a3e18b299 100644 --- a/client/src/pages/simplified-parts/simplified-parts.page.component.jsx +++ b/client/src/pages/simplified-parts/simplified-parts.page.component.jsx @@ -10,7 +10,6 @@ import ConflictComponent from "../../components/conflict/conflict.component.jsx" import ErrorBoundary from "../../components/error-boundary/error-boundary.component.jsx"; import GlobalFooter from "../../components/global-footer/global-footer.component.jsx"; import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component.jsx"; -import PrintCenterModalContainer from "../../components/print-center-modal/print-center-modal.container.jsx"; import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-status.component.jsx"; import UpdateAlert from "../../components/update-alert/update-alert.component.jsx"; import { useNotification } from "../../contexts/Notifications/notificationContext.jsx"; @@ -29,7 +28,9 @@ const EmailOverlayContainer = lazy(() => import("../../components/email-overlay/ const FeatureRequestPage = lazy(() => import("../feature-request/feature-request.page.jsx")); const ReportCenterModal = lazy(() => import("../../components/report-center-modal/report-center-modal.container.jsx")); const Help = lazy(() => import("../help/help.page.jsx")); - +const PrintCenterModalContainer = lazy( + () => import("../../components/print-center-modal/print-center-modal.container") +); const { Content } = Layout; const mapStateToProps = createStructuredSelector({ diff --git a/client/src/pages/tech/tech.page.component.jsx b/client/src/pages/tech/tech.page.component.jsx index 5f66bb970..43b971a38 100644 --- a/client/src/pages/tech/tech.page.component.jsx +++ b/client/src/pages/tech/tech.page.component.jsx @@ -1,5 +1,5 @@ import { Card, FloatButton, Layout } from "antd"; -import React, { lazy, Suspense, useEffect } from "react"; +import { lazy, Suspense, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; import { Route, Routes, useNavigate } from "react-router-dom"; @@ -40,7 +40,7 @@ const { Content } = Layout; const mapStateToProps = createStructuredSelector({ technician: selectTechnician }); -const mapDispatchToProps = (dispatch) => ({ +const mapDispatchToProps = () => ({ //setUserLanguage: language => dispatch(setUserLanguage(language)) }); From 0ac9bbd97cd2b8c0379c1c7fa4bd623b7a6e8bb9 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Mon, 21 Jul 2025 15:28:03 -0400 Subject: [PATCH 28/98] feature/IO-3255-simplified-parts-management -Checkpoint --- .../sign-in-form/sign-in-form.component.jsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/client/src/components/sign-in-form/sign-in-form.component.jsx b/client/src/components/sign-in-form/sign-in-form.component.jsx index 1aa888c22..637042f54 100644 --- a/client/src/components/sign-in-form/sign-in-form.component.jsx +++ b/client/src/components/sign-in-form/sign-in-form.component.jsx @@ -42,16 +42,19 @@ export function SignInComponent({ emailSignInStart, currentUser, signInError, se } }, [currentUser, redirect, navigate]); - // Add event listener for seamless login useEffect(() => { const handleSeamlessLogin = (event) => { - const { email, password, origin: requestOrigin } = event.detail || {}; + console.log("Received message event:", event); // Log the received message event + if (event.data?.type !== "seamlessLoginRequest") return; // Filter to only handle relevant messages + console.log("Received seamless login request:", event.data); + const { email, password } = event.data || {}; // Use event.data instead of event.detail + const requestOrigin = event.origin; // Use event.origin automatically - // Validate input + // Validate input (rest of your code remains the same) if (!email || !password) { window.parent.postMessage( { type: "seamlessLoginResponse", status: "error", message: "Email and password are required" }, - requestOrigin || "*" // Use specific origin for security if known + requestOrigin || "*" ); return; } @@ -69,12 +72,10 @@ export function SignInComponent({ emailSignInStart, currentUser, signInError, se window.parent.postMessage({ type: "seamlessLoginResponse", status: "login_attempted" }, requestOrigin || "*"); }; - // Add event listener for custom seamless login event - window.addEventListener("seamlessLoginRequest", handleSeamlessLogin); + window.addEventListener("message", handleSeamlessLogin); // Listen for "message" - // Cleanup to remove the event listener on unmount return () => { - window.removeEventListener("seamlessLoginRequest", handleSeamlessLogin); + window.removeEventListener("message", handleSeamlessLogin); }; }, [emailSignInStart, currentUser, navigate, redirect]); From 6b5ad3dafa075c230e29809798a412614d01f2ca Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Tue, 22 Jul 2025 12:20:59 -0400 Subject: [PATCH 29/98] feature/IO-3255-simplified-parts-management -Checkpoint --- client/src/App/App.jsx | 15 +++++++++++---- .../sign-in-form/sign-in-form.component.jsx | 19 +++++++++++-------- .../redux/application/application.actions.js | 5 +++++ .../redux/application/application.reducer.js | 5 +++++ .../application/application.selectors.js | 1 + .../redux/application/application.types.js | 3 ++- 6 files changed, 35 insertions(+), 13 deletions(-) diff --git a/client/src/App/App.jsx b/client/src/App/App.jsx index cbbaf4432..f499cb55c 100644 --- a/client/src/App/App.jsx +++ b/client/src/App/App.jsx @@ -7,13 +7,13 @@ import { connect } from "react-redux"; import { Route, Routes, useNavigate } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import DocumentEditorContainer from "../components/document-editor/document-editor.container"; -import ErrorBoundary from "../components/error-boundary/error-boundary.component"; // Component Imports +import ErrorBoundary from "../components/error-boundary/error-boundary.component"; import LoadingSpinner from "../components/loading-spinner/loading-spinner.component"; import DisclaimerPage from "../pages/disclaimer/disclaimer.page"; import LandingPage from "../pages/landing/landing.page"; import TechPageContainer from "../pages/tech/tech.page.container"; import SimplifiedPartsPageContainer from "../pages/simplified-parts/simplified-parts.page.container.jsx"; -import { setOnline } from "../redux/application/application.actions"; +import { setIsPartsEntry, setOnline } from "../redux/application/application.actions"; import { selectOnline } from "../redux/application/application.selectors"; import { checkUserSession } from "../redux/user/user.actions"; import { selectBodyshop, selectCurrentEula, selectCurrentUser } from "../redux/user/user.selectors"; @@ -39,10 +39,11 @@ const mapStateToProps = createStructuredSelector({ const mapDispatchToProps = (dispatch) => ({ checkUserSession: () => dispatch(checkUserSession()), - setOnline: (isOnline) => dispatch(setOnline(isOnline)) + setOnline: (isOnline) => dispatch(setOnline(isOnline)), + setIsPartsEntry: (isParts) => dispatch(setIsPartsEntry(isParts)) }); -export function App({ bodyshop, checkUserSession, currentUser, online, setOnline, currentEula }) { +export function App({ bodyshop, checkUserSession, currentUser, online, setOnline, setIsPartsEntry, currentEula }) { const client = useSplitClient().client; const [listenersAdded, setListenersAdded] = useState(false); const { t } = useTranslation(); @@ -56,6 +57,12 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline checkUserSession(); }, [checkUserSession, setOnline]); + useEffect(() => { + const pathname = window.location.pathname; + const isParts = pathname.startsWith("/parts/"); + setIsPartsEntry(isParts); + }, [setIsPartsEntry]); + //const b = Grid.useBreakpoint(); // console.log("Breakpoints:", b); diff --git a/client/src/components/sign-in-form/sign-in-form.component.jsx b/client/src/components/sign-in-form/sign-in-form.component.jsx index 637042f54..a72eee218 100644 --- a/client/src/components/sign-in-form/sign-in-form.component.jsx +++ b/client/src/components/sign-in-form/sign-in-form.component.jsx @@ -10,6 +10,7 @@ import RomeLogo from "../../assets/RomeOnlineBlue.png"; import ImEXOnlineLogo from "../../assets/logo192.png"; import { emailSignInStart, sendPasswordReset } from "../../redux/user/user.actions"; import { selectCurrentUser, selectLoginLoading, selectSignInError } from "../../redux/user/user.selectors"; +import { selectIsPartsEntry } from "../../redux/application/application.selectors"; import InstanceRenderManager from "../../utils/instanceRenderMgr"; import AlertComponent from "../alert/alert.component"; import "./sign-in-form.styles.scss"; @@ -17,7 +18,8 @@ import "./sign-in-form.styles.scss"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, signInError: selectSignInError, - loginLoading: selectLoginLoading + loginLoading: selectLoginLoading, + isPartsEntry: selectIsPartsEntry }); const mapDispatchToProps = (dispatch) => ({ @@ -25,7 +27,7 @@ const mapDispatchToProps = (dispatch) => ({ sendPasswordReset: (email) => dispatch(sendPasswordReset(email)) }); -export function SignInComponent({ emailSignInStart, currentUser, signInError, sendPasswordReset, loginLoading }) { +export function SignInComponent({ emailSignInStart, currentUser, signInError, loginLoading, isPartsEntry }) { const { redirect } = queryString.parse(useLocation().search); const navigate = useNavigate(); @@ -38,15 +40,16 @@ export function SignInComponent({ emailSignInStart, currentUser, signInError, se useEffect(() => { if (currentUser.authorized === true) { - navigate(redirect || "/manage/"); + navigate(redirect || (isPartsEntry ? "/parts/" : "/manage/")); } - }, [currentUser, redirect, navigate]); + }, [currentUser, redirect, navigate, isPartsEntry]); useEffect(() => { const handleSeamlessLogin = (event) => { console.log("Received message event:", event); // Log the received message event + if (event.data?.type !== "seamlessLoginRequest") return; // Filter to only handle relevant messages - console.log("Received seamless login request:", event.data); + const { email, password } = event.data || {}; // Use event.data instead of event.detail const requestOrigin = event.origin; // Use event.origin automatically @@ -62,7 +65,7 @@ export function SignInComponent({ emailSignInStart, currentUser, signInError, se // Check if the user is already logged in if (currentUser.authorized === true) { console.log("User is already logged in, redirecting..."); - navigate(redirect || "/manage/"); + navigate(redirect || (isPartsEntry ? "/parts/" : "/manage/")); window.parent.postMessage({ type: "seamlessLoginResponse", status: "already_logged_in" }, requestOrigin || "*"); return; } @@ -72,12 +75,12 @@ export function SignInComponent({ emailSignInStart, currentUser, signInError, se window.parent.postMessage({ type: "seamlessLoginResponse", status: "login_attempted" }, requestOrigin || "*"); }; - window.addEventListener("message", handleSeamlessLogin); // Listen for "message" + window.addEventListener("message", handleSeamlessLogin); return () => { window.removeEventListener("message", handleSeamlessLogin); }; - }, [emailSignInStart, currentUser, navigate, redirect]); + }, [emailSignInStart, currentUser, navigate, redirect, isPartsEntry]); return (
diff --git a/client/src/redux/application/application.actions.js b/client/src/redux/application/application.actions.js index 4d362c6d8..430408b06 100644 --- a/client/src/redux/application/application.actions.js +++ b/client/src/redux/application/application.actions.js @@ -77,3 +77,8 @@ export const setWssStatus = (status) => ({ type: ApplicationActionTypes.SET_WSS_STATUS, payload: status }); + +export const setIsPartsEntry = (isParts) => ({ + type: ApplicationActionTypes.PARTS_ENTRY, + payload: isParts +}); diff --git a/client/src/redux/application/application.reducer.js b/client/src/redux/application/application.reducer.js index 6d5421e27..1ad66964d 100644 --- a/client/src/redux/application/application.reducer.js +++ b/client/src/redux/application/application.reducer.js @@ -104,6 +104,11 @@ const applicationReducer = (state = INITIAL_STATE, action) => { alerts: newAlertsMap }; } + case ApplicationActionTypes.PARTS_ENTRY: + return { + ...state, + isPartsEntry: action.payload + }; default: return state; } diff --git a/client/src/redux/application/application.selectors.js b/client/src/redux/application/application.selectors.js index 6b0d1c2c4..99ffd5b22 100644 --- a/client/src/redux/application/application.selectors.js +++ b/client/src/redux/application/application.selectors.js @@ -24,3 +24,4 @@ export const selectProblemJobs = createSelector([selectApplication], (applicatio export const selectUpdateAvailable = createSelector([selectApplication], (application) => application.updateAvailable); export const selectWssStatus = createSelector([selectApplication], (application) => application.wssStatus); export const selectAlerts = createSelector([selectApplication], (application) => application.alerts); +export const selectIsPartsEntry = createSelector([selectApplication], (application) => application.isPartsEntry); diff --git a/client/src/redux/application/application.types.js b/client/src/redux/application/application.types.js index 26c1b4c7d..7699eb9f3 100644 --- a/client/src/redux/application/application.types.js +++ b/client/src/redux/application/application.types.js @@ -14,6 +14,7 @@ const ApplicationActionTypes = { SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS", SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE", SET_WSS_STATUS: "SET_WSS_STATUS", - ADD_ALERTS: "ADD_ALERTS" + ADD_ALERTS: "ADD_ALERTS", + PARTS_ENTRY: "PARTS_ENTRY" }; export default ApplicationActionTypes; From e4fb8b61b0b38f3a052d04ea5030bfcafbafb2c0 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Fri, 25 Jul 2025 12:26:36 -0400 Subject: [PATCH 30/98] feature/IO-3255-simplified-parts-management - Deprovisoning route --- .../partsManagementDeprovisioning.js | 187 ++++++++++++++++++ server/routes/intergrationRoutes.js | 4 + 2 files changed, 191 insertions(+) create mode 100644 server/integrations/partsManagement/endpoints/partsManagementDeprovisioning.js diff --git a/server/integrations/partsManagement/endpoints/partsManagementDeprovisioning.js b/server/integrations/partsManagement/endpoints/partsManagementDeprovisioning.js new file mode 100644 index 000000000..084afef7d --- /dev/null +++ b/server/integrations/partsManagement/endpoints/partsManagementDeprovisioning.js @@ -0,0 +1,187 @@ +const admin = require("firebase-admin"); +const client = require("../../../graphql-client/graphql-client").client; + +const { DELETE_SHOP } = require("../partsManagement.queries"); + +// Define corrected DELETE_VENDORS_BY_SHOP locally +const DELETE_VENDORS_BY_SHOP = ` + mutation DELETE_VENDORS_BY_SHOP($shopId: uuid!) { + delete_vendors(where: {bodyshopid: {_eq: $shopId}}) { + affected_rows + } + } +`; + +// New queries for deprovisioning +const GET_BODYSHOP = ` + query GetBodyshop($id: uuid!) { + bodyshops_by_pk(id: $id) { + external_shop_id + shopname + } + } +`; + +const GET_ASSOCIATED_USERS = ` + query GetAssociatedUsers($shopId: uuid!) { + associations(where: {shopid: {_eq: $shopId}}) { + user { + authid + email + } + } + } +`; + +const DELETE_ASSOCIATIONS_BY_SHOP = ` + mutation DeleteAssociationsByShop($shopId: uuid!) { + delete_associations(where: {shopid: {_eq: $shopId}}) { + affected_rows + } + } +`; + +const GET_USER_ASSOCIATIONS_COUNT = ` + query GetUserAssociationsCount($userEmail: String!) { + associations_aggregate(where: {useremail: {_eq: $userEmail}}) { + aggregate { + count + } + } + } +`; + +const DELETE_USER = ` + mutation DeleteUser($email: String!) { + delete_users(where: {email: {_eq: $email}}) { + affected_rows + } + } +`; + +const GET_VENDORS = ` + query GetVendors($shopId: uuid!) { + vendors(where: {bodyshopid: {_eq: $shopId}}) { + name + } + } +`; + +/** + * Deletes a Firebase user by UID. + * @param uid + * @returns {Promise} + */ +const deleteFirebaseUser = async (uid) => { + return admin.auth().deleteUser(uid); +}; + +/** + * Deletes all vendors associated with a shop. + * @param shopId + * @returns {Promise} + */ +const deleteVendorsByShop = async (shopId) => { + await client.request(DELETE_VENDORS_BY_SHOP, { shopId }); +}; + +/** + * Deletes a bodyshop from the database. + * @param shopId + * @returns {Promise} + */ +const deleteBodyshop = async (shopId) => { + await client.request(DELETE_SHOP, { id: shopId }); +}; + +/** + * Handles deprovisioning a shop for parts management. + * @param req + * @param res + * @returns {Promise<*>} + */ +const partsManagementDeprovisioning = async (req, res) => { + const { logger } = req; + const p = req.body; + + if (process.env.NODE_ENV === "production") { + return res.status(403).json({ error: "Deprovisioning not allowed in production environment." }); + } + + try { + if (!p.shopId) { + throw { status: 400, message: "shopId is required." }; + } + + // Fetch bodyshop and check external_shop_id + const shopResp = await client.request(GET_BODYSHOP, { id: p.shopId }); + const shop = shopResp.bodyshops_by_pk; + if (!shop) { + throw { status: 404, message: `Bodyshop with id ${p.shopId} not found.` }; + } + if (!shop.external_shop_id) { + throw { status: 400, message: "Cannot delete bodyshop without external_shop_id." }; + } + + logger.log("admin-delete-shop", "debug", null, null, { + shopId: p.shopId, + shopname: shop.shopname, + ioadmin: true + }); + + // Get vendors + const vendorsResp = await client.request(GET_VENDORS, { shopId: p.shopId }); + const deletedVendors = vendorsResp.vendors.map((v) => v.name); + + // Get associated users + const assocResp = await client.request(GET_ASSOCIATED_USERS, { shopId: p.shopId }); + const associatedUsers = assocResp.associations.map((assoc) => ({ + authId: assoc.user.authid, + email: assoc.user.email + })); + + // Delete associations for the shop + const assocDeleteResp = await client.request(DELETE_ASSOCIATIONS_BY_SHOP, { shopId: p.shopId }); + const associationsDeleted = assocDeleteResp.delete_associations.affected_rows; + + // For each user, check if they have remaining associations; if not, delete user and Firebase account + const deletedUsers = []; + for (const user of associatedUsers) { + const countResp = await client.request(GET_USER_ASSOCIATIONS_COUNT, { userEmail: user.email }); + const assocCount = countResp.associations_aggregate.aggregate.count; + if (assocCount === 0) { + await client.request(DELETE_USER, { email: user.email }); + await deleteFirebaseUser(user.authId); + deletedUsers.push(user.email); + } + } + + // Delete vendors + await deleteVendorsByShop(p.shopId); + + // Delete shop + await deleteBodyshop(p.shopId); + + // Summary log + console.log( + `Deleted bodyshop ${p.shopId} (${shop.shopname}), ${associationsDeleted} associations, ${deletedUsers.length} users (${deletedUsers.join(", ") || "none"}), ${deletedVendors.length} vendors (${deletedVendors.join(", ") || "none"}).` + ); + + return res.status(200).json({ + message: `Bodyshop ${p.shopId} and associated resources deleted successfully.`, + deletedShop: { id: p.shopId, name: shop.shopname }, + deletedAssociationsCount: associationsDeleted, + deletedUsers: deletedUsers, + deletedVendors: deletedVendors + }); + } catch (err) { + logger.log("admin-delete-shop-error", "error", null, null, { + message: err.message, + detail: err.detail || err + }); + + return res.status(err.status || 500).json({ error: err.message || "Internal server error" }); + } +}; + +module.exports = partsManagementDeprovisioning; diff --git a/server/routes/intergrationRoutes.js b/server/routes/intergrationRoutes.js index 829809478..93c84d5b8 100644 --- a/server/routes/intergrationRoutes.js +++ b/server/routes/intergrationRoutes.js @@ -19,6 +19,7 @@ if (typeof PARTS_MANAGEMENT_INTEGRATION_SECRET === "string" && PARTS_MANAGEMENT_ const XML_BODY_LIMIT = "10mb"; // Set a limit for XML body size const partsManagementProvisioning = require("../integrations/partsManagement/endpoints/partsManagementProvisioning"); + const partsManagementDeprovisioning = require("../integrations/partsManagement/endpoints/partsManagementDeprovisioning"); const partsManagementIntegrationMiddleware = require("../middleware/partsManagementIntegrationMiddleware"); const partsManagementVehicleDamageEstimateAddRq = require("../integrations/partsManagement/endpoints/vehicleDamageEstimateAddRq"); const partsManagementVehicleDamageEstimateChqRq = require("../integrations/partsManagement/endpoints/vehicleDamageEstimateChgRq"); @@ -43,6 +44,9 @@ if (typeof PARTS_MANAGEMENT_INTEGRATION_SECRET === "string" && PARTS_MANAGEMENT_ partsManagementVehicleDamageEstimateChqRq ); + // Deprovisioning route + router.post("/parts-management/deprovision", partsManagementIntegrationMiddleware, partsManagementDeprovisioning); + /** * Route to handle Parts Management Provisioning */ From 952feeb685bc87d32a710f5550f91d2382039daf Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Tue, 29 Jul 2025 14:37:51 -0400 Subject: [PATCH 31/98] feature/IO-3255-simplified-parts-management - Adjust routes / Deps --- client/package-lock.json | 372 ++++++++++------------- client/package.json | 32 +- client/src/App/App.jsx | 5 +- client/src/graphql/bodyshop.queries.js | 1 + package-lock.json | 404 ++++++++++++------------- package.json | 32 +- 6 files changed, 386 insertions(+), 460 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 5454ff712..bc33ab1a3 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "dependencies": { "@ant-design/pro-layout": "^7.22.6", - "@apollo/client": "^3.13.6", + "@apollo/client": "^3.13.9", "@emotion/is-prop-valid": "^1.3.1", "@fingerprintjs/fingerprintjs": "^4.6.1", "@firebase/analytics": "^0.10.17", @@ -20,22 +20,22 @@ "@firebase/messaging": "^0.12.22", "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", - "@sentry/cli": "^2.50.0", - "@sentry/react": "^9.40.0", - "@sentry/vite-plugin": "^4.0.0", + "@sentry/cli": "^2.50.2", + "@sentry/react": "^9.43.0", + "@sentry/vite-plugin": "^4.0.2", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.6", + "antd": "^5.26.7", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", - "axios": "^1.10.0", + "axios": "^1.11.0", "classnames": "^2.5.1", "css-box-model": "^1.2.1", "dayjs": "^1.11.13", "dayjs-business-days2": "^1.3.0", "dinero.js": "^1.9.1", - "dotenv": "^17.2.0", + "dotenv": "^17.2.1", "env-cmd": "^10.1.0", "exifr": "^7.1.3", "graphql": "^16.11.0", @@ -60,7 +60,7 @@ "react-drag-listview": "^2.0.0", "react-grid-gallery": "^1.0.1", "react-grid-layout": "1.3.4", - "react-i18next": "^15.6.0", + "react-i18next": "^15.6.1", "react-icons": "^5.5.0", "react-image-lightbox": "^5.1.4", "react-markdown": "^10.1.0", @@ -91,14 +91,14 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.48.2", + "@dotenvx/dotenvx": "^1.48.3", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", - "@eslint/js": "^9.31.0", + "@eslint/js": "^9.32.0", "@playwright/test": "^1.54.1", - "@sentry/webpack-plugin": "^4.0.0", - "@testing-library/dom": "^10.4.0", - "@testing-library/jest-dom": "^6.6.3", + "@sentry/webpack-plugin": "^4.0.2", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^6.6.4", "@testing-library/react": "^16.3.0", "@vitejs/plugin-react": "^4.6.0", "browserslist": "^4.25.1", @@ -109,17 +109,17 @@ "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "jsdom": "^26.0.0", - "memfs": "^4.17.2", + "memfs": "^4.23.0", "os-browserify": "^0.3.0", "playwright": "^1.54.1", "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", - "vite": "^7.0.5", + "vite": "^7.0.6", "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", "vite-plugin-node-polyfills": "^0.24.0", - "vite-plugin-pwa": "^1.0.1", + "vite-plugin-pwa": "^1.0.2", "vite-plugin-style-import": "^2.0.0", "vitest": "^3.2.4", "workbox-window": "^7.3.0" @@ -418,9 +418,9 @@ } }, "node_modules/@apollo/client": { - "version": "3.13.8", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.13.8.tgz", - "integrity": "sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg==", + "version": "3.13.9", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.13.9.tgz", + "integrity": "sha512-RStSzQfL1XwL6/NWd7W8avhGQYTgPCtJ+qHkkTTSj9Upp3VVm6Oppv81YWdXG1FgEpDPW4hvCrTUELdcC4inCQ==", "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", @@ -2585,9 +2585,9 @@ } }, "node_modules/@dotenvx/dotenvx": { - "version": "1.48.2", - "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.48.2.tgz", - "integrity": "sha512-6ui++YMlQwXsP3p5wmwwxK79Xe6a4PLI64aN2mdbAf2154wrsLEhKNsAqk8QXyra/kBFKgdO3ssBzoIWaont8g==", + "version": "1.48.3", + "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.48.3.tgz", + "integrity": "sha512-7Tk0Rzgz0SEkaJRGijbKtVDHHztHz9fyXwcDT86VtD1fGVRirk4aBKUud1PEQdhwcg+jDblKGoXeA+I7J60CxQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2922,9 +2922,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz", - "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", "dev": true, "license": "MIT", "engines": { @@ -3745,9 +3745,9 @@ } }, "node_modules/@rc-component/trigger": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.7.tgz", - "integrity": "sha512-Qggj4Z0AA2i5dJhzlfFSmg1Qrziu8dsdHOihROL5Kl18seO2Eh/ZaTYt2c8a/CyGaTChnFry7BEYew1+/fhSbA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.3.0.tgz", + "integrity": "sha512-iwaxZyzOuK0D7lS+0AQEtW52zUWxoGqTGkke3dRyb8pYiShmRpCjB/8TzPI4R6YySCH7Vm9BZj/31VPiiQTLBg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.2", @@ -4465,88 +4465,88 @@ "license": "MIT" }, "node_modules/@sentry-internal/browser-utils": { - "version": "9.40.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.40.0.tgz", - "integrity": "sha512-Ajvz6jN+EEMKrOHcUv2+HlhbRUh69uXhhRoBjJw8sc61uqA2vv3QWyBSmTRoHdTnLGboT5bKEhHIkzVXb+YgEw==", + "version": "9.43.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.43.0.tgz", + "integrity": "sha512-DLv10USYC0w+2ap5GlxlBYTe5dTylzFZB6WHi3kpuYpjUwdye8/G88K8ZDqdMFr73XUFDxRJbOihXOb0vDQNRQ==", "license": "MIT", "dependencies": { - "@sentry/core": "9.40.0" + "@sentry/core": "9.43.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/feedback": { - "version": "9.40.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.40.0.tgz", - "integrity": "sha512-39UbLdGWGvSJ7bAzRnkv91cBdd6fLbdkLVVvqE2ZUfegm7+rH1mRPglmEhw4VE4mQfKZM1zWr/xus2+XPqJcYw==", + "version": "9.43.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.43.0.tgz", + "integrity": "sha512-yAZvSB/85jZT9bZf/NOXYh8+CkUIqPfPma4b3Kvq6QZE2Xp/WP80YvZHgoh+KA5gSK0d3uAqkSdj0cQF9wpGEg==", "license": "MIT", "dependencies": { - "@sentry/core": "9.40.0" + "@sentry/core": "9.43.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay": { - "version": "9.40.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.40.0.tgz", - "integrity": "sha512-WrmCvqbLJQC45IFRVN3k0J5pU5NkdX0e9o6XxjcmDiATKk00RHnW4yajnCJ8J1cPR4918yqiJHPX5xpG08BZNA==", + "version": "9.43.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.43.0.tgz", + "integrity": "sha512-I9kQfoSiVq8zzCzfJAlBGFZftIKZxFX9Hv4M+jskzoCQwTfcGWY5qmGyX+KEzLAI/39onV7S1p8x/iAVlSICuA==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.40.0", - "@sentry/core": "9.40.0" + "@sentry-internal/browser-utils": "9.43.0", + "@sentry/core": "9.43.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "9.40.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.40.0.tgz", - "integrity": "sha512-GLoJ4R4Uipd7Vb+0LzSJA2qCyN1J6YalQIoDuOJTfYyykHvKltds5D8a/5S3Q6d8PcL/nxTn93fynauGEZt2Ow==", + "version": "9.43.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.43.0.tgz", + "integrity": "sha512-cs1yClG5bwL1+lMn2i9v8UiuWiBbu7OS+pD9xePjNYNWywRU0JJ9mTNC2HPP7ic9kDr7vDZy2hRNaDd2IDgF4g==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "9.40.0", - "@sentry/core": "9.40.0" + "@sentry-internal/replay": "9.43.0", + "@sentry/core": "9.43.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/babel-plugin-component-annotate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-4.0.0.tgz", - "integrity": "sha512-1sozj4esnQBhJ2QO4imiLMl1858StkLjUxFF1KxgX/X1uEL/QlW2MYL8CKzbLeACy1SkR9h4V8GXSZvCnci5Dw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-4.0.2.tgz", + "integrity": "sha512-Nr/VamvpQs6w642EI5t+qaCUGnVEro0qqk+S8XO1gc8qSdpc8kkZJFnUk7ozAr+ljYWGfVgWXrxI9lLiriLsRA==", "license": "MIT", "engines": { "node": ">= 14" } }, "node_modules/@sentry/browser": { - "version": "9.40.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.40.0.tgz", - "integrity": "sha512-qz/1Go817vcsbcIwgrz4/T34vi3oQ4UIqikosuaCTI9wjZvK0HyW3QmLvTbAnsE7G7h6+UZsVkpO5R16IQvQhQ==", + "version": "9.43.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.43.0.tgz", + "integrity": "sha512-F+zMc+ratJ1MqV9YQqkrHqC+rED3meWHgO7+C6bYG5HPynCYqIGapJFNmFFC57pbU8lT191CiMgBWYT6DuMduw==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.40.0", - "@sentry-internal/feedback": "9.40.0", - "@sentry-internal/replay": "9.40.0", - "@sentry-internal/replay-canvas": "9.40.0", - "@sentry/core": "9.40.0" + "@sentry-internal/browser-utils": "9.43.0", + "@sentry-internal/feedback": "9.43.0", + "@sentry-internal/replay": "9.43.0", + "@sentry-internal/replay-canvas": "9.43.0", + "@sentry/core": "9.43.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/bundler-plugin-core": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-4.0.0.tgz", - "integrity": "sha512-dTdbcctT5MJUwdbttZm2zomO+ui1F062ZIkogHeHqlA938Fwd1+9JIJ328+XL4XdcUG2yiFAZBWUPW3bYwoN9A==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-4.0.2.tgz", + "integrity": "sha512-LeARs8qHhEw19tk+KZd9DDV+Rh/UeapIH0+C09fTmff9p8Y82Cj89pEQ2a1rdUiF/oYIjQX45vnZscB7ra42yw==", "license": "MIT", "dependencies": { "@babel/core": "^7.18.5", - "@sentry/babel-plugin-component-annotate": "4.0.0", + "@sentry/babel-plugin-component-annotate": "4.0.2", "@sentry/cli": "^2.49.0", "dotenv": "^16.3.1", "find-up": "^5.0.0", @@ -4571,9 +4571,9 @@ } }, "node_modules/@sentry/cli": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.50.0.tgz", - "integrity": "sha512-OHRRQPUNjBpzOT6arNhxXQ71DKs5jSziCfDzmEGwAs+K8J/I1QxnvJkto88HbXE54oiWhSEJwL0pvcowFXyVbA==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.50.2.tgz", + "integrity": "sha512-m1L9shxutF3WHSyNld6Y1vMPoXfEyQhoRh1V3SYSdl+4AB40U+zr2sRzFa2OPm7XP4zYNaWuuuHLkY/iHITs8Q==", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { @@ -4590,20 +4590,20 @@ "node": ">= 10" }, "optionalDependencies": { - "@sentry/cli-darwin": "2.50.0", - "@sentry/cli-linux-arm": "2.50.0", - "@sentry/cli-linux-arm64": "2.50.0", - "@sentry/cli-linux-i686": "2.50.0", - "@sentry/cli-linux-x64": "2.50.0", - "@sentry/cli-win32-arm64": "2.50.0", - "@sentry/cli-win32-i686": "2.50.0", - "@sentry/cli-win32-x64": "2.50.0" + "@sentry/cli-darwin": "2.50.2", + "@sentry/cli-linux-arm": "2.50.2", + "@sentry/cli-linux-arm64": "2.50.2", + "@sentry/cli-linux-i686": "2.50.2", + "@sentry/cli-linux-x64": "2.50.2", + "@sentry/cli-win32-arm64": "2.50.2", + "@sentry/cli-win32-i686": "2.50.2", + "@sentry/cli-win32-x64": "2.50.2" } }, "node_modules/@sentry/cli-darwin": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.50.0.tgz", - "integrity": "sha512-Aj+cLBZ0dCw+pdUxvJ1U71PnKh2YjvpzLN9h1ZTe8UI3FqmkKkSH/J8mN/5qmR7qUHjDcm2l+wfgVUaaP8CWbA==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.50.2.tgz", + "integrity": "sha512-0Pjpl0vQqKhwuZm19z6AlEF+ds3fJg1KWabv8WzGaSc/fwxMEwjFwOZj+IxWBJPV578cXXNvB39vYjjpCH8j7A==", "license": "BSD-3-Clause", "optional": true, "os": [ @@ -4614,9 +4614,9 @@ } }, "node_modules/@sentry/cli-linux-arm": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.50.0.tgz", - "integrity": "sha512-SGPAFwOY2of2C+RUBJcxMN2JXikVFEk8ypYOsQTEvV/48cLejcO/O2mHIj/YKgIkrfn3t7LlqdK6g75lkz+F8Q==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.50.2.tgz", + "integrity": "sha512-jzFwg9AeeuFAFtoCcyaDEPG05TU02uOy1nAX09c1g7FtsyQlPcbhI94JQGmnPzdRjjDmORtwIUiVZQrVTkDM7w==", "cpu": [ "arm" ], @@ -4632,9 +4632,9 @@ } }, "node_modules/@sentry/cli-linux-arm64": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.50.0.tgz", - "integrity": "sha512-p6hIh4Bb87qBfEz9w5dxEPAohIKcw68qoy5VUTx+cCanO8uXNWWsT78xtUNFRscW9zc6MxQMSITTWaCEIKvxRA==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.50.2.tgz", + "integrity": "sha512-03Cj215M3IdoHAwevCxm5oOm9WICFpuLR05DQnODFCeIUsGvE1pZsc+Gm0Ky/ZArq2PlShBJTpbHvXbCUka+0w==", "cpu": [ "arm64" ], @@ -4650,9 +4650,9 @@ } }, "node_modules/@sentry/cli-linux-i686": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.50.0.tgz", - "integrity": "sha512-umhGmbiCUG7MvjTm8lXFmFxQjyTVtYakilBwPTVzRELmNKxxhfKRxwSSA+hUKetAUzNd8fJx8K7yqdw+qRA7Pg==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.50.2.tgz", + "integrity": "sha512-J+POvB34uVyHbIYF++Bc/OCLw+gqKW0H/y/mY7rRZCiocgpk266M4NtsOBl6bEaurMx1D+BCIEjr4nc01I/rqA==", "cpu": [ "x86", "ia32" @@ -4669,9 +4669,9 @@ } }, "node_modules/@sentry/cli-linux-x64": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.50.0.tgz", - "integrity": "sha512-ugIIx9+wUmguxOUe9ZVacvdCffZwqtFSKwpJ06Nqes0XfL4ZER4Qlq3/miCZ8m150C4xK5ym/QCwB41ffBqI4g==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.50.2.tgz", + "integrity": "sha512-81yQVRLj8rnuHoYcrM7QbOw8ubA3weiMdPtTxTim1s6WExmPgnPTKxLCr9xzxGJxFdYo3xIOhtf5JFpUX/3j4A==", "cpu": [ "x64" ], @@ -4687,9 +4687,9 @@ } }, "node_modules/@sentry/cli-win32-arm64": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.50.0.tgz", - "integrity": "sha512-fMyBSKLrVHY9944t8oTpul+6osyQeuN8GGGP3diDxGQpynYL+vhcHZIpXFRH398+3kedG/IFoY7EwGgIEqWzmw==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.50.2.tgz", + "integrity": "sha512-QjentLGvpibgiZlmlV9ifZyxV73lnGH6pFZWU5wLeRiaYKxWtNrrHpVs+HiWlRhkwQ0mG1/S40PGNgJ20DJ3gA==", "cpu": [ "arm64" ], @@ -4703,9 +4703,9 @@ } }, "node_modules/@sentry/cli-win32-i686": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.50.0.tgz", - "integrity": "sha512-VbC+l2Y2kB7Lsun2c8t7ZGwmljmXnyncZLW9PjdEyJSTAJ9GnEnSvyFSPXNLV/eHJnfQffzU7QTjU8vkQ7XMYg==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.50.2.tgz", + "integrity": "sha512-UkBIIzkQkQ1UkjQX8kHm/+e7IxnEhK6CdgSjFyNlxkwALjDWHJjMztevqAPz3kv4LdM6q1MxpQ/mOqXICNhEGg==", "cpu": [ "x86", "ia32" @@ -4720,9 +4720,9 @@ } }, "node_modules/@sentry/cli-win32-x64": { - "version": "2.50.0", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.50.0.tgz", - "integrity": "sha512-nMktyF93NtQUOViAAKHpHSWACOGjOkKjiewi4pD6W3sWllFiPPyt15XoyApqWwnICDRQu2DI5vnil4ck6/k7mw==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.50.2.tgz", + "integrity": "sha512-tE27pu1sRRub1Jpmemykv3QHddBcyUk39Fsvv+n4NDpQyMgsyVPcboxBZyby44F0jkpI/q3bUH2tfCB1TYDNLg==", "cpu": [ "x64" ], @@ -4757,22 +4757,22 @@ } }, "node_modules/@sentry/core": { - "version": "9.40.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.40.0.tgz", - "integrity": "sha512-cZkuz6BDna6VXSqvlWnrRsaDx4QBKq1PcfQrqhVz8ljs0M7Gcl+Mtj8dCzUxx12fkYM62hQXG72DEGNlAQpH/Q==", + "version": "9.43.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.43.0.tgz", + "integrity": "sha512-xuvERSUkSNBAldIlgihX3fz+JkcaAPvg0HulPtv3BH9qrKqvataeQ8TiTnqiRC7kWzF7EcxhQJ6WJRl/r3aH3w==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@sentry/react": { - "version": "9.40.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.40.0.tgz", - "integrity": "sha512-y00d33qozmQAKroQ4Kk2jxhznprPBOb55SL4LOpNPRHGEomxZCUeM3geltczrf14JsGowCr5+xlT+cZQ2XcNlA==", + "version": "9.43.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-9.43.0.tgz", + "integrity": "sha512-bDJ1piXH1IPzyPypxnw/hWUVKk5xgeOKVvYJEFO9ypACKDpitgsskl7QasAmxKd1ghvbULgYksyUy5Zpaiu2cg==", "license": "MIT", "dependencies": { - "@sentry/browser": "9.40.0", - "@sentry/core": "9.40.0", + "@sentry/browser": "9.43.0", + "@sentry/core": "9.43.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -4783,12 +4783,12 @@ } }, "node_modules/@sentry/vite-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-4.0.0.tgz", - "integrity": "sha512-JX5irzvyoOSKto0U0eXDqigsTXdXnPRQaAms/kcU6A6Bf+WaPfCTE5NrJWg6ZeLvi7GiPWch11OO+TB6ZN8RKA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-4.0.2.tgz", + "integrity": "sha512-rStdvDGj0VcJBsl2NANE3OQF5m13VCJ+2Ovs5pb2LAqOW72/1GLmef9Mo3b9BwzCjWOQIcgtllwOfSV5Pse03w==", "license": "MIT", "dependencies": { - "@sentry/bundler-plugin-core": "4.0.0", + "@sentry/bundler-plugin-core": "4.0.2", "unplugin": "1.0.1" }, "engines": { @@ -4796,13 +4796,13 @@ } }, "node_modules/@sentry/webpack-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-4.0.0.tgz", - "integrity": "sha512-Uhfjqnuxv4eYIt0GbPAdlFPum3BtasNhQrO3OJuVQRYRq21En7ARKXISoOhZHMo4tRRiiv+3npKYmpzHTALbQg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-4.0.2.tgz", + "integrity": "sha512-UklVtG7Iiw+AvcL0PfiiyW/u3XT+joDAMDvWbx90rFhVSU10ENW5AV5y4pC41qChqEu3P1eBFdaSxg+kdLeqvw==", "dev": true, "license": "MIT", "dependencies": { - "@sentry/bundler-plugin-core": "4.0.0", + "@sentry/bundler-plugin-core": "4.0.2", "unplugin": "1.0.1", "uuid": "^9.0.0" }, @@ -4926,9 +4926,9 @@ } }, "node_modules/@testing-library/dom": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", - "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", "dependencies": { @@ -4936,61 +4936,28 @@ "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", - "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", + "picocolors": "1.1.1", "pretty-format": "^27.0.2" }, "engines": { "node": ">=18" } }, - "node_modules/@testing-library/dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/@testing-library/jest-dom": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", - "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.4.tgz", + "integrity": "sha512-xDXgLjVunjHqczScfkCJ9iyjdNOVHvvCdqHSSxwM9L0l/wHkTRum67SDc020uAlCoqktJplgO2AAQeLP1wgqDQ==", "dev": true, "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", - "chalk": "^3.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "lodash": "^4.17.21", + "picocolors": "^1.1.1", "redent": "^3.0.0" }, "engines": { @@ -4999,36 +4966,6 @@ "yarn": ">=1" } }, - "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", @@ -5966,9 +5903,9 @@ } }, "node_modules/antd": { - "version": "5.26.6", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.6.tgz", - "integrity": "sha512-k8ipeT+UL2tP/x4jHTXElScAxsD94JgrIEeGHj80nNO4dL9hqcmaOUBpHo3ieCf6MFjhS7gLUthysQeP6e7DUg==", + "version": "5.26.7", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.26.7.tgz", + "integrity": "sha512-iCyXN6+i2CUVEOSzzJKfbKeg115qoJhGvSkCh5uzAf9hANwHUOJQhsMn+KtN+Lx/2NQ6wfM7nGZ+7NPNO5Pn1w==", "license": "MIT", "dependencies": { "@ant-design/colors": "^7.2.1", @@ -5982,7 +5919,7 @@ "@rc-component/mutate-observer": "^1.1.0", "@rc-component/qrcode": "~1.0.0", "@rc-component/tour": "~1.15.1", - "@rc-component/trigger": "^2.2.7", + "@rc-component/trigger": "^2.3.0", "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.11", @@ -6012,7 +5949,7 @@ "rc-switch": "~4.1.0", "rc-table": "~7.51.1", "rc-tabs": "~15.6.1", - "rc-textarea": "~1.10.0", + "rc-textarea": "~1.10.1", "rc-tooltip": "~6.4.0", "rc-tree": "~5.13.1", "rc-tree-select": "~5.27.0", @@ -6428,13 +6365,13 @@ } }, "node_modules/axios": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", - "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, @@ -8141,9 +8078,9 @@ } }, "node_modules/dotenv": { - "version": "17.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.0.tgz", - "integrity": "sha512-Q4sgBT60gzd0BB0lSyYD3xM4YxrXA9y4uBDof1JNYGzOXrQdQ6yX+7XIAqoFOGQFOTK1D3Hts5OllpxMDZFONQ==", + "version": "17.2.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz", + "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -9505,14 +9442,15 @@ } }, "node_modules/form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -11711,9 +11649,9 @@ } }, "node_modules/memfs": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", - "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.23.0.tgz", + "integrity": "sha512-SucHN2lcWf0jrnw+jP6FoVW6l/zGJiXfNMdApZzG0x/0mAIMdwAeR5mjfsCH5U3BoqpUEtqzz+dSQSO0H/eqxg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -13157,9 +13095,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -14027,9 +13965,9 @@ } }, "node_modules/rc-textarea": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.10.0.tgz", - "integrity": "sha512-ai9IkanNuyBS4x6sOL8qu/Ld40e6cEs6pgk93R+XLYg0mDSjNBGey6/ZpDs5+gNLD7urQ14po3V6Ck2dJLt9SA==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.10.2.tgz", + "integrity": "sha512-HfaeXiaSlpiSp0I/pvWpecFEHpVysZ9tpDLNkxQbMvMz6gsr7aVZ7FpWP9kt4t7DB+jJXesYS0us1uPZnlRnwQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.1", @@ -14287,9 +14225,9 @@ } }, "node_modules/react-i18next": { - "version": "15.6.0", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.6.0.tgz", - "integrity": "sha512-W135dB0rDfiFmbMipC17nOhGdttO5mzH8BivY+2ybsQBbXvxWIwl3cmeH3T9d+YPBSJu/ouyJKFJTtkK7rJofw==", + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.6.1.tgz", + "integrity": "sha512-uGrzSsOUUe2sDBG/+FJq2J1MM+Y4368/QW8OLEKSFvnDflHBbZhSd1u3UkW0Z06rMhZmnB/AQrhCpYfE5/5XNg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.27.6", @@ -17359,15 +17297,15 @@ } }, "node_modules/vite": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.5.tgz", - "integrity": "sha512-1mncVwJxy2C9ThLwz0+2GKZyEXuC3MyWtAAlNftlZZXZDP3AJt5FmwcMit/IGGaNZ8ZOB2BNO/HFUB+CpN0NQw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.6.tgz", + "integrity": "sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", - "picomatch": "^4.0.2", + "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.40.0", "tinyglobby": "^0.2.14" @@ -17543,9 +17481,9 @@ } }, "node_modules/vite-plugin-pwa": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.0.1.tgz", - "integrity": "sha512-STyUomQbydj7vGamtgQYIJI0YsUZ3T4pJLGBQDQPhzMse6aGSncmEN21OV35PrFsmCvmtiH+Nu1JS1ke4RqBjQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-1.0.2.tgz", + "integrity": "sha512-O3UwjsCnoDclgJANoOgzzqW7SFgwXE/th2OmUP/ILxHKwzWxxKDBu+B/Xa9Cv4IgSVSnj2HgRVIJ7F15+vQFkA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/client/package.json b/client/package.json index 231212d89..2adda7538 100644 --- a/client/package.json +++ b/client/package.json @@ -9,7 +9,7 @@ "proxy": "http://localhost:4000", "dependencies": { "@ant-design/pro-layout": "^7.22.6", - "@apollo/client": "^3.13.6", + "@apollo/client": "^3.13.9", "@emotion/is-prop-valid": "^1.3.1", "@fingerprintjs/fingerprintjs": "^4.6.1", "@firebase/analytics": "^0.10.17", @@ -19,22 +19,22 @@ "@firebase/messaging": "^0.12.22", "@jsreport/browser-client": "^3.1.0", "@reduxjs/toolkit": "^2.8.2", - "@sentry/cli": "^2.50.0", - "@sentry/react": "^9.40.0", - "@sentry/vite-plugin": "^4.0.0", + "@sentry/cli": "^2.50.2", + "@sentry/react": "^9.43.0", + "@sentry/vite-plugin": "^4.0.2", "@splitsoftware/splitio-react": "^2.3.1", "@tanem/react-nprogress": "^5.0.53", - "antd": "^5.26.6", + "antd": "^5.26.7", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.3.0", "autosize": "^6.0.1", - "axios": "^1.10.0", + "axios": "^1.11.0", "classnames": "^2.5.1", "css-box-model": "^1.2.1", "dayjs": "^1.11.13", "dayjs-business-days2": "^1.3.0", "dinero.js": "^1.9.1", - "dotenv": "^17.2.0", + "dotenv": "^17.2.1", "env-cmd": "^10.1.0", "exifr": "^7.1.3", "graphql": "^16.11.0", @@ -59,7 +59,7 @@ "react-drag-listview": "^2.0.0", "react-grid-gallery": "^1.0.1", "react-grid-layout": "1.3.4", - "react-i18next": "^15.6.0", + "react-i18next": "^15.6.1", "react-icons": "^5.5.0", "react-image-lightbox": "^5.1.4", "react-markdown": "^10.1.0", @@ -131,14 +131,14 @@ "@ant-design/icons": "^6.0.0", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-react": "^7.27.1", - "@dotenvx/dotenvx": "^1.48.2", + "@dotenvx/dotenvx": "^1.48.3", "@emotion/babel-plugin": "^11.13.5", "@emotion/react": "^11.14.0", - "@eslint/js": "^9.31.0", + "@eslint/js": "^9.32.0", "@playwright/test": "^1.54.1", - "@sentry/webpack-plugin": "^4.0.0", - "@testing-library/dom": "^10.4.0", - "@testing-library/jest-dom": "^6.6.3", + "@sentry/webpack-plugin": "^4.0.2", + "@testing-library/dom": "^10.4.1", + "@testing-library/jest-dom": "^6.6.4", "@testing-library/react": "^16.3.0", "@vitejs/plugin-react": "^4.6.0", "browserslist": "^4.25.1", @@ -149,17 +149,17 @@ "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "jsdom": "^26.0.0", - "memfs": "^4.17.2", + "memfs": "^4.23.0", "os-browserify": "^0.3.0", "playwright": "^1.54.1", "react-error-overlay": "^6.1.0", "redux-logger": "^3.0.6", "source-map-explorer": "^2.5.3", - "vite": "^7.0.5", + "vite": "^7.0.6", "vite-plugin-babel": "^1.3.2", "vite-plugin-eslint": "^1.8.1", "vite-plugin-node-polyfills": "^0.24.0", - "vite-plugin-pwa": "^1.0.1", + "vite-plugin-pwa": "^1.0.2", "vite-plugin-style-import": "^2.0.0", "vitest": "^3.2.4", "workbox-window": "^7.3.0" diff --git a/client/src/App/App.jsx b/client/src/App/App.jsx index f499cb55c..34481232c 100644 --- a/client/src/App/App.jsx +++ b/client/src/App/App.jsx @@ -53,15 +53,14 @@ export function App({ bodyshop, checkUserSession, currentUser, online, setOnline if (!navigator.onLine) { setOnline(false); } - checkUserSession(); }, [checkUserSession, setOnline]); useEffect(() => { const pathname = window.location.pathname; - const isParts = pathname.startsWith("/parts/"); + const isParts = pathname.startsWith("/parts/") && bodyshop?.external_shop_id; setIsPartsEntry(isParts); - }, [setIsPartsEntry]); + }, [setIsPartsEntry, bodyshop?.external_shop_id]); //const b = Grid.useBreakpoint(); // console.log("Breakpoints:", b); diff --git a/client/src/graphql/bodyshop.queries.js b/client/src/graphql/bodyshop.queries.js index 73e222c01..cdb806e55 100644 --- a/client/src/graphql/bodyshop.queries.js +++ b/client/src/graphql/bodyshop.queries.js @@ -139,6 +139,7 @@ export const QUERY_BODYSHOP = gql` tt_enforce_hours_for_tech_console md_tasks_presets use_paint_scale_data + external_shop_id intellipay_config md_ro_guard notification_followers diff --git a/package-lock.json b/package-lock.json index 44fb54769..5cfb4e7ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,29 +9,29 @@ "version": "0.2.0", "license": "UNLICENSED", "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.849.0", - "@aws-sdk/client-elasticache": "^3.848.0", - "@aws-sdk/client-s3": "^3.848.0", - "@aws-sdk/client-secrets-manager": "^3.848.0", - "@aws-sdk/client-ses": "^3.848.0", - "@aws-sdk/credential-provider-node": "^3.848.0", - "@aws-sdk/lib-storage": "^3.848.0", - "@aws-sdk/s3-request-presigner": "^3.848.0", + "@aws-sdk/client-cloudwatch-logs": "^3.855.0", + "@aws-sdk/client-elasticache": "^3.855.0", + "@aws-sdk/client-s3": "^3.855.0", + "@aws-sdk/client-secrets-manager": "^3.855.0", + "@aws-sdk/client-ses": "^3.855.0", + "@aws-sdk/credential-provider-node": "^3.855.0", + "@aws-sdk/lib-storage": "^3.855.0", + "@aws-sdk/s3-request-presigner": "^3.855.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", "archiver": "^7.0.1", "aws4": "^1.13.2", - "axios": "^1.10.0", + "axios": "^1.11.0", "better-queue": "^3.8.12", - "bullmq": "^5.56.5", + "bullmq": "^5.56.8", "chart.js": "^4.5.0", "cloudinary": "^2.7.0", "compression": "^1.8.1", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.60.0", + "dd-trace": "^5.61.1", "dinero.js": "^1.9.1", "dotenv": "^16.4.5", "express": "^4.21.1", @@ -54,11 +54,11 @@ "recursive-diff": "^1.0.9", "rimraf": "^6.0.1", "skia-canvas": "^2.0.2", - "soap": "^1.1.12", + "soap": "^1.2.1", "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "ssh2-sftp-client": "^11.0.0", - "twilio": "^5.7.3", + "twilio": "^5.8.0", "uuid": "^11.1.0", "winston": "^3.17.0", "winston-cloudwatch": "^6.3.0", @@ -67,14 +67,14 @@ "yazl": "^3.3.1" }, "devDependencies": { - "@eslint/js": "^9.31.0", - "eslint": "^9.31.0", + "@eslint/js": "^9.32.0", + "eslint": "^9.32.0", "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "mock-require": "^3.0.3", "p-limit": "^3.1.0", "prettier": "^3.6.2", - "supertest": "^7.1.3", + "supertest": "^7.1.4", "vitest": "^3.2.4" }, "engines": { @@ -285,24 +285,24 @@ } }, "node_modules/@aws-sdk/client-cloudwatch-logs": { - "version": "3.849.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.849.0.tgz", - "integrity": "sha512-+11BgdFro0hV+ypIogNiRofvAGsVNZs1MxkX8fsjuGq6/uflLg3x6/RRmZCFl14Y/NAuGe3ojBp+8UCvBIf8Sg==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.855.0.tgz", + "integrity": "sha512-/92yfiNg/LT0h6Sjmetxc+tnMIfgV5mnBSlE92seJlOF2fCdYgh85gpwvaGz4XCbE2s/KYCWiuGWZ7HH4U+Vuw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.846.0", - "@aws-sdk/credential-provider-node": "3.848.0", + "@aws-sdk/core": "3.855.0", + "@aws-sdk/credential-provider-node": "3.855.0", "@aws-sdk/middleware-host-header": "3.840.0", "@aws-sdk/middleware-logger": "3.840.0", "@aws-sdk/middleware-recursion-detection": "3.840.0", - "@aws-sdk/middleware-user-agent": "3.848.0", + "@aws-sdk/middleware-user-agent": "3.855.0", "@aws-sdk/region-config-resolver": "3.840.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-endpoints": "3.848.0", "@aws-sdk/util-user-agent-browser": "3.840.0", - "@aws-sdk/util-user-agent-node": "3.848.0", + "@aws-sdk/util-user-agent-node": "3.855.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.7.0", "@smithy/eventstream-serde-browser": "^4.0.4", @@ -353,24 +353,24 @@ } }, "node_modules/@aws-sdk/client-elasticache": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.848.0.tgz", - "integrity": "sha512-Ufvrd7p6DxqUEH+3JfEqaXd0fL8FQIbaq8NpOwAiVsqF3dUHJKcMZVTnPBdIfLGjAfmeaD3PgJBDQXi0b9U9bg==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-elasticache/-/client-elasticache-3.855.0.tgz", + "integrity": "sha512-B2j9Dg9cyNWmcfu2XNjftrvpPTh0QSQN8C7Cc9Z6xnfDYrVg3Vu+A4q7QWotyfyx7Oxk7HpXSk8AcSIoTxLzmQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.846.0", - "@aws-sdk/credential-provider-node": "3.848.0", + "@aws-sdk/core": "3.855.0", + "@aws-sdk/credential-provider-node": "3.855.0", "@aws-sdk/middleware-host-header": "3.840.0", "@aws-sdk/middleware-logger": "3.840.0", "@aws-sdk/middleware-recursion-detection": "3.840.0", - "@aws-sdk/middleware-user-agent": "3.848.0", + "@aws-sdk/middleware-user-agent": "3.855.0", "@aws-sdk/region-config-resolver": "3.840.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-endpoints": "3.848.0", "@aws-sdk/util-user-agent-browser": "3.840.0", - "@aws-sdk/util-user-agent-node": "3.848.0", + "@aws-sdk/util-user-agent-node": "3.855.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.7.0", "@smithy/fetch-http-handler": "^5.1.0", @@ -404,32 +404,32 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.848.0.tgz", - "integrity": "sha512-6uT+THQfsB92eAH0p5zvpGiSCtO2ZhGwmuw6HWEngui53YIWz7W/GCnN0G7nrKpgD5DPrMaBwqZvKuoAh9NHAQ==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.855.0.tgz", + "integrity": "sha512-f8EP7ia+5LwrCLT/Etsw0LmZZMcz5kyBBK+96IJAKj3JNTB9zViGMDzasAwt/Vdo3eDnca7r4+XJ3U/Lw2TC3w==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.846.0", - "@aws-sdk/credential-provider-node": "3.848.0", + "@aws-sdk/core": "3.855.0", + "@aws-sdk/credential-provider-node": "3.855.0", "@aws-sdk/middleware-bucket-endpoint": "3.840.0", "@aws-sdk/middleware-expect-continue": "3.840.0", - "@aws-sdk/middleware-flexible-checksums": "3.846.0", + "@aws-sdk/middleware-flexible-checksums": "3.855.0", "@aws-sdk/middleware-host-header": "3.840.0", "@aws-sdk/middleware-location-constraint": "3.840.0", "@aws-sdk/middleware-logger": "3.840.0", "@aws-sdk/middleware-recursion-detection": "3.840.0", - "@aws-sdk/middleware-sdk-s3": "3.846.0", + "@aws-sdk/middleware-sdk-s3": "3.855.0", "@aws-sdk/middleware-ssec": "3.840.0", - "@aws-sdk/middleware-user-agent": "3.848.0", + "@aws-sdk/middleware-user-agent": "3.855.0", "@aws-sdk/region-config-resolver": "3.840.0", - "@aws-sdk/signature-v4-multi-region": "3.846.0", + "@aws-sdk/signature-v4-multi-region": "3.855.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-endpoints": "3.848.0", "@aws-sdk/util-user-agent-browser": "3.840.0", - "@aws-sdk/util-user-agent-node": "3.848.0", + "@aws-sdk/util-user-agent-node": "3.855.0", "@aws-sdk/xml-builder": "3.821.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.7.0", @@ -486,24 +486,24 @@ } }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.848.0.tgz", - "integrity": "sha512-T1SRQrBvUD8KGArFpWeVuXD1Qh2zqMErayRvJiTvVMy8ru1jXDr58MVdoIDnRVLQFeE4k9f0jtPbUXJsRIoGIQ==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.855.0.tgz", + "integrity": "sha512-qQ9G9nQB85DM7d7uyjmPXKN+VYai25hPJzd8hc21gLT8vFRwcoq3FWrMKO3OBqSlGsGasx7kVLFljdmKP2eVQg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.846.0", - "@aws-sdk/credential-provider-node": "3.848.0", + "@aws-sdk/core": "3.855.0", + "@aws-sdk/credential-provider-node": "3.855.0", "@aws-sdk/middleware-host-header": "3.840.0", "@aws-sdk/middleware-logger": "3.840.0", "@aws-sdk/middleware-recursion-detection": "3.840.0", - "@aws-sdk/middleware-user-agent": "3.848.0", + "@aws-sdk/middleware-user-agent": "3.855.0", "@aws-sdk/region-config-resolver": "3.840.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-endpoints": "3.848.0", "@aws-sdk/util-user-agent-browser": "3.840.0", - "@aws-sdk/util-user-agent-node": "3.848.0", + "@aws-sdk/util-user-agent-node": "3.855.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.7.0", "@smithy/fetch-http-handler": "^5.1.0", @@ -551,24 +551,24 @@ } }, "node_modules/@aws-sdk/client-ses": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.848.0.tgz", - "integrity": "sha512-CyDE1KqM3U9oS2aNn2eiCNlVsMdT7j3yEJQc+qrLJAvVKDirfdDtdBTzHLvi8oJoeXcvUHFrTOOBuHvyvulsbw==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.855.0.tgz", + "integrity": "sha512-G5OMlMr83JBNH0uwXtp0J/VjyYBHewo6hsYJfuk5rMTLJvHquOwhjszxzmaK+hJuxbT/znacid+eSlcRRIrQ+w==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.846.0", - "@aws-sdk/credential-provider-node": "3.848.0", + "@aws-sdk/core": "3.855.0", + "@aws-sdk/credential-provider-node": "3.855.0", "@aws-sdk/middleware-host-header": "3.840.0", "@aws-sdk/middleware-logger": "3.840.0", "@aws-sdk/middleware-recursion-detection": "3.840.0", - "@aws-sdk/middleware-user-agent": "3.848.0", + "@aws-sdk/middleware-user-agent": "3.855.0", "@aws-sdk/region-config-resolver": "3.840.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-endpoints": "3.848.0", "@aws-sdk/util-user-agent-browser": "3.840.0", - "@aws-sdk/util-user-agent-node": "3.848.0", + "@aws-sdk/util-user-agent-node": "3.855.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.7.0", "@smithy/fetch-http-handler": "^5.1.0", @@ -602,23 +602,23 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.848.0.tgz", - "integrity": "sha512-mD+gOwoeZQvbecVLGoCmY6pS7kg02BHesbtIxUj+PeBqYoZV5uLvjUOmuGfw1SfoSobKvS11urxC9S7zxU/Maw==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.855.0.tgz", + "integrity": "sha512-4gFvnn8oL9DeJp4fc5KoOB/v20eUuoYkElMCegnGA2AG1nPkf6igib16+Dt2xhoCmkA3cX5FET9gKI2hY7RiQw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.846.0", + "@aws-sdk/core": "3.855.0", "@aws-sdk/middleware-host-header": "3.840.0", "@aws-sdk/middleware-logger": "3.840.0", "@aws-sdk/middleware-recursion-detection": "3.840.0", - "@aws-sdk/middleware-user-agent": "3.848.0", + "@aws-sdk/middleware-user-agent": "3.855.0", "@aws-sdk/region-config-resolver": "3.840.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-endpoints": "3.848.0", "@aws-sdk/util-user-agent-browser": "3.840.0", - "@aws-sdk/util-user-agent-node": "3.848.0", + "@aws-sdk/util-user-agent-node": "3.855.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.7.0", "@smithy/fetch-http-handler": "^5.1.0", @@ -651,9 +651,9 @@ } }, "node_modules/@aws-sdk/core": { - "version": "3.846.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.846.0.tgz", - "integrity": "sha512-7CX0pM906r4WSS68fCTNMTtBCSkTtf3Wggssmx13gD40gcWEZXsU00KzPp1bYheNRyPlAq3rE22xt4wLPXbuxA==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.855.0.tgz", + "integrity": "sha512-viFAe3IB64xEFjl/OMw0af+tD+v8Ei09+0Fn69y+HoF5ESSJyNIZnj/U69OhpzdSCO65aathBNdYhG+AMbMLhw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "3.840.0", @@ -707,12 +707,12 @@ "license": "MIT" }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.846.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.846.0.tgz", - "integrity": "sha512-QuCQZET9enja7AWVISY+mpFrEIeHzvkx/JEEbHYzHhUkxcnC2Kq2c0bB7hDihGD0AZd3Xsm653hk1O97qu69zg==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.855.0.tgz", + "integrity": "sha512-2hKTkrb4RG+eXE+OpKW0ST75ti32ExtJlzK5TEDd+STVJBWTf6W6bxhP6GzfeyYQ5XGSUSI94X5eXhBOLdAJ6A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.846.0", + "@aws-sdk/core": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -723,12 +723,12 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.846.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.846.0.tgz", - "integrity": "sha512-Jh1iKUuepdmtreMYozV2ePsPcOF5W9p3U4tWhi3v6nDvz0GsBjzjAROW+BW8XMz9vAD3I9R+8VC3/aq63p5nlw==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.855.0.tgz", + "integrity": "sha512-JxZ6VBpU9z6YQLhIDIC9wYojsgAGKmYaFQt0fBvwaeUF/P65kN8q+y/35tMFDPSiJ9XXu6tsJrgFvIldYt6+Zw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.846.0", + "@aws-sdk/core": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/fetch-http-handler": "^5.1.0", "@smithy/node-http-handler": "^4.1.0", @@ -744,18 +744,18 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.848.0.tgz", - "integrity": "sha512-r6KWOG+En2xujuMhgZu7dzOZV3/M5U/5+PXrG8dLQ3rdPRB3vgp5tc56KMqLwm/EXKRzAOSuw/UE4HfNOAB8Hw==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.855.0.tgz", + "integrity": "sha512-wbdQI1N9xU3bnFDzU9Iq4fqpJbgNq4sVvxdhx0YgBMir+cmAuHgjmAuNZIBKHbH3+23snySzDfY6hTAZeBkPag==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.846.0", - "@aws-sdk/credential-provider-env": "3.846.0", - "@aws-sdk/credential-provider-http": "3.846.0", - "@aws-sdk/credential-provider-process": "3.846.0", - "@aws-sdk/credential-provider-sso": "3.848.0", - "@aws-sdk/credential-provider-web-identity": "3.848.0", - "@aws-sdk/nested-clients": "3.848.0", + "@aws-sdk/core": "3.855.0", + "@aws-sdk/credential-provider-env": "3.855.0", + "@aws-sdk/credential-provider-http": "3.855.0", + "@aws-sdk/credential-provider-process": "3.855.0", + "@aws-sdk/credential-provider-sso": "3.855.0", + "@aws-sdk/credential-provider-web-identity": "3.855.0", + "@aws-sdk/nested-clients": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -768,17 +768,17 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.848.0.tgz", - "integrity": "sha512-AblNesOqdzrfyASBCo1xW3uweiSro4Kft9/htdxLeCVU1KVOnFWA5P937MNahViRmIQm2sPBCqL8ZG0u9lnh5g==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.855.0.tgz", + "integrity": "sha512-n6IH1wLrAJYb2JSN/hKzNU1h7UiqnxpI4m3ScTNZJmkpCub9Q+TVugnnWGdyRmszz5gsKim5n9AiNVXddtA/UQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.846.0", - "@aws-sdk/credential-provider-http": "3.846.0", - "@aws-sdk/credential-provider-ini": "3.848.0", - "@aws-sdk/credential-provider-process": "3.846.0", - "@aws-sdk/credential-provider-sso": "3.848.0", - "@aws-sdk/credential-provider-web-identity": "3.848.0", + "@aws-sdk/credential-provider-env": "3.855.0", + "@aws-sdk/credential-provider-http": "3.855.0", + "@aws-sdk/credential-provider-ini": "3.855.0", + "@aws-sdk/credential-provider-process": "3.855.0", + "@aws-sdk/credential-provider-sso": "3.855.0", + "@aws-sdk/credential-provider-web-identity": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/credential-provider-imds": "^4.0.6", "@smithy/property-provider": "^4.0.4", @@ -791,12 +791,12 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.846.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.846.0.tgz", - "integrity": "sha512-mEpwDYarJSH+CIXnnHN0QOe0MXI+HuPStD6gsv3z/7Q6ESl8KRWon3weFZCDnqpiJMUVavlDR0PPlAFg2MQoPg==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.855.0.tgz", + "integrity": "sha512-GmJ6eCB7TYicXKPIq+hxq9ZBJDn6fGPdH/ptgSj0MNKzmie8zqWKRYDri9cy3zLmz7+b7JHy1t158Z8kp7RsXQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.846.0", + "@aws-sdk/core": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -808,14 +808,14 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.848.0.tgz", - "integrity": "sha512-pozlDXOwJZL0e7w+dqXLgzVDB7oCx4WvtY0sk6l4i07uFliWF/exupb6pIehFWvTUcOvn5aFTTqcQaEzAD5Wsg==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.855.0.tgz", + "integrity": "sha512-oXI/YQdTj/9unzyOQM/OxAtd85U3oACleyVoldawl/n5NdY215sEGW94uEw1Jg20jIoRFYt++Fw0UDXMQhhNow==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.848.0", - "@aws-sdk/core": "3.846.0", - "@aws-sdk/token-providers": "3.848.0", + "@aws-sdk/client-sso": "3.855.0", + "@aws-sdk/core": "3.855.0", + "@aws-sdk/token-providers": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -827,13 +827,13 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.848.0.tgz", - "integrity": "sha512-D1fRpwPxtVDhcSc/D71exa2gYweV+ocp4D3brF0PgFd//JR3XahZ9W24rVnTQwYEcK9auiBZB89Ltv+WbWN8qw==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.855.0.tgz", + "integrity": "sha512-x4BqqvqFc5aUxT9jNSm3yUiRkrQuXbdTMtshmG5/zzErASuLIixOmaPreqdb5MMqoyqdrNJSoL+u6YEfvOeB1Q==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.846.0", - "@aws-sdk/nested-clients": "3.848.0", + "@aws-sdk/core": "3.855.0", + "@aws-sdk/nested-clients": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/types": "^4.3.1", @@ -844,9 +844,9 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.848.0.tgz", - "integrity": "sha512-Q23bI829ZQBHP6Iab9YsfCrZKvek2uMIVYEQjPa0Ekib5bmqURFCXhNtrP++TOCaZNr5DmSPAqAs8EGHWTOZiw==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.855.0.tgz", + "integrity": "sha512-t1fIt58rrRVVdp4TUD45cU+j1k0e4jPphHZJrvnydyDcSPNbzajFwlpdDRDJMlvbwrr7/nZwV1t15ILFx+iwWw==", "license": "Apache-2.0", "dependencies": { "@smithy/abort-controller": "^4.0.4", @@ -861,7 +861,7 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.848.0" + "@aws-sdk/client-s3": "^3.855.0" } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { @@ -898,15 +898,15 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.846.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.846.0.tgz", - "integrity": "sha512-CdkeVfkwt3+bDLhmOwBxvkUf6oY9iUhvosaUnqkoPsOqIiUEN54yTGOnO8A0wLz6mMsZ6aBlfFrQhFnxt3c+yw==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.855.0.tgz", + "integrity": "sha512-IoLYv0rpOX7if/ecHXQkMV+cexW03DP6lm9j763j/3vGdUvs+gHaPs2q8LXC9UCsjEDCincEC/GKbCWMOPtTDA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "3.846.0", + "@aws-sdk/core": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/is-array-buffer": "^4.0.0", "@smithy/node-config-provider": "^4.1.3", @@ -980,12 +980,12 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.846.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.846.0.tgz", - "integrity": "sha512-jP9x+2Q87J5l8FOP+jlAd7vGLn0cC6G9QGmf386e5OslBPqxXKcl3RjqGLIOKKos2mVItY3ApP5xdXQx7jGTVA==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.855.0.tgz", + "integrity": "sha512-X7HsCCaTQcbBGR78gUSYTUFbPoDvWE4tq54WKn+ZFQPFFHIA1/EsVlQc0svWvhLFe4/DG4dySuyRRUFlu+Zd5w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.846.0", + "@aws-sdk/core": "3.855.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-arn-parser": "3.804.0", "@smithy/core": "^3.7.0", @@ -1019,12 +1019,12 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.848.0.tgz", - "integrity": "sha512-rjMuqSWJEf169/ByxvBqfdei1iaduAnfolTshsZxwcmLIUtbYrFUmts0HrLQqsAG8feGPpDLHA272oPl+NTCCA==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.855.0.tgz", + "integrity": "sha512-jYi5ZI+xy0/Xj7fCeSFMNWab2APnwqYhMbZEb71P5YTyYFgIGhPUOXkSxGRX5Y+aSifG3Kw+/OYVE0AKJioPbQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.846.0", + "@aws-sdk/core": "3.855.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-endpoints": "3.848.0", "@smithy/core": "^3.7.0", @@ -1037,23 +1037,23 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.848.0.tgz", - "integrity": "sha512-joLsyyo9u61jnZuyYzo1z7kmS7VgWRAkzSGESVzQHfOA1H2PYeUFek6vLT4+c9xMGrX/Z6B0tkRdzfdOPiatLg==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.855.0.tgz", + "integrity": "sha512-l/ZpcSCYQ+cJsY9NgsEZjn1RR71JQwOMCGJUqAz+dxg7qovmy2ckuHzknBr3W5N6rNcVESbhjzcZKCmu2UaeFQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.846.0", + "@aws-sdk/core": "3.855.0", "@aws-sdk/middleware-host-header": "3.840.0", "@aws-sdk/middleware-logger": "3.840.0", "@aws-sdk/middleware-recursion-detection": "3.840.0", - "@aws-sdk/middleware-user-agent": "3.848.0", + "@aws-sdk/middleware-user-agent": "3.855.0", "@aws-sdk/region-config-resolver": "3.840.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-endpoints": "3.848.0", "@aws-sdk/util-user-agent-browser": "3.840.0", - "@aws-sdk/util-user-agent-node": "3.848.0", + "@aws-sdk/util-user-agent-node": "3.855.0", "@smithy/config-resolver": "^4.1.4", "@smithy/core": "^3.7.0", "@smithy/fetch-http-handler": "^5.1.0", @@ -1103,12 +1103,12 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.848.0.tgz", - "integrity": "sha512-fm75L4M98UOPjFORyLdIgsPOuSXdbfpfOl3bNWcWFmeG8tDhqY+lGOyALYEZw/0O1MzEnyeK7wEGwAOf2PO5ZQ==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.855.0.tgz", + "integrity": "sha512-m1WoOwuuYGIO+cE5KwyAIlIMglU9gKQQC8OiI5ZFRKdRja58COga2tFLmstT9oe9C0YeO1MOLQ5ItQfEwQLAZg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/signature-v4-multi-region": "3.846.0", + "@aws-sdk/signature-v4-multi-region": "3.855.0", "@aws-sdk/types": "3.840.0", "@aws-sdk/util-format-url": "3.840.0", "@smithy/middleware-endpoint": "^4.1.15", @@ -1122,12 +1122,12 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.846.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.846.0.tgz", - "integrity": "sha512-ZMfIMxUljqZzPJGOcraC6erwq/z1puNMU35cO1a/WdhB+LdYknMn1lr7SJuH754QwNzzIlZbEgg4hoHw50+DpQ==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.855.0.tgz", + "integrity": "sha512-Vj7QfuGUZGLM4kQ5dVodNAo3HXlPk53Ff9UPaRaGF8BQQM8j00W2ydnraUKeHvjt/yzRdG4o/giWukqH7wCiTw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.846.0", + "@aws-sdk/middleware-sdk-s3": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/protocol-http": "^5.1.2", "@smithy/signature-v4": "^5.1.2", @@ -1139,13 +1139,13 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.848.0.tgz", - "integrity": "sha512-oNPyM4+Di2Umu0JJRFSxDcKQ35+Chl/rAwD47/bS0cDPI8yrao83mLXLeDqpRPHyQW4sXlP763FZcuAibC0+mg==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.855.0.tgz", + "integrity": "sha512-Ieh86MA+lOtvLAuCsT/gX5PSHkfmE7AnItT2ZFZddvu+s4LWWjDfAF0ktsR0H6166P7yAWTovfbEtORB3XzoTQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.846.0", - "@aws-sdk/nested-clients": "3.848.0", + "@aws-sdk/core": "3.855.0", + "@aws-sdk/nested-clients": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/property-provider": "^4.0.4", "@smithy/shared-ini-file-loader": "^4.0.4", @@ -1237,12 +1237,12 @@ } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.848.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.848.0.tgz", - "integrity": "sha512-Zz1ft9NiLqbzNj/M0jVNxaoxI2F4tGXN0ZbZIj+KJ+PbJo+w5+Jo6d0UDAtbj3AEd79pjcCaP4OA9NTVzItUdw==", + "version": "3.855.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.855.0.tgz", + "integrity": "sha512-leDOlnChk+0qRYtc70X1KZCe/TAFNHUGtvqLE6bqdr08V446hYhmtHT9LXnZtflzbIb9zpgrzSXXigWz3GH6uA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "3.848.0", + "@aws-sdk/middleware-user-agent": "3.855.0", "@aws-sdk/types": "3.840.0", "@smithy/node-config-provider": "^4.1.3", "@smithy/types": "^4.3.1", @@ -1470,9 +1470,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", - "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", + "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1520,9 +1520,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz", - "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", "dev": true, "license": "MIT", "engines": { @@ -1543,13 +1543,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", - "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", + "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.14.0", + "@eslint/core": "^0.15.1", "levn": "^0.4.1" }, "engines": { @@ -3869,13 +3869,13 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", - "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, @@ -4056,9 +4056,9 @@ } }, "node_modules/bullmq": { - "version": "5.56.5", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.56.5.tgz", - "integrity": "sha512-nhcVxoE9Y0YUuNYtvaD+N0Bk2kqcU+rXzJwdQIr8i8qC/fxoghwUYb9a+CidTv24pi1eqstLnBoa8xkR/P7Mdw==", + "version": "5.56.8", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.56.8.tgz", + "integrity": "sha512-4vcgfLCyHKDWKDUxJGNz/plBVNWFsvOm1r63XIqA2BkfaUjmnq7G8zV+0liV5SEGy1lQb8zFMTVoG1uFUOkjNg==", "license": "MIT", "dependencies": { "cron-parser": "^4.9.0", @@ -4886,18 +4886,18 @@ "license": "MIT" }, "node_modules/dc-polyfill": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/dc-polyfill/-/dc-polyfill-0.1.9.tgz", - "integrity": "sha512-D5mJThEEk9hf+CJPwTf9JFsrWdlWp8Pccjxkhf7uUT/E/cU9Mx3ebWe2Bz2OawRmJ6WS9eaDPBkeBE4uOKq9uw==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/dc-polyfill/-/dc-polyfill-0.1.10.tgz", + "integrity": "sha512-9iSbB8XZ7aIrhUtWI5ulEOJ+IyUN+axquodHK+bZO4r7HfY/xwmo6I4fYYf+aiDom+WMcN/wnzCz+pKvHDDCug==", "license": "MIT", "engines": { "node": ">=12.17" } }, "node_modules/dd-trace": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.60.0.tgz", - "integrity": "sha512-jMV/bQcGVKxWpMyXNg6p+qGWrXsUh6+GupLjeZvQYT2rGkG1W0DWUOaETmw1jGdiKMOHoyuo3ZKUnf1DM5AKIA==", + "version": "5.61.1", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.61.1.tgz", + "integrity": "sha512-voBRs3k1ZduBqSuVAEfbgDs22NSyyWxqa1tpq3iMId0ct0LF1cLMoxJudx+AYgJ3PkSjenyiLmmo4/D9KLVmHw==", "hasInstallScript": true, "license": "(Apache-2.0 OR BSD-3-Clause)", "dependencies": { @@ -4912,7 +4912,7 @@ "@opentelemetry/api": "1.8.0", "@opentelemetry/core": "^1.14.0", "crypto-randomuuid": "^1.0.0", - "dc-polyfill": "^0.1.9", + "dc-polyfill": "^0.1.10", "ignore": "^7.0.5", "import-in-the-middle": "^1.14.2", "istanbul-lib-coverage": "^3.2.2", @@ -5687,9 +5687,9 @@ } }, "node_modules/eslint": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.31.0.tgz", - "integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.32.0.tgz", + "integrity": "sha512-LSehfdpgMeWcTZkWZVIJl+tkZ2nuSkyyB9C27MZqFWXuph7DvaowgcTvKqxvpLW1JZIk8PN7hFY3Rj9LQ7m7lg==", "dev": true, "license": "MIT", "dependencies": { @@ -5699,8 +5699,8 @@ "@eslint/config-helpers": "^0.3.0", "@eslint/core": "^0.15.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.31.0", - "@eslint/plugin-kit": "^0.3.1", + "@eslint/js": "9.32.0", + "@eslint/plugin-kit": "^0.3.4", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -5820,19 +5820,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/core": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", - "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/espree": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", @@ -6359,14 +6346,15 @@ } }, "node_modules/form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -10382,12 +10370,12 @@ } }, "node_modules/soap": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/soap/-/soap-1.1.12.tgz", - "integrity": "sha512-bfgy09VAA2Pnv8I/qDpMvPFPV//eIGr/DOeaLx3uexpMrI+gq8Xuvp3KlTZYMhKFwjwgcLd+YpabFbOv82R5gQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/soap/-/soap-1.2.1.tgz", + "integrity": "sha512-QRkgCb8C99x1SxZ84jCJAd5VDFpp0MNL5O1X6vKtHp3Hba6UnN1Wdy0Lq+o1CmvBkxyxBYIW/Y+xPQLPq+Sv6g==", "license": "MIT", "dependencies": { - "axios": "^1.9.0", + "axios": "^1.11.0", "axios-ntlm": "^1.4.4", "debug": "^4.4.1", "formidable": "^3.5.4", @@ -10976,21 +10964,21 @@ "optional": true }, "node_modules/superagent": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.2.tgz", - "integrity": "sha512-vWMq11OwWCC84pQaFPzF/VO3BrjkCeewuvJgt1jfV0499Z1QSAWN4EqfMM5WlFDDX9/oP8JjlDKpblrmEoyu4Q==", + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.3.tgz", + "integrity": "sha512-y/hkYGeXAj7wUMjxRbB21g/l6aAEituGXM9Rwl4o20+SX3e8YOSV6BxFXl+dL3Uk0mjSL3kCbNkwURm8/gEDig==", "dev": true, "license": "MIT", "dependencies": { - "component-emitter": "^1.3.0", + "component-emitter": "^1.3.1", "cookiejar": "^2.1.4", - "debug": "^4.3.4", + "debug": "^4.3.7", "fast-safe-stringify": "^2.1.1", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "formidable": "^3.5.4", "methods": "^1.1.2", "mime": "2.6.0", - "qs": "^6.11.0" + "qs": "^6.11.2" }, "engines": { "node": ">=14.18.0" @@ -11010,14 +10998,14 @@ } }, "node_modules/supertest": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.3.tgz", - "integrity": "sha512-ORY0gPa6ojmg/C74P/bDoS21WL6FMXq5I8mawkEz30/zkwdu0gOeqstFy316vHG6OKxqQ+IbGneRemHI8WraEw==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.4.tgz", + "integrity": "sha512-tjLPs7dVyqgItVFirHYqe2T+MfWc2VOBQ8QFKKbWTA3PU7liZR8zoSpAi/C1k1ilm9RsXIKYf197oap9wXGVYg==", "dev": true, "license": "MIT", "dependencies": { "methods": "^1.1.2", - "superagent": "^10.2.2" + "superagent": "^10.2.3" }, "engines": { "node": ">=14.18.0" @@ -11292,12 +11280,12 @@ "license": "Unlicense" }, "node_modules/twilio": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.7.3.tgz", - "integrity": "sha512-RuCjbQRLorFZrqd52KZ4JzeUbCbs/3KJVdawcAQ2yR53S2D0VwBQ+1Pkcnc20Y8QLKCP41TkQ98MHbF7upRhtA==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/twilio/-/twilio-5.8.0.tgz", + "integrity": "sha512-aJLBvI7ODLmFHI7ZYLBiMZKIdHuF9PrPeRM/GBMDg/AAzGXs4V8gEnNPHyTVThK0/8J48YHSqXMlQ+WJR5nxoQ==", "license": "MIT", "dependencies": { - "axios": "^1.8.3", + "axios": "^1.11.0", "dayjs": "^1.11.9", "https-proxy-agent": "^5.0.0", "jsonwebtoken": "^9.0.2", diff --git a/package.json b/package.json index 9b038bcca..79fac7ece 100644 --- a/package.json +++ b/package.json @@ -16,29 +16,29 @@ "job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js" }, "dependencies": { - "@aws-sdk/client-cloudwatch-logs": "^3.849.0", - "@aws-sdk/client-elasticache": "^3.848.0", - "@aws-sdk/client-s3": "^3.848.0", - "@aws-sdk/client-secrets-manager": "^3.848.0", - "@aws-sdk/client-ses": "^3.848.0", - "@aws-sdk/credential-provider-node": "^3.848.0", - "@aws-sdk/lib-storage": "^3.848.0", - "@aws-sdk/s3-request-presigner": "^3.848.0", + "@aws-sdk/client-cloudwatch-logs": "^3.855.0", + "@aws-sdk/client-elasticache": "^3.855.0", + "@aws-sdk/client-s3": "^3.855.0", + "@aws-sdk/client-secrets-manager": "^3.855.0", + "@aws-sdk/client-ses": "^3.855.0", + "@aws-sdk/credential-provider-node": "^3.855.0", + "@aws-sdk/lib-storage": "^3.855.0", + "@aws-sdk/s3-request-presigner": "^3.855.0", "@opensearch-project/opensearch": "^2.13.0", "@socket.io/admin-ui": "^0.5.1", "@socket.io/redis-adapter": "^8.3.0", "archiver": "^7.0.1", "aws4": "^1.13.2", - "axios": "^1.10.0", + "axios": "^1.11.0", "better-queue": "^3.8.12", - "bullmq": "^5.56.5", + "bullmq": "^5.56.8", "chart.js": "^4.5.0", "cloudinary": "^2.7.0", "compression": "^1.8.1", "cookie-parser": "^1.4.7", "cors": "^2.8.5", "crisp-status-reporter": "^1.2.2", - "dd-trace": "^5.60.0", + "dd-trace": "^5.61.1", "dinero.js": "^1.9.1", "dotenv": "^16.4.5", "express": "^4.21.1", @@ -61,11 +61,11 @@ "recursive-diff": "^1.0.9", "rimraf": "^6.0.1", "skia-canvas": "^2.0.2", - "soap": "^1.1.12", + "soap": "^1.2.1", "socket.io": "^4.8.1", "socket.io-adapter": "^2.5.5", "ssh2-sftp-client": "^11.0.0", - "twilio": "^5.7.3", + "twilio": "^5.8.0", "uuid": "^11.1.0", "winston": "^3.17.0", "winston-cloudwatch": "^6.3.0", @@ -74,14 +74,14 @@ "yazl": "^3.3.1" }, "devDependencies": { - "@eslint/js": "^9.31.0", - "eslint": "^9.31.0", + "@eslint/js": "^9.32.0", + "eslint": "^9.32.0", "eslint-plugin-react": "^7.37.5", "globals": "^15.15.0", "mock-require": "^3.0.3", "p-limit": "^3.1.0", "prettier": "^3.6.2", - "supertest": "^7.1.3", + "supertest": "^7.1.4", "vitest": "^3.2.4" } } From 0ed41de95621b522312d6cd3163b7164ce5b2393 Mon Sep 17 00:00:00 2001 From: Dave Richer Date: Tue, 5 Aug 2025 16:04:07 -0400 Subject: [PATCH 32/98] feature/IO-3255-simplified-parts-management - Add Shop / Vendor Configuration --- .../parts-queue-card.component.jsx | 3 +- .../parts-business-info.component.jsx | 129 ++++++++++++++++++ .../parts-email-presets.component.jsx | 60 ++++++++ .../parts-locations.component.jsx | 63 +++++++++ .../parts-order-comments.component.jsx | 74 ++++++++++ .../parts-orders-comments.component.jsx | 61 +++++++++ ...arts-shop-info-email-presets.component.jsx | 70 ++++++++++ .../parts-shop-info-limited.component.jsx | 80 +++++++++++ .../parts-shop-info-locations.component.jsx | 48 +++++++ .../parts-shop-info.component.jsx | 79 +++++++++++ .../parts-shop-info.container.jsx | 71 ++++++++++ .../parts-shop-management.component.jsx | 56 ++++++++ .../simplified-parts-jobs-list.component.jsx | 12 +- .../parts-settings.page.component.jsx | 77 +++++++++++ .../simplified-parts.page.component.jsx | 9 ++ 15 files changed, 889 insertions(+), 3 deletions(-) create mode 100644 client/src/components/parts-shop-info/parts-business-info.component.jsx create mode 100644 client/src/components/parts-shop-info/parts-email-presets.component.jsx create mode 100644 client/src/components/parts-shop-info/parts-locations.component.jsx create mode 100644 client/src/components/parts-shop-info/parts-order-comments.component.jsx create mode 100644 client/src/components/parts-shop-info/parts-orders-comments.component.jsx create mode 100644 client/src/components/parts-shop-info/parts-shop-info-email-presets.component.jsx create mode 100644 client/src/components/parts-shop-info/parts-shop-info-limited.component.jsx create mode 100644 client/src/components/parts-shop-info/parts-shop-info-locations.component.jsx create mode 100644 client/src/components/parts-shop-info/parts-shop-info.component.jsx create mode 100644 client/src/components/parts-shop-info/parts-shop-info.container.jsx create mode 100644 client/src/components/parts-shop-info/parts-shop-management.component.jsx create mode 100644 client/src/pages/parts-settings/parts-settings.page.component.jsx diff --git a/client/src/components/parts-queue-card/parts-queue-card.component.jsx b/client/src/components/parts-queue-card/parts-queue-card.component.jsx index 3044c7e97..34c47bf77 100644 --- a/client/src/components/parts-queue-card/parts-queue-card.component.jsx +++ b/client/src/components/parts-queue-card/parts-queue-card.component.jsx @@ -1,9 +1,8 @@ import { useQuery } from "@apollo/client"; import { Card, Divider, Drawer, Grid } from "antd"; import queryString from "query-string"; -import React from "react"; import { useTranslation } from "react-i18next"; -import { Link, useNavigate, useLocation } from "react-router-dom"; +import { Link, useLocation, useNavigate } from "react-router-dom"; import { QUERY_PARTS_QUEUE_CARD_DETAILS } from "../../graphql/jobs.queries"; import AlertComponent from "../alert/alert.component"; import JobsDetailHeader from "../jobs-detail-header/jobs-detail-header.component"; diff --git a/client/src/components/parts-shop-info/parts-business-info.component.jsx b/client/src/components/parts-shop-info/parts-business-info.component.jsx new file mode 100644 index 000000000..ad119477d --- /dev/null +++ b/client/src/components/parts-shop-info/parts-business-info.component.jsx @@ -0,0 +1,129 @@ +import { Form, Input, InputNumber, Select } from "antd"; +import { useTranslation } from "react-i18next"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +import PhoneFormItem, { PhoneItemFormatterValidation } from "../form-items-formatted/phone-form-item.component"; +import LayoutFormRow from "../layout-form-row/layout-form-row.component"; + +// eslint-disable-next-line no-undef +const timeZonesList = Intl.supportedValuesOf("timeZone"); + +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop +}); + +const mapDispatchToProps = () => ({}); + +export function PartsBusinessInfoComponent({ form }) { + const { t } = useTranslation(); + + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + PhoneItemFormatterValidation(getFieldValue, "phone")]} + > + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +} + +export default connect(mapStateToProps, mapDispatchToProps)(PartsBusinessInfoComponent); diff --git a/client/src/components/parts-shop-info/parts-email-presets.component.jsx b/client/src/components/parts-shop-info/parts-email-presets.component.jsx new file mode 100644 index 000000000..449a35ac3 --- /dev/null +++ b/client/src/components/parts-shop-info/parts-email-presets.component.jsx @@ -0,0 +1,60 @@ +import { DeleteFilled } from "@ant-design/icons"; +import { Button, Form, Input, Select, Space } from "antd"; +import { useTranslation } from "react-i18next"; +import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component"; +import LayoutFormRow from "../layout-form-row/layout-form-row.component"; + +export default function PartsEmailPresetsComponent({ form }) { + const { t } = useTranslation(); + + return ( +
+ + + {(fields, { add, remove, move }) => { + return ( +
+ {fields.map((field, index) => ( + + + + + + + + + + { + remove(field.name); + }} + /> + + + + + ))} + + + +
+ ); + }} +
+
+
+ ); +} diff --git a/client/src/components/parts-shop-info/parts-order-comments.component.jsx b/client/src/components/parts-shop-info/parts-order-comments.component.jsx new file mode 100644 index 000000000..536f1a2e9 --- /dev/null +++ b/client/src/components/parts-shop-info/parts-order-comments.component.jsx @@ -0,0 +1,74 @@ +import { DeleteFilled } from "@ant-design/icons"; +import { Button, Form, Input, Space } from "antd"; +import { useTranslation } from "react-i18next"; +import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component"; +import LayoutFormRow from "../layout-form-row/layout-form-row.component"; + +export default function PartsOrderCommentsComponent({ form }) { + const { t } = useTranslation(); + + return ( +
+ + + {(fields, { add, remove, move }) => { + return ( +
+ {fields.map((field, index) => ( + + + + + + + + + + + { + remove(field.name); + }} + /> + + + + + ))} + + + +
+ ); + }} +
+
+
+ ); +} diff --git a/client/src/components/parts-shop-info/parts-orders-comments.component.jsx b/client/src/components/parts-shop-info/parts-orders-comments.component.jsx new file mode 100644 index 000000000..7815bca9b --- /dev/null +++ b/client/src/components/parts-shop-info/parts-orders-comments.component.jsx @@ -0,0 +1,61 @@ +import { Button, Card, Divider, Form, Input, Space } from "antd"; +import { DeleteOutlined, PlusOutlined } from "@ant-design/icons"; +import { useTranslation } from "react-i18next"; + +const { TextArea } = Input; + +export default function PartsOrdersCommentsComponent({ form }) { + const { t } = useTranslation(); + + return ( + + + {(fields, { add, remove }) => ( + <> + {fields.map(({ key, name, ...restField }) => ( + + + + + +