Skip to content

dev ➡️ main 반영#83

Merged
JayongLee merged 48 commits intomainfrom
dev
Sep 29, 2025
Merged

dev ➡️ main 반영#83
JayongLee merged 48 commits intomainfrom
dev

Conversation

@JayongLee
Copy link
Member

@JayongLee JayongLee commented Sep 29, 2025

No description provided.

JayongLee and others added 30 commits September 11, 2025 13:56
[refactor] 블로그 상세조회 응답 DTO에 수정 가능 여부 반환 & @userid 관련 수정 / #64
[refactor] Blog/Project 기본 정보 응답 DTO 필드에 생성일/수정일 추가 / #68
[refactor] Progress Enum 값 변경
[refactor] Category Enum 값 변경 / #71
[feat] 블로그 글 수정 및 삭제 api 구현 / #66
[refactor] 허용 / 거부 URI List로 추출 및 List를 통해 검증로직을 수행하도록 수정 / #75
JayongLee and others added 18 commits September 25, 2025 18:14
[chore] 블로그 업데이트 엔드포인트 오류 수정
[feat] 구글 API를 이용한 유저 프로필 이미지 조회 및 저장 / #78
[feat] 프로젝트 삭제 & 프로젝트-멤버 추가, 삭제 API 구현 / #63
@gemini-code-assist
Copy link

Summary of Changes

Hello @JayongLee, 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!

이 Pull Request는 블로그 및 프로젝트 관리 기능을 대폭 확장하고 개선하는 것을 목표로 합니다. 블로그 게시글의 생성, 조회, 수정, 삭제 기능을 완성하고, 프로젝트 멤버 관리 기능을 추가하여 사용자 경험을 향상시켰습니다. 또한, 데이터 모델과 API 응답 구조를 재정비하고, 인증 및 권한 처리 로직을 강화하여 시스템의 안정성과 유연성을 높였습니다.

Highlights

  • 블로그 CRUD 기능 추가 및 개선: 블로그 게시글 수정 및 삭제 기능이 추가되었으며, 블로그 상세 조회 시 작성자 여부를 확인할 수 있도록 개선되었습니다. 또한, 블로그 생성/수정 요청 DTO가 통합되고, 블로그 엔티티에 업데이트 로직이 추가되었습니다.
  • 프로젝트 관리 기능 확장: 프로젝트 삭제, 멤버 추가 및 삭제 기능이 추가되었습니다. 프로젝트 리더만 해당 작업을 수행할 수 있도록 권한 검증 로직이 포함되었습니다.
  • 블로그 카테고리 및 진행 상태(Progress) 세분화: 블로그 카테고리(Category)와 진행 상태(ProgressValue) Enum이 확장되어 '회고', '트러블슈팅', '딥다이브', '기타' 등 더 다양한 유형의 게시글을 지원하고 각 유형에 맞는 세부 진행 상태를 정의했습니다.
  • 인증 및 권한 처리 강화: JWT 인증 필터가 익명 사용자 접근을 허용하도록 개선되었으며, 특정 URL에 대한 접근 제어 로직이 추가되었습니다. 또한, AccessDeniedException 핸들링이 전역 예외 처리기에 추가되었습니다.
  • 사용자 프로필 정보 동기화 및 표시: 로그인 시 Google 프로필 이미지 URL이 동기화되도록 Member 엔티티에 profileUrl 필드가 추가되었고, 블로그 기본 정보 및 상세 정보 응답 DTO에 작성자의 프로필 URL이 포함되도록 개선되었습니다.
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.

@JayongLee JayongLee merged commit ac9a5ce into main Sep 29, 2025
3 checks passed
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은 블로그 CRUD, 프로젝트 멤버 관리 등 많은 기능 추가와 개선이 이루어졌습니다. 전반적으로 코드 품질이 좋고, 새로운 기능들이 잘 구현되었습니다. 몇 가지 개선점을 제안합니다. 프로젝트 삭제 시 관련된 블로그 게시글이 삭제되지 않는 심각한 버그가 있어 수정이 필요합니다. 또한, 서비스 로직의 효율성을 높이기 위한 최적화와 필터의 인가 로직을 더 명확하게 리팩토링하는 것을 제안합니다.

