-
Notifications
You must be signed in to change notification settings - Fork 0
✨ Feat: S3 관련 설정, 파일 업로드 관련 기능 구현 #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4be0deb
50b6140
9048df4
72e22f1
e167f5a
d966150
bba6c41
71e87ff
52e3faf
ce725b1
0b69dcc
98f1487
3da13c4
5cc8010
dbb2890
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package com.be.sportizebe.domain.club.dto.response; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
||
| @Schema(description = "동호회 이미지 응답") | ||
| public record ClubImageResponse( | ||
| @Schema(description = "동호회 이미지 URL", example = "https://bucket.s3.ap-northeast-2.amazonaws.com/club/uuid.jpg") | ||
| String clubImageUrl | ||
| ) { | ||
| public static ClubImageResponse from(String clubImageUrl) { | ||
| return new ClubImageResponse(clubImageUrl); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,27 +1,31 @@ | ||||||
| package com.be.sportizebe.domain.user.controller; | ||||||
|
|
||||||
| import com.be.sportizebe.domain.auth.exception.AuthErrorCode; | ||||||
| import com.be.sportizebe.domain.user.dto.request.SignUpRequest; | ||||||
| import com.be.sportizebe.domain.user.dto.response.ProfileImageResponse; | ||||||
| import com.be.sportizebe.domain.user.dto.response.SignUpResponse; | ||||||
| import com.be.sportizebe.domain.user.service.UserService; | ||||||
| import com.be.sportizebe.domain.user.entity.User; | ||||||
| import com.be.sportizebe.domain.user.service.UserServiceImpl; | ||||||
| import com.be.sportizebe.global.exception.CustomException; | ||||||
| import com.be.sportizebe.global.response.BaseResponse; | ||||||
| import io.swagger.v3.oas.annotations.Operation; | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
| import jakarta.validation.Valid; | ||||||
| import lombok.RequiredArgsConstructor; | ||||||
| import org.springframework.http.HttpStatus; | ||||||
| import org.springframework.http.MediaType; | ||||||
| import org.springframework.http.ResponseEntity; | ||||||
| import org.springframework.web.bind.annotation.PostMapping; | ||||||
| import org.springframework.web.bind.annotation.RequestBody; | ||||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||||
| import org.springframework.web.bind.annotation.RestController; | ||||||
| import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||||||
| import org.springframework.web.bind.annotation.*; | ||||||
| import org.springframework.web.multipart.MultipartFile; | ||||||
|
|
||||||
| @RestController | ||||||
| @RequiredArgsConstructor | ||||||
| @RequestMapping("/api/users") | ||||||
| @Tag(name = "user", description = "사용자 관련 API") | ||||||
| public class UserController { | ||||||
|
|
||||||
| private final UserService userService; | ||||||
| private final UserServiceImpl userService; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 인터페이스 대신 구체 클래스 주입 사용
♻️ 인터페이스 타입 사용 제안- private final UserServiceImpl userService;
+ private final UserService userService;import도 함께 수정: -import com.be.sportizebe.domain.user.service.UserServiceImpl;
+import com.be.sportizebe.domain.user.service.UserService;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| @PostMapping("/signup") | ||||||
| @Operation(summary = "회원가입", description = "이메일과 비밀번호로 회원가입") | ||||||
|
|
@@ -30,4 +34,14 @@ public ResponseEntity<BaseResponse<SignUpResponse>> signUp(@RequestBody @Valid S | |||||
| return ResponseEntity.status(HttpStatus.CREATED) | ||||||
| .body(BaseResponse.success("회원가입 성공", response)); | ||||||
| } | ||||||
|
|
||||||
| @PostMapping(value = "/profile-image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) | ||||||
| @Operation(summary = "프로필 사진 업로드", description = "사용자 프로필 사진을 업로드합니다. (최대 5MB, jpg/jpeg/png/gif/webp 지원)") | ||||||
| public ResponseEntity<BaseResponse<ProfileImageResponse>> uploadProfileImage( | ||||||
| @AuthenticationPrincipal User user, | ||||||
| @RequestPart("file") MultipartFile file | ||||||
| ) { | ||||||
| ProfileImageResponse response = userService.uploadProfileImage(user.getId(), file); | ||||||
| return ResponseEntity.ok(BaseResponse.success("프로필 사진 업로드 성공", response)); | ||||||
| } | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
기존 이미지 삭제를 업로드 성공 이후로 미루세요.
현재 순서는 업로드 실패 시 기존 이미지가 소실됩니다. 새 이미지 업로드 성공 후에 기존 이미지를 삭제하는 방식이 더 안전합니다.
✅ 제안 수정안
🤖 Prompt for AI Agents