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

khu-khlug / sight-backend / 14247600948

03 Apr 2025 04:05PM UTC coverage: 50.988% (-1.0%) from 51.939%
14247600948

push

github

web-flow
feat: 디스코드 메신저 구현 (#118)

823 of 2618 branches covered (31.44%)

Branch coverage included in aggregate %.

29 of 64 new or added lines in 13 files covered. (45.31%)

45 existing lines in 10 files now uncovered.

2272 of 3452 relevant lines covered (65.82%)

12.83 hits per line

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

77.57
/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 {
1✔
15
  IMessenger,
1✔
16
  MessengerToken,
1✔
17
} from '@khlug/app/domain/adapter/IMessenger';
1✔
18
import {
1✔
19
  GroupLogger,
1✔
20
  IGroupLogger,
1✔
21
} from '@khlug/app/domain/group/IGroupLogger';
1✔
22
import {
1✔
23
  GroupMemberRepository,
1✔
24
  IGroupMemberRepository,
25
} from '@khlug/app/domain/group/IGroupMemberRepository';
35!
UNCOV
26
import {
×
27
  GroupRepository,
28
  IGroupRepository,
29
} from '@khlug/app/domain/group/IGroupRepository';
30
import { Group } from '@khlug/app/domain/group/model/Group';
31
import { PointGrantService } from '@khlug/app/domain/user/service/PointGrantService';
32

33
import { Message } from '@khlug/constant/error';
35✔
34
import { Point } from '@khlug/constant/point';
35
import { Template } from '@khlug/constant/template';
35✔
36

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

53
  @Transactional()
7✔
54
  async execute(command: DisablePortfolioCommand): Promise<void> {
7✔
55
    const { groupId, requesterUserId } = command;
7✔
56

2✔
57
    const group = await this.groupRepository.findById(groupId);
58
    if (!group) {
5✔
59
      throw new NotFoundException(Message.GROUP_NOT_FOUND);
4✔
60
    }
4✔
61

4✔
62
    this.checkGroupAdmin(group, requesterUserId);
4✔
63
    this.checkNotCustomerServiceGroup(group);
4✔
64

4✔
65
    group.disablePortfolio();
66
    await this.groupRepository.save(group);
67

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

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

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

87
  private async collectPointFromMembers(group: Group): Promise<void> {
88
    if (group.isPracticeGroup()) {
89
      return;
90
    }
91

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

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

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

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

1✔
115
    this.slackSender.send({
116
      targetUserId: group.adminUserId,
117
      message,
118
    });
1!
119
  }
120
}
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