Skip to content

Feat 사진 업로드 기능 구현 - #145

Merged
MINO1020 merged 2 commits into
developfrom
feat-사진-업로드-기능-구현
Mar 8, 2026

Hidden character warning

The head ref may contain hidden characters: "feat-\uc0ac\uc9c4-\uc5c5\ub85c\ub4dc-\uae30\ub2a5-\uad6c\ud604"
Merged

Feat 사진 업로드 기능 구현#145
MINO1020 merged 2 commits into
developfrom
feat-사진-업로드-기능-구현

Conversation

@MINO1020

@MINO1020 MINO1020 commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

#️⃣연관된 이슈

close #144

📝작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

  • 게시글 이미지 업로드 삭제 수정

스크린샷 (선택)

💬리뷰 요구사항(선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요?

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능
    • 채용공고에 이미지 업로드 기능이 추가되었습니다.
    • 이미지 관리 기능이 구현되어, 채용공고 생성 및 수정 시 이미지를 추가, 수정, 삭제할 수 있습니다.
    • 게시물당 최대 2개까지의 이미지 업로드 제한이 적용됩니다.

@MINO1020 MINO1020 self-assigned this Mar 8, 2026
@MINO1020 MINO1020 added the ✨ feature 기능 개발 label Mar 8, 2026
@MINO1020 MINO1020 linked an issue Mar 8, 2026 that may be closed by this pull request
@MINO1020
MINO1020 merged commit 88d2fd6 into develop Mar 8, 2026
1 check passed
@coderabbitai

coderabbitai Bot commented Mar 8, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 61680c8d-726c-41e9-bc7f-33752b5f180f

📥 Commits

Reviewing files that changed from the base of the PR and between f90cff0 and 51de4a6.

📒 Files selected for processing (11)
  • src/main/java/teamficial/teamficial_be/domain/profile/controller/PreSignedUrlController.java
  • src/main/java/teamficial/teamficial_be/domain/profile/service/PreSignedUrlService.java
  • src/main/java/teamficial/teamficial_be/domain/recruitingPost/controller/ImageUploadController.java
  • src/main/java/teamficial/teamficial_be/domain/recruitingPost/controller/RecruitingPostController.java
  • src/main/java/teamficial/teamficial_be/domain/recruitingPost/dto/RecruitingPostDto.java
  • src/main/java/teamficial/teamficial_be/domain/recruitingPost/entity/PostImage.java
  • src/main/java/teamficial/teamficial_be/domain/recruitingPost/entity/RecruitingPost.java
  • src/main/java/teamficial/teamficial_be/domain/recruitingPost/repository/PostImageRepository.java
  • src/main/java/teamficial/teamficial_be/domain/recruitingPost/service/PostImageService.java
  • src/main/java/teamficial/teamficial_be/domain/recruitingPost/service/RecruitingPostService.java
  • src/main/java/teamficial/teamficial_be/global/apiPayload/code/status/ErrorStatus.java

Walkthrough

모집글 작성 시 이미지 업로드 기능을 구현하였습니다. PreSignedUrlService API를 확장하여 저장소 경로 구분(프로필/게시글)을 지원하며, 새로운 이미지 업로드 엔드포인트, PostImage 엔티티, 이미지 관리 서비스를 추가하고 기존 RecruitingPostService에 이미지 생명주기 관리를 통합했습니다.

Changes

Cohort / File(s) Summary
PreSignedUrlService API 확장
src/main/java/teamficial/teamficial_be/domain/profile/service/PreSignedUrlService.java, src/main/java/teamficial/teamficial_be/domain/profile/controller/PreSignedUrlController.java
메서드 시그니처 변경: getPreSignedUrl(String imageName)getPreSignedUrl(String prefix, String imageName). 저장소 경로 구분을 지원하도록 prefix 매개변수 추가. 새로운 moveTempImageToPost(String objectKey, Long postId) 메서드 추가로 임시 이미지를 게시글별 경로로 이동.
이미지 업로드 엔드포인트
src/main/java/teamficial/teamficial_be/domain/recruitingPost/controller/ImageUploadController.java
새로운 REST 컨트롤러 추가 (/post-images). POST /post-images/presigned-url 엔드포인트에서 파일명 목록을 받아 프리사인된 URL 리스트 반환. 최대 2개 이미지 제한 검증.
이미지 엔티티 및 저장소
src/main/java/teamficial/teamficial_be/domain/recruitingPost/entity/PostImage.java, src/main/java/teamficial/teamficial_be/domain/recruitingPost/repository/PostImageRepository.java
새로운 JPA 엔티티 PostImage 추가 (objectKey, imageOrder, RecruitingPost와의 ManyToOne 관계). 게시글별 이미지 조회 쿼리 메서드 제공.
이미지 관계 설정
src/main/java/teamficial/teamficial_be/domain/recruitingPost/entity/RecruitingPost.java
PostImage와의 OneToMany 관계 추가. CASCADE REMOVE 및 orphanRemoval 설정으로 게시글 삭제 시 이미지도 함께 삭제.
이미지 서비스 계층
src/main/java/teamficial/teamficial_be/domain/recruitingPost/service/PostImageService.java
새로운 서비스 클래스 추가. 이미지 저장(saveImages), 삭제(deleteImagesByPostId), URL 조회(getPostImageUrls), 업데이트(updatePostImages) 기능 제공. PreSignedUrlService를 통한 S3 연동.
게시글 서비스 통합
src/main/java/teamficial/teamficial_be/domain/recruitingPost/service/RecruitingPostService.java
PostImageService 의존성 주입. 게시글 생성/업데이트/조회 시 이미지 처리 로직 통합. 응답 DTO에 imageUrls 포함.
DTO 확장
src/main/java/teamficial/teamficial_be/domain/recruitingPost/dto/RecruitingPostDto.java
Request DTO에 imageKeys 필드 추가. Response DTO(RecruitingPostDetailResponseDTO, RecruitingPostModifyResponseDTO)에 imageUrls 필드 추가. 관련 from() 메서드 시그니처 업데이트.
에러 처리
src/main/java/teamficial/teamficial_be/global/apiPayload/code/status/ErrorStatus.java
새로운 에러 상태 상수 POST_IMAGE_LIMIT_EXCEEDED 추가 (BAD_REQUEST, "POST4001", 최대 2개 이미지 제한 메시지).
코드 정리
src/main/java/teamficial/teamficial_be/domain/recruitingPost/controller/RecruitingPostController.java
불필요한 공백 라인 제거 (기능 변화 없음).

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ImageUploadController
    participant PreSignedUrlService
    participant S3
    participant ImageUploadController2 as (Response)

    Client->>ImageUploadController: POST /post-images/presigned-url<br/>(fileNames: List<String>)
    ImageUploadController->>ImageUploadController: 이미지 개수 검증<br/>(최대 2개)
    loop 각 파일명
        ImageUploadController->>PreSignedUrlService: getPreSignedUrl("post/temp", fileName)
        PreSignedUrlService->>S3: 임시 경로용 프리사인 URL 생성
        S3-->>PreSignedUrlService: preSigned URL
        PreSignedUrlService-->>ImageUploadController: PreSignedUrlResponseDto
    end
    ImageUploadController-->>ImageUploadController2: List<PreSignedUrlResponseDto>
    ImageUploadController2-->>Client: ApiResponse(200 OK)
Loading
sequenceDiagram
    participant Client
    participant RecruitingPostController
    participant RecruitingPostService
    participant PostImageService
    participant PreSignedUrlService
    participant PostImageRepository
    participant S3

    Client->>RecruitingPostController: POST /recruiting-posts<br/>(dto with imageKeys)
    RecruitingPostController->>RecruitingPostService: createPost(dto)
    RecruitingPostService->>RecruitingPostService: 게시글 엔티티 생성 및 저장
    RecruitingPostService->>PostImageService: saveImages(post, imageKeys)
    
    loop 각 imageKey
        PostImageService->>PreSignedUrlService: moveTempImageToPost(key, postId)
        PreSignedUrlService->>S3: 임시 경로에서 최종 경로로 복사<br/>(post/{postId}/{filename})
        S3->>S3: 원본 임시 파일 삭제
        PreSignedUrlService-->>PostImageService: 최종 objectKey
        PostImageService->>PostImageRepository: PostImage 엔티티 저장<br/>(objectKey, imageOrder)
        PostImageRepository-->>PostImageService: 저장 완료
    end
    
    PostImageService-->>RecruitingPostService: 이미지 저장 완료
    RecruitingPostService-->>Client: RecruitingPostCreateResponseDto
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • #29 — PreSignedUrlService의 초기 구현과 컨트롤러 추가. 본 PR이 이 서비스의 API를 prefix 지원으로 확장하므로 직접적인 연관성 있음.
  • #51 — RecruitingPostService의 DTO 반환 타입 및 응답 구조 변경. 본 PR이 응답 DTO에 imageUrls을 추가하므로 코드 수준 연관성 있음.
  • #120 — recruitingPost 도메인의 서비스 및 엔티티 관련 변경. 동일 도메인 클래스 수정으로 인한 코드 수준 연관성 있음.
✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-사진-업로드-기능-구현

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 사진 업로드 기능 구현

1 participant