• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

khu-khlug / sight-backend / 14190117854

01 Apr 2025 07:47AM UTC coverage: 51.423%. Remained the same
14190117854

push

github

web-flow
refactor: 메시지 전송 클래스 구현을 위해 기존 클래스 및 파일 이름 변경 (#115)

796 of 2513 branches covered (31.68%)

Branch coverage included in aggregate %.

29 of 34 new or added lines in 18 files covered. (85.29%)

36 existing lines in 6 files now uncovered.

2222 of 3356 relevant lines covered (66.21%)

13.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.78
/src/app/application/group/command/disablePortfolio/DisablePortfolioCommandHandler.ts
1
import {
2
  ForbiddenException,
1✔
3
  Inject,
4
  NotFoundException,
5
  UnprocessableEntityException,
1✔
6
} from '@nestjs/common';
7
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
8

14✔
9
import { MessageBuilder } from '@khlug/core/message/MessageBuilder';
10
import { Transactional } from '@khlug/core/persistence/transaction/Transactional';
11

1✔
12
import { DisablePortfolioCommand } from '@khlug/app/application/group/command/disablePortfolio/DisablePortfolioCommand';
1✔
13

1✔
14
import { INotifier, NotifierToken } from '@khlug/app/domain/adapter/INotifier';
1✔
15
import {
1✔
16
  GroupLogger,
1✔
17
  IGroupLogger,
1✔
18
} from '@khlug/app/domain/group/IGroupLogger';
1✔
19
import {
1✔
20
  GroupMemberRepository,
1✔
21
  IGroupMemberRepository,
1✔
22
} from '@khlug/app/domain/group/IGroupMemberRepository';
1✔
23
import {
1✔
24
  GroupRepository,
1✔
25
  IGroupRepository,
26
} from '@khlug/app/domain/group/IGroupRepository';
35!
UNCOV
27
import { Group } from '@khlug/app/domain/group/model/Group';
×
28
import { NotificationCategory } from '@khlug/constant/notification';
29
import { PointGrantService } from '@khlug/app/domain/user/service/PointGrantService';
30

31
import { Message } from '@khlug/constant/error';
32
import { Point } from '@khlug/constant/point';
33
import { Template } from '@khlug/constant/template';
34

35✔
35
@CommandHandler(DisablePortfolioCommand)
36
export class DisablePortfolioCommandHandler
35✔
37
  implements ICommandHandler<DisablePortfolioCommand>
38
{
39
  constructor(
2!
40
    private readonly pointGrantService: PointGrantService,
2!
UNCOV
41
    @Inject(GroupRepository)
×
42
    private readonly groupRepository: IGroupRepository,
2✔
43
    @Inject(GroupMemberRepository)
44
    private readonly groupMemberRepository: IGroupMemberRepository,
45
    @Inject(GroupLogger)
5!
46
    private readonly groupLogger: IGroupLogger,
47
    @Inject(NotifierToken)
48
    private readonly slackSender: INotifier,
4✔
49
  ) {}
4✔
50

51
  @Transactional()
52
  async execute(command: DisablePortfolioCommand): Promise<void> {
53
    const { groupId, requesterUserId } = command;
54

7✔
55
    const group = await this.groupRepository.findById(groupId);
7✔
56
    if (!group) {
7✔
57
      throw new NotFoundException(Message.GROUP_NOT_FOUND);
2✔
58
    }
59

5✔
60
    this.checkGroupAdmin(group, requesterUserId);
4✔
61
    this.checkNotCustomerServiceGroup(group);
4✔
62

4✔
63
    group.disablePortfolio();
4✔
64
    await this.groupRepository.save(group);
4✔
65

4✔
66
    await this.groupLogger.log(groupId, '포트폴리오 발행이 중단되었습니다.');
67
    await this.collectPointFromMembers(group);
68
    this.sendMessageToAdminUser(group);
5✔
69
  }
1✔
70

71
  private checkGroupAdmin(group: Group, requesterUserId: number): void {
72
    if (group.adminUserId !== requesterUserId) {
73
      throw new ForbiddenException(Message.ONLY_GROUP_ADMIN_CAN_EDIT_GROUP);
4!
UNCOV
74
    }
×
75
  }
76

77
  private checkNotCustomerServiceGroup(group: Group): void {
78
    if (group.isCustomerServiceGroup()) {
4!
UNCOV
79
      throw new UnprocessableEntityException(
×
80
        Message.CANNOT_MODIFY_CUSTOMER_SERVICE_GROUP,
81
      );
4✔
82
    }
83
  }
84

4✔
85
  private async collectPointFromMembers(group: Group): Promise<void> {
4✔
86
    if (group.isPracticeGroup()) {
4✔
87
      return;
88
    }
89

90
    const reason = MessageBuilder.build(
91
      Template.DISABLE_GROUP_PORTFOLIO.point,
92
      { groupTitle: group.title },
93
    );
4✔
94

95
    const groupMembers = await this.groupMemberRepository.findByGroupId(
96
      group.id,
97
    );
4✔
98
    const userIds = groupMembers.map((groupMember) => groupMember.userId);
99

100
    await this.pointGrantService.grant({
101
      targetUserIds: userIds,
102
      amount: -Point.GROUP_ENABLED_PORTFOLIO,
103
      reason,
104
    });
7✔
105
  }
7✔
106

7✔
107
  private sendMessageToAdminUser(group: Group): void {
7✔
108
    const message = MessageBuilder.build(
7✔
109
      Template.DISABLE_GROUP_PORTFOLIO.notification,
7✔
110
      { groupId: group.id, groupTitle: group.title },
7✔
111
    );
7✔
112

7✔
113
    this.slackSender.send({
7✔
114
      category: NotificationCategory.GROUP_ACTIVITY,
115
      targetUserId: group.adminUserId,
116
      message,
1✔
117
    });
118
  }
119
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc