feat: add CW members, opportunity create/update, and integrator interceptor

This commit is contained in:
2026-03-07 18:15:17 -06:00
parent 0ce1eda606
commit c0a4d4f919
27 changed files with 2504 additions and 16 deletions
+77
View File
@@ -0,0 +1,77 @@
import { prisma } from "../constants";
import { CwMemberController } from "../controllers/CwMemberController";
import GenericError from "../Errors/GenericError";
/**
* CW Members Manager
*
* Thin persistence layer wrapping Prisma calls for the CwMember model.
* Returns CwMemberController instances as domain objects.
*/
export const cwMembers = {
/**
* Fetch a single CW member by internal ID, CW member ID, or identifier.
*/
fetch: async (idOrIdentifier: string): Promise<CwMemberController> => {
const isNumeric = /^\d+$/.test(idOrIdentifier);
const record = await prisma.cwMember.findFirst({
where: isNumeric
? { cwMemberId: Number(idOrIdentifier) }
: {
OR: [{ id: idOrIdentifier }, { identifier: idOrIdentifier }],
},
});
if (!record) {
throw new GenericError({
status: 404,
name: "CwMemberNotFound",
message: `CW Member "${idOrIdentifier}" not found`,
});
}
return new CwMemberController(record);
},
/**
* Fetch all CW members with optional filtering.
*/
fetchAll: async (opts?: {
includeInactive?: boolean;
}): Promise<CwMemberController[]> => {
const where = opts?.includeInactive ? {} : { inactiveFlag: false };
const records = await prisma.cwMember.findMany({
where,
orderBy: { lastName: "asc" },
});
return records.map((r) => new CwMemberController(r));
},
/**
* Count CW members.
*/
count: async (opts?: { includeInactive?: boolean }): Promise<number> => {
const where = opts?.includeInactive ? {} : { inactiveFlag: false };
return prisma.cwMember.count({ where });
},
/**
* Update the API key for a CW member.
*/
updateApiKey: async (
idOrIdentifier: string,
apiKey: string | null,
): Promise<CwMemberController> => {
const member = await cwMembers.fetch(idOrIdentifier);
const updated = await prisma.cwMember.update({
where: { id: member.id },
data: { apiKey },
});
return new CwMemberController(updated);
},
};