20260226 #236 관리자 페이지 통계 대시보드 실시간 활동 로그 추가#254
Hidden character warning
Conversation
회원가입, 로그인, 베팅 참여, 게시물 작성, 출석 체크인에 이벤트 추가 완료 백테스팅, 댓글, 좋아요 이벤트 추가 고려 QrStreamService에 SseService 코드 사용 고려
백테스팅, 퀀트봇에 이벤트 발생 고려 QrStreamService에 SseService 코드 사용 고려 yml 수정에 따른 securityConfig 수정
oauth2를 더이상 쓰지 않으므로 변경
targetId String -> UUID로 변경 회원가입 시 출석 type 사용 오류 수정
모든 메시지 형식에 행위 대상 제외
이관된 메서드 비밀번호 초기화 및 변경 uri 변경에 따른 인증 화이트리스트 변경
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
Walkthrough인증 엔드포인트를 AuthController로 통합하고(Activity 관련 엔드포인트 포함), ActivityLog/ActivityEvent 필드명(type→activityType) 및 관련 저장소·리스너를 갱신했으며, 사용자 활동 조회 API와 관리자 컨트롤러 경로 변경 등을 적용했습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant AuthCtrl as AuthController
participant AuthSvc as AuthService
participant EmailSvc as EmailService
participant Redis as RedisService
participant UserRepo as UserRepository
participant TokenSvc as RefreshTokenService
Client->>AuthCtrl: POST /api/auth/password/reset/send (email, studentId)
AuthCtrl->>AuthSvc: passwordResetSendCode(req)
AuthSvc->>UserRepo: findByEmailAndStudentId(...)
UserRepo-->>AuthSvc: user
AuthSvc->>EmailSvc: sendResetEmail(email)
EmailSvc->>Redis: set(PASSWORD_RESET:{email}, code, ttl)
EmailSvc-->>AuthSvc: success
AuthSvc-->>AuthCtrl: 200 OK
Client->>AuthCtrl: POST /api/auth/password/reset/confirm (email, studentId, code, newPassword)
AuthCtrl->>AuthSvc: resetPasswordByCode(req)
AuthSvc->>Redis: get(PASSWORD_RESET:{email})
Redis-->>AuthSvc: code
AuthSvc->>UserRepo: updatePassword(userId, encodedPassword)
AuthSvc->>TokenSvc: deleteByUserId(userId)
AuthSvc-->>AuthCtrl: 200 OK
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
backend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.java (1)
451-461:⚠️ Potential issue | 🟠 Major회원 탈퇴 테스트의 stub과 검증이 주석 처리됨
userService.deleteUserWithOauth(userId)에 대한 stub과 검증이 모두 주석 처리되어 있습니다. 테스트가 실제 회원 탈퇴 로직을 검증하지 않고 있습니다.새로운 탈퇴 로직(
deleteUserSoftDelete)을 테스트하도록 업데이트하거나, 기존 로직이 필요한 경우 주석을 해제해야 합니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.java` around lines 451 - 461, The test currently skips stubbing and verifying user deletion by commenting out userService.deleteUserWithOauth(userId); update the test to reflect the actual deletion method: either un-comment and use userService.deleteUserWithOauth(userId) for stubbing and verify it was called, or change the stub/verify to the new method userService.deleteUserSoftDelete(userId) (and adjust any signatures) so mockMvc.perform(delete("/api/auth/withdraw")...) both stubs the correct userService method and verifies it was invoked (in addition to the existing refreshTokenService.deleteByUserId(userId) stub/verify).backend/src/test/java/org/sejongisc/backend/user/service/UserServiceTest.java (1)
346-350:⚠️ Potential issue | 🟡 Minor테스트 검증 로직이 실제 구현과 불일치합니다.
verify(userRepository).save(existingUser)를 호출하지만,UserService.updateUser()메서드는 명시적으로save()를 호출하지 않고 JPA dirty checking에 의존합니다. 이 테스트는 실패하거나 잘못된 동작을 검증하고 있습니다.🔧 수정 제안
- verify(userRepository).save(existingUser); + // JPA dirty checking이 사용되므로 save() 호출 검증 제거 verifyNoInteractions(passwordEncoder); // 비밀번호 인코더 안 씀🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/src/test/java/org/sejongisc/backend/user/service/UserServiceTest.java` around lines 346 - 350, The test currently verifies userRepository.save(existingUser) but UserService.updateUser() uses JPA dirty checking and does not call save explicitly; remove or change that assertion to reflect reality: replace verify(userRepository).save(existingUser) with verify(userRepository, never()).save(any()) or simply remove the save verification, while keeping verify(userRepository).findById(userId) and verifyNoInteractions(passwordEncoder) so the test matches UserService.updateUser() behavior.backend/src/main/java/org/sejongisc/backend/user/service/UserService.java (1)
5-40:⚠️ Potential issue | 🟡 Minor사용하지 않는 import 제거 필요
signup 로직이
AuthService로 이동하고 OAuth2 관련 코드가 주석 처리된 후, 다음 import들이 더 이상 사용되지 않습니다:
SignupRequest,SignupResponse(lines 9-10)EmailService(line 11)OptimisticRetry(line 13)EmailProperties(line 14)RedisKey,RedisService(lines 17-18)AccountEntry,Account,AccountName,TransactionReason(lines 19-22)AccountService,PointLedgerService(lines 23-24)PasswordResetConfirmRequest,PasswordResetSendRequest(lines 25-26)ApplicationEventPublisher(line 34)DataIntegrityViolationException(line 35)Slice(line 36)RedisTemplate(line 37)이들 import는 모두 주석 처리된 OAuth 관련 코드(lines 143-196)에서만 사용되므로 제거해도 무방합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/src/main/java/org/sejongisc/backend/user/service/UserService.java` around lines 5 - 40, Remove the unused imports from UserService.java that only supported the moved signup/OAuth code: delete SignupRequest, SignupResponse, EmailService, OptimisticRetry, EmailProperties, RedisKey, RedisService, AccountEntry, Account, AccountName, TransactionReason, AccountService, PointLedgerService, PasswordResetConfirmRequest, PasswordResetSendRequest, ApplicationEventPublisher, DataIntegrityViolationException, Slice, and RedisTemplate; verify compilation and run static analysis to ensure no remaining references (check commented OAuth block around lines 143-196 and methods in class UserService that previously referenced these symbols).
🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java (1)
14-18: 사용하지 않는 import 존재
AuthService와Sliceimport가 사용되지 않는 것으로 보입니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java` around lines 14 - 18, Remove the unused imports AuthService and Slice from UserController.java: locate the import statements for org.sejongisc.backend.common.auth.service.AuthService and org.springframework.data.domain.Slice at the top of the UserController class and delete them (ensure no remaining references to AuthService or Slice in methods like any controller endpoints or fields before removal).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@backend/src/main/java/org/sejongisc/backend/activity/entity/ActivityLog.java`:
- Around line 45-49: The ActivityLog constructor currently assigns the incoming
message directly which can exceed the DB column length and cause save failures;
update the ActivityLog(UUID userId, String username, ActivityType activityType,
String message, UUID targetId, String boardName) constructor to defensively
normalize the message by introducing a MAX_MESSAGE_LENGTH constant (30),
handling null (treat as empty string), and truncating message to
MAX_MESSAGE_LENGTH (optionally add an ellipsis if you prefer) before assigning
to the message field so persistence won’t fail.
In
`@backend/src/main/java/org/sejongisc/backend/activity/repository/ActivityLogRepository.java`:
- Around line 20-23: The query method
findByUserIdAndActivityTypesOrderByCreatedAtDesc in ActivityLogRepository
currently returns an unbounded List which risks OOM for users with many logs;
change its signature to enforce pagination by accepting a Pageable parameter and
returning a Page<ActivityLog> (or Slice<ActivityLog>) and keep the `@Query` (or
adapt it) so results are ordered by createdAt DESC; update all callers to pass a
Pageable and handle the Page/Slice response accordingly.
In
`@backend/src/main/java/org/sejongisc/backend/common/auth/controller/AuthController.java`:
- Around line 114-139: The API docs in AuthController's confirmReset method
incorrectly reference PasswordResetSendRequest in the `@Operation` description;
update the documentation string to reference the correct DTO
PasswordResetConfirmRequest (and fix any other occurrences in the same Javadoc
block) so the description matches the method signature public ResponseEntity<?>
confirmReset(`@RequestBody` `@Valid` PasswordResetConfirmRequest req) and avoids
confusing API consumers.
In
`@backend/src/main/java/org/sejongisc/backend/common/auth/service/AuthService.java`:
- Around line 214-231: The two helper methods getEmailFromRedis and
deleteResetTokenFromRedis are unused and inconsistent with resetPasswordByCode's
direct redisTemplate usage; either remove these unused helpers or refactor
resetPasswordByCode to use them and the RedisKey.PASSWORD_RESET abstraction. If
you choose refactor: change resetPasswordByCode to call getEmailFromRedis(token)
instead of redisTemplate.opsForValue().get(...) and call
deleteResetTokenFromRedis(token) instead of redisTemplate.delete(...), and
ensure the key format expected by RedisKey.PASSWORD_RESET matches the existing
emailProperties.getKeyPrefix().getReset() + email pattern (update RedisKey or
redisService behavior accordingly). If you choose removal: delete
getEmailFromRedis and deleteResetTokenFromRedis and keep resetPasswordByCode's
current direct redisTemplate calls, removing any unused imports/fields
(redisService) left behind.
In
`@backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java`:
- Around line 61-71: Change the read-only endpoints to use GET and normalize the
path casing: replace `@PatchMapping` with `@GetMapping` on the methods
getAttendanceLogs and getBoardLogs, and update the route for getBoardLogs from
"/logs/Board" to a consistent lowercase "/logs/board" (or match whichever casing
convention the project uses); ensure the method signatures and returned types
remain unchanged and update any related route docs/annotations if present.
In
`@backend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.java`:
- Around line 351-352: The commented-out stub for userService.findOrCreateUser
in AuthControllerTest leaves the OAuth test without a user and causes failures;
restore or replace that stub so the controller receives a valid User: re-enable
a when(userService.findOrCreateUser(any())).thenReturn(...) (or update to the
current method signature if it changed) returning a User built with the required
fields (userId, name, role) used by the test, or if the OAuth flow was
redesigned, refactor the test to mock the new service call(s) that create/return
the User (ensure mocks reference userService.findOrCreateUser or the new method
name and produce a non-null User to avoid NPEs).
- Around line 191-194: Tests reference jwtProvider.createToken(...) but
jwtProvider is not declared and jwtUtils is used elsewhere; either declare and
annotate a mock for jwtProvider (e.g., add a `@Mock` JwtProvider jwtProvider in
AuthControllerTest and initialize it in the test setup) and stub
jwtProvider.createToken(...) and jwtProvider.createRefreshToken(...)
accordingly, or change the calls to use the existing jwtUtils mock (replace
jwtProvider.createToken(...) with jwtUtils.createToken(...) and use
jwtUtils.createRefreshToken(...)) so the mocked symbol names are consistent with
the mocks defined in AuthControllerTest.
In
`@backend/src/test/java/org/sejongisc/backend/user/service/UserServiceTest.java`:
- Around line 62-63: Tests declare `@InjectMocks` AuthService but do not provide
its dependencies, causing NPEs; add `@Mock` fields for JwtParser, JwtProvider,
EmailService, RedisTemplate (or RedisTemplate<String, Object>), EmailProperties,
RedisService, RefreshTokenService (and any other constructor/injected
dependencies used by AuthService) in the UserServiceTest class and ensure
Mockito is initialized (e.g., annotate the test class with
`@ExtendWith`(MockitoExtension.class) or call MockitoAnnotations.openMocks(this))
so AuthService is constructed with mocked collaborators during tests.
---
Outside diff comments:
In `@backend/src/main/java/org/sejongisc/backend/user/service/UserService.java`:
- Around line 5-40: Remove the unused imports from UserService.java that only
supported the moved signup/OAuth code: delete SignupRequest, SignupResponse,
EmailService, OptimisticRetry, EmailProperties, RedisKey, RedisService,
AccountEntry, Account, AccountName, TransactionReason, AccountService,
PointLedgerService, PasswordResetConfirmRequest, PasswordResetSendRequest,
ApplicationEventPublisher, DataIntegrityViolationException, Slice, and
RedisTemplate; verify compilation and run static analysis to ensure no remaining
references (check commented OAuth block around lines 143-196 and methods in
class UserService that previously referenced these symbols).
In
`@backend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.java`:
- Around line 451-461: The test currently skips stubbing and verifying user
deletion by commenting out userService.deleteUserWithOauth(userId); update the
test to reflect the actual deletion method: either un-comment and use
userService.deleteUserWithOauth(userId) for stubbing and verify it was called,
or change the stub/verify to the new method
userService.deleteUserSoftDelete(userId) (and adjust any signatures) so
mockMvc.perform(delete("/api/auth/withdraw")...) both stubs the correct
userService method and verifies it was invoked (in addition to the existing
refreshTokenService.deleteByUserId(userId) stub/verify).
In
`@backend/src/test/java/org/sejongisc/backend/user/service/UserServiceTest.java`:
- Around line 346-350: The test currently verifies
userRepository.save(existingUser) but UserService.updateUser() uses JPA dirty
checking and does not call save explicitly; remove or change that assertion to
reflect reality: replace verify(userRepository).save(existingUser) with
verify(userRepository, never()).save(any()) or simply remove the save
verification, while keeping verify(userRepository).findById(userId) and
verifyNoInteractions(passwordEncoder) so the test matches
UserService.updateUser() behavior.
---
Nitpick comments:
In
`@backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java`:
- Around line 14-18: Remove the unused imports AuthService and Slice from
UserController.java: locate the import statements for
org.sejongisc.backend.common.auth.service.AuthService and
org.springframework.data.domain.Slice at the top of the UserController class and
delete them (ensure no remaining references to AuthService or Slice in methods
like any controller endpoints or fields before removal).
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
backend/src/main/java/org/sejongisc/backend/activity/entity/ActivityLog.javabackend/src/main/java/org/sejongisc/backend/activity/listener/ActivityEventListener.javabackend/src/main/java/org/sejongisc/backend/activity/repository/ActivityLogRepository.javabackend/src/main/java/org/sejongisc/backend/admin/controller/AdminBettingController.javabackend/src/main/java/org/sejongisc/backend/admin/controller/AdminBoardController.javabackend/src/main/java/org/sejongisc/backend/attendance/service/AttendanceService.javabackend/src/main/java/org/sejongisc/backend/betting/service/BettingService.javabackend/src/main/java/org/sejongisc/backend/board/service/PostInteractionService.javabackend/src/main/java/org/sejongisc/backend/board/service/PostServiceImpl.javabackend/src/main/java/org/sejongisc/backend/common/auth/controller/AuthController.javabackend/src/main/java/org/sejongisc/backend/common/auth/service/AuthService.javabackend/src/main/java/org/sejongisc/backend/common/config/security/SecurityConstants.javabackend/src/main/java/org/sejongisc/backend/user/controller/UserController.javabackend/src/main/java/org/sejongisc/backend/user/service/UserService.javabackend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.javabackend/src/test/java/org/sejongisc/backend/user/service/UserServiceTest.javafrontend/src/utils/auth.js
backend/src/main/java/org/sejongisc/backend/activity/entity/ActivityLog.java
Show resolved
Hide resolved
backend/src/main/java/org/sejongisc/backend/activity/repository/ActivityLogRepository.java
Show resolved
Hide resolved
backend/src/main/java/org/sejongisc/backend/common/auth/controller/AuthController.java
Show resolved
Hide resolved
backend/src/main/java/org/sejongisc/backend/common/auth/service/AuthService.java
Show resolved
Hide resolved
backend/src/main/java/org/sejongisc/backend/user/controller/UserController.java
Show resolved
Hide resolved
backend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.java
Show resolved
Hide resolved
backend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.java
Show resolved
Hide resolved
backend/src/test/java/org/sejongisc/backend/user/service/UserServiceTest.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
backend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.java (1)
189-191:⚠️ Potential issue | 🟠 MajorOAuth 테스트가 불완전하여 실패할 수 있습니다.
userService.findOrCreateUser(...)stub이 주석 처리되어 있지만, Line 190에서user객체의 필드를 직접 사용하고 있습니다. OAuth 흐름에서 실제로 사용자가 생성/조회되지 않으면 테스트가 예상대로 동작하지 않을 수 있습니다.테스트를 완전히 구현하거나, 현재 OAuth 인증 흐름에 맞게 리팩토링이 필요합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.java` around lines 189 - 191, The test stubs JWT creation but leaves userService.findOrCreateUser(...) commented out, so the OAuth flow may not get a valid user; in AuthControllerTest un-comment and/or add a Mockito stub for userService.findOrCreateUser(any()) to return the prepared user instance (the same user used for jwtUtils.createToken(...) and createRefreshToken(...)) so the controller receives the created/found user during the test, or alternatively refactor the test to bypass findOrCreateUser and inject the user directly into the controller flow to match the OAuth path being tested.
🧹 Nitpick comments (1)
docker-compose.yml (1)
22-28: 오래된 주석 업데이트 필요Line 22의 주석 "1GB 램 서버 생존을 위한 메모리 제한"이 현재 설정과 맞지 않습니다. 현재 총 메모리 사용량은 약 6.3GB (API: 3.5G + Redis: 250M + Web: 512M + AI: 2G)이며, Line 15의 주석에서 언급한 "8GB 서버 기준"과 일치합니다.
♻️ 주석 업데이트 제안
- # 1GB 램 서버 생존을 위한 메모리 제한 (Docker 레벨) + # 8GB 램 서버 기준 메모리 제한 (Docker 레벨)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docker-compose.yml` around lines 22 - 28, Update the outdated comment above the deploy block that currently reads "1GB 램 서버 생존을 위한 메모리 제한" to reflect the actual configuration and context: replace it with a concise note stating this compose sets per-service memory limits for an 8GB server (e.g., total approximate usage ~6.3GB) and reference the configured values such as the deploy.resources.limits.memory entry (memory: 3500M) so readers understand the API/Redis/Web/AI splits; ensure the new comment aligns with the earlier "8GB 서버 기준" note.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@backend/src/main/java/org/sejongisc/backend/common/auth/service/EmailService.java`:
- Around line 114-115: In EmailService, you call generateCode() twice causing
mismatched codes; capture the generated value in the local variable code (as
already done) and use that same code when calling
redisService.set(RedisKey.PASSWORD_RESET, email, ... ) instead of calling
generateCode() again so the code sent via email and the code stored in Redis are
identical.
---
Duplicate comments:
In
`@backend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.java`:
- Around line 189-191: The test stubs JWT creation but leaves
userService.findOrCreateUser(...) commented out, so the OAuth flow may not get a
valid user; in AuthControllerTest un-comment and/or add a Mockito stub for
userService.findOrCreateUser(any()) to return the prepared user instance (the
same user used for jwtUtils.createToken(...) and createRefreshToken(...)) so the
controller receives the created/found user during the test, or alternatively
refactor the test to bypass findOrCreateUser and inject the user directly into
the controller flow to match the OAuth path being tested.
---
Nitpick comments:
In `@docker-compose.yml`:
- Around line 22-28: Update the outdated comment above the deploy block that
currently reads "1GB 램 서버 생존을 위한 메모리 제한" to reflect the actual configuration and
context: replace it with a concise note stating this compose sets per-service
memory limits for an 8GB server (e.g., total approximate usage ~6.3GB) and
reference the configured values such as the deploy.resources.limits.memory entry
(memory: 3500M) so readers understand the API/Redis/Web/AI splits; ensure the
new comment aligns with the earlier "8GB 서버 기준" note.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
backend/src/main/java/org/sejongisc/backend/activity/event/ActivityEvent.javabackend/src/main/java/org/sejongisc/backend/common/auth/controller/AuthController.javabackend/src/main/java/org/sejongisc/backend/common/auth/service/AuthService.javabackend/src/main/java/org/sejongisc/backend/common/auth/service/EmailService.javabackend/src/main/java/org/sejongisc/backend/common/config/EmailProperties.javabackend/src/main/java/org/sejongisc/backend/user/controller/UserController.javabackend/src/main/java/org/sejongisc/backend/user/service/UserService.javabackend/src/main/resources/application-prod.ymlbackend/src/test/java/org/sejongisc/backend/auth/controller/AuthControllerTest.javabackend/src/test/java/org/sejongisc/backend/auth/service/EmailServiceTest.javadocker-compose.yml
💤 Files with no reviewable changes (3)
- backend/src/main/java/org/sejongisc/backend/common/config/EmailProperties.java
- backend/src/main/resources/application-prod.yml
- backend/src/test/java/org/sejongisc/backend/auth/service/EmailServiceTest.java
Summary by CodeRabbit
릴리스 노트
New Features
Refactor
Frontend
Chores