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

khu-khlug / sight-backend / 13205579048

07 Feb 2025 06:13PM UTC coverage: 58.287% (-0.4%) from 58.658%
13205579048

push

github

web-flow
feat: 회원 목록에 태그 추가 (#101)

583 of 1544 branches covered (37.76%)

Branch coverage included in aggregate %.

0 of 9 new or added lines in 1 file covered. (0.0%)

16 existing lines in 1 file now uncovered.

1506 of 2040 relevant lines covered (73.82%)

9.67 hits per line

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

0.0
/src/app/application/user/query/listUser/ListUserQueryHandler.ts
1
import { EntityRepository } from '@mikro-orm/mysql';
2
import { InjectRepository } from '@mikro-orm/nestjs';
×
3
import { Injectable } from '@nestjs/common';
×
4
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs';
×
5

×
6
import { ListUserQuery } from '@khlug/app/application/user/query/listUser/ListUserQuery';
7
import { ListUserQueryResult } from '@khlug/app/application/user/query/listUser/ListUserQueryResult';
8
import { UserWithTagListView } from '@khlug/app/application/user/query/view/UserListView';
×
9

10
import { FeeHistory } from '@khlug/app/domain/fee/model/FeeHistory';
NEW
11
import { UserStatus } from '@khlug/app/domain/user/model/constant';
×
12
import { User } from '@khlug/app/domain/user/model/User';
×
13

14
import { UnivPeriod } from '@khlug/util/univPeriod';
15

16
@Injectable()
17
@QueryHandler(ListUserQuery)
18
export class ListUserQueryHandler
19
  implements IQueryHandler<ListUserQuery, ListUserQueryResult>
20
{
21
  constructor(
22
    @InjectRepository(User)
23
    private readonly userRepository: EntityRepository<User>,
24
    @InjectRepository(FeeHistory)
25
    private readonly feeHistoryRepository: EntityRepository<FeeHistory>,
26
  ) {}
27

28
  async execute(query: ListUserQuery): Promise<ListUserQueryResult> {
UNCOV
29
    const {
×
UNCOV
30
      email,
×
31
      phone,
32
      name,
UNCOV
33
      number,
×
34
      college,
×
35
      grade,
×
36
      studentStatus,
×
37
      limit,
38
      offset,
39
    } = query;
UNCOV
40

×
41
    const qb = this.userRepository.createQueryBuilder('user');
×
42

43
    if (email) {
44
      qb.andWhere('email LIKE ?', [`%${email}%`]);
UNCOV
45
    }
×
46

×
47
    if (phone) {
48
      qb.andWhere('phone LIKE ?', [`%${phone}%`]);
49
    }
UNCOV
50

×
51
    if (name) {
×
52
      qb.andWhere('realname LIKE ?', [`%${name}%`]);
53
    }
54

UNCOV
55
    if (number) {
×
56
      qb.andWhere('number LIKE ?', [`%${number}%`]);
×
57
    }
58

59
    if (college) {
UNCOV
60
      qb.andWhere('college LIKE ?', [`%${college}%`]);
×
61
    }
×
62

63
    if (grade) {
64
      qb.andWhere('grade = ?', [grade]);
UNCOV
65
    }
×
66

×
67
    if (studentStatus) {
68
      qb.andWhere('state = ?', [studentStatus]);
69
    }
UNCOV
70

×
71
    const [users, count] = await qb
72
      .limit(limit)
UNCOV
73
      .offset(offset)
×
74
      .orderBy({ id: 'ASC' })
×
UNCOV
75
      .getResultAndCount();
×
76

77
    const feeTargetUserIds = users
78
      .filter((user) => user.needPayFee())
79
      .map((user) => user.id);
80
    const thisTerm = UnivPeriod.fromDate(new Date()).toTerm();
81

NEW
82
    const feeHistories = await this.feeHistoryRepository.find({
×
NEW
83
      user: { $in: feeTargetUserIds },
×
84
      year: thisTerm.year,
85
      semester: thisTerm.semester,
NEW
86
    });
×
NEW
87
    const userFeeHistorySet = new Set<number>(
×
NEW
88
      feeHistories.map((feeHistory) => feeHistory.user),
×
NEW
89
    );
×
90

91
    const listView: UserWithTagListView = {
×
92
      count,
×
93
      users: users.map((user) => {
94
        const normalTags: string[] = [];
×
UNCOV
95
        const redTags: string[] = [];
×
96

97
        if (user.needAuth()) {
×
UNCOV
98
          redTags.push('미인증');
×
99
        }
×
100

NEW
101
        if (user.status === UserStatus.INACTIVE) {
×
102
          redTags.push('차단');
103
        }
NEW
104

×
105
        if (user.point < 0) {
106
          redTags.push('-exp');
107
        }
108

109
        if (user.needPayFee() && !userFeeHistorySet.has(user.id)) {
110
          if (user.needPayHalfFee()) {
111
            normalTags.push('반액 납부 대상');
112
          } else {
113
            normalTags.push('납부 대상');
114
          }
115
        }
116

117
        return {
118
          id: user.id,
119
          name: user.name,
120
          profile: {
121
            name: user.profile.name,
122
            college: user.profile.college,
123
            grade: user.profile.grade,
124
            number: user.profile.number,
125
            email: user.profile.email,
126
            phone: user.profile.phone,
127
            homepage: user.profile.homepage,
128
            language: user.profile.language,
129
            prefer: user.profile.prefer,
130
          },
131
          admission: user.admission,
132
          studentStatus: user.studentStatus,
133
          point: user.point,
134
          status: user.status,
135
          manager: user.manager,
136
          slack: user.slack,
UNCOV
137
          rememberToken: user.rememberToken,
×
138
          khuisAuthAt: user.khuisAuthAt,
139
          returnAt: user.returnAt,
UNCOV
140
          returnReason: user.returnReason,
×
141
          lastLoginAt: user.lastLoginAt,
142
          lastEnterAt: user.lastEnterAt,
143
          createdAt: user.createdAt,
144
          updatedAt: user.updatedAt,
145
          normalTags,
146
          redTags,
147
        };
×
148
      }),
×
149
    };
150
    return new ListUserQueryResult(listView);
151
  }
152
}
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