Fix: Correct agent filtering to aggregate results for fields with identical slugs across different sections using OR logic.
This commit is contained in:
@@ -339,53 +339,60 @@ export class AgentsService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const slugToField = new Map(fields.map((f) => [f.slug, f]));
|
// Group fields by slug (same slug can exist in multiple type-specific sections)
|
||||||
|
const slugToFields = new Map<string, typeof fields>();
|
||||||
|
for (const f of fields) {
|
||||||
|
const existing = slugToFields.get(f.slug) || [];
|
||||||
|
existing.push(f);
|
||||||
|
slugToFields.set(f.slug, existing);
|
||||||
|
}
|
||||||
|
|
||||||
// For each filter, find agents that have ANY of the selected values
|
// For each filter, find agents that have ANY of the selected values
|
||||||
// Use AND logic between different fields
|
// Use AND logic between different filter slugs, OR logic within same slug
|
||||||
const filterConditions: string[][] = [];
|
const filterConditions: string[][] = [];
|
||||||
|
|
||||||
for (const [slug, selectedValues] of Object.entries(parsedFilters)) {
|
for (const [slug, selectedValues] of Object.entries(parsedFilters)) {
|
||||||
const field = slugToField.get(slug);
|
const slugFields = slugToFields.get(slug);
|
||||||
if (!field || !selectedValues || selectedValues.length === 0) continue;
|
if (!slugFields || slugFields.length === 0 || !selectedValues || selectedValues.length === 0) continue;
|
||||||
|
|
||||||
// Build set of agent type IDs that have access to this field's section
|
// Search across ALL fields with this slug (e.g. loan_type in both Professional and Lender sections)
|
||||||
const isGlobal = field.section.isGlobal;
|
const allMatchingAgentIds: string[] = [];
|
||||||
const allowedAgentTypeIds = new Set(
|
|
||||||
field.section.agentTypeSections.map((ats) => ats.agentTypeId),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Find agentProfileIds where jsonValue contains ANY of the selected values
|
for (const field of slugFields) {
|
||||||
const matchingValues = await this.prisma.agentProfileFieldValue.findMany({
|
const isGlobal = field.section.isGlobal;
|
||||||
where: { fieldId: field.id },
|
const allowedAgentTypeIds = new Set(
|
||||||
select: {
|
field.section.agentTypeSections.map((ats) => ats.agentTypeId),
|
||||||
agentProfileId: true,
|
);
|
||||||
jsonValue: true,
|
|
||||||
agentProfile: {
|
const matchingValues = await this.prisma.agentProfileFieldValue.findMany({
|
||||||
select: { agentTypeId: true },
|
where: { fieldId: field.id },
|
||||||
|
select: {
|
||||||
|
agentProfileId: true,
|
||||||
|
jsonValue: true,
|
||||||
|
agentProfile: {
|
||||||
|
select: { agentTypeId: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Filter in memory:
|
const matchingIds = matchingValues
|
||||||
// 1. Check if jsonValue array contains any selected value
|
.filter((fv) => {
|
||||||
// 2. Check if the agent's type has access to this field's section
|
const jsonVal = fv.jsonValue as string[] | null;
|
||||||
const matchingAgentIds = matchingValues
|
if (!jsonVal || !Array.isArray(jsonVal)) return false;
|
||||||
.filter((fv) => {
|
if (!selectedValues.some((sv) => jsonVal.includes(sv))) return false;
|
||||||
const jsonVal = fv.jsonValue as string[] | null;
|
|
||||||
if (!jsonVal || !Array.isArray(jsonVal)) return false;
|
|
||||||
if (!selectedValues.some((sv) => jsonVal.includes(sv))) return false;
|
|
||||||
|
|
||||||
// Validate that this agent's type has access to the field's section
|
const agentTypeId = fv.agentProfile.agentTypeId;
|
||||||
const agentTypeId = fv.agentProfile.agentTypeId;
|
if (!isGlobal && (!agentTypeId || !allowedAgentTypeIds.has(agentTypeId))) {
|
||||||
if (!isGlobal && (!agentTypeId || !allowedAgentTypeIds.has(agentTypeId))) {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
return true;
|
||||||
return true;
|
})
|
||||||
})
|
.map((fv) => fv.agentProfileId);
|
||||||
.map((fv) => fv.agentProfileId);
|
|
||||||
|
|
||||||
filterConditions.push(matchingAgentIds);
|
allMatchingAgentIds.push(...matchingIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
filterConditions.push([...new Set(allMatchingAgentIds)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AND all filter conditions - find intersection of all matching agent IDs
|
// AND all filter conditions - find intersection of all matching agent IDs
|
||||||
|
|||||||
Reference in New Issue
Block a user