Skip to content

[feature] cover image 업로드 및 삭제 기능 구현#537

Merged
Zepelown merged 4 commits intodevelop/befrom
feature/#535-cover_image
Jul 11, 2025
Merged

[feature] cover image 업로드 및 삭제 기능 구현#537
Zepelown merged 4 commits intodevelop/befrom
feature/#535-cover_image

Conversation

@PororoAndFriends
Copy link
Collaborator

@PororoAndFriends PororoAndFriends commented Jul 11, 2025

#️⃣연관된 이슈

ex) #535

📝작업 내용

커버 이미지 업로드 기능을 구현하였습니다!

Summary by CodeRabbit

  • 신규 기능

    • 동아리 커버 이미지 업로드 및 삭제 기능이 추가되었습니다.
    • 동아리 상세 정보에 커버 이미지 정보가 포함됩니다.
  • 버그 수정

    • 불필요한 의존성 및 필드가 제거되었습니다.
  • 리팩터

    • Google Cloud Storage, Google Drive 관련 이미지 서비스 구현이 비활성화되었습니다.
  • 기타

    • AWS SDK S3 및 인증 모듈 버전이 업데이트되었습니다.
    • 사용하지 않는 import 문이 정리되었습니다.

@PororoAndFriends PororoAndFriends self-assigned this Jul 11, 2025
@PororoAndFriends PororoAndFriends added ✨ Feature 기능 개발 💾 BE Backend labels Jul 11, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 11, 2025

Warning

Rate limit exceeded

@PororoAndFriends has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 19 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 045263e and c3b59c2.

📒 Files selected for processing (2)
  • backend/src/test/java/moadong/media/service/CloudflareClubImageServiceFeedTest.java (1 hunks)
  • backend/src/test/java/moadong/media/service/CloudflareClubImageServiceLogoTest.java (1 hunks)

"""

Walkthrough

클럽의 커버 이미지 관리 기능이 추가되었습니다. 클럽 엔티티와 DTO에 커버 이미지 필드가 도입되었으며, 커버 이미지 업로드 및 삭제를 위한 API 엔드포인트와 서비스 메서드가 구현되었습니다. 기존 Google Cloud/Drive 관련 서비스는 전체 주석 처리되어 비활성화되었습니다. AWS SDK 관련 Gradle 의존성이 최신 버전으로 명시적으로 변경되었습니다.

Changes

파일/경로 요약 변경 요약
backend/build.gradle AWS SDK S3/auth 의존성을 BOM에서 명시적 버전(2.26.0)으로 변경, netty-nio-client 주석 추가
backend/src/main/java/moadong/club/entity/Club.java updateCover(String cover) 메서드 추가
backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java cover 필드(최대 1024, unique) 및 updateCover 메서드 추가
backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java DTO에 cover 필드 추가, of 팩토리 메서드에서 cover 값 초기화
backend/src/main/java/moadong/media/controller/ClubImageController.java 커버 이미지 업로드/삭제용 POST/DELETE 엔드포인트 2개 추가
backend/src/main/java/moadong/media/domain/FileType.java enum에 COVER("cover") 상수 추가
backend/src/main/java/moadong/media/service/CloudflareImageService.java uploadCover, deleteCover 메서드 추가
backend/src/main/java/moadong/media/service/ClubImageService.java 인터페이스에 uploadCover, deleteCover 메서드 추가
backend/src/main/java/moadong/media/service/GcsClubImageService.java 전체 클래스 및 메서드 주석 처리(비활성화)
backend/src/main/java/moadong/media/service/GoogleDriveClubImageService.java 전체 클래스 및 메서드 주석 처리(비활성화)
backend/src/main/java/moadong/media/util/GoogleDriveConfig.java 불필요한 import 2개 제거
backend/src/main/java/moadong/media/util/S3Config.java 불필요한 import 2개 제거, 주석 삭제
backend/src/main/java/moadong/user/controller/UserController.java JwtProvider jwtProvider 필드 제거
backend/src/test/java/moadong/media/service/CloudflareClubImageServiceFeedTest.java 테스트 클래스명 및 서비스 타입 변경, Google Drive 관련 mock 제거
backend/src/test/java/moadong/media/service/CloudflareClubImageServiceLogoTest.java 테스트 클래스명 및 서비스 타입 변경, Google Drive 관련 mock 제거 및 불필요 import 제거

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ClubImageController
    participant ClubImageService
    participant Club
    participant Repository

    Client->>ClubImageController: POST /{clubId}/cover (multipart file)
    ClubImageController->>ClubImageService: uploadCover(clubId, file)
    ClubImageService->>Repository: findById(clubId)
    Repository-->>ClubImageService: Club
    ClubImageService->>Club: updateCover(newCoverPath)
    ClubImageService->>Repository: save(Club)
    ClubImageService-->>ClubImageController: newCoverUrl
    ClubImageController-->>Client: 응답(newCoverUrl)

    Client->>ClubImageController: DELETE /{clubId}/cover
    ClubImageController->>ClubImageService: deleteCover(clubId)
    ClubImageService->>Repository: findById(clubId)
    Repository-->>ClubImageService: Club
    ClubImageService->>Club: updateCover(null)
    ClubImageService->>Repository: save(Club)
    ClubImageService-->>ClubImageController: 완료
    ClubImageController-->>Client: 성공 메시지
Loading

Possibly related PRs

  • 이미지 저장소 cloudflare로 고정 #500: 클라우드플레어 이미지 서비스 관련 코드 변경과 컨트롤러 주입 업데이트를 포함하며, 본 PR과 커버 이미지 관리 기능 확장 측면에서 관련 있음.

Suggested labels

💻 FE

Suggested reviewers

  • Zepelown
  • lepitaaar
    """
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 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.

