Lots of updates and cleaning up.

This commit is contained in:
2026-02-14 12:08:23 -06:00
parent 7466bbdeac
commit 3ab443790c
17 changed files with 484 additions and 52 deletions
@@ -0,0 +1,30 @@
import { connectWiseApi } from "../../constants";
import { ConfigurationResponse } from "../../types/ConnectWiseTypes";
import {
processConfigurationResponse,
ProcessedConfiguration,
} from "./processConfigurationResponse";
import GenericError from "../../Errors/GenericError";
export const fetchCompanyConfigurations = async (
cwCompanyId: number,
): Promise<ProcessedConfiguration> => {
try {
const response = await connectWiseApi.get(
`/company/configurations?conditions=company/id=${cwCompanyId}`,
);
return processConfigurationResponse(response.data);
} catch (error) {
const errBody = (error as any).response?.data || error;
console.error(
`Error fetching configurations for company ID ${cwCompanyId}:`,
errBody,
);
throw new GenericError({
name: "FetchCompanyConfigurationsError",
message: `Failed to fetch configurations for company ${cwCompanyId}`,
cause: typeof errBody === "string" ? errBody : JSON.stringify(errBody),
status: 502,
});
}
};
@@ -0,0 +1,22 @@
import { ConfigurationResponse } from "../../types/ConnectWiseTypes";
export type ProcessedConfiguration = ReturnType<
typeof processConfigurationResponse
>;
export const processConfigurationResponse = (c: ConfigurationResponse) => {
return c.map((item) => ({
id: item.id,
name: item.name,
active: item.activeFlag,
serialNumber: item.serialNumber,
type: item.type,
questions: item.questions.map((q) => ({
id: q.questionId,
question: q.question,
answer: q.answer,
fieldType: q.fieldType,
})),
info: item._info,
}));
};
+27 -20
View File
@@ -3,7 +3,7 @@ import { events } from "../globalEvents";
import { fetchAllCwCompanies } from "./fetchAllCompanies";
export const refreshCompanies = async () => {
events.emit("cw:companies:refreshed:check");
events.emit("cw:companies:refresh:check");
// Dynamically import to avoid circular dependency
const internalCompanyCount = await prisma.company.count();
@@ -11,28 +11,35 @@ export const refreshCompanies = async () => {
(await connectWiseApi.get("/company/companies/count")).data.count - 1;
if (internalCompanyCount !== externalCompanyCount) {
console.log(
`Company count mismatch detected. Internal: ${internalCompanyCount}, External: ${externalCompanyCount}. Refreshing...`,
);
events.emit("cw:companies:refresh:started");
const allCompanies = await fetchAllCwCompanies();
await Promise.all(
allCompanies.map(async (company) => {
return await prisma.company.upsert({
where: { cw_CompanyId: company.id },
create: {
cw_CompanyId: company.id,
cw_Identifier: company.identifier,
name: company.name,
},
update: {
name: company.name,
},
});
}),
);
events.emit("cw:companies:refreshed", {
const updatedCount = (
await Promise.all(
allCompanies.map(async (company) => {
return await prisma.company.upsert({
where: { cw_CompanyId: company.id },
create: {
cw_CompanyId: company.id,
cw_Identifier: company.identifier,
name: company.name,
},
update: {
name: company.name,
},
});
}),
)
).length;
events.emit("cw:companies:refresh:completed", {
internalCompaniesCount: internalCompanyCount,
externalCompaniesCount: externalCompanyCount,
companiesUpdated: updatedCount,
});
} else {
events.emit("cw:companies:refresh:skipped", {
internalCompaniesCount: internalCompanyCount,
externalCompaniesCount: externalCompanyCount,
});
+54 -5
View File
@@ -5,11 +5,15 @@ import {
SessionTokensObject,
} from "../controllers/SessionController";
import { RoleController } from "../controllers/RoleController";
import { CompanyController } from "../controllers/CompanyController";
import { JsonWebTokenError } from "jsonwebtoken";
import { User } from "../../generated/prisma/client";
import { User, Company } from "../../generated/prisma/client";
interface EventTypes {
// API Lifecycle
"api:started": () => void;
// User Events
"user:created": (user: UserController) => void;
"user:updated": (data: {
user: UserController;
@@ -19,6 +23,16 @@ interface EventTypes {
user: UserController;
tokens: SessionTokensObject;
}) => void;
"user:role:assigned": (data: {
user: UserController;
role: RoleController;
}) => void;
"user:role:removed": (data: {
user: UserController;
role: RoleController;
}) => void;
// Session Events
"session:created": (data: {
user: UserController;
session: SessionController;
@@ -33,18 +47,33 @@ interface EventTypes {
}) => void;
"session:invalidated": (session: SessionController) => void;
"session:terminated": (session: SessionController) => void;
// Role Events
"role:created": (role: RoleController) => void;
"role:deleted": (role: RoleController) => void;
"role:updated": (data: {
role: RoleController;
updateData: Parameters<typeof RoleController.prototype.update>["0"];
}) => void;
"role:permissions:updated": (data: {
"role:permissions:set": (data: {
previous: string[];
previousSigned: string;
current: string[];
currentSigned: string;
action: "set" | "added" | "removed";
role: RoleController;
}) => void;
"role:permissions:added": (data: {
previous: string[];
previousSigned: string;
added: string[];
currentSigned: string;
role: RoleController;
}) => void;
"role:permissions:removed": (data: {
previous: string[];
previousSigned: string;
removed: string[];
currentSigned: string;
role: RoleController;
}) => void;
"role:permissions:verification_error": (data: {
@@ -53,10 +82,30 @@ interface EventTypes {
err: Error;
role: RoleController;
}) => void;
"cw:companies:refreshed:check": () => void;
"cw:companies:refreshed": (data: {
// Company Events
"company:fetched": (company: CompanyController) => void;
"company:refreshed_from_cw": (company: CompanyController) => void;
"company:configurations_fetched": (data: {
company: CompanyController;
configurationCount: number;
}) => void;
// ConnectWise Integration Events
"cw:companies:refresh:check": () => void;
"cw:companies:refresh:started": () => void;
"cw:companies:refresh:completed": (data: {
internalCompaniesCount: number;
externalCompaniesCount: number;
companiesUpdated: number;
}) => void;
"cw:companies:refresh:skipped": (data: {
internalCompaniesCount: number;
externalCompaniesCount: number;
}) => void;
"cw:company:data:updated": (data: {
company: CompanyController;
updatedFields: Partial<Company>;
}) => void;
}