/** * Identity Resolution Service * * Handles identity resolution (lookup) between local and remote instances. * Optimized for read-heavy operations. */ import { Injectable, Logger } from "@nestjs/common"; import { IdentityLinkingService } from "./identity-linking.service"; import type { IdentityResolutionResponse, BulkIdentityResolutionResponse, } from "./types/identity-linking.types"; @Injectable() export class IdentityResolutionService { private readonly logger = new Logger(IdentityResolutionService.name); constructor(private readonly identityLinkingService: IdentityLinkingService) {} /** * Resolve a remote user to a local user * * Looks up the identity mapping by remote instance and user ID. */ async resolveIdentity( remoteInstanceId: string, remoteUserId: string ): Promise { this.logger.debug(`Resolving identity: ${remoteUserId}@${remoteInstanceId}`); const identity = await this.identityLinkingService.resolveLocalIdentity( remoteInstanceId, remoteUserId ); if (!identity) { return { found: false, remoteUserId, remoteInstanceId, }; } return { found: true, localUserId: identity.localUserId, remoteUserId: identity.remoteUserId, remoteInstanceId: identity.remoteInstanceId, email: identity.email, metadata: identity.metadata, }; } /** * Reverse resolve a local user to a remote identity * * Looks up the identity mapping by local user ID and remote instance. */ async reverseResolveIdentity( localUserId: string, remoteInstanceId: string ): Promise { this.logger.debug(`Reverse resolving identity: ${localUserId}@${remoteInstanceId}`); const identity = await this.identityLinkingService.resolveRemoteIdentity( localUserId, remoteInstanceId ); if (!identity) { return { found: false, localUserId, remoteInstanceId, }; } return { found: true, localUserId: identity.localUserId, remoteUserId: identity.remoteUserId, remoteInstanceId: identity.remoteInstanceId, email: identity.email, metadata: identity.metadata, }; } /** * Bulk resolve multiple remote users to local users * * Efficient batch operation for resolving many identities at once. * Useful for aggregated dashboard views and multi-user operations. */ async bulkResolveIdentities( remoteInstanceId: string, remoteUserIds: string[] ): Promise { this.logger.debug( `Bulk resolving ${remoteUserIds.length.toString()} identities for ${remoteInstanceId}` ); if (remoteUserIds.length === 0) { return { mappings: {}, notFound: [], }; } const mappings: Record = {}; const notFound: string[] = []; // Resolve each identity // TODO: Optimize with a single database query using IN clause for (const remoteUserId of remoteUserIds) { const identity = await this.identityLinkingService.resolveLocalIdentity( remoteInstanceId, remoteUserId ); if (identity) { mappings[remoteUserId] = identity.localUserId; } else { notFound.push(remoteUserId); } } this.logger.debug( `Bulk resolution complete: ${Object.keys(mappings).length.toString()} found, ${notFound.length.toString()} not found` ); return { mappings, notFound, }; } }