@github-actions
Copy link

github-actions bot commented Jul 11, 2025

Test Results

75 tests   75 ✅  2s ⏱️
12 suites   0 💤
12 files     0 ❌

Results for commit c3b59c2.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (1)
backend/src/main/java/moadong/media/service/GcsClubImageService.java (1)

1-161: GCS 마이그레이션 후 주석 처리된 코드 및 관련 설정·의존성 정리 필요

현재 전체 서비스 클래스가 주석 처리되어 있지만, GCS 관련 의존성은 여전히 남아 있습니다. 마이그레이션 상태에 따라 다음을 검토해 주세요:

  • backend/src/main/java/moadong/media/service/GcsClubImageService.java
    • 마이그레이션이 완료되었다면 파일을 삭제하거나 별도 브랜치로 이동
    • 롤백 가능성을 위해 보관이 필요하다면 TODO 주석이나 이슈 링크로 제거 계획 명시
  • backend/build.gradle
    • implementation 'com.google.cloud:spring-cloud-gcp-storage:5.8.0' → 더 이상 사용되지 않는다면 제거
  • application.properties/application.yml
    • google.cloud.storage.bucket.name 설정 여부 확인 후 미사용 시 제거

위 항목을 정리하여 코드 가독성과 유지보수성을 확보하세요.

🧹 Nitpick comments (2)
backend/build.gradle (1)

59-59: 주석 처리된 의존성의 필요성을 명확히 하세요.

netty-nio-client 의존성이 주석 처리되어 있는 이유와 향후 필요성에 대해 명확히 문서화하거나 완전히 제거하는 것이 좋겠습니다.

backend/src/main/java/moadong/media/service/GoogleDriveClubImageService.java (1)

1-173: 전체 서비스 구현체가 주석 처리됨

Google Drive 기반 이미지 서비스 전체가 주석 처리되어 비활성화되었습니다. Cloudflare 기반 서비스로의 완전한 전환이 확정되었다면, 주석 처리된 코드를 제거하는 것을 고려해 보세요.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4aadd3b and 4740731.

📒 Files selected for processing (13)
  • backend/build.gradle (1 hunks)
  • backend/src/main/java/moadong/club/entity/Club.java (1 hunks)
  • backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java (2 hunks)
  • backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java (2 hunks)
  • backend/src/main/java/moadong/media/controller/ClubImageController.java (1 hunks)
  • backend/src/main/java/moadong/media/domain/FileType.java (1 hunks)
  • backend/src/main/java/moadong/media/service/CloudflareImageService.java (1 hunks)
  • backend/src/main/java/moadong/media/service/ClubImageService.java (1 hunks)
  • backend/src/main/java/moadong/media/service/GcsClubImageService.java (1 hunks)
  • backend/src/main/java/moadong/media/service/GoogleDriveClubImageService.java (1 hunks)
  • backend/src/main/java/moadong/media/util/GoogleDriveConfig.java (0 hunks)
  • backend/src/main/java/moadong/media/util/S3Config.java (1 hunks)
  • backend/src/main/java/moadong/user/controller/UserController.java (0 hunks)
💤 Files with no reviewable changes (2)
  • backend/src/main/java/moadong/user/controller/UserController.java
  • backend/src/main/java/moadong/media/util/GoogleDriveConfig.java
🧰 Additional context used
🧠 Learnings (8)
backend/src/main/java/moadong/club/entity/Club.java (1)
Learnt from: lepitaaar
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
backend/src/main/java/moadong/media/service/GoogleDriveClubImageService.java (1)
Learnt from: lepitaaar
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java (1)
Learnt from: lepitaaar
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
backend/src/main/java/moadong/media/service/CloudflareImageService.java (1)
Learnt from: lepitaaar
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java (1)
Learnt from: lepitaaar
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
backend/src/main/java/moadong/media/service/GcsClubImageService.java (1)
Learnt from: lepitaaar
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
backend/src/main/java/moadong/media/controller/ClubImageController.java (1)
Learnt from: lepitaaar
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
backend/src/main/java/moadong/media/service/ClubImageService.java (1)
Learnt from: lepitaaar
PR: Moadong/moadong#406
File: backend/src/main/java/moadong/club/service/ClubApplyService.java:34-38
Timestamp: 2025-05-19T05:45:52.957Z
Learning: The code duplication between createClubApplication and editClubApplication methods in ClubApplyService.java is acknowledged but will be addressed in a future refactoring, as per the developer's plan.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (11)
backend/src/main/java/moadong/media/util/S3Config.java (1)

30-30: 코드 정리 변경사항 승인.

불필요한 import 제거와 주석 정리로 코드가 더 깔끔해졌습니다.

backend/src/main/java/moadong/club/entity/Club.java (1)

118-121: 일관된 패턴으로 구현된 메서드입니다.

기존 updateLogo 메서드와 동일한 패턴으로 구현되어 코드 일관성이 유지되었습니다.

backend/src/main/java/moadong/media/domain/FileType.java (1)

8-9: enum 확장이 올바르게 구현되었습니다.

기존 패턴과 일관되게 COVER 타입이 추가되어 커버 이미지 기능을 지원합니다.

backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java (2)

34-36: @unique 어노테이션 사용의 적절성 검토 필요

커버 이미지 필드에 @Unique 어노테이션이 적용되어 있습니다. 만약 여러 클럽이 동일한 커버 이미지 URL을 공유할 가능성이 있다면, 이 제약 조건이 문제가 될 수 있습니다. 커버 이미지 URL이 클럽별로 고유해야 하는지 확인해 주세요.


116-118: LGTM!

updateCover 메서드가 기존 업데이트 메서드들과 일관된 패턴으로 구현되어 있습니다.

backend/src/main/java/moadong/media/service/ClubImageService.java (1)

19-21: LGTM!

커버 이미지 업로드 및 삭제를 위한 새로운 인터페이스 메서드들이 기존 메서드들과 일관된 패턴으로 잘 정의되어 있습니다.

backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java (2)

15-15: LGTM!

DTO에 커버 이미지 필드가 올바르게 추가되었습니다.


44-45: LGTM!

커버 이미지 필드 초기화 로직이 기존 필드들과 일관된 null 체크 패턴을 따르고 있습니다.

backend/src/main/java/moadong/media/service/CloudflareImageService.java (2)

123-135: LGTM!

uploadCover 메서드가 기존 uploadLogo 메서드와 동일한 패턴으로 구현되어 있으며, 기존 uploadFile 메서드를 재사용하여 코드 중복을 방지했습니다.


137-146: LGTM!

deleteCover 메서드가 기존 deleteLogo 메서드와 일관된 패턴으로 구현되어 있습니다. 기존 deleteFile 메서드를 재사용하여 코드 일관성을 유지했습니다.

backend/src/main/java/moadong/media/controller/ClubImageController.java (1)

71-76: 깔끔한 구현입니다.

DELETE 엔드포인트가 기존 패턴과 일관성 있게 구현되었습니다. 서비스 레이어에 적절히 위임하고 있습니다.

Comment on lines +57 to +59
implementation 'software.amazon.awssdk:s3:2.26.0'
implementation 'software.amazon.awssdk:auth:2.26.0'
// implementation 'software.amazon.awssdk:netty-nio-client:2.26.0'
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

의존성 관리 방식을 재검토하세요.

AWS SDK 의존성을 platform BOM에서 명시적 버전으로 변경하는 것은 다음과 같은 문제를 야기할 수 있습니다:

  • 각 모듈 간 버전 일관성 관리가 어려워짐
  • 의존성 충돌 가능성 증가
  • 향후 업그레이드 시 각 모듈을 개별적으로 관리해야 함

기존 platform BOM 방식을 유지하면서 필요한 경우에만 특정 모듈의 버전을 재정의하는 것을 권장합니다.

-	implementation 'software.amazon.awssdk:s3:2.26.0'
-	implementation 'software.amazon.awssdk:auth:2.26.0'
-//	implementation 'software.amazon.awssdk:netty-nio-client:2.26.0'
+	implementation platform('software.amazon.awssdk:bom:2.26.0')
+	implementation 'software.amazon.awssdk:s3'
+	implementation 'software.amazon.awssdk:auth'
+//	implementation 'software.amazon.awssdk:netty-nio-client'
🤖 Prompt for AI Agents
In backend/build.gradle around lines 57 to 59, the AWS SDK dependencies are
specified with explicit versions instead of using the platform BOM. This can
cause version inconsistency and dependency conflicts. To fix this, revert to
using the platform BOM for AWS SDK dependencies to manage versions centrally,
and only override specific module versions if absolutely necessary by specifying
them separately without changing the overall BOM approach.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
backend/src/test/java/moadong/media/service/CloudflareClubImageServiceLogoTest.java (2)

14-14: 사용되지 않는 import를 제거하세요.

Google Drive API 관련 import가 더 이상 사용되지 않습니다. Cloudflare로 마이그레이션하면서 불필요해진 import를 제거해주세요.

-import com.google.api.services.drive.Drive;

64-65: 주석 처리된 코드를 제거하세요.

마이그레이션 과정에서 주석 처리된 기존 Google Drive 관련 코드가 남아있습니다. 더 이상 필요하지 않다면 제거하는 것이 좋겠습니다.

-//        doReturn( "https://drive.google.com/file/d/" + club.getId() + "/LOGO/" + mockFile.getOriginalFilename() + "/view" )
-//                .when(clubImageService).uploadFile(any(), eq(mockFile), eq(FileType.LOGO));
backend/src/test/java/moadong/media/service/CloudflareClubImageServiceFeedTest.java (1)

11-11: 사용되지 않는 import를 제거하세요.

Google Drive API 관련 import가 더 이상 사용되지 않습니다. Cloudflare로 마이그레이션하면서 불필요해진 import를 제거해주세요.

-import com.google.api.services.drive.Drive;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4740731 and 045263e.

📒 Files selected for processing (3)
  • backend/src/main/java/moadong/media/controller/ClubImageController.java (1 hunks)
  • backend/src/test/java/moadong/media/service/CloudflareClubImageServiceFeedTest.java (1 hunks)
  • backend/src/test/java/moadong/media/service/CloudflareClubImageServiceLogoTest.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/main/java/moadong/media/controller/ClubImageController.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (4)
backend/src/test/java/moadong/media/service/CloudflareClubImageServiceLogoTest.java (2)

34-34: 클래스명 변경이 적절합니다.

Google Drive에서 Cloudflare로의 마이그레이션을 반영하여 클래스명이 적절하게 변경되었습니다.


38-38: 서비스 타입 변경이 적절합니다.

테스트 대상 서비스가 CloudflareImageService로 올바르게 변경되어 마이그레이션을 정확히 반영하고 있습니다.

backend/src/test/java/moadong/media/service/CloudflareClubImageServiceFeedTest.java (2)

35-35: 클래스명 변경이 적절합니다.

Google Drive에서 Cloudflare로의 마이그레이션을 반영하여 클래스명이 적절하게 변경되었습니다.


39-39: 서비스 타입 변경이 적절합니다.

테스트 대상 서비스가 CloudflareImageService로 올바르게 변경되어 마이그레이션을 정확히 반영하고 있습니다.

Copy link
Contributor

@lepitaaar lepitaaar left a comment

Choose a reason for hiding this comment

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

좋네요 !!. 클라우드 플레어 이전 기대됩니다

Copy link
Member

@Zepelown Zepelown left a comment

Choose a reason for hiding this comment

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

고생하셨습니다~

Comment on lines +1 to +173
//package moadong.media.service;
//
//import static moadong.media.util.ClubImageUtil.containsInvalidChars;
//
//import com.google.api.client.http.FileContent;
//import com.google.api.services.drive.Drive;
//import com.google.api.services.drive.model.File;
//import com.google.api.services.drive.model.Permission;
//import java.io.IOException;
//import java.util.Collections;
//import java.util.List;
//import lombok.RequiredArgsConstructor;
//import moadong.club.entity.Club;
//import moadong.club.repository.ClubRepository;
//import moadong.global.exception.ErrorCode;
//import moadong.global.exception.RestApiException;
//import moadong.global.util.ObjectIdConverter;
//import moadong.global.util.RandomStringUtil;
//import moadong.media.domain.FileType;
//import org.bson.types.ObjectId;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Service;
//import org.springframework.web.multipart.MultipartFile;
//
//@Service("googleDrive")
//@RequiredArgsConstructor
//public class GoogleDriveClubImageService implements ClubImageService {
//
// @Value("${google.drive.share-file-id}")
// String shareFileId;
// @Value("${server.feed.max-count}")
// private int MAX_FEED_COUNT;
//
// private final Drive googleDrive;
// private final ClubRepository clubRepository;
//
// private final String PREFIX = "https://drive.google.com/file/d/";
// private final String SUFFIX = "/view";
//
// @Override
// public String uploadLogo(String clubId, MultipartFile file) {
// ObjectId objectId = ObjectIdConverter.convertString(clubId);
// Club club = clubRepository.findClubById(objectId)
// .orElseThrow(() -> new RestApiException(ErrorCode.CLUB_NOT_FOUND));
//
// if (club.getClubRecruitmentInformation().getLogo() != null) {
// deleteFile(club, club.getClubRecruitmentInformation().getLogo());
// }
//
// String filePath = uploadFile(clubId, file, FileType.LOGO);
// club.updateLogo(filePath);
// clubRepository.save(club);
// return filePath;
// }
//
// @Override
// public void deleteLogo(String clubId) {
// ObjectId objectId = ObjectIdConverter.convertString(clubId);
// Club club = clubRepository.findClubById(objectId)
// .orElseThrow(() -> new RestApiException(ErrorCode.CLUB_NOT_FOUND));
//
// if (club.getClubRecruitmentInformation().getLogo() != null) {
// deleteFile(club, club.getClubRecruitmentInformation().getLogo());
// }
// club.updateLogo(null);
// clubRepository.save(club);
// }
//
// @Override
// public String uploadFeed(String clubId, MultipartFile file) {
// ObjectId objectId = ObjectIdConverter.convertString(clubId);
// int feedImagesCount = clubRepository.findClubById(objectId)
// .orElseThrow(() -> new RestApiException(ErrorCode.CLUB_NOT_FOUND))
// .getClubRecruitmentInformation().getFeedImages().size();
//
// if (feedImagesCount + 1 > MAX_FEED_COUNT) {
// throw new RestApiException(ErrorCode.TOO_MANY_FILES);
// }
// return uploadFile(clubId, file, FileType.FEED);
// }
//
// @Override
// public void updateFeeds(String clubId, List<String> newFeedImageList) {
// ObjectId objectId = ObjectIdConverter.convertString(clubId);
// Club club = clubRepository.findClubById(objectId)
// .orElseThrow(() -> new RestApiException(ErrorCode.CLUB_NOT_FOUND));
//
// if (newFeedImageList.size() > MAX_FEED_COUNT) {
// throw new RestApiException(ErrorCode.TOO_MANY_FILES);
// }
//
// List<String> feedImages = club.getClubRecruitmentInformation().getFeedImages();
// if (feedImages != null && !feedImages.isEmpty()) {
// deleteFeedImages(club, feedImages, newFeedImageList);
// }
// club.updateFeedImages(newFeedImageList);
// clubRepository.save(club);
// }
//
// private void deleteFeedImages(Club club, List<String> feedImages, List<String> newFeedImages) {
// for (String feedsImage : feedImages) {
// if (!newFeedImages.contains(feedsImage)) {
// deleteFile(club, feedsImage);
// }
// }
// }
//
// @Override
// public void deleteFile(Club club, String filePath) {
// //"https://drive.google.com/file/d/{fileId}/view" -> {fileId}
// String fileId = filePath.split("/")[5];
// try {
// googleDrive.files()
// .delete(fileId)
// .setSupportsAllDrives(true) // 공유 드라이브(Shared Drive)도 지원할 경우
// .execute();
// } catch (IOException e) {
// throw new RestApiException(ErrorCode.IMAGE_DELETE_FAILED);
// }
// }
//
// private String uploadFile(String clubId, MultipartFile file, FileType fileType) {
// if (file == null) {
// throw new RestApiException(ErrorCode.FILE_NOT_FOUND);
// }
// // MultipartFile → java.io.File 변환
// java.io.File tempFile;
// try {
// tempFile = java.io.File.createTempFile("upload-", file.getOriginalFilename());
// file.transferTo(tempFile);
// } catch (IOException e) {
// throw new RestApiException(ErrorCode.FILE_TRANSFER_ERROR);
// }
//
// // 메타데이터 생성
// File fileMetadata = new File();
// String fileName = file.getOriginalFilename();
// if (containsInvalidChars(fileName)) {
// fileName = RandomStringUtil.generateRandomString(10);
// }
//
// fileMetadata.setName(clubId + "/" + fileType + "/" + fileName);
// fileMetadata.setMimeType(file.getContentType());
// // 공유 ID 설정
// fileMetadata.setParents(Collections.singletonList(shareFileId));
//
// // 파일 업로드
// FileContent mediaContent = new FileContent(file.getContentType(), tempFile);
// // 전체 공개 권한 설정
// Permission publicPermission = new Permission()
// .setType("anyone") // 누구나
// .setRole("reader"); // 읽기 권한
//
// File uploadedFile;
// try {
// uploadedFile= googleDrive.files().create(fileMetadata, mediaContent)
// .setFields("id")
// .execute();
//
// googleDrive.permissions().create(uploadedFile.getId(), publicPermission)
// .setFields("id")
// .execute();
// } catch (Exception e) {
// throw new RestApiException(ErrorCode.IMAGE_UPLOAD_FAILED);
// }finally {
// // 임시 파일 삭제
// tempFile.delete();
// }
// // 공유 링크 반환
// return PREFIX + uploadedFile.getId() + SUFFIX;
// }
//
//}
Copy link
Member

Choose a reason for hiding this comment

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

차후에 사용할지도 몰라 주석 처리해 놓으셨나요?

@Zepelown Zepelown merged commit 2fcf20a into develop/be Jul 11, 2025
3 checks passed
@PororoAndFriends PororoAndFriends deleted the feature/#535-cover_image branch September 14, 2025 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💾 BE Backend ✨ Feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments