Skip to content

Commit 643eb67

Browse files
committed
CLAP-81 Add: 로그인 기록에 대한 필터링 조회
1 parent 62c7f86 commit 643eb67

File tree

11 files changed

+111
-40
lines changed

11 files changed

+111
-40
lines changed

src/main/java/clap/server/adapter/inbound/web/dto/log/MemberLogRequest.java renamed to src/main/java/clap/server/adapter/inbound/web/dto/log/FilterLogRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import java.util.List;
88

9-
public record MemberLogRequest(
9+
public record FilterLogRequest(
1010
@Schema(description = "검색 기간 (단위: 시간)", example = "1, 24, 168, 730, 2190 (1시간, 24시간, 1주일, 1개월, 3개월)")
1111
Integer term,
1212
@NotNull

src/main/java/clap/server/adapter/inbound/web/log/LogController.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
import clap.server.adapter.inbound.security.SecurityUserDetails;
44
import clap.server.adapter.inbound.web.dto.log.AnonymousLogResponse;
5-
import clap.server.adapter.inbound.web.dto.log.MemberLogRequest;
5+
import clap.server.adapter.inbound.web.dto.log.FilterLogRequest;
66
import clap.server.adapter.inbound.web.dto.log.MemberLogResponse;
7-
import clap.server.adapter.inbound.web.dto.task.FilterTaskListRequest;
87
import clap.server.application.port.inbound.log.FindApiLogsUsecase;
98
import clap.server.common.annotation.architecture.WebAdapter;
109
import lombok.RequiredArgsConstructor;
@@ -27,16 +26,21 @@ public class LogController {
2726

2827
@Secured({"ROLE_ADMIN"})
2928
@GetMapping("/login")
30-
public List<AnonymousLogResponse> getLoginAttempts() {
31-
return findApiLogsUsecase.getAnonymousLogs();
29+
public Page<AnonymousLogResponse> getLoginAttempts(
30+
@RequestParam(defaultValue = "0") int page,
31+
@RequestParam(defaultValue = "20") int pageSize,
32+
@ModelAttribute FilterLogRequest anonymousLogRequest,
33+
@AuthenticationPrincipal SecurityUserDetails userInfo) {
34+
Pageable pageable = PageRequest.of(page, pageSize);
35+
return findApiLogsUsecase.filterAnonymousLogs(anonymousLogRequest, pageable);
3236
}
3337

3438
@Secured({"ROLE_ADMIN"})
3539
@GetMapping("/general")
3640
public Page<MemberLogResponse> getApiCalls(
3741
@RequestParam(defaultValue = "0") int page,
3842
@RequestParam(defaultValue = "20") int pageSize,
39-
@ModelAttribute MemberLogRequest memberLogRequest,
43+
@ModelAttribute FilterLogRequest memberLogRequest,
4044
@AuthenticationPrincipal SecurityUserDetails userInfo) {
4145
Pageable pageable = PageRequest.of(page, pageSize);
4246
return findApiLogsUsecase.filterMemberLogs(memberLogRequest, pageable);

src/main/java/clap/server/adapter/outbound/persistense/ApiLogPersistenceAdapter.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package clap.server.adapter.outbound.persistense;
22

3-
import clap.server.adapter.inbound.web.dto.log.MemberLogRequest;
3+
import clap.server.adapter.inbound.web.dto.log.AnonymousLogResponse;
4+
import clap.server.adapter.inbound.web.dto.log.FilterLogRequest;
45

56
import clap.server.adapter.inbound.web.dto.log.MemberLogResponse;
6-
import clap.server.adapter.outbound.persistense.entity.log.MemberLogEntity;
77
import clap.server.adapter.outbound.persistense.mapper.ApiLogPersistenceMapper;
88
import clap.server.adapter.outbound.persistense.mapper.MemberPersistenceMapper;
99
import clap.server.adapter.outbound.persistense.repository.log.AnonymousLogRepository;
@@ -40,7 +40,7 @@ public void saveMemberLog(MemberLog memberLog) {
4040
}
4141

4242
@Override
43-
public void saveAnonymousLog(AnonymousLog anonymousLog){
43+
public void saveAnonymousLog(AnonymousLog anonymousLog) {
4444
apiLogRepository.save(apiLogPersistenceMapper.mapAnonymousLogToEntity(anonymousLog, anonymousLog.getLoginNickname()));
4545
}
4646

@@ -52,16 +52,15 @@ public List<ApiLog> findAllLogs() {
5252
}
5353

5454
@Override
55-
public List<AnonymousLog> findAnonymousLogs() {
56-
return anonymousLogRepository.findAll().stream()
57-
.map(apiLogPersistenceMapper::mapAnonymousLogEntityToDomain)
58-
.toList();
59-
}
60-
61-
@Override
62-
public Page<MemberLogResponse> filterMemberLogs(MemberLogRequest memberLogRequest, Pageable pageable) {
55+
public Page<MemberLogResponse> filterMemberLogs(FilterLogRequest memberLogRequest, Pageable pageable) {
6356
Page<MemberLog> memberLogs = memberLogRepository.filterMemberLogs(memberLogRequest, pageable)
6457
.map(apiLogPersistenceMapper::mapMemberLogEntityToDomain);
6558
return memberLogs.map(LogMapper::toMemberLogResponse);
6659
}
60+
61+
@Override
62+
public Page<AnonymousLog> filterAnonymousLogs(FilterLogRequest anonymousLogRequest, Pageable pageable) {
63+
return anonymousLogRepository.filterAnonymousLogs(anonymousLogRequest, pageable)
64+
.map(apiLogPersistenceMapper::mapAnonymousLogEntityToDomain);
65+
}
6766
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package clap.server.adapter.outbound.persistense.repository.log;
2+
3+
import clap.server.adapter.inbound.web.dto.log.FilterLogRequest;
4+
import clap.server.adapter.outbound.persistense.entity.log.AnonymousLogEntity;
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
7+
8+
public interface AnonymousLogCustomRepository {
9+
Page<AnonymousLogEntity> filterAnonymousLogs(FilterLogRequest anonymousLogRequest, Pageable pageable);
10+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package clap.server.adapter.outbound.persistense.repository.log;
2+
3+
import clap.server.adapter.inbound.web.dto.log.FilterLogRequest;
4+
import clap.server.adapter.outbound.persistense.entity.log.AnonymousLogEntity;
5+
import com.querydsl.core.BooleanBuilder;
6+
import com.querydsl.jpa.impl.JPAQueryFactory;
7+
import lombok.RequiredArgsConstructor;
8+
import org.springframework.data.domain.Page;
9+
import org.springframework.data.domain.PageImpl;
10+
import org.springframework.data.domain.Pageable;
11+
import org.springframework.stereotype.Repository;
12+
13+
import java.time.LocalDateTime;
14+
import java.util.List;
15+
16+
import static clap.server.adapter.outbound.persistense.entity.log.QAnonymousLogEntity.anonymousLogEntity;
17+
18+
@Repository
19+
@RequiredArgsConstructor
20+
public class AnonymousLogCustomRepositoryImpl implements AnonymousLogCustomRepository{
21+
22+
private final JPAQueryFactory queryFactory;
23+
@Override
24+
public Page<AnonymousLogEntity> filterAnonymousLogs(FilterLogRequest request, Pageable pageable) {
25+
BooleanBuilder builder = new BooleanBuilder();
26+
27+
if (request.term() != null) {
28+
LocalDateTime fromDate = LocalDateTime.now().minusHours(request.term());
29+
builder.and(anonymousLogEntity.createdAt.after(fromDate));
30+
}
31+
if (!request.logStatus().isEmpty()) {
32+
builder.and(anonymousLogEntity.logStatus.in(request.logStatus()));
33+
}
34+
if (!request.nickName().isEmpty()) {
35+
builder.and(anonymousLogEntity.loginNickname.contains(request.nickName()));
36+
}
37+
if (!request.ipAddress().isEmpty()) {
38+
builder.and(anonymousLogEntity.serverIp.eq(request.ipAddress()));
39+
}
40+
41+
List<AnonymousLogEntity> result = queryFactory
42+
.selectFrom(anonymousLogEntity)
43+
.where(builder)
44+
.orderBy(anonymousLogEntity.createdAt.desc())
45+
.offset(pageable.getOffset())
46+
.limit(pageable.getPageSize())
47+
.fetch();
48+
long total = queryFactory
49+
.selectFrom(anonymousLogEntity)
50+
.where(builder)
51+
.fetch().size();
52+
return new PageImpl<>(result, pageable, total);
53+
}
54+
}
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package clap.server.adapter.outbound.persistense.repository.log;
22

3+
import aj.org.objectweb.asm.commons.Remapper;
4+
import clap.server.adapter.inbound.web.dto.log.FilterLogRequest;
35
import clap.server.adapter.outbound.persistense.entity.log.AnonymousLogEntity;
6+
import clap.server.domain.model.log.AnonymousLog;
7+
import org.springframework.data.domain.Page;
8+
import org.springframework.data.domain.Pageable;
49
import org.springframework.data.jpa.repository.JpaRepository;
510
import org.springframework.stereotype.Repository;
611

712
import java.util.List;
813

914
@Repository
10-
public interface AnonymousLogRepository extends JpaRepository<AnonymousLogEntity, Long> {
15+
public interface AnonymousLogRepository extends JpaRepository<AnonymousLogEntity, Long>, AnonymousLogCustomRepository{
1116
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package clap.server.adapter.outbound.persistense.repository.log;
22

3-
import clap.server.adapter.inbound.web.dto.log.MemberLogRequest;
3+
import clap.server.adapter.inbound.web.dto.log.FilterLogRequest;
44
import clap.server.adapter.outbound.persistense.entity.log.MemberLogEntity;
55
import org.springframework.data.domain.Page;
66
import org.springframework.data.domain.Pageable;
77

88
public interface MemberLogCustomRepository {
9-
Page<MemberLogEntity> filterMemberLogs(MemberLogRequest memberLogRequest, Pageable pageable);
9+
Page<MemberLogEntity> filterMemberLogs(FilterLogRequest memberLogRequest, Pageable pageable);
1010
}

src/main/java/clap/server/adapter/outbound/persistense/repository/log/MemberLogCustomRepositoryImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package clap.server.adapter.outbound.persistense.repository.log;
22

33

4-
import clap.server.adapter.inbound.web.dto.log.MemberLogRequest;
4+
import clap.server.adapter.inbound.web.dto.log.FilterLogRequest;
55
import clap.server.adapter.outbound.persistense.entity.log.MemberLogEntity;
66
import com.querydsl.core.BooleanBuilder;
77
import com.querydsl.jpa.impl.JPAQueryFactory;
@@ -25,14 +25,14 @@ public class MemberLogCustomRepositoryImpl implements MemberLogCustomRepository{
2525
private final JPAQueryFactory queryFactory;
2626

2727
@Override
28-
public Page<MemberLogEntity> filterMemberLogs(MemberLogRequest request, Pageable pageable) {
28+
public Page<MemberLogEntity> filterMemberLogs(FilterLogRequest request, Pageable pageable) {
2929
BooleanBuilder builder = new BooleanBuilder();
3030

3131
if (request.term() != null) {
3232
LocalDateTime fromDate = LocalDateTime.now().minusHours(request.term());
3333
builder.and(memberLogEntity.createdAt.after(fromDate));
3434
}
35-
if (request.logStatus().isEmpty()) {
35+
if (!request.logStatus().isEmpty()) {
3636
builder.and(memberLogEntity.logStatus.in(request.logStatus()));
3737
}
3838
if (!request.nickName().isEmpty()) {

src/main/java/clap/server/application/port/inbound/log/FindApiLogsUsecase.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
import clap.server.adapter.inbound.web.dto.log.AnonymousLogResponse;
5-
import clap.server.adapter.inbound.web.dto.log.MemberLogRequest;
5+
import clap.server.adapter.inbound.web.dto.log.FilterLogRequest;
66
import clap.server.adapter.inbound.web.dto.log.MemberLogResponse;
77
import clap.server.domain.model.log.ApiLog;
88
import org.springframework.data.domain.Page;
@@ -11,7 +11,7 @@
1111
import java.util.List;
1212

1313
public interface FindApiLogsUsecase {
14-
List<AnonymousLogResponse> getAnonymousLogs();
14+
Page<AnonymousLogResponse> filterAnonymousLogs(FilterLogRequest anonymousLogsRequest, Pageable pageable);
15+
Page<MemberLogResponse> filterMemberLogs(FilterLogRequest memberLogRequest, Pageable pageable);
1516
List<ApiLog> getApiLogs();
16-
Page<MemberLogResponse> filterMemberLogs(MemberLogRequest memberLogRequest, Pageable pageable);
1717
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package clap.server.application.port.outbound.log;
22

3-
import clap.server.adapter.inbound.web.dto.log.MemberLogRequest;
3+
import clap.server.adapter.inbound.web.dto.log.AnonymousLogResponse;
4+
import clap.server.adapter.inbound.web.dto.log.FilterLogRequest;
45
import clap.server.adapter.inbound.web.dto.log.MemberLogResponse;
56
import clap.server.domain.model.log.AnonymousLog;
67
import clap.server.domain.model.log.ApiLog;
7-
import clap.server.domain.model.log.MemberLog;
88
import org.springframework.data.domain.Page;
99
import org.springframework.data.domain.Pageable;
1010

1111
import java.util.List;
1212

1313
public interface LoadLogPort {
1414
List<ApiLog> findAllLogs();
15-
List<AnonymousLog> findAnonymousLogs();
15+
Page<AnonymousLog> filterAnonymousLogs(FilterLogRequest anonymousLogRequest, Pageable pageable);
1616

17-
Page<MemberLogResponse> filterMemberLogs(MemberLogRequest memberLogRequest, Pageable pageable);
17+
Page<MemberLogResponse> filterMemberLogs(FilterLogRequest memberLogRequest, Pageable pageable);
1818
}

0 commit comments

Comments
 (0)