Skip to content

v1.0.0#82

Merged
swthewhite merged 383 commits into
mainfrom
develop
Jan 1, 2026
Merged

v1.0.0#82
swthewhite merged 383 commits into
mainfrom
develop

Conversation

@swthewhite
Copy link
Copy Markdown
Contributor

No description provided.

arkchive and others added 30 commits December 11, 2025 11:36
feat: 토큰 재발급 및 로그아웃 기능 구현
chore: docker compose가 .env를 사용할 수 있도록 개선
feat: 로컬 회원가입 및 로그인 API 구현
marulog and others added 27 commits December 24, 2025 09:41
feat: 버그수정, 신규유저, 업데이트 시각 쿼리 추가
fix: 모니터링을 위해 추가 엔드포인트 인증 예외처리
feat: 로그 모니터링을 위한 환경 구축
fix: 인증/인가 관련 에러 로그 제거
@swthewhite swthewhite merged commit e01d894 into main Jan 1, 2026
1 of 2 checks passed
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

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

This pull request represents a foundational release, v1.0.0, significantly enhancing the backend's capabilities and infrastructure. It establishes a secure, maintainable, and observable application by integrating modern development practices, robust security mechanisms, and essential operational tools. The changes lay the groundwork for future feature development by providing a solid architectural base for user interactions, data processing, and external service integrations.

Highlights

  • Project Setup & Dependencies: Integrated new Gradle plugins for code quality (Checkstyle, JaCoCo, Spotless, SonarQube) and downgraded the Java version from 21 to 17 across the project. Removed MongoDB dependency and added new libraries for JWT, Slack integration, advanced logging (Logstash, Loki), and QueryDSL for enhanced data access.
  • Security & Authentication Overhaul: Implemented a comprehensive JWT-based authentication system with dedicated providers for access and refresh tokens. Introduced custom Spring Security filters and handlers for JWT validation, exception handling, access control, and CORS configuration, ensuring robust API security.
  • New Features: Ranking, User Management & Slack Integration: Added core functionalities for user management (Baekjoon ID verification, sign-up), a dynamic ranking system with period-based aggregation and rank change notifications, and extensive Slack integration for daily rank messages and command handling (e.g., toggling notifications).
  • Code Quality & Observability: Configured Checkstyle and Spotless for automated code style enforcement and formatting. Integrated JaCoCo for code coverage analysis and SonarQube for static code analysis. Enhanced observability with Prometheus metrics, Loki logging, and AOP-based request logging for better monitoring and debugging.
  • Development Workflow Improvements: Introduced structured GitHub issue templates (Bug, CI, Feature, Fix, Refactor, Test) and a pull request template to standardize reporting and review processes. Added .gitattributes for consistent line ending management across different development environments.
