Skip to content

Main <- Develop#171

Merged
Seol-JY merged 14 commits intomainfrom
develop
Mar 23, 2026
Merged

Main <- Develop#171
Seol-JY merged 14 commits intomainfrom
develop

Conversation

@Seol-JY
Copy link
Copy Markdown
Member

@Seol-JY Seol-JY commented Mar 23, 2026

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 관리자 계정 관리 기능 추가
    • 사용자 문의 제출, 조회, 수정 기능 구현
    • 관리자 문의 답변 및 관리 기능 추가
    • 문의에 이미지 첨부 기능 지원
  • 개선 사항

    • 이벤트 상세 정보 필드명 및 설명 개선

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 23, 2026

Caution

Review failed

The pull request is closed.

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'auto_resolve_threads', 'spring_specific'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • 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
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fee20418-afd7-4d48-acd6-6467ead32de5

📥 Commits

Reviewing files that changed from the base of the PR and between f5ce561 and 9f24240.

⛔ Files ignored due to path filters (1)
  • README.md is excluded by !**/README.md
📒 Files selected for processing (58)
  • sql/init.sql
  • src/main/java/im/toduck/domain/admin/common/mapper/AdminMapper.java
  • src/main/java/im/toduck/domain/admin/domain/service/AdminService.java
  • src/main/java/im/toduck/domain/admin/domain/usecase/AdminUseCase.java
  • src/main/java/im/toduck/domain/admin/persistence/entity/Admin.java
  • src/main/java/im/toduck/domain/admin/persistence/repository/AdminRepository.java
  • src/main/java/im/toduck/domain/admin/persistence/repository/querydsl/AdminRepositoryCustom.java
  • src/main/java/im/toduck/domain/admin/persistence/repository/querydsl/AdminRepositoryCustomImpl.java
  • src/main/java/im/toduck/domain/admin/presentation/api/AdminApi.java
  • src/main/java/im/toduck/domain/admin/presentation/controller/AdminController.java
  • src/main/java/im/toduck/domain/admin/presentation/dto/request/AdminCreateRequest.java
  • src/main/java/im/toduck/domain/admin/presentation/dto/request/AdminUpdateRequest.java
  • src/main/java/im/toduck/domain/admin/presentation/dto/response/AdminListResponse.java
  • src/main/java/im/toduck/domain/admin/presentation/dto/response/AdminResponse.java
  • src/main/java/im/toduck/domain/diary/domain/service/DiaryService.java
  • src/main/java/im/toduck/domain/diary/domain/usecase/DiaryUseCase.java
  • src/main/java/im/toduck/domain/diary/persistence/entity/Diary.java
  • src/main/java/im/toduck/domain/diary/persistence/entity/DiaryImage.java
  • src/main/java/im/toduck/domain/events/detail/domain/service/EventsDetailService.java
  • src/main/java/im/toduck/domain/events/detail/domain/usecase/EventsDetailUseCase.java
  • src/main/java/im/toduck/domain/events/detail/persistence/entity/EventsDetail.java
  • src/main/java/im/toduck/domain/events/detail/persistence/entity/EventsDetailImg.java
  • src/main/java/im/toduck/domain/events/detail/presentation/api/EventsDetailApi.java
  • src/main/java/im/toduck/domain/events/detail/presentation/dto/request/EventsDetailCreateRequest.java
  • src/main/java/im/toduck/domain/events/detail/presentation/dto/response/EventsDetailResponse.java
  • src/main/java/im/toduck/domain/inquiry/common/mapper/InquiryImgMapper.java
  • src/main/java/im/toduck/domain/inquiry/common/mapper/InquiryMapper.java
  • src/main/java/im/toduck/domain/inquiry/domain/service/InquiryAnswerService.java
  • src/main/java/im/toduck/domain/inquiry/domain/service/InquiryService.java
  • src/main/java/im/toduck/domain/inquiry/domain/usecase/InquiryAnswerUseCase.java
  • src/main/java/im/toduck/domain/inquiry/domain/usecase/InquiryUseCase.java
  • src/main/java/im/toduck/domain/inquiry/persistence/entity/Inquiry.java
  • src/main/java/im/toduck/domain/inquiry/persistence/entity/InquiryAnswer.java
  • src/main/java/im/toduck/domain/inquiry/persistence/entity/InquiryImage.java
  • src/main/java/im/toduck/domain/inquiry/persistence/entity/Status.java
  • src/main/java/im/toduck/domain/inquiry/persistence/entity/Type.java
  • src/main/java/im/toduck/domain/inquiry/persistence/repository/InquiryAnswerRepository.java
  • src/main/java/im/toduck/domain/inquiry/persistence/repository/InquiryImgRepository.java
  • src/main/java/im/toduck/domain/inquiry/persistence/repository/InquiryRepository.java
  • src/main/java/im/toduck/domain/inquiry/persistence/repository/querydsl/InquiryRepositoryCustom.java
  • src/main/java/im/toduck/domain/inquiry/persistence/repository/querydsl/InquiryRepositoryCustomImpl.java
  • src/main/java/im/toduck/domain/inquiry/presentation/api/InquiryAnswerApi.java
  • src/main/java/im/toduck/domain/inquiry/presentation/api/InquiryApi.java
  • src/main/java/im/toduck/domain/inquiry/presentation/controller/InquiryAnswerController.java
  • src/main/java/im/toduck/domain/inquiry/presentation/controller/InquiryController.java
  • src/main/java/im/toduck/domain/inquiry/presentation/dto/request/InquiryAnswerCreateRequest.java
  • src/main/java/im/toduck/domain/inquiry/presentation/dto/request/InquiryAnswerUpdateRequest.java
  • src/main/java/im/toduck/domain/inquiry/presentation/dto/request/InquiryCreateRequest.java
  • src/main/java/im/toduck/domain/inquiry/presentation/dto/request/InquiryUpdateRequest.java
  • src/main/java/im/toduck/domain/inquiry/presentation/dto/response/InquiryListResponse.java
  • src/main/java/im/toduck/domain/inquiry/presentation/dto/response/InquiryResponse.java
  • src/main/java/im/toduck/domain/mypage/domain/usecase/MyPageUseCase.java
  • src/main/java/im/toduck/domain/user/persistence/entity/User.java
  • src/main/java/im/toduck/global/exception/ExceptionCode.java
  • src/test/java/im/toduck/domain/admin/presentation/controller/AdminControllerTest.java
  • src/test/java/im/toduck/domain/events/detail/domain/usecase/EventsDetailUseCaseTest.java
  • src/test/java/im/toduck/domain/inquiry/presentation/controller/InquiryAnswerControllerTest.java
  • src/test/java/im/toduck/domain/inquiry/presentation/controller/InquiryControllerTest.java

