Skip to content

feat: 회원 도메인/API 개발#1

Merged
bebeis merged 121 commits intomainfrom
development
May 24, 2025
Merged

feat: 회원 도메인/API 개발#1
bebeis merged 121 commits intomainfrom
development

Conversation

@bebeis
Copy link
Contributor

@bebeis bebeis commented May 24, 2025

  1. 음식 추천의 데이터로 사용할 엔티티 개발
  2. Domain Layer 개발
  3. Service Layer 개발
  4. 회원 가입/로그인 API 개발(OAuth, 이메일)
  5. 주소, 예산, 음식 취향 API 개발

Summary by CodeRabbit

  • New Features

    • Introduced comprehensive member, profile, group, budget, food category, and social account management features, including registration, login (email/social), password management, JWT authentication, and address handling.
    • Added REST APIs for member, profile, group, and term management, including endpoints for login, signup, profile editing, address management, category preferences, and budget limits.
    • Implemented OAuth2 login with Google and Kakao, JWT token issuance/refresh, and token blacklisting for secure authentication.
    • Integrated Swagger UI for API documentation and Redis for token management.
    • Provided global error handling with standardized API responses.
  • Bug Fixes

    • Not applicable (initial implementation).
  • Documentation

    • Added Swagger/OpenAPI documentation for API endpoints.
  • Chores

    • Set up CI/CD workflow for automated build and deployment.
    • Updated .gitignore to manage workflow and configuration files.
  • Tests

    • Added extensive unit, integration, and controller tests for all major features to ensure reliability and correctness.

bebeis added 30 commits May 1, 2025 22:48
비밀번호 변경 시 새로운 비밀번호에 대한 Policy 검증 부분을 추가하였습니다.
@coderabbitai
Copy link

coderabbitai bot commented May 24, 2025

Caution

Review failed

Failed to post review comments.

Walkthrough

This update introduces a comprehensive backend foundation for a Spring Boot application, encompassing core domain models, repositories, services, controllers, security, configuration, and CI/CD pipeline. It implements user management, authentication (including JWT and social login), member profiles, address handling, group and budget management, category preferences, terms agreements, and robust error handling. Extensive unit and integration tests are included.

Changes

File(s) / Area Change Summary
.github/workflows/ci-cd.yml, .gitignore, Dockerfile, build.gradle Added CI/CD pipeline, Docker support, Gradle dependencies, and ignore rules for workflow files.
src/main/java/com/stcom/smartmealtable/SmartmealtableApplication.java Enabled JPA auditing in main application class.
src/main/java/com/stcom/smartmealtable/config/SwaggerConfig.java Added Swagger/OpenAPI configuration for API documentation and JWT security scheme.
Domain: domain/Address, domain/Budget, domain/common, domain/food, domain/group, Introduced core domain entities: Address, Budget (with Daily/Monthly), Base entities, FoodCategory, Group (Company/School),
domain/member, domain/social, domain/term Member, SocialAccount, Term, enums, and supporting classes.
src/main/java/com/stcom/smartmealtable/exception/ Added custom exceptions for password policies, external API errors, etc.
src/main/java/com/stcom/smartmealtable/infrastructure/, infrastructure/config, infrastructure/dto Added Redis config, DTOs, Kakao/Google social login, address API integration, year-month converter.
src/main/java/com/stcom/smartmealtable/repository/ Added JPA repositories for all major domain entities with custom queries where needed.
src/main/java/com/stcom/smartmealtable/security/ Introduced JWT token service, blacklist service for token revocation.
src/main/java/com/stcom/smartmealtable/service/ Implemented business logic: member, profile, login, social account, group, budget, preferences, terms, etc.
src/main/java/com/stcom/smartmealtable/service/dto/ Added DTOs for authentication, member, and term agreement flows.
src/main/java/com/stcom/smartmealtable/web/ Added WebConfig, argument resolver for user context, JWT interceptor, and REST controllers for member, profile, group, term, login.
src/main/java/com/stcom/smartmealtable/web/dto/ApiResponse.java Standardized API response wrapper with success, fail, and error formats.
src/main/java/com/stcom/smartmealtable/web/exhandler/ExControllerAdvice.java Added global exception handling for REST APIs.
src/test/java/com/stcom/smartmealtable/ Added extensive unit and integration tests for domain, service, repository, controller, and infrastructure layers.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant LoginController
    participant LoginService
    participant MemberRepository
    participant JwtTokenService

    Client->>LoginController: POST /api/v1/auth/login (email, password)
    LoginController->>LoginService: loginWithEmail(email, password)
    LoginService->>MemberRepository: findByEmail(email)
    MemberRepository-->>LoginService: Member
    LoginService-->>LoginController: AuthResultDto (memberId, profileId, newUser)
    LoginController->>JwtTokenService: createTokenDto(memberId, profileId)
    JwtTokenService-->>LoginController: JwtTokenResponseDto
    LoginController-->>Client: ApiResponse<JwtTokenResponseDto>
Loading
sequenceDiagram
    participant Client
    participant OAuth2Controller
    participant SocialAuthService
    participant LoginService
    participant JwtTokenService

    Client->>OAuth2Controller: POST /api/v1/auth/oauth2/code (provider, code)
    OAuth2Controller->>SocialAuthService: getTokenResponse(provider, code)
    SocialAuthService-->>OAuth2Controller: TokenDto
    OAuth2Controller->>LoginService: socialLogin(TokenDto)
    LoginService-->>OAuth2Controller: AuthResultDto
    OAuth2Controller->>JwtTokenService: createTokenDto(memberId, profileId)
    JwtTokenService-->>OAuth2Controller: JwtTokenResponseDto
    OAuth2Controller-->>Client: ApiResponse<JwtTokenResponseDto>
Loading
sequenceDiagram
    participant Client
    participant MemberProfileController
    participant MemberProfileService
    participant MemberProfileRepository

    Client->>MemberProfileController: GET /api/v1/members/profile/me
    MemberProfileController->>MemberProfileService: getProfileFetch(profileId)
    MemberProfileService->>MemberProfileRepository: findMemberProfileEntityGraphById(profileId)
    MemberProfileRepository-->>MemberProfileService: MemberProfile
    MemberProfileService-->>MemberProfileController: MemberProfile
    MemberProfileController-->>Client: ApiResponse<MemberProfilePageResponse>
Loading

Poem

A warren of code, a garden anew,
With Spring Boot roots and CI that grew.
JWT hops, profiles bloom,
Social logins chase away the gloom.
Tests abound, so bugs are few—
This rabbit's proud of what you do!
🐇🌱🚀

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@bebeis bebeis merged commit 1e7eaca into main May 24, 2025
3 checks passed
@bebeis bebeis requested a review from Copilot September 7, 2025 12:42
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

이 PR은 음식 추천 서비스의 기본적인 회원 관리 시스템을 구축하는 것을 목적으로 하며, 회원 도메인, 인증/권한, 음식 취향 관리, 예산 관리 등의 핵심 기능을 포함합니다.

  • 완전한 회원 관리 시스템 (가입, 로그인, 프로필 관리)
  • OAuth2 소셜 로그인 지원 (카카오, 구글)
  • JWT 기반 인증 및 토큰 블랙리스트 관리
  • 음식 카테고리 선호도 및 예산 관리 기능

Reviewed Changes

Copilot reviewed 106 out of 108 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
table.ddl 회원, 프로필, 예산, 음식 취향 등 핵심 데이터베이스 스키마 정의
domain/ 회원, 그룹, 주소, 예산, 음식 카테고리 등 도메인 객체 구현
service/ 비즈니스 로직 처리 (로그인, 회원관리, 프로필관리, 소셜계정 관리)
web/controller/ REST API 엔드포인트 구현
security/ JWT 토큰 서비스 및 블랙리스트 관리
infrastructure/ 외부 API 연동 (소셜 로그인, 주소 검색)
test/ 단위 테스트, 통합 테스트, 컨트롤러 테스트

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@RequestBody JwtRefreshTokenRequest request) {
String accessToken = jwtTokenService.createAccessToken(memberDto.getMemberId(), memberDto.getProfileId());
return ApiResponse.createSuccess(
new JwtRefreshedAccessTokenDto(accessToken, 3600, "Bearar")
Copy link

Copilot AI Sep 7, 2025

Choose a reason for hiding this comment

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

Line 52에서 'Bearar'는 'Bearer'의 오타입니다.

Suggested change
new JwtRefreshedAccessTokenDto(accessToken, 3600, "Bearar")
new JwtRefreshedAccessTokenDto(accessToken, 3600, "Bearer")

Copilot uses AI. Check for mistakes.

void deleteMemberProfileByMember(Member member);

@EntityGraph(attributePaths = {"member", "addressHistory, group"})
Copy link

Copilot AI Sep 7, 2025

Choose a reason for hiding this comment

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

Line 18에서 문자열 형식이 잘못되었습니다. 'addressHistory, group' 대신 'addressHistory', 'group'으로 분리하거나 따옴표를 올바르게 처리해야 합니다.

Suggested change
@EntityGraph(attributePaths = {"member", "addressHistory, group"})
@EntityGraph(attributePaths = {"member", "addressHistory", "group"})

Copilot uses AI. Check for mistakes.
}

public boolean isProfileRegistered() {
return memberProfile == null;
Copy link

Copilot AI Sep 7, 2025

Choose a reason for hiding this comment

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

로직이 반대입니다. 프로필이 등록되어 있으면 true를 반환해야 하므로 'return memberProfile != null;'이어야 합니다.

Suggested change
return memberProfile == null;
return memberProfile != null;

Copilot uses AI. Check for mistakes.
if (!findMember.isMatchedPassword(password)) {
throw new IllegalArgumentException("비밀번호가 일치하지 않습니다");
}
boolean newUser = findMember.isProfileRegistered();
Copy link

Copilot AI Sep 7, 2025

Choose a reason for hiding this comment

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

isProfileRegistered() 메서드의 로직이 반대이므로, 여기서도 논리가 반전되어야 합니다. newUser 변수는 !findMember.isProfileRegistered()여야 하거나, 조건문을 수정해야 합니다.

Suggested change
boolean newUser = findMember.isProfileRegistered();
boolean newUser = !findMember.isProfileRegistered();

Copilot uses AI. Check for mistakes.
@Override
public Group findGroupByGroupId(Long groupId) {
return groupRepository.findById(groupId)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다"));
Copy link

Copilot AI Sep 7, 2025

Choose a reason for hiding this comment

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

그룹을 찾는 메서드에서 에러 메시지가 '존재하지 않는 회원입니다'로 잘못되어 있습니다. '존재하지 않는 그룹입니다'로 수정해야 합니다.

Suggested change
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다"));
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 그룹입니다"));

Copilot uses AI. Check for mistakes.
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