Skip to content

feat: admin controller#21

Merged
AlphaBs merged 1 commit intodevelopfrom
feat/admin-test
Jan 10, 2026
Merged

feat: admin controller#21
AlphaBs merged 1 commit intodevelopfrom
feat/admin-test

Conversation

@AlphaBs
Copy link
Member

@AlphaBs AlphaBs commented Jan 10, 2026

작업 내용

변경 사항

관련 이슈

closes #

@AlphaBs AlphaBs merged commit 9776ba0 into develop Jan 10, 2026
@AlphaBs AlphaBs deleted the feat/admin-test branch January 10, 2026 18:32
@gemini-code-assist
Copy link

Summary of Changes

Hello @AlphaBs, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 관리자 기능을 위한 초기 인프라를 구축하고, 기존 모의 데이터를 관리하는 방식을 개선하는 데 중점을 둡니다. 특히, 관리자 계정 생성 및 인증 토큰 발급을 위한 테스트용 API를 도입하여 개발 및 테스트 환경에서 관리자 역할의 기능을 쉽게 검증할 수 있도록 합니다. 또한, 기본 추천 데이터 관리 로직을 모의 서비스에서 정식 서비스로 전환하여 시스템의 핵심 기능을 강화하고, 데이터베이스 상호작용 방식을 최적화했습니다. 전반적으로 시스템의 관리 및 테스트 용이성을 향상시키는 변경 사항들입니다.

Highlights

  • 관리자 테스트용 API 추가: 관리자 계정 생성, JWT 토큰 발급, 기본 추천 데이터 관리(삭제 및 생성)를 위한 새로운 테스트용 관리자 API 엔드포인트들이 AdminTestController에 추가되었습니다.
  • 기본 추천 서비스 리팩토링: 기존 MockDefaultRecommendationServiceDefaultRecommendationService로 이름이 변경되고 mock 패키지에서 recommendation.service 패키지로 이동하여, 더 이상 모의 서비스가 아닌 정식 서비스로 승격되었습니다. 이에 따라 MockController에서는 해당 기능 관련 엔드포인트가 제거되었습니다.
  • 데이터 삭제 방식 변경: MockMemoryService에서 happyMemoryRepository.deleteAllInBatch() 호출이 happyMemoryRepository.deleteAll()로 변경되었습니다. 이는 대량 삭제 시 JPA의 동작 방식에 영향을 줄 수 있습니다.
  • 보안 설정 변경: 테스트 편의를 위해 SecurityConfigPUBLIC_ENDPOINTS가 임시로 /**로 설정되어 모든 경로에 대한 인증 없이 접근이 허용되었으며, 관리자 권한 검증 경로가 /api/admin/**에서 /admin/**으로 변경되었습니다.
  • 새로운 에러 코드 추가: 관리자 계정 중복 생성 시 발생할 ADMIN_ALREADY_EXISTS 에러 코드가 ErrorCode enum에 추가되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이번 PR은 관리자 기능 추가를 위한 컨트롤러 및 관련 설정을 변경하는 내용을 담고 있습니다. 테스트용 관리자 계정 생성, 토큰 발급, 기본 추천 데이터 관리 등의 기능이 추가되었습니다. 전반적으로 기능 구현은 잘 되었으나, 몇 가지 중요한 성능 및 보안 관련 이슈가 발견되었습니다.

  • 성능: AdminTestController에서 findAll()을 사용하여 전체 사용자를 조회하는 부분은 사용자 수가 많아질 경우 심각한 성능 저하를 유발할 수 있습니다. 데이터베이스 레벨에서 필터링하는 방식으로 개선이 필요합니다. 또한 MockMemoryService에서 deleteAllInBatch() 대신 deleteAll()을 사용하도록 변경한 부분도 성능 저하의 원인이 될 수 있어 확인이 필요합니다.
  • 보안: SecurityConfig에서 모든 경로를 허용(/**)하도록 변경한 부분은 심각한 보안 취약점입니다. 또한, 관리자 경로에 대한 권한 설정이 실제 컨트롤러 경로와 일치하지 않아 권한 제어가 제대로 동작하지 않을 수 있습니다.

자세한 내용은 각 파일에 남긴 리뷰 코멘트를 참고해 주세요. 제공된 규칙에 따라 수정되거나 삭제된 코멘트는 없습니다.

Comment on lines +36 to 51
"/**",
// // Root (Swagger 리다이렉트)
// "/",
// // Actuator
// "/actuator/health",
// // Auth (로그인, 콜백, 토큰 재발급, 개발용 토큰)
// "/auth/**",
// // Admin Test (테스트용 관리자 계정 생성/토큰 발급)
// "/admin/test/**",
// // H2 Console (local only)
// "/h2-console/**",
// // Swagger
// "/swagger-ui/**",
// "/swagger-ui.html",
// "/v3/api-docs/**",
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

모든 경로(/**)에 대한 접근을 허용하면 인증이 필요한 API까지 외부에 노출되어 심각한 보안 문제가 발생합니다. 개발 환경의 편의를 위해 임시로 변경한 것이라면, 병합 전 반드시 원래대로 복구해야 합니다. 또한, 주석 처리된 관리자 테스트 경로가 /admin/test/**로 되어 있으나 실제 컨트롤러는 /api/admin/test에 있으므로, 이 경로도 /api/admin/test/**로 수정해야 합니다.

Suggested change
"/**",
// // Root (Swagger 리다이렉트)
// "/",
// // Actuator
// "/actuator/health",
// // Auth (로그인, 콜백, 토큰 재발급, 개발용 토큰)
// "/auth/**",
// // Admin Test (테스트용 관리자 계정 생성/토큰 발급)
// "/admin/test/**",
// // H2 Console (local only)
// "/h2-console/**",
// // Swagger
// "/swagger-ui/**",
// "/swagger-ui.html",
// "/v3/api-docs/**",
};
// Root (Swagger 리다이렉트)
"/",
// Actuator
"/actuator/health",
// Auth (로그인, 콜백, 토큰 재발급, 개발용 토큰)
"/auth/**",
// Admin Test (테스트용 관리자 계정 생성/토큰 발급)
"/api/admin/test/**",
// H2 Console (local only)
"/h2-console/**",
// Swagger
"/swagger-ui/**",
"/swagger-ui.html",
"/v3/api-docs/**",

.authorizeHttpRequests(auth -> auth
.requestMatchers(PUBLIC_ENDPOINTS).permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/admin/**").hasRole("ADMIN")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

관리자 API 경로에 대한 권한 설정이 /admin/**으로 되어 있습니다. 하지만 AdminTestController@RequestMapping("/api/admin/test")으로 설정되어 있어, 이 규칙이 적용되지 않습니다. 따라서 관리자 API가 ADMIN 역할 없이도 접근 가능하게 될 수 있습니다. 이전과 같이 /api/admin/**으로 수정해야 합니다.

Suggested change
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/api/admin/**").hasRole("ADMIN")

Comment on lines +52 to +53
boolean adminExists = userRepository.findAll().stream()
.anyMatch(user -> user.getRole() == Role.ADMIN);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

데이터베이스에서 모든 사용자를 가져와 메모리에서 필터링하는 것은 매우 비효율적이며, 사용자 수가 많아지면 성능 문제를 일으킬 수 있습니다. UserRepositoryexistsByRole(Role role)과 같은 쿼리 메서드를 추가하여 데이터베이스 수준에서 확인하는 것이 좋습니다. 이 변경을 적용하려면 UserRepositoryboolean existsByRole(Role role); 메서드를 추가해야 합니다.

        boolean adminExists = userRepository.existsByRole(Role.ADMIN);

Comment on lines +94 to +100
User admin = userRepository.findAll().stream()
.filter(user -> user.getRole() == Role.ADMIN)
.findFirst()
.orElseThrow(() -> {
log.warn("[AdminTestController.issueAdminToken] Admin account not found");
return new CustomException(ErrorCode.MEMBER_NOT_FOUND);
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

createAdminAccount 메서드와 마찬가지로, findAll()을 사용하여 모든 사용자를 가져오는 것은 비효율적입니다. UserRepositoryfindFirstByRole(Role role)과 같은 메서드를 추가하여 ADMIN 권한을 가진 첫 번째 사용자를 직접 조회하는 것이 좋습니다. 이 변경을 적용하려면 UserRepositoryOptional<User> findFirstByRole(Role role); 메서드를 추가해야 합니다.

        User admin = userRepository.findFirstByRole(Role.ADMIN)
                .orElseThrow(() -> {
                    log.warn("[AdminTestController.issueAdminToken] Admin account not found");
                    return new CustomException(ErrorCode.MEMBER_NOT_FOUND);
                });

}

happyMemoryRepository.deleteAllInBatch(memories);
happyMemoryRepository.deleteAll(memories);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

deleteAllInBatch()에서 deleteAll()로 변경하면 성능이 저하될 수 있습니다. deleteAll()은 삭제할 각 엔티티에 대해 별도의 DELETE 쿼리를 생성하는 반면, deleteAllInBatch()는 단일 쿼리로 모든 엔티티를 삭제하므로 훨씬 효율적입니다. Cascade 삭제나 엔티티 생명주기 콜백이 필요한 특별한 경우가 아니라면 deleteAllInBatch()를 사용하는 것이 좋습니다.

Suggested change
happyMemoryRepository.deleteAll(memories);
happyMemoryRepository.deleteAllInBatch(memories);

List<HappyMemory> existing = happyMemoryRepository.findAllByUser(user);
if (!existing.isEmpty()) {
happyMemoryRepository.deleteAllInBatch(existing);
happyMemoryRepository.deleteAll(existing);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

deleteAllInBatch()에서 deleteAll()로 변경하면 성능이 저하될 수 있습니다. deleteAll()은 삭제할 각 엔티티에 대해 별도의 DELETE 쿼리를 생성하는 반면, deleteAllInBatch()는 단일 쿼리로 모든 엔티티를 삭제하므로 훨씬 효율적입니다. Cascade 삭제나 엔티티 생명주기 콜백이 필요한 특별한 경우가 아니라면 deleteAllInBatch()를 사용하는 것이 좋습니다.

Suggested change
happyMemoryRepository.deleteAll(existing);
happyMemoryRepository.deleteAllInBatch(existing);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant