• 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

0.0
/src/app/application/group/eventHandler/GroupStateChangedHandler.ts
1
import { Inject } from '@nestjs/common';
2
import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
×
3

×
4
import { Transactional } from '@khlug/core/persistence/transaction/Transactional';
5

6
import { INotifier, NotifierToken } from '@khlug/app/domain/adapter/INotifier';
7
import { GroupStateChanged } from '@khlug/app/domain/group/event/GroupStateChanged';
8
import {
9
  GroupMemberRepository,
UNCOV
10
  IGroupMemberRepository,
×
11
} from '@khlug/app/domain/group/IGroupMemberRepository';
12
import {
×
13
  GroupRepository,
14
  IGroupRepository,
15
} from '@khlug/app/domain/group/IGroupRepository';
×
UNCOV
16
import { GroupState } from '@khlug/app/domain/group/model/constant';
×
NEW
17
import { NotificationCategory } from '@khlug/constant/notification';
×
18
import { PointGrantService } from '@khlug/app/domain/user/service/PointGrantService';
×
19

20
import { Point } from '@khlug/constant/point';
21

×
22
// TODO[lery]: 그룹 상태 핸들러가 분리되면 그때 제거하기
23
@EventsHandler(GroupStateChanged)
UNCOV
24
export class GroupStateChangedHandler
×
UNCOV
25
  implements IEventHandler<GroupStateChanged>
×
26
{
27
  constructor(
28
    private readonly pointGrantService: PointGrantService,
29
    @Inject(GroupRepository)
30
    private readonly groupRepository: IGroupRepository,
31
    @Inject(GroupMemberRepository)
32
    private readonly groupMemberRepository: IGroupMemberRepository,
33
    @Inject(NotifierToken)
34
    private readonly slackSender: INotifier,
35
  ) {}
36

37
  @Transactional()
38
  async handle(event: GroupStateChanged): Promise<void> {
39
    const { groupId, prevState, nextState } = event;
40

UNCOV
41
    if (nextState === GroupState.PENDING) {
×
42
      return;
×
43
    }
×
44

UNCOV
45
    const group = await this.groupRepository.findById(groupId);
×
46
    if (!group) {
×
47
      return;
×
48
    }
UNCOV
49

×
UNCOV
50
    const members = await this.groupMemberRepository.findByGroupId(groupId);
×
51
    members.forEach((member) =>
52
      this.slackSender.send({
53
        targetUserId: member.userId,
54
        category: NotificationCategory.GROUP_ACTIVITY,
UNCOV
55
        message: `<a href="/group/${groupId}><u>${
×
UNCOV
56
          group.title
×
57
        }</u></a> ${this.buildMessage(nextState)}`,
58
      }),
59
    );
60

61
    const userIds = members.map((m) => m.userId);
62
    this.pointGrantService.grant({
UNCOV
63
      targetUserIds: userIds,
×
64
      amount: this.buildPoint(prevState, nextState),
UNCOV
65
      reason: `<u>${group.title}</u> ${this.buildMessage(nextState)}`,
×
66
    });
UNCOV
67
  }
×
68

UNCOV
69
  private buildMessage(nextState: GroupState): string {
×
70
    switch (nextState) {
UNCOV
71
      case 'PROGRESS':
×
72
        return '그룹이 다시 진행 중입니다.';
UNCOV
73
      case 'END_SUCCESS':
×
74
        return '그룹이 종료(성공)되었습니다.';
75
      case 'END_FAIL':
76
        return '그룹이 종료(실패)되었습니다.';
77
      case 'SUSPEND':
×
78
        return '그룹이 중단 처리되었습니다.';
×
UNCOV
79
      default:
×
80
        return 'not reachable';
×
81
    }
×
82
  }
83

×
84
  private buildPoint(prevState: GroupState, nextState: GroupState): number {
×
85
    if (nextState === GroupState.PROGRESS) {
×
86
      if (prevState == GroupState.END_SUCCESS) {
×
87
        return -Point.GROUP_ENDED_WITH_SUCCESS;
×
88
      } else if (prevState == GroupState.END_FAIL) {
×
UNCOV
89
        return -Point.GROUP_ENDED_WITH_FAIL;
×
UNCOV
90
      }
×
91
    } else if (nextState === GroupState.END_SUCCESS) {
×
92
      return Point.GROUP_ENDED_WITH_SUCCESS;
93
    } else if (nextState === GroupState.END_FAIL) {
94
      return Point.GROUP_ENDED_WITH_FAIL;
×
95
    } else if (nextState === GroupState.SUSPEND) {
96
      if (prevState == GroupState.END_SUCCESS) {
97
        return -Point.GROUP_ENDED_WITH_SUCCESS;
×
98
      } else if (prevState == GroupState.END_FAIL) {
×
99
        return -Point.GROUP_ENDED_WITH_FAIL;
×
100
      }
×
101
    }
×
UNCOV
102

×
UNCOV
103
    return 0;
×
104
  }
×
105
}
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