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

khu-khlug / sight-backend / 13325716355

14 Feb 2025 08:50AM UTC coverage: 58.222%. Remained the same
13325716355

push

github

web-flow
fix: 회원 목록 조회가 정상적으로 동작하도록 수정 (#104)

584 of 1548 branches covered (37.73%)

Branch coverage included in aggregate %.

0 of 10 new or added lines in 2 files covered. (0.0%)

33 existing lines in 3 files now uncovered.

1512 of 2052 relevant lines covered (73.68%)

9.65 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 {
×
NEW
12
  StudentStatus,
×
13
  UserStatus,
14
} from '@khlug/app/domain/user/model/constant';
15
import { User } from '@khlug/app/domain/user/model/User';
16

17
import { UnivPeriod } from '@khlug/util/univPeriod';
18

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

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

44
    const qb = this.userRepository.createQueryBuilder('user');
UNCOV
45

×
NEW
46
    if (email !== null) {
×
47
      qb.andWhere('email LIKE ?', [`%${email}%`]);
48
    }
49

NEW
50
    if (phone !== null) {
×
UNCOV
51
      qb.andWhere('phone LIKE ?', [`%${phone}%`]);
×
52
    }
53

54
    if (name !== null) {
UNCOV
55
      qb.andWhere('realname LIKE ?', [`%${name}%`]);
×
UNCOV
56
    }
×
57

58
    if (number !== null) {
59
      qb.andWhere('number LIKE ?', [`%${number}%`]);
UNCOV
60
    }
×
UNCOV
61

×
62
    if (college !== null) {
63
      qb.andWhere('college LIKE ?', [`%${college}%`]);
64
    }
UNCOV
65

×
NEW
66
    if (grade !== null) {
×
67
      qb.andWhere('grade = ?', [grade]);
68
    }
69

NEW
70
    if (studentStatus !== null) {
×
71
      qb.andWhere('state = ?', [studentStatus]);
72
    }
73

74
    const [users, count] = await qb
NEW
75
      .andWhere('active != 0')
×
NEW
76
      .andWhere('state != ?', [StudentStatus.UNITED])
×
77
      .limit(limit)
×
78
      .offset(offset)
79
      .orderBy({ realname: 'ASC' })
80
      .getResultAndCount();
81

82
    const feeTargetUserIds = users
83
      .filter((user) => user.needPayFee())
UNCOV
84
      .map((user) => user.id);
×
UNCOV
85
    const thisTerm = UnivPeriod.fromDate(new Date()).toTerm();
×
86

87
    const feeHistories = await this.feeHistoryRepository.find({
88
      user: { $in: feeTargetUserIds },
×
UNCOV
89
      year: thisTerm.year,
×
UNCOV
90
      semester: thisTerm.semester,
×
91
    });
×
92
    const userFeeHistorySet = new Set<number>(
93
      feeHistories.map((feeHistory) => feeHistory.user),
×
94
    );
×
95

96
    const listView: UserWithTagListView = {
×
97
      count,
×
98
      users: users.map((user) => {
99
        const normalTags: string[] = [];
×
100
        const redTags: string[] = [];
×
UNCOV
101

×
102
        if (user.needAuth()) {
103
          redTags.push('미인증');
×
104
        }
105

106
        if (user.status === UserStatus.INACTIVE) {
×
107
          redTags.push('차단');
108
        }
109

110
        if (user.point < 0) {
111
          redTags.push('-exp');
112
        }
113

114
        if (user.needPayFee() && !userFeeHistorySet.has(user.id)) {
115
          if (user.needPayHalfFee()) {
116
            normalTags.push('반액 납부 대상');
117
          } else {
118
            normalTags.push('납부 대상');
119
          }
120
        }
121

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