Untitled
unknown
plain_text
3 months ago
3.6 kB
7
Indexable
import { Injectable } from '@nestjs/common';
import {
EmployeeProfile,
EmployeeProfileFields,
NestedProjection,
Projection,
} from './type/employee.types';
import { RSuiteLoggerService } from '@rooster-cluck-cluck/rooster-suite';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';
type EmployeeProfileDbRecord = Omit<EmployeeProfile, 'accountId'> & {
accountId: number;
};
@Injectable()
export class EmployeeService {
/**
* An array of allowed fields that can be included in the employee profile projection.
*
* This property defines the fields that can be requested when fetching an employee's
* profile, either as flat fields or as nested objects. The fields included are:
*
**/
private allowedFields: (EmployeeProfileFields | NestedProjection)[] = [
'_id',
'companyId',
'workEmail',
{ accountDetails: ['firstName', 'lastName', 'profileUrl'] },
];
constructor(
@InjectConnection() private readonly _connection: Connection,
private readonly _rSuiteLoggerService: RSuiteLoggerService,
) {}
private constructMongoProjection(
fields: (EmployeeProfileFields | NestedProjection)[],
parentKey = '',
): Record<string, 1> {
const projection: Record<string, 1> = {};
for (const field of fields) {
if (typeof field === 'string') {
projection[parentKey ? `${parentKey}.${field}` : field] = 1;
continue;
}
for (const [key, nestedFields] of Object.entries(field)) {
const nestedProjection = this.constructMongoProjection(
nestedFields as (EmployeeProfileFields | NestedProjection)[],
parentKey ? `${parentKey}.${key}` : key,
);
Object.assign(projection, nestedProjection);
}
}
return projection;
}
/**
* Retrieves the profile of an employee by their account ID.
*
* @param projection - An optional object specifying which fields to include in the response.
* @param employeeId - The ID of the employee whose profile is to be retrieved.
* @param token - An optional authorization token for the request.
*
* @returns A Promise that resolves to the EmployeeProfile object.
*
* @throws Error if the request to fetch the employee profile fails.
*/
public async getEmployeeProfile(
projection?: Projection,
employeeId?: number,
token?: string,
): Promise<EmployeeProfile> {
this._rSuiteLoggerService.trace('Starting employee service methods: %o', {
user: employeeId,
});
const projectionFields = this.constructMongoProjection(
projection?.fields || this.allowedFields,
);
try {
this._rSuiteLoggerService.trace(
'Starting mongo method for get employee details: %o',
{
user: employeeId,
},
);
if (!employeeId) {
throw new Error('Employee id is required');
}
const response = (await this._connection
.collection<EmployeeProfileDbRecord>('EmployeeProfile')
.findOne(
{ accountId: employeeId },
{ projection: projectionFields },
)) as unknown as EmployeeProfile;
this._rSuiteLoggerService.info('Employee details get successfully: %o', {
user: employeeId,
});
return response;
} catch (error) {
throw new Error(
`Error fetching employee profile: ${
error instanceof Error ? error.message : String(error)
}`,
);
}
}
}
Editor is loading...
Leave a Comment