Walkthrough

데이터베이스 스키마에 관리자, 문의, 문의 이미지, 문의 답변 테이블을 추가하고, 관리자와 문의 관리 기능을 위한 엔티티, 저장소, 서비스, 컨트롤러, DTO, 매퍼를 구현했습니다. 일기 및 이벤트 상세 도메인의 soft-delete 처리를 조정했습니다.

Changes

Cohort / File(s) Summary
Database Schema
sql/init.sql
admin, inquiry, inquiry_image_file, inquiry_answer 테이블 추가. 관리자-사용자 1:1 관계, 문의-사용자 M:1 관계, 문의답변-관리자 M:1 및 문의-답변 1:1 관계 정의.
Admin Domain Layer
src/main/java/im/toduck/domain/admin/persistence/entity/Admin.java, ...repository/AdminRepository.java, ...repository/querydsl/AdminRepositoryCustom.java, ...repository/querydsl/AdminRepositoryCustomImpl.java, ...domain/service/AdminService.java, ...domain/usecase/AdminUseCase.java
관리자 엔티티, 저장소, 커스텀 QueryDSL 쿼리, 서비스(조회/생성/수정/삭제), 유스케이스(역할 승격/강등) 구현.
Admin Presentation Layer
src/main/java/im/toduck/domain/admin/presentation/api/AdminApi.java, ...controller/AdminController.java, ...common/mapper/AdminMapper.java, ...dto/request/AdminCreateRequest.java, ...dto/request/AdminUpdateRequest.java, ...dto/response/AdminResponse.java, ...dto/response/AdminListResponse.java
관리자 REST API, 컨트롤러, 매퍼, 요청/응답 DTO 정의. ROLE_ADMIN 권한 제한 적용.
Inquiry Domain Layer
src/main/java/im/toduck/domain/inquiry/persistence/entity/Inquiry.java, ...entity/InquiryImage.java, ...entity/InquiryAnswer.java, ...entity/Type.java, ...entity/Status.java, ...repository/InquiryRepository.java, ...repository/InquiryImgRepository.java, ...repository/InquiryAnswerRepository.java, ...repository/querydsl/InquiryRepositoryCustom.java, ...repository/querydsl/InquiryRepositoryCustomImpl.java, ...domain/service/InquiryService.java, ...domain/service/InquiryAnswerService.java, ...domain/usecase/InquiryUseCase.java, ...domain/usecase/InquiryAnswerUseCase.java
문의/문의답변 엔티티, Type/Status 열거형, 저장소, 커스텀 쿼리, 서비스(CRUD/답변 관리), 유스케이스 구현.
Inquiry Presentation Layer
src/main/java/im/toduck/domain/inquiry/presentation/api/InquiryApi.java, ...api/InquiryAnswerApi.java, ...controller/InquiryController.java, ...controller/InquiryAnswerController.java, ...common/mapper/InquiryMapper.java, ...common/mapper/InquiryImgMapper.java, ...dto/request/InquiryCreateRequest.java, ...dto/request/InquiryUpdateRequest.java, ...dto/request/InquiryAnswerCreateRequest.java, ...dto/request/InquiryAnswerUpdateRequest.java, ...dto/response/InquiryResponse.java, ...dto/response/InquiryListResponse.java
문의/문의답변 REST API, 컨트롤러, 매퍼, 요청/응답 DTO. 사용자 소유권 검증 및 ADMIN 역할 제한 적용.
Supporting Domain Changes
src/main/java/im/toduck/domain/diary/persistence/entity/Diary.java, ...persistence/entity/DiaryImage.java, ...domain/service/DiaryService.java, ...domain/usecase/DiaryUseCase.java
Diary.diaryImages에서 orphanRemoval=true 제거. DiaryImage의 Hibernate soft-delete 어노테이션 삭제. 이미지 soft-delete를 유스케이스에서 명시적으로 관리.
Events Detail Domain Changes
src/main/java/im/toduck/domain/events/detail/persistence/entity/EventsDetail.java, ...persistence/entity/EventsDetailImg.java, ...domain/service/EventsDetailService.java, ...domain/usecase/EventsDetailUseCase.java, ...presentation/api/EventsDetailApi.java, ...presentation/dto/request/EventsDetailCreateRequest.java, ...presentation/dto/response/EventsDetailResponse.java
EventsDetail.eventsDetailImgs에서 orphanRemoval=true 제거. EventsDetailImg의 soft-delete 어노테이션 삭제 및 softDelete() 메서드 추가. 메서드명 오타 수정(addEventsDetailImgesaddEventsDetailImages). API 문서화 개선.
Global Exceptions & User Domain
src/main/java/im/toduck/global/exception/ExceptionCode.java, ...domain/user/persistence/entity/User.java, ...domain/mypage/domain/usecase/MyPageUseCase.java
문의/관리자 관련 6개 새 예외 코드 추가. UserpromoteToAdmin() / demoteToUser() 메서드 추가. 계정 삭제 시 관리자 데이터 함께 삭제.
Test Classes
src/test/java/im/toduck/domain/admin/presentation/controller/AdminControllerTest.java, ...inquiry/presentation/controller/InquiryControllerTest.java, ...inquiry/presentation/controller/InquiryAnswerControllerTest.java, ...events/detail/domain/usecase/EventsDetailUseCaseTest.java
관리자 CRUD, 문의/문의답변 생성/수정/삭제, soft-delete 동작, 권한 검증, 상태 전이 통합 테스트 추가.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant InquiryController
    participant InquiryUseCase
    participant UserService
    participant InquiryService
    participant InquiryRepository
    
    User->>InquiryController: POST /v1/inquiries (InquiryCreateRequest)
    InquiryController->>InquiryUseCase: createInquiry(request, userId)
    InquiryUseCase->>UserService: getUser(userId)
    UserService-->>InquiryUseCase: User
    InquiryUseCase->>InquiryService: createInquiry(request, user)
    InquiryService->>InquiryRepository: save(inquiry)
    InquiryRepository-->>InquiryService: saved Inquiry
    InquiryUseCase->>InquiryService: addInquiryImages(inquiry, imgUrls)
    InquiryService->>InquiryRepository: saveAll(inquiryImages)
    InquiryRepository-->>InquiryService: saved Images
    InquiryUseCase-->>InquiryController: Inquiry
    InquiryController-->>User: 201 Created
