* Replace n x m array functions with maps * feat: add attributeIds filter to findManyByOrgMembershipIds Allow filtering attribute-to-user assignments by specific attribute IDs. This enables querying only the attributes needed for a routing rule instead of fetching all attributes for all team members. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: extract attribute IDs from routing rules and filter queries Add extractAttributeIdsFromQueryValue helper to parse routing rules and identify which attributes are referenced. Pass these IDs through getAttributesAssignmentData to _queryAllData to only fetch the attribute assignments that are actually needed for evaluation. For a team with 785 members and 14 attributes, if a routing rule only references 2-3 attributes, this reduces the query from ~3500 rows to ~500 rows. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: use attribute filtering in findTeamMembersMatchingAttributeLogic Extract attribute IDs from the routing rules (main + fallback) and pass them to getAttributesForLogic to only fetch necessary data. This completes the optimization to reduce database load when evaluating routing rules that only reference a subset of attributes. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: filter attributes query by attribute IDs Also filter the attributes query (not just attributeToUser assignments) by the attribute IDs referenced in routing rules. For a routing rule that references 2 out of 14 attributes with 6524 total options, this reduces: - Attributes fetched: 14 → 2 - Options fetched: 6524 → ~930 (proportional reduction) - Fewer regex replacements in replaceAttributeOptionIdsWithOptionLabel Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test: add comprehensive test coverage for attribute routing query optimization Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Revert "Replace n x m array functions with maps" This reverts commit 312eeb03bd1aba19760f093c798861a23b5fc66f. * fix: re-establish extractAttributeIdsFromQueryValue mock after resetAllMocks Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
63 lines
1.7 KiB
TypeScript
63 lines
1.7 KiB
TypeScript
import type { PrismaClient } from "@calcom/prisma";
|
|
import type { Prisma } from "@calcom/prisma/generated/prisma/client";
|
|
|
|
export class PrismaAttributeToUserRepository {
|
|
constructor(private prismaClient: PrismaClient) {}
|
|
|
|
async createManySkipDuplicates(data: Prisma.AttributeToUserCreateManyInput[]) {
|
|
return await this.prismaClient.attributeToUser.createMany({ data, skipDuplicates: true });
|
|
}
|
|
|
|
async deleteMany(where: Prisma.AttributeToUserWhereInput) {
|
|
if (Object.keys(where).length === 0) {
|
|
throw new Error("Empty where clause provided to deleteMany. Potential data loss risk.");
|
|
}
|
|
return await this.prismaClient.attributeToUser.deleteMany({ where });
|
|
}
|
|
|
|
async findManyIncludeAttribute(where: Prisma.AttributeToUserWhereInput) {
|
|
return await this.prismaClient.attributeToUser.findMany({
|
|
where,
|
|
include: {
|
|
attributeOption: {
|
|
select: {
|
|
attribute: true,
|
|
value: true,
|
|
slug: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
async findManyByOrgMembershipIds({
|
|
orgMembershipIds,
|
|
attributeIds,
|
|
}: {
|
|
orgMembershipIds: number[];
|
|
attributeIds?: string[];
|
|
}) {
|
|
if (!orgMembershipIds.length) {
|
|
return [];
|
|
}
|
|
|
|
const attributesAssignedToTeamMembers = await this.prismaClient.attributeToUser.findMany({
|
|
where: {
|
|
memberId: {
|
|
in: orgMembershipIds,
|
|
},
|
|
// Only filter by attribute IDs if provided
|
|
...(attributeIds?.length && {
|
|
attributeOption: {
|
|
attributeId: {
|
|
in: attributeIds,
|
|
},
|
|
},
|
|
}),
|
|
},
|
|
});
|
|
|
|
return attributesAssignedToTeamMembers;
|
|
}
|
|
}
|