import { batchFetchUserProfiles } from "./user-profile.utils";
/**
* Enriches an investigation response DTO with detailed author and editor profile information.
*
* Fetches user profiles from the Auth gRPC service using batch fetch and populates
* the `metadata.author` and `metadata.editorsDetailed` fields with user details such as
* name, email, and avatar.
* @category Utils
* @param {IInvestigation} investigation - The investigation object containing metadata.
* @param {IInvestigationResponseDto} dto - The investigation response DTO to enrich.
* @param {AuthGrpcService} grpcClient - The Auth gRPC client used to fetch user profiles.
* @returns {Promise<void>} - Enriches the `dto` object in-place.
*/
export async function enrichInvestigationResponse(investigation, dto, grpcClient) {
const metadata = dto.metadata;
const authorId = investigation.metadata?.author?.toString() ?? metadata.author?.id ?? null;
const editorIds = Array.isArray(investigation.metadata?.editors)
? investigation.metadata.editors
.map((id) => id?.toString())
.filter((id) => Boolean(id))
: [];
// Collect all user IDs for batch fetch
const allUserIds = [...(authorId ? [authorId] : []), ...editorIds];
// Batch fetch all profiles in a single gRPC call
const profilesMap = allUserIds.length > 0
? await batchFetchUserProfiles(allUserIds, grpcClient)
: new Map();
// Populate author
if (authorId) {
const profile = profilesMap.get(authorId);
metadata.author = {
id: authorId,
name: profile?.name ?? null,
email: profile?.email ?? null,
avatar: profile?.avatar ?? null,
};
}
else {
metadata.author = {
id: null,
name: null,
email: null,
avatar: null,
};
}
// Populate editors
if (editorIds.length > 0) {
metadata.editorsDetailed = editorIds.map((id) => {
const profile = profilesMap.get(id);
return {
id,
name: profile?.name ?? null,
email: profile?.email ?? null,
avatar: profile?.avatar ?? null,
};
});
}
else {
metadata.editorsDetailed = [];
}
}
Source