Ignored Files
  • Ignored by pattern: .github/workflows/** (2)
    • .github/workflows/deploy.yml
    • .github/workflows/integrate.yml
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
Copy Markdown

@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은 JWT를 사용한 보안, QueryDSL을 사용한 데이터베이스 엔티티 및 리포지토리, 다양한 유틸리티 클래스, 컨트롤러, 서비스, 그리고 Checkstyle, JaCoCo, Spotless, SonarQube와 같은 CI/CD 도구 설정을 포함하여 전체 백엔드 프로젝트 구조를 설정하는 대규모의 새로운 기능들을 도입하고 있습니다. 전반적인 구조는 잘 설계되었으며 최신 Java 및 Spring Boot 관행을 따르고 있습니다.

하지만, 몇 가지 중요하고 심각도가 높은 문제들이 해결되어야 합니다. 가장 중요한 것은 README.md 파일에 SonarCloud 토큰이 하드코딩되어 있다는 점으로, 이는 주요 보안 위험입니다. 또한 오류 처리의 일관성 부족, 잘못된 테스트 케이스, 그리고 정리해야 할 일부 코드가 있습니다.

아래에 이러한 문제들에 대한 구체적인 의견을 남겼습니다. 이 문제들이 해결되면 프로젝트의 매우 견고한 기반이 될 것입니다.

Comment thread README.md
Comment on lines +3 to +4
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ureca-mini2-div4_backend&metric=alert_status&token=a505e5c800bebfddaeda329d3d94e030c1ad8a2a)](https://sonarcloud.io/summary/new_code?id=ureca-mini2-div4_backend)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=ureca-mini2-div4_backend&metric=coverage&token=a505e5c800bebfddaeda329d3d94e030c1ad8a2a)](https://sonarcloud.io/summary/new_code?id=ureca-mini2-div4_backend)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-critical critical

SonarCloud 토큰이 README.md 파일에 하드코딩되어 있습니다. 이는 심각한 보안 취약점입니다. 이 토큰은 GitHub Secrets와 같은 보안 저장소에 저장하고, CI/CD 파이프라인에서 환경 변수로 주입하여 사용해야 합니다. SonarCloud 프로젝트 설정에서 이 토큰을 즉시 폐기하고 새로운 토큰을 발급받는 것을 강력히 권장합니다.

ApiResponse<Void> apiResponse = ApiResponse.error(errorCode);
String responseBody = objectMapper.writeValueAsString(apiResponse);

response.setStatus(errorCode.getStatus().value());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

인증 실패 시 응답 상태 코드를 errorCode.getStatus().value()로 설정하고 있습니다. 이는 다른 예외 핸들러(GlobalExceptionHandler, JwtExceptionFilter)가 항상 200 OK를 반환하는 것과 일관되지 않습니다. API 응답의 일관성을 위해 이 핸들러도 HttpServletResponse.SC_OK를 반환하도록 수정하는 것을 권장합니다. API의 성공/실패 여부는 응답 본문의 success 필드로 판단하는 것이 일관된 설계입니다.

Suggested change
response.setStatus(errorCode.getStatus().value());
response.setStatus(HttpServletResponse.SC_OK);

Comment on lines +27 to +37
String expected = """
🏆 오늘의 랭킹

🥇 1위 유재석 - 7 solved (+48)
🥈 2위 정형돈 - 5 solved (+32)
🥉 3위 노홍철 - 4 solved (+30)
""";

String result = util.formatDailyRank(ranks);

assertThat(result).isEqualTo(expected);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

dailyRankFormatTest 테스트 케이스가 실패할 것으로 보입니다. expected 문자열의 제목은 "🏆 오늘의 랭킹"이지만, MessageFormatUtil의 실제 구현은 "📊 오늘 진행 중인 랭킹"을 생성합니다. 또한, text block을 사용할 때 들여쓰기 문제로 인해 isEqualTo 비교가 실패할 수 있습니다. 테스트가 실제 구현과 일치하도록 수정해야 합니다.

Suggested change
String expected = """
🏆 오늘의 랭킹
🥇 1 유재석 - 7 solved (+48)
🥈 2 정형돈 - 5 solved (+32)
🥉 3 노홍철 - 4 solved (+30)
""";
String result = util.formatDailyRank(ranks);
assertThat(result).isEqualTo(expected);
String expected = "📊 오늘 진행 중인 랭킹\n\n" +
"🥇 1위 유재석 - 7 solved (+48)\n" +
"🥈 2위 정형돈 - 5 solved (+32)\n" +
"🥉 3위 노홍철 - 4 solved (+30)\n";
String result = util.formatDailyRank(ranks);
assertThat(result).isEqualTo(expected);

@@ -0,0 +1 @@

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

로그 파일이 Git 저장소에 포함되어 있습니다. 로그 파일은 일반적으로 버전 관리에서 제외해야 합니다. 프로젝트 루트에 있는 .gitignore 파일에 logs/ 디렉토리를 추가하여 앞으로 로그 파일이 커밋되지 않도록 해주세요.

private final UserDetailsService securityUserDetailsService;
private final JwtProvider accessTokenProvider;
private final AccessDeniedHandler accessDeniedHandler;
private final AspectUtil aspectUtil;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

aspectUtil 필드가 주입되었지만 필터 내에서 사용되지 않고 있습니다. 불필요한 의존성이므로 이 필드와 생성자의 관련 파라미터를 제거하는 것이 좋습니다.

Comment on lines +70 to +88
/** private RankingRowExtendedResponse(RankingRowResponse base, boolean newUser) {
Objects.requireNonNull(base, "base must not be null");

this.userId = base.getUserId();
this.rank = base.getRank();
this.tier = base.getTier();
this.name = base.getName();
this.totalScore = base.getTotalScore();
this.solvedCount = base.getSolvedCount();
this.baekjoonId = base.getBaekjoonId();
this.team = base.getTeam();
this.diff = base.getDiff();
this.newUser = newUser;
}

// ✅ 정적 팩토리 메서드
public static RankingRowExtendedResponse from(RankingRowResponse base, boolean newUser) {
return new RankingRowExtendedResponse(base, newUser);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

주석 처리된 코드가 남아있습니다. 더 이상 사용하지 않는 코드라면 가독성을 위해 제거하는 것이 좋습니다.

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.

5 participants