Comment on lines +134 to +140
public void deleteProject(Long projectId, Long leaderId) {
Project project = findProjectBy(projectId);
// TODO : Spring Interceptor를 적용하여 추후 분리
checkAccessPermission(projectId, leaderId);
List<ProjectMember> projectMembers = projectMemberRepository.findAllByProject(project);
projectMemberRepository.deleteAll(projectMembers);
projectRepository.delete(project);

Choose a reason for hiding this comment

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

critical

프로젝트 삭제 시 해당 프로젝트에 속한 블로그 게시글들을 처리하지 않아 외래 키 제약 조건 위반으로 DataIntegrityViolationException이 발생할 수 있습니다. 프로젝트에 속한 Blog 엔티티를 먼저 삭제한 후, ProjectMemberProject를 삭제해야 합니다. 또한, 불필요한 데이터베이스 조회를 피하기 위해 권한 확인 로직을 먼저 수행하는 것이 좋습니다.

    public void deleteProject(Long projectId, Long leaderId) {
        // TODO : Spring Interceptor를 적용하여 추후 분리
        checkAccessPermission(projectId, leaderId);
        Project project = findProjectBy(projectId);

        blogRepository.deleteAll(blogRepository.findAllByProject(project));

        List<ProjectMember> projectMembers = projectMemberRepository.findAllByProject(project);
        projectMemberRepository.deleteAll(projectMembers);
        projectRepository.delete(project);
    }

*/
@Transactional
public BlogDetailInfoRes getBlogInfo(Long postId) {
public BlogDetailInfoRes getBlogInfo(Optional<Long> memberId, Long postId) {

Choose a reason for hiding this comment

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

medium

로그인한 사용자가 글 작성자인지 확인하는 로직을 getBlogInfo 메서드에 추가하셨는데, 이 로직을 블로그 수정(updateBlog) 및 삭제(deleteBlog) 시에도 활용할 수 있도록 findBlogAndCheckOwnerShip 메서드 내에서 처리하는 것이 더 일관성 있고 재사용성이 높습니다. 현재는 updateBlogdeleteBlog에서만 소유권 확인을 하고 있어, getBlogInfo에서도 동일한 로직을 사용하면 중복을 줄일 수 있습니다.

Comment on lines +151 to +154
Project project = findProjectBy(projectId);
Member requestMember = findMemberBy(memberId);
// TODO : Spring Interceptor를 적용하여 추후 분리
checkAccessPermission(projectId, leaderId);

Choose a reason for hiding this comment

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

medium

데이터베이스에서 ProjectMember 엔티티를 조회하기 전에 권한 확인을 먼저 수행하는 것이 더 효율적입니다. 사용자가 권한이 없는 경우 불필요한 데이터베이스 조회를 피할 수 있습니다.

        // TODO : Spring Interceptor를 적용하여 추후 분리
        checkAccessPermission(projectId, leaderId);
        Project project = findProjectBy(projectId);
        Member requestMember = findMemberBy(memberId);

Comment on lines +93 to +108
private boolean isPermit(final HttpServletRequest request) {
String uri = request.getRequestURI();

if ("GET".equalsIgnoreCase(request.getMethod())) {
// DENY_URL 리스트에 존재하는 URL 요청일 경우 거부
if (DENY_URL.stream().anyMatch(deny -> pathMatcher.match(deny, uri))) {
return false;
}
// PERMIT_URL 리스트에 존재하는 URL 요청일 경우 허용
if (PERMIT_URL.stream().anyMatch(permit -> pathMatcher.match(permit, uri))) {
return true;
}
}
// DENY_URL, PERMIT_URL 외의 WhiteList URL들의 경우엔 허용
return whiteList.stream().anyMatch(pattern -> pathMatcher.match(pattern, uri));
}

Choose a reason for hiding this comment

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

medium

isPermit 메서드의 인증/인가 로직이 복잡하고 여러 리스트(DENY_URL, PERMIT_URL, whiteList)에 분산되어 있어 유지보수가 어렵습니다. 특히 GET 요청에 대한 특별 처리는 전체적인 규칙을 파악하기 어렵게 만듭니다. Spring Security의 SecurityFilterChain 설정 내에서 requestMatchers를 사용하여 선언적으로 경로와 HTTP 메서드에 따른 접근 제어 규칙을 중앙에서 관리하는 것이 더 명확하고 일반적인 방법입니다. 이렇게 하면 코드의 가독성이 향상되고 보안 규칙을 한 곳에서 관리할 수 있습니다.

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.

2 participants