feature/IO-3255-simplified-parts-management Deprovision route can now remove jobs, joblines, and audit trail
This commit is contained in:
@@ -1,71 +1,20 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
`;
|
||||
const {
|
||||
DELETE_SHOP,
|
||||
DELETE_VENDORS_BY_SHOP,
|
||||
GET_BODYSHOP,
|
||||
GET_ASSOCIATED_USERS,
|
||||
DELETE_ASSOCIATIONS_BY_SHOP,
|
||||
GET_USER_ASSOCIATIONS_COUNT,
|
||||
DELETE_USER,
|
||||
GET_VENDORS,
|
||||
GET_JOBS_BY_SHOP,
|
||||
DELETE_JOBLINES_BY_JOB_IDS,
|
||||
DELETE_JOBS_BY_IDS,
|
||||
DELETE_AUDIT_TRAIL_BY_SHOP
|
||||
} = require("../partsManagement.queries");
|
||||
|
||||
/**
|
||||
* Deletes a Firebase user by UID.
|
||||
@@ -94,6 +43,38 @@ const deleteBodyshop = async (shopId) => {
|
||||
await client.request(DELETE_SHOP, { id: shopId });
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch job ids for a given shop
|
||||
* @param shopId
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
const getJobIdsForShop = async (shopId) => {
|
||||
const resp = await client.request(GET_JOBS_BY_SHOP, { shopId });
|
||||
return resp.jobs.map((j) => j.id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete joblines for the given job ids
|
||||
* @param jobIds {string[]}
|
||||
* @returns {Promise<number>} affected rows
|
||||
*/
|
||||
const deleteJoblinesForJobs = async (jobIds) => {
|
||||
if (!jobIds.length) return 0;
|
||||
const resp = await client.request(DELETE_JOBLINES_BY_JOB_IDS, { jobIds });
|
||||
return resp.delete_joblines.affected_rows;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete jobs for the given job ids
|
||||
* @param jobIds {string[]}
|
||||
* @returns {Promise<number>} affected rows
|
||||
*/
|
||||
const deleteJobsByIds = async (jobIds) => {
|
||||
if (!jobIds.length) return 0;
|
||||
const resp = await client.request(DELETE_JOBS_BY_IDS, { jobIds });
|
||||
return resp.delete_jobs.affected_rows;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles deprovisioning a shop for parts management.
|
||||
* @param req
|
||||
@@ -156,6 +137,15 @@ const partsManagementDeprovisioning = async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
// Get all job ids for this shop, then delete joblines and jobs (joblines first)
|
||||
const jobIds = await getJobIdsForShop(p.shopId);
|
||||
const joblinesDeleted = await deleteJoblinesForJobs(jobIds);
|
||||
const jobsDeleted = await deleteJobsByIds(jobIds);
|
||||
|
||||
// Delete any audit trail entries tied to this bodyshop to avoid FK violations
|
||||
const auditResp = await client.request(DELETE_AUDIT_TRAIL_BY_SHOP, { shopId: p.shopId });
|
||||
const auditDeleted = auditResp.delete_audit_trail.affected_rows;
|
||||
|
||||
// Delete vendors
|
||||
await deleteVendorsByShop(p.shopId);
|
||||
|
||||
@@ -163,16 +153,26 @@ const partsManagementDeprovisioning = async (req, res) => {
|
||||
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"}).`
|
||||
);
|
||||
logger.log("admin-delete-shop-summary", "info", null, null, {
|
||||
shopId: p.shopId,
|
||||
shopname: shop.shopname,
|
||||
associationsDeleted,
|
||||
deletedUsers,
|
||||
deletedVendors,
|
||||
joblinesDeleted,
|
||||
jobsDeleted,
|
||||
auditDeleted
|
||||
});
|
||||
|
||||
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
|
||||
deletedVendors: deletedVendors,
|
||||
deletedJoblinesCount: joblinesDeleted,
|
||||
deletedJobsCount: jobsDeleted,
|
||||
deletedAuditTrailCount: auditDeleted
|
||||
});
|
||||
} catch (err) {
|
||||
logger.log("admin-delete-shop-error", "error", null, null, {
|
||||
|
||||
@@ -126,7 +126,7 @@ const CREATE_SHOP = `
|
||||
|
||||
const DELETE_VENDORS_BY_SHOP = `
|
||||
mutation DELETE_VENDORS($shopId: uuid!) {
|
||||
delete_vendors(where: { shopid: { _eq: $shopId } }) {
|
||||
delete_vendors(where: { bodyshopid: { _eq: $shopId } }) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
@@ -147,6 +147,92 @@ const CREATE_USER = `
|
||||
}
|
||||
`;
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const GET_JOBS_BY_SHOP = `
|
||||
query GetJobsByShop($shopId: uuid!) {
|
||||
jobs(where: {shopid: {_eq: $shopId}}) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const DELETE_JOBLINES_BY_JOB_IDS = `
|
||||
mutation DeleteJoblinesByJobIds($jobIds: [uuid!]!) {
|
||||
delete_joblines(where: {jobid: {_in: $jobIds}}) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const DELETE_JOBS_BY_IDS = `
|
||||
mutation DeleteJobsByIds($jobIds: [uuid!]!) {
|
||||
delete_jobs(where: {id: {_in: $jobIds}}) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const DELETE_AUDIT_TRAIL_BY_SHOP = `
|
||||
mutation DeleteAuditTrailByShop($shopId: uuid!) {
|
||||
delete_audit_trail(where: {bodyshopid: {_eq: $shopId}}) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
module.exports = {
|
||||
GET_BODYSHOP_STATUS,
|
||||
GET_VEHICLE_BY_SHOP_VIN,
|
||||
@@ -162,5 +248,15 @@ module.exports = {
|
||||
CREATE_SHOP,
|
||||
DELETE_VENDORS_BY_SHOP,
|
||||
DELETE_SHOP,
|
||||
CREATE_USER
|
||||
CREATE_USER,
|
||||
GET_BODYSHOP,
|
||||
GET_ASSOCIATED_USERS,
|
||||
DELETE_ASSOCIATIONS_BY_SHOP,
|
||||
GET_USER_ASSOCIATIONS_COUNT,
|
||||
DELETE_USER,
|
||||
GET_VENDORS,
|
||||
GET_JOBS_BY_SHOP,
|
||||
DELETE_JOBLINES_BY_JOB_IDS,
|
||||
DELETE_JOBS_BY_IDS,
|
||||
DELETE_AUDIT_TRAIL_BY_SHOP
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user