Loading
sequenceDiagram
    actor Admin
    participant InquiryAnswerController
    participant InquiryAnswerUseCase
    participant UserService
    participant AdminService
    participant InquiryAnswerService
    participant InquiryService
    participant InquiryRepository
    
    Admin->>InquiryAnswerController: POST /v1/inquiry-answers (InquiryAnswerCreateRequest)
    InquiryAnswerController->>InquiryAnswerUseCase: createInquiryAnswer(request, adminUserId)
    InquiryAnswerUseCase->>UserService: getUser(adminUserId)
    UserService-->>InquiryAnswerUseCase: User
    InquiryAnswerUseCase->>AdminService: getAdminBySameUser(userId)
    AdminService-->>InquiryAnswerUseCase: Admin
    InquiryAnswerUseCase->>InquiryAnswerService: createInquiryAnswer(request, admin)
    InquiryAnswerService->>InquiryService: getInquiryById(inquiryId)
    InquiryService-->>InquiryAnswerService: Inquiry
    InquiryAnswerService->>InquiryRepository: findAnyByInquiryIdIncludingDeleted()
    InquiryRepository-->>InquiryAnswerService: Optional(existing answer)
    alt Answer exists (not deleted)
        InquiryAnswerService-->>InquiryAnswerUseCase: CommonException(ALREADY_ANSWERED)
    else Answer deleted or not exists
        InquiryAnswerService->>InquiryAnswerService: createInquiryAnswer entity
        InquiryAnswerService->>InquiryRepository: save(inquiry with answer)
        InquiryRepository-->>InquiryAnswerService: saved
    end
    InquiryAnswerUseCase-->>InquiryAnswerController: InquiryAnswer
    InquiryAnswerController-->>Admin: 200 OK
Loading
sequenceDiagram
    actor User
    participant InquiryController
    participant InquiryUseCase
    participant UserService
    participant InquiryService
    participant InquiryRepository
    
    User->>InquiryController: PATCH /v1/inquiries/{inquiryId} (InquiryUpdateRequest)
    InquiryController->>InquiryUseCase: updateInquiry(inquiryId, request, userId)
    InquiryUseCase->>UserService: getUser(userId)
    UserService-->>InquiryUseCase: User
    InquiryUseCase->>InquiryService: getInquiryById(inquiryId)
    InquiryService-->>InquiryUseCase: Inquiry
    alt User owns inquiry and no answer exists
        InquiryUseCase->>InquiryService: updateInquiry(request, inquiry)
        InquiryService->>InquiryRepository: delete(old images)
        InquiryService->>InquiryRepository: saveAll(new images)
        InquiryRepository-->>InquiryService: saved
        InquiryService-->>InquiryUseCase: void
    else Unauthorized or already answered
        InquiryUseCase-->>InquiryController: CommonException
    end
    InquiryUseCase-->>InquiryController: Inquiry
    InquiryController-->>User: 200 OK
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • PR #166: 동일한 관리자 및 문의 기능을 구현하며, 동일한 데이터베이스 테이블(admin, inquiry, inquiry_image_file, inquiry_answer)과 대응하는 Java 아티팩트(엔티티, 저장소, 서비스, 유스케이스, 컨트롤러)를 추가합니다.
  • PR #142: 이벤트 상세 도메인의 동일한 코드를 수정하며, EventsDetailService, EventsDetailUseCase, EventsDetailImg/EventsDetail 엔티티 매핑 및 이미지 처리 메서드를 변경합니다.
  • PR #141: 동일한 핵심 파일(User.java, ExceptionCode)을 수정하며, 사용자 역할/관리자 메서드와 새 예외 코드를 추가합니다.

Suggested labels

✨ Feature

Suggested reviewers

  • wafla
  • kang20
  • Junad-Park

Poem

🐰 관리자가 나타나고 문의가 날아오네,
데이터베이스에 네 테이블이 춤을 춘다네,
CRUD의 환희, 권한의 검증,
이제 토덕은 더욱 똑똑해졌네!
날개짓하며 기뻐하는 우리 토끼 🐇✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Seol-JY Seol-JY merged commit 5b1f141 into main Mar 23, 2026
2 of 4 checks passed
@github-actions
Copy link
Copy Markdown

📝 Jacoco Test Coverage

Overall Project 51.24% -1.26% 🍏
Files changed 73.91% 🍏

File Coverage
AdminRepositoryCustomImpl.java 100% 🍏
InquiryMapper.java 100% 🍏
InquiryListResponse.java 100% 🍏
InquiryRepositoryCustomImpl.java 100% 🍏
InquiryService.java 100% 🍏
Type.java 100% 🍏
Status.java 100% 🍏
AdminMapper.java 100% 🍏
ExceptionCode.java 99.68% 🍏
InquiryAnswerUseCase.java 90.48% -9.52% 🍏
Inquiry.java 90% -10% 🍏
AdminUpdateRequest.java 87.1% -12.9% 🍏
InquiryAnswerUpdateRequest.java 87.1% -12.9% 🍏
AdminCreateRequest.java 86.96% -13.04% 🍏
InquiryAnswerCreateRequest.java 86.96% -13.04% 🍏
EventsDetail.java 86.73% 🍏
AdminListResponse.java 86.49% -13.51% 🍏
EventsDetailCreateRequest.java 85.87% 🍏
EventsDetailUseCase.java 85.71% 🍏
InquiryCreateRequest.java 84.13% -15.87% 🍏
InquiryUpdateRequest.java 84.13% -15.87% 🍏
EventsDetailService.java 82.05% -3.85%
Admin.java 81.97% -18.03% 🍏
MyPageUseCase.java 79.79% -5.18%
AdminUseCase.java 77.39% -22.61% 🍏
InquiryUseCase.java 76.65% -23.35% 🍏
InquiryAnswer.java 75.53% -24.47% 🍏
Diary.java 74.48% 🍏
User.java 72.46% 🍏
InquiryAnswerService.java 72.18% -27.82% 🍏
InquiryImgMapper.java 70% -30% 🍏
AdminService.java 65.25% -34.75% 🍏
DiaryImage.java 64.91% 🍏
InquiryImage.java 64.91% -35.09% 🍏
EventsDetailImg.java 56.92% -6.15%
DiaryService.java 40.5% 🍏
InquiryResponse.java 31.58% -68.42%
DiaryUseCase.java 30.28% -1.83%
AdminResponse.java 29.51% -70.49%
EventsDetailResponse.java 28.04% 🍏
InquiryAnswerController.java 16.22% -83.78%
AdminController.java 12.24% -87.76%
InquiryController.java 10.17% -89.83%

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