Source

utils/investigation-response.utils.js

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 = [];
    }
}