Skip to content

Develop -> main 머지#158

Merged
CheChe903 merged 81 commits intomainfrom
develop
Mar 23, 2026
Merged

Develop -> main 머지#158
CheChe903 merged 81 commits intomainfrom
develop

Conversation

@CheChe903
Copy link
Copy Markdown
Member

No description provided.

2Jin1031 and others added 30 commits November 9, 2025 17:48
tmp: 임시 dev cd 트리거
2Jin1031 and others added 26 commits December 14, 2025 20:20
feat: ssh가 아닌 self hosted 로 접근
feat: prod CI / CD 파이프라인 구축
* refactor: 코틀린 파일 삭제 및 자바 파일 추가

* fix: 테스트 오류 수정
- 조직 문서와 크루 문서 모두가 조회되는지 확인한다.
test: 문서 조회 테스트 추가
feat: 특정 문서에 대한 조직 문서 삭제 API 구현
* feat: DTO 네이밍 및 공용 래퍼 정리

record 전환과 이름 규칙을 반영해 공용 요청/응답 DTO를 정리하고 관련 사용처를 갱신

* feat: 테스트 네이밍 규칙 적용

@nested 클래스명과 테스트 메서드명을 규칙에 맞게 정리

* feat: 컨벤션 문서 추가

프로젝트 규칙을 한국어로 정리하고 예시를 추가
[FEAT] 일반 문서 삭제 시, 연결된 조직 문서 해제
test: DocumentService 분리로 Crew/Organization 테스트 분리
[FEAT] 기존 조직 문서를 조직 문서에 연결하는 기능
feat: 조직 문서를 조회할 때 연결된 크루 문서 목록도 함께 반환하도록 기능을 구현
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, 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은 애플리케이션의 문서 관리 시스템을 개선하고 컨테이너화 지원을 추가합니다. 주요 변경 사항으로는 문서 삭제 로직을 UUID 기반으로 전환하고, 크루 문서 관련 기능을 전담하는 CrewDocumentService를 도입하여 기존 DocumentService의 역할을 분리했습니다. 또한, 문서 관련 API 엔드포인트를 DocumentController로 통합하고, 페이징 및 응답 DTO를 개선하여 API의 일관성과 사용성을 높였습니다. Dockerfile 추가를 통해 배포 환경 설정이 용이해졌으며, 조직 문서와 크루 문서 간의 연결 기능을 추가하여 문서 간의 관계 관리를 강화했습니다.

Highlights

  • 애플리케이션 컨테이너화 지원: 애플리케이션을 Docker 컨테이너로 빌드하고 실행하기 위한 Dockerfile이 추가되었습니다.
  • 문서 삭제 로직 개선: 문서 삭제 시 ID 대신 UUID를 사용하도록 변경되었으며, AdminService에서 DocumentService 대신 새로 추가된 CrewDocumentService를 사용하도록 수정되었습니다.
  • 크루 문서 전담 서비스 및 컨트롤러 추가: 크루 문서 관련 CRUD 및 조회 로직을 담당하는 CrewDocumentService와 API 엔드포인트를 정의하는 DocumentController가 새로 추가되었습니다.
  • 문서 관련 DTO 및 도메인 확장: Document 도메인에 DocumentType을 반환하는 메서드가 추가되었고, DocumentListResponse, DocumentResponse, DocumentSearchResponse, DocumentUpdateRequest, ViewFlushRequest 등 다양한 문서 관련 DTO가 레코드(record) 형태로 추가되었습니다.
  • 페이징 및 응답 형식 리팩토링: 기존 PageRequestDtoPagingRequest로 이름이 변경되고, 페이징된 응답을 위한 PagedResponse 레코드가 추가되었으며, ApiResponse의 내부 클래스들이 레코드로 변경되었습니다.
  • 조직 문서 연결 기능 추가 및 개선: 기존 조직 문서를 크루 문서에 연결하는 API 및 관련 서비스 로직이 추가되었고, 조직 문서 생성 및 업데이트 시 이력 저장이 포함되었으며, 조직 문서 조회 시 연결된 크루 문서 목록을 함께 반환하도록 개선되었습니다.
  • 설정 파일 및 테스트 코드 리팩토링: 개발 및 로컬 환경 설정을 위한 YAML 파일이 추가되었고, application.yml의 활성 프로필이 변경되었습니다. 또한, 테스트 코드에서 DocumentFixtureCrewDocumentFixture로 변경되는 등 전반적인 테스트 코드의 명확성이 개선되었습니다.
Ignored Files
  • Ignored by pattern: docs/** (1)
    • docs/CONVENTIONS.md
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.

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은 develop 브랜치를 main으로 병합하는 것으로, 문서 관리 기능에 대한 대규모 리팩토링과 기능 추가를 포함하고 있습니다. 주요 변경 사항으로는 문서 식별자로 Long ID 대신 UUID를 사용하도록 변경하고, DocumentServiceCrewDocumentServiceDocumentService로 분리하여 역할을 명확히 한 점, 그리고 조직 문서를 크루 문서에 연결하는 새로운 기능을 추가한 점이 있습니다. 전반적으로 코드의 구조가 개선되고, DTO에 Java record를 사용하는 등 최신 Java 기능을 잘 활용했습니다. 테스트 코드도 BDD 스타일로 개선되어 가독성이 좋아졌습니다. 몇 가지 개선점을 제안 드리며, 이는 코드의 효율성과 유지보수성을 더욱 높이는 데 도움이 될 것입니다.

Comment on lines +74 to +81
public DocumentResponse getRandom() {
List<CrewDocument> documents = crewDocumentRepository.findAll();
if (documents.isEmpty()) {
throw new WikiException(ErrorCode.DOCUMENT_NOT_FOUND);
}
CrewDocument document = documents.get(random.nextInt(documents.size()));
return mapToResponse(document);
}
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

getRandom() 메서드에서 crewDocumentRepository.findAll()을 호출하여 모든 문서를 메모리에 로드하는 방식은 문서 수가 많아질 경우 성능 저하 및 OutOfMemoryError를 유발할 수 있습니다. 데이터베이스에서 직접 임의의 문서 하나만 가져오도록 최적화하는 것이 좋습니다. 예를 들어, 전체 문서 수를 구한 뒤 임의의 오프셋을 지정하여 Pageable로 하나의 데이터만 조회하는 방식을 사용할 수 있습니다. 제안된 코드를 적용하려면 org.springframework.data.domain.Pageorg.springframework.data.domain.PageRequest를 임포트해야 합니다.

    public DocumentResponse getRandom() {
        long count = crewDocumentRepository.count();
        if (count == 0) {
            throw new WikiException(ErrorCode.DOCUMENT_NOT_FOUND);
        }
        int randomIndex = random.nextInt((int) count);
        Page<CrewDocument> documentPage = crewDocumentRepository.findAll(PageRequest.of(randomIndex, 1));
        if (documentPage.isEmpty()) {
            throw new WikiException(ErrorCode.DOCUMENT_NOT_FOUND);
        }
        CrewDocument document = documentPage.getContent().get(0);
        return mapToResponse(document);
    }

adminService.deleteDocumentByDocumentId(documentId);
@Operation(summary = "문서 삭제", description = "문서 Uuid로 문서를 삭제합니다.")
@DeleteMapping("/documents/{documentUuid}")
public ApiResponse<ApiResponse.SuccessBody<Void>> deleteDocumentByDocumentId(@PathVariable UUID documentUuid) {
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

메서드 이름 deleteDocumentByDocumentId가 파라미터 documentUuid와 일치하지 않아 혼란을 줄 수 있습니다. 메서드의 역할과 파라미터를 명확하게 나타내기 위해 메서드 이름을 deleteDocumentByDocumentUuid로 변경하는 것을 권장합니다.

Suggested change
public ApiResponse<ApiResponse.SuccessBody<Void>> deleteDocumentByDocumentId(@PathVariable UUID documentUuid) {
public ApiResponse<ApiResponse.SuccessBody<Void>> deleteDocumentByDocumentUuid(@PathVariable UUID documentUuid) {

Comment on lines +90 to +92
public DocumentType getDocumentType() {
return type();
}
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

getDocumentType() 메서드는 public abstract 메서드인 type()을 단순히 호출만 하고 있습니다. type() 메서드가 이미 public이므로 getDocumentType()은 불필요해 보입니다. 코드를 간결하게 유지하기 위해 이 메서드를 제거하고, 호출하는 쪽에서 type()을 직접 사용하도록 하는 것이 좋습니다.

Comment on lines +126 to +158
@Nested
@DisplayName("문서 uuid로 삭제 기능")
class DeleteByUuid {

@DisplayName("존재하는 문서 id일 경우 문서가 로그들과 함께 삭제된다")
@Test
void deleteByUuid_success_byExistingDocument() {
// given
DocumentResponse documentResponse = crewDocumentService.create(
CrewDocumentFixture.createDocumentCreateRequest("title1", "content1", "writer1", 10L,
UUID.randomUUID()));

// before then
assertThat(documentRepository.findAll()).hasSize(1);
assertThat(historyRepository.findAll()).hasSize(1);

// when
crewDocumentService.deleteByUuid(documentResponse.documentUUID());

// after then
assertThat(documentRepository.findAll()).hasSize(0);
assertThat(historyRepository.findAll()).hasSize(0);
}

@DisplayName("존재하지 않는 문서의 id일 경우 예외가 발생한다 : WikiException.DOCUMENT_NOT_FOUND")
@Test
void deleteByUuid_fail_byNonExistingDocument() {
// when & then
WikiException ex = assertThrows(WikiException.class,
() -> crewDocumentService.deleteByUuid(UUID.randomUUID()));
assertThat(ex.getErrorCode()).isEqualTo(DOCUMENT_NOT_FOUND);
}
}
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

DeleteByUuid 테스트 클래스는 바로 위의 deleteByUuid 클래스와 내용이 완전히 중복됩니다. 불필요한 중복 코드를 제거하기 위해 이 클래스를 삭제해 주세요. 또한, GetByUuidFind 클래스도 내용이 유사하므로 하나로 통합하는 것을 고려해 보세요.

# Conflicts:
#	src/main/java/com/wooteco/wiki/organizationdocument/repository/DocumentOrganizationLinkRepository.java
@CheChe903 CheChe903 merged commit 2afa339 into main Mar 23, 2026
3 checks passed
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.

3 participants