All files / src/domains/hr/organization team.service.ts

0% Statements 0/44
0% Branches 0/27
0% Functions 0/10
0% Lines 0/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                                                                                                                                                                                                                                       
import {
  Injectable,
  NotFoundException,
  ConflictException,
} from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Team, TeamMembership } from './schemas/team.schema';
import { AuditLogService } from '../../../platform/audit/audit-log.service';
import { EventBusService } from '../../../platform/events/event-bus.service';
 
@Injectable()
export class TeamService {
  constructor(
    @InjectModel(Team.name) private readonly teamModel: Model<Team>,
    @InjectModel(TeamMembership.name)
    private readonly membershipModel: Model<TeamMembership>,
    private readonly auditLog: AuditLogService,
    private readonly eventBus: EventBusService,
  ) {}
 
  async create(tenantId: string, data: any, userId: string) {
    const existing = await this.teamModel
      .findOne({ tenantId, teamCode: data.teamCode })
      .exec();
    if (existing)
      throw new ConflictException(`Team code ${data.teamCode} already exists.`);
    const team = await this.teamModel.create({
      ...data,
      tenantId,
      createdBy: userId,
    });
    await this.auditLog.log({
      tenantId,
      userId,
      action: 'CREATE',
      resource: 'Team',
      resourceId: team.id,
      newValues: data,
      moduleName: 'HR',
    });
    await this.eventBus.publish(
      'hr.team.created.v1',
      { tenantId, teamId: team.id },
      tenantId,
    );
    return team;
  }
 
  async findAll(tenantId: string) {
    return this.teamModel
      .find({ tenantId, deletedAt: null })
      .sort({ teamName: 1 })
      .lean()
      .exec();
  }
 
  async findOne(tenantId: string, id: string) {
    const team = await this.teamModel
      .findOne({ tenantId, _id: id, deletedAt: null })
      .lean()
      .exec();
    if (!team) throw new NotFoundException('Team not found');
    return team;
  }
 
  async update(tenantId: string, id: string, data: any, userId: string) {
    const team = await this.teamModel
      .findOne({ tenantId, _id: id, deletedAt: null })
      .exec();
    if (!team) throw new NotFoundException('Team not found');
    Object.assign(team, data, { updatedBy: userId });
    await team.save();
    return team;
  }
 
  async addMember(
    tenantId: string,
    teamId: string,
    employeeId: string,
    role: string = 'Member',
  ) {
    const existing = await this.membershipModel
      .findOne({ tenantId, teamId, employeeId })
      .exec();
    if (existing)
      throw new ConflictException('Employee is already a member of this team.');
    return this.membershipModel.create({ tenantId, teamId, employeeId, role });
  }
 
  async removeMember(tenantId: string, teamId: string, employeeId: string) {
    const result = await this.membershipModel
      .deleteOne({ tenantId, teamId, employeeId })
      .exec();
    if (result.deletedCount === 0)
      throw new NotFoundException('Membership not found');
    return { success: true };
  }
 
  async getMembers(tenantId: string, teamId: string) {
    return this.membershipModel.find({ tenantId, teamId }).lean().exec();
  }
 
  async getEmployeeTeams(tenantId: string, employeeId: string) {
    const memberships = await this.membershipModel
      .find({ tenantId, employeeId })
      .lean()
      .exec();
    const teamIds = memberships.map((m: any) => m.teamId);
    return this.teamModel
      .find({ tenantId, _id: { $in: teamIds } })
      .lean()
      .exec();
  }
}