Skip to content

Commit 88d8a26

Browse files
authored
Merge pull request #349 from mosu-dev/refactor/mosu-348
Refactor/mosu 348 비밀번호 정규식 수정, admin application NPE 해결
2 parents 57b1aa8 + 02cd07f commit 88d8a26

File tree

6 files changed

+52
-53
lines changed

6 files changed

+52
-53
lines changed

src/main/java/life/mosu/mosuserver/application/notify/NotifyService.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,10 @@ public void notify(LunaNotificationEvent event) {
3737
NotifySender<LunaNotificationVariable> sender = senderResolver.resolve(event.status());
3838

3939
sender.send(phone, event, notifyVariable);
40-
log.info("[NotifyService] 알림톡 전송 성공: userId={}, status={}", event.userId(), event.status());
4140
}
4241

4342
@Recover
4443
public void recover(CustomRuntimeException exception, LunaNotificationEvent event) {
45-
log.warn(
46-
"[NotifyService] 알림톡 전송 실패: userId={}, status={}, reason={}",
47-
event.userId(), event.status(), exception.getMessage()
48-
);
4944
DiscordExceptionNotifyEventRequest request = DiscordExceptionNotifyEventRequest.of(
5045
exception.getCause() != null ? exception.getCause().toString() : "N/A",
5146
exception.getMessage(),

src/main/java/life/mosu/mosuserver/global/annotation/PasswordPattern.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import java.lang.annotation.RetentionPolicy;
1010
import java.lang.annotation.Target;
1111

12-
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,20}$", message = "비밀번호 형식이 올바르지 않습니다.")
12+
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*_/+=])[A-Za-z\\d!@#$%^&*_/+=]{8,20}$", message = "비밀번호 형식이 올바르지 않습니다.")
1313
@NotBlank
1414
@Target({ElementType.FIELD, ElementType.PARAMETER})
1515
@Retention(RetentionPolicy.RUNTIME)

src/main/java/life/mosu/mosuserver/infra/persistence/jpa/ApplicationQueryRepositoryImpl.java

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import com.querydsl.core.Tuple;
44
import com.querydsl.core.types.Predicate;
5-
import com.querydsl.core.types.dsl.EnumPath;
6-
import com.querydsl.core.types.dsl.Expressions;
75
import com.querydsl.jpa.impl.JPAQuery;
86
import com.querydsl.jpa.impl.JPAQueryFactory;
97
import java.time.format.DateTimeFormatter;
@@ -18,7 +16,12 @@
1816
import life.mosu.mosuserver.domain.exam.entity.QExamJpaEntity;
1917
import life.mosu.mosuserver.domain.examapplication.entity.QExamApplicationJpaEntity;
2018
import life.mosu.mosuserver.domain.examapplication.entity.QExamSubjectJpaEntity;
19+
import life.mosu.mosuserver.domain.payment.entity.PaymentMethod;
20+
import life.mosu.mosuserver.domain.payment.entity.PaymentStatus;
2121
import life.mosu.mosuserver.domain.payment.entity.QPaymentJpaEntity;
22+
import life.mosu.mosuserver.domain.profile.entity.Education;
23+
import life.mosu.mosuserver.domain.profile.entity.Gender;
24+
import life.mosu.mosuserver.domain.profile.entity.Grade;
2225
import life.mosu.mosuserver.domain.profile.entity.QProfileJpaEntity;
2326
import life.mosu.mosuserver.domain.user.entity.QUserJpaEntity;
2427
import life.mosu.mosuserver.infra.persistence.s3.S3Service;
@@ -65,9 +68,9 @@ public Page<ApplicationListResponse> searchAllApplications(ApplicationFilter fil
6568

6669
List<ApplicationListResponse> content = query.fetch().stream()
6770
.map(tuple -> {
68-
Long appSchoolId = tuple.get(examApplication.id);
69-
Set<Subject> subjects = appSchoolId != null
70-
? findSubjectsByExamApplicationId(appSchoolId)
71+
Long examApplicationId = tuple.get(examApplication.id);
72+
Set<Subject> subjects = examApplicationId != null
73+
? findSubjectsByExamApplicationId(examApplicationId)
7174
: new HashSet<>();
7275
return mapToResponse(tuple, subjects);
7376
})
@@ -81,9 +84,9 @@ public List<ApplicationExcelDto> searchAllApplicationsForExcel() {
8184
JPAQuery<Tuple> query = baseQuery();
8285
return query.fetch().stream()
8386
.map(tuple -> {
84-
Long appSchoolId = tuple.get(examApplication.id);
85-
Set<Subject> subjects = appSchoolId != null
86-
? findSubjectsByExamApplicationId(appSchoolId)
87+
Long examApplicationId = tuple.get(examApplication.id);
88+
Set<Subject> subjects = examApplicationId != null
89+
? findSubjectsByExamApplicationId(examApplicationId)
8790
: new HashSet<>();
8891
return mapToExcel(tuple, subjects);
8992
})
@@ -96,9 +99,9 @@ private JPAQuery<Tuple> baseQuery() {
9699
examApplication.id,
97100
payment.paymentKey,
98101
examApplication.examNumber,
99-
profile.userName,
100-
profile.gender,
101-
profile.birth,
102+
user.name,
103+
user.gender,
104+
user.birth,
102105
profile.phoneNumber,
103106
application.parentPhoneNumber,
104107
profile.recommenderPhoneNumber,
@@ -116,19 +119,20 @@ private JPAQuery<Tuple> baseQuery() {
116119
application.createdAt
117120
)
118121
.from(examApplication)
119-
.leftJoin(exam).on(examApplication.examId.eq(exam.id))
120-
.leftJoin(application).on(examApplication.applicationId.eq(application.id))
121-
.leftJoin(payment).on(payment.examApplicationId.eq(examApplication.id))
122-
.leftJoin(user).on(application.userId.eq(user.id))
123-
.leftJoin(profile).on(profile.userId.eq(user.id))
124-
.leftJoin(examTicketImage)
125-
.on(examTicketImage.applicationId.eq(application.id));
122+
.join(exam).on(examApplication.examId.eq(exam.id))
123+
.join(application).on(examApplication.applicationId.eq(application.id))
124+
.join(payment).on(payment.examApplicationId.eq(examApplication.id))
125+
.join(user).on(application.userId.eq(user.id))
126+
.join(profile).on(profile.userId.eq(user.id))
127+
.join(examTicketImage)
128+
.on(examTicketImage.applicationId.eq(application.id))
129+
.where(payment.paymentStatus.in(PaymentStatus.DONE, PaymentStatus.ABORTED));
126130
}
127131

128132
private Predicate buildNameCondition(String name) {
129133
return (name == null || name.isBlank())
130134
? null
131-
: profile.userName.contains(name);
135+
: user.name.contains(name);
132136
}
133137

134138
private Predicate buildPhoneCondition(String phone) {
@@ -138,7 +142,6 @@ private Predicate buildPhoneCondition(String phone) {
138142
}
139143

140144
private Set<Subject> findSubjectsByExamApplicationId(Long examApplicationId) {
141-
EnumPath<Subject> subject = Expressions.enumPath(Subject.class, "subject");
142145
return new HashSet<>(
143146
queryFactory
144147
.select(
@@ -160,32 +163,37 @@ private ApplicationListResponse mapToResponse(Tuple tuple, Set<Subject> subjects
160163

161164
ExamTicketResponse examTicketResponse = ExamTicketResponse.of(
162165
url,
163-
tuple.get(profile.userName),
164-
tuple.get(profile.birth),
166+
tuple.get(user.name),
167+
tuple.get(user.birth),
165168
tuple.get(examApplication.examNumber),
166169
subjectNames,
167170
tuple.get(exam.schoolName)
168171
);
169172

173+
Gender gender = tuple.get(profile.gender);
174+
Education education = tuple.get(profile.education);
175+
Grade grade = tuple.get(profile.grade);
176+
PaymentMethod paymentMethod = tuple.get(payment.paymentMethod);
177+
170178
return new ApplicationListResponse(
171179
tuple.get(payment.paymentKey),
172180
tuple.get(examApplication.examNumber),
173-
tuple.get(profile.userName),
174-
tuple.get(profile.gender).getGenderName(),
175-
tuple.get(profile.birth),
181+
tuple.get(user.name),
182+
gender != null ? gender.getGenderName() : null,
183+
tuple.get(user.birth),
176184
tuple.get(profile.phoneNumber),
177185
tuple.get(application.parentPhoneNumber),
178-
tuple.get(profile.education).getEducationName(),
186+
education != null ? education.getEducationName() : null,
179187
tuple.get(profile.schoolInfo.schoolName),
180-
tuple.get(profile.grade).getGradeName(),
188+
grade != null ? grade.getGradeName() : null,
181189
tuple.get(examApplication.isLunchChecked),
182190
tuple.get(exam.lunchName),
183191
subjectNames,
184192
tuple.get(exam.schoolName),
185193
tuple.get(exam.examDate),
186194
tuple.get(examTicketImage.fileName),
187195
tuple.get(payment.paymentStatus),
188-
tuple.get(payment.paymentMethod),
196+
paymentMethod != null ? paymentMethod.getName() : null,
189197
tuple.get(application.createdAt),
190198
examTicketResponse
191199
);
@@ -196,32 +204,33 @@ private ApplicationExcelDto mapToExcel(Tuple tuple, Set<Subject> subjects) {
196204
.map(Subject::getSubjectName)
197205
.collect(Collectors.toSet());
198206

199-
String lunchName = tuple.get(exam.lunchName);
200-
String genderName = tuple.get(profile.gender).getGenderName();
201-
String gradeName = tuple.get(profile.grade).getGradeName();
202-
String educationName = tuple.get(profile.education).getEducationName();
207+
Gender gender = tuple.get(profile.gender);
208+
Education education = tuple.get(profile.education);
209+
Grade grade = tuple.get(profile.grade);
210+
PaymentMethod paymentMethod = tuple.get(payment.paymentMethod);
211+
203212
String appliedAt = tuple.get(application.createdAt)
204213
.format(EXCEL_DT_FORMATTER);
205214

206215
return new ApplicationExcelDto(
207216
tuple.get(payment.paymentKey),
208217
tuple.get(examApplication.examNumber),
209-
tuple.get(profile.userName),
210-
genderName,
211-
tuple.get(profile.birth),
218+
tuple.get(user.name),
219+
gender != null ? gender.getGenderName() : null,
220+
tuple.get(user.birth),
212221
tuple.get(profile.phoneNumber),
213222
tuple.get(application.parentPhoneNumber),
214223
tuple.get(profile.recommenderPhoneNumber),
215-
educationName,
224+
education != null ? education.getEducationName() : null,
216225
tuple.get(profile.schoolInfo.schoolName),
217-
gradeName,
218-
lunchName,
226+
grade != null ? grade.getGradeName() : null,
227+
tuple.get(exam.lunchName),
219228
subjectNames,
220229
tuple.get(exam.schoolName),
221230
tuple.get(exam.examDate),
222231
tuple.get(examTicketImage.fileName),
223232
tuple.get(payment.paymentStatus),
224-
tuple.get(payment.paymentMethod),
233+
paymentMethod != null ? paymentMethod.getName() : null,
225234
appliedAt
226235
);
227236
}

src/main/java/life/mosu/mosuserver/infra/persistence/jpa/RefundQueryRepositoryImpl.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,7 @@ public Page<RefundListResponse> searchAllRefunds(Pageable pageable) {
5555
public List<RefundExcelDto> searchAllRefundsForExcel() {
5656
JPAQuery<Tuple> query = baseQuery();
5757
return query.fetch().stream()
58-
.map(tuple -> {
59-
log.info("tuple log : {} ", tuple);
60-
return mapToExcel(tuple);
61-
})
58+
.map(this::mapToExcel)
6259
.toList();
6360
}
6461

src/main/java/life/mosu/mosuserver/presentation/admin/dto/ApplicationExcelDto.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import io.swagger.v3.oas.annotations.media.Schema;
44
import java.time.LocalDate;
55
import java.util.Set;
6-
import life.mosu.mosuserver.domain.payment.entity.PaymentMethod;
76
import life.mosu.mosuserver.domain.payment.entity.PaymentStatus;
87
import life.mosu.mosuserver.global.annotation.ExcelColumn;
98

@@ -26,7 +25,7 @@ public record ApplicationExcelDto(
2625
@Schema(description = "시험 일자", example = "2025-08-10") @ExcelColumn(headerName = "시험 일자") LocalDate examDate,
2726
@Schema(description = "수험표 이미지 URL", example = "https://s3.amazonaws.com/bucket/admission/2025-00001.jpg") @ExcelColumn(headerName = "수험표 사진") String admissionTicketImage,
2827
@Schema(description = "결제 상태", example = "COMPLETED") @ExcelColumn(headerName = "결제 상태") PaymentStatus paymentStatus,
29-
@Schema(description = "결제 방법", example = "CARD") @ExcelColumn(headerName = "결제 방법") PaymentMethod paymentMethod,
28+
@Schema(description = "결제 방법", example = "CARD") @ExcelColumn(headerName = "결제 방법") String paymentMethod,
3029
@Schema(description = "신청 일시", example = "2025-07-10 15:30:00") @ExcelColumn(headerName = "신청 일시") String applicationDate) {
3130

3231
}

src/main/java/life/mosu/mosuserver/presentation/admin/dto/ApplicationListResponse.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.time.LocalDate;
55
import java.time.LocalDateTime;
66
import java.util.List;
7-
import life.mosu.mosuserver.domain.payment.entity.PaymentMethod;
87
import life.mosu.mosuserver.domain.payment.entity.PaymentStatus;
98

109
@Schema(description = "관리자 신청 목록 응답 DTO")
@@ -62,7 +61,7 @@ public record ApplicationListResponse(
6261
PaymentStatus paymentStatus,
6362

6463
@Schema(description = "결제 방법", example = "CARD")
65-
PaymentMethod paymentMethod,
64+
String paymentMethod,
6665

6766
@Schema(description = "신청 일시", example = "2025-07-10T15:30:00")
6867
LocalDateTime applicationDate,

0 commit comments

Comments
 (0)