[FEAT] #212 어드민 패널 구현 (SSR) - #224
Conversation
- Thymeleaf + Bootstrap 5 기반 SSR 어드민 패널 추가 - InMemoryUserDetailsManager로 환경변수 기반 어드민 계정 관리 - Spring Security 별도 FilterChain(@order(1))으로 API와 세션 분리 - 대시보드(통계), 유저 관리(정지/해제/강제탈퇴), 분철글 관리(상태필터/삭제) 구현 - UserStatus에 SUSPENDED 추가, User에 suspend/unsuspend/withdraw(reason) 메서드 추가 - ErrorStatus에 PROMPT_ERROR(50005) 추가
- Keep Thymeleaf dependencies (admin SSR) - Keep admin credentials config (ADMIN_USERNAME, ADMIN_PASSWORD) - Merge withdraw() with reason param and validateNoActiveTransaction from develop - Keep suspend()/unsuspend() methods in User added for admin panel
- deletePost() 실행 전 주문 존재 여부 체크 추가 - 주문이 있으면 POST_HAS_ORDERS(40020) 예외 반환 - OrderRepository에 existsByGroupBuyPost_Id() 추가
- CLOSED/PAYMENT_DONE/SHIPPING 상태 글은 주문 유무 무관하게 삭제 차단 (POST_IN_PROGRESS 40021) - 상태 기반 체크를 주문 존재 체크보다 먼저 수행 - 프론트 confirm: RECRUITING은 일반 경고, 그 외 상태는 '진행 중' 강조 메시지로 구분
- User.suspend/unsuspend: WITHDRAWN 계정 상태 변경 시도 시 예외 발생 - AdminService.forceWithdrawUser: 이미 탈퇴한 유저 중복 탈퇴 차단 - AdminController: BusinessException 발생 시 JSON 대신 flash 메시지로 redirect - layout.html: 에러 메시지 alert 영역 추가
탈퇴한 유저에 대해 suspend/unsuspend 호출 시 IllegalStateException 대신 BusinessException을 던져 AdminController에서 flash 에러로 정상 처리되도록 수정
- 사이드바: 다크 테마, 활성 메뉴 accent 색상, 계층 구조 개선 - 대시보드: 컬러 스탯 카드 + 아이콘 + 빠른 이동 섹션 - 유저/분철글 테이블: 상태별 색상 배지, 액션 버튼 시각화 - 분철글 상태 필터를 pill 탭으로 교체 - confirm 다이얼로그를 JS 함수로 분리하여 가독성 향상
|
Warning Review limit reached
Next review available in: 41 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough관리자 전용 보안 필터 체인과 공통 레이아웃을 추가하고, 대시보드·사용자·분철글 화면을 새 UI로 구성했습니다. 사용자 상태 변경과 강제 탈퇴 시 FCM 토큰 정리 동작도 보완했습니다. Changes관리자 SSR 패널
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/org/sopt/poti/domain/admin/service/AdminService.java`:
- Around line 76-83: Update AdminService.forceWithdrawUser to call
fcmTokenService.deleteAllByUserId with the withdrawn user’s ID, matching the
cleanup performed by AuthService.withdraw, while preserving the existing
withdrawal and refresh-token deletion flow.
- Around line 99-102: Update the deletion flow in AdminService to serialize the
order-existence check and group-buy post deletion using the same post-level
state or lock as order creation. Keep the operation atomic, and catch the
resulting integrity/FK violation to translate it into BusinessException with
ErrorStatus.POST_HAS_ORDERS instead of allowing a server error.
- Around line 61-62: Update the suspension flow around AdminService so
previously issued access JWTs cannot authenticate after user.suspend(). Enforce
SUSPENDED users as INVALID_TOKEN in JwtAuthenticationFilter on every request, or
integrate equivalent access-token revocation during suspension; keep
refresh-token deletion and ensure suspended users are rejected until
reactivated.
In `@src/main/java/org/sopt/poti/global/config/AdminSecurityConfig.java`:
- Around line 56-60: Update the logoutSuccessUrl configuration in
AdminSecurityConfig to redirect to the admin login path with the logout query
parameter present, so login.html can render the logout-success message. Keep the
existing logout URL and session invalidation behavior unchanged.
- Around line 15-16: Move the chain ordering annotations from the configuration
classes to their bean methods: in
src/main/java/org/sopt/poti/global/config/AdminSecurityConfig.java lines 15-16,
remove the class-level `@Order`(1) and place it directly below `@Bean` on
adminFilterChain; in
src/main/java/org/sopt/poti/global/security/SecurityConfig.java line 21, remove
the class-level `@Order`(2) and place it directly below `@Bean` on filterChain.
In `@src/main/resources/templates/admin/users.html`:
- Around line 141-159: Update the pagination controls in
src/main/resources/templates/admin/users.html lines 141-159 and
src/main/resources/templates/admin/posts.html lines 150-168 so first/last page
controls render without an href when users.first or users.last is true, while
retaining the existing navigation URLs for enabled controls. Use the existing
pagination symbols and preserve the disabled styling and page-number links.
- Around line 2-3: Update the layout invocations in
src/main/resources/templates/admin/users.html lines 2-3 and
src/main/resources/templates/admin/posts.html lines 2-3 so each passes its
page-specific style and script resources along with the section content. Ensure
the layout receives the confirmSuspend, confirmWithdraw, and confirmDelete
functions and the associated styles, either by placing them inside the section
fragment or by extending the layout arguments, so the existing confirmation
dialogs continue to work.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: e233d30c-2ec2-4537-bcf6-afff566d9f01
📒 Files selected for processing (17)
build.gradlesrc/main/java/org/sopt/poti/domain/admin/controller/AdminController.javasrc/main/java/org/sopt/poti/domain/admin/service/AdminService.javasrc/main/java/org/sopt/poti/domain/auth/service/AuthService.javasrc/main/java/org/sopt/poti/domain/groupbuy/repository/GroupBuyRepository.javasrc/main/java/org/sopt/poti/domain/order/repository/OrderRepository.javasrc/main/java/org/sopt/poti/domain/user/entity/User.javasrc/main/java/org/sopt/poti/global/config/AdminSecurityConfig.javasrc/main/java/org/sopt/poti/global/error/ErrorStatus.javasrc/main/java/org/sopt/poti/global/security/SecurityConfig.javasrc/main/resources/application.ymlsrc/main/resources/templates/admin/dashboard.htmlsrc/main/resources/templates/admin/layout.htmlsrc/main/resources/templates/admin/login.htmlsrc/main/resources/templates/admin/posts.htmlsrc/main/resources/templates/admin/users.htmlsrc/test/resources/application-test.yml
📌 관련 이슈
✨ 변경 사항
@Order(1))📸 테스트 증명 (필수)
https://dev.poti.kr/admin/login에서 로컬 및 dev 서버 동작 확인📚 리뷰어 참고 사항
ADMIN_USERNAME/ADMIN_PASSWORD로 관리.env에 해당 변수 추가 필요 (현재 dev만 적용됨)/admin/**경로를 선점하므로 JWT 필터와 충돌 없음✅ 체크리스트
Summary by CodeRabbit
새 기능
버그 수정