-
Notifications
You must be signed in to change notification settings - Fork 0
Feat/이미지 관련 기능 구현 #87
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
The head ref may contain hidden characters: "feat/\uC774\uBBF8\uC9C0-\uAD00\uB828-\uAE30\uB2A5-\uAD6C\uD604"
Changes from all commits
174d19a
81cbdee
1560527
bc0027b
8deedc3
716d07e
572df1f
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,38 @@ | ||
| package com.pinHouse.server.core.config; | ||
|
|
||
| import org.springframework.beans.factory.annotation.Value; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; | ||
| import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; | ||
| import software.amazon.awssdk.regions.Region; | ||
| import software.amazon.awssdk.services.s3.S3Client; | ||
|
|
||
| /** | ||
| * AWS S3 클라이언트 설정 클래스 | ||
| */ | ||
| @Configuration | ||
| public class S3Config { | ||
|
|
||
| @Value("${aws.s3.region}") | ||
| private String region; | ||
|
|
||
| @Value("${aws.s3.access-key}") | ||
| private String accessKey; | ||
|
|
||
| @Value("${aws.s3.secret-key}") | ||
| private String secretKey; | ||
|
|
||
| /** | ||
| * S3Client Bean 생성 | ||
| */ | ||
| @Bean | ||
| public S3Client s3Client() { | ||
| AwsBasicCredentials credentials = AwsBasicCredentials.create(accessKey, secretKey); | ||
|
|
||
| return S3Client.builder() | ||
| .region(Region.of(region)) | ||
| .credentialsProvider(StaticCredentialsProvider.create(credentials)) | ||
| .build(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package com.pinHouse.server.core.exception.code; | ||
|
|
||
| import com.pinHouse.server.core.response.response.ErrorCode; | ||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.http.HttpStatus; | ||
|
|
||
| /** | ||
| * 이미지 관련 예외처리 클래스입니다. | ||
| */ | ||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public enum ImageErrorCode implements ErrorCode { | ||
|
|
||
| // ======================== | ||
| // 400 Bad Request | ||
| // ======================== | ||
| INVALID_FILE_TYPE(400_301, HttpStatus.BAD_REQUEST, "지원하지 않는 이미지 형식입니다. (jpg, jpeg, png, gif만 가능)"), | ||
| INVALID_FILE_EXTENSION(400_302, HttpStatus.BAD_REQUEST, "파일 확장자가 유효하지 않습니다."), | ||
| FILE_SIZE_EXCEEDED(400_303, HttpStatus.BAD_REQUEST, "파일 크기가 5MB를 초과합니다."), | ||
|
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. 🧩 Analysis chain🏁 Script executed: rg -n "FILE_SIZE_EXCEEDED" --type javaRepository: PinHouse/PinHouse_BE Length of output: 219 🏁 Script executed: rg -n "400_303" --type javaRepository: PinHouse/PinHouse_BE Length of output: 219 🏁 Script executed: rg -n "FILE_SIZE|파일 크기" --type java -iRepository: PinHouse/PinHouse_BE Length of output: 379 FILE_SIZE_EXCEEDED 에러 코드를 제거하세요
🤖 Prompt for AI Agents |
||
| INVALID_FILE_NAME(400_304, HttpStatus.BAD_REQUEST, "파일명이 유효하지 않습니다."), | ||
|
|
||
| // ======================== | ||
| // 500 Internal Server Error | ||
| // ======================== | ||
| S3_PRESIGNED_URL_GENERATION_FAILED(500_301, HttpStatus.INTERNAL_SERVER_ERROR, "이미지 업로드 URL 생성에 실패했습니다."), | ||
| S3_CLIENT_ERROR(500_302, HttpStatus.INTERNAL_SERVER_ERROR, "S3 서버와 통신 중 오류가 발생했습니다."); | ||
|
|
||
| /** | ||
| * 에러 코드 (고유값) | ||
| */ | ||
| private final Integer code; | ||
|
|
||
| /** | ||
| * HTTP 상태 코드 | ||
| */ | ||
| private final HttpStatus httpStatus; | ||
|
|
||
| /** | ||
| * 에러 메시지 | ||
| */ | ||
| private final String message; | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| package com.pinHouse.server.platform.diagnostic.diagnosis.application.dto; | ||
|
|
||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import lombok.Builder; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Builder | ||
| @Schema(name = "[응답][진단] 추천 그룹", description = "추천 임대 유형을 공고 유형별로 묶은 정보") | ||
| public record DiagnosisRecommendationGroup( | ||
|
|
||
| @Schema(description = "공고 유형", example = "통합공공임대") | ||
| String noticeType, | ||
|
|
||
| @Schema(description = "추천 공급 유형 리스트", example = "[\"청년 특별공급\", \"신혼부부 특별공급\"]") | ||
| List<String> supplyTypes | ||
| ) { | ||
|
|
||
| public static DiagnosisRecommendationGroup of(String noticeType, List<String> supplyTypes) { | ||
| return DiagnosisRecommendationGroup.builder() | ||
| .noticeType(noticeType) | ||
| .supplyTypes(supplyTypes) | ||
| .build(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package com.pinHouse.server.platform.diagnostic.diagnosis.application.dto; | ||
|
|
||
| import com.pinHouse.server.platform.diagnostic.rule.domain.entity.EvaluationContext; | ||
| import com.pinHouse.server.platform.diagnostic.rule.domain.entity.SupplyRentalCandidate; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import lombok.Builder; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.LinkedHashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
| @Builder | ||
| @Schema(name = "[응답][진단] 청약 진단 결과 v2", description = "추천 임대주택을 공고 유형별로 그룹화한 응답") | ||
| public record DiagnosisResponseV2( | ||
|
|
||
| @Schema(description = "최종 자격 여부 (추천 임대주택이 있는지 여부)", example = "true") | ||
| boolean eligible, | ||
|
|
||
| @Schema(description = "최종 요약 메시지", example = "추천 임대주택이 있습니다") | ||
| String decisionMessage, | ||
|
|
||
| @Schema(description = "추천 임대주택 후보 그룹", example = "[{\"noticeType\":\"통합공공임대\",\"supplyTypes\":[\"청년 특별공급\",\"신혼부부 특별공급\"]}]") | ||
| List<DiagnosisRecommendationGroup> recommended | ||
| ) { | ||
|
|
||
| public static DiagnosisResponseV2 from(EvaluationContext context) { | ||
| List<SupplyRentalCandidate> candidates = context.getCurrentCandidates(); | ||
|
|
||
| if (candidates.isEmpty()) { | ||
| return DiagnosisResponseV2.builder() | ||
| .eligible(false) | ||
| .decisionMessage("모든 조건 미충족") | ||
| .recommended(List.of()) | ||
| .build(); | ||
| } | ||
|
|
||
| Map<String, List<String>> grouped = new LinkedHashMap<>(); | ||
|
|
||
| for (SupplyRentalCandidate candidate : candidates) { | ||
| String noticeType = candidate.noticeType().getValue(); | ||
| String supplyType = candidate.supplyType().getValue(); | ||
| grouped.computeIfAbsent(noticeType, k -> new ArrayList<>()); | ||
| if (!grouped.get(noticeType).contains(supplyType)) { | ||
| grouped.get(noticeType).add(supplyType); | ||
| } | ||
| } | ||
|
|
||
| List<DiagnosisRecommendationGroup> groups = grouped.entrySet().stream() | ||
| .map(e -> DiagnosisRecommendationGroup.of(e.getKey(), e.getValue())) | ||
| .toList(); | ||
|
|
||
| return DiagnosisResponseV2.builder() | ||
| .eligible(true) | ||
| .decisionMessage("추천 임대주택이 있습니다") | ||
| .recommended(groups) | ||
| .build(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,6 +12,9 @@ public record HomeNoticeListResponse( | |||||||||
| @Schema(description = "공통 지역", example = "성남시") | ||||||||||
| String region, | ||||||||||
|
|
||||||||||
| @Schema(description = "목록 설명/출처", example = "진단 기반 추천") | ||||||||||
| String title, | ||||||||||
|
Comment on lines
+15
to
+16
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. 🧩 Analysis chain🏁 Script executed: # First, find and read the HomeNoticeListResponse.java file
fd -t f "HomeNoticeListResponse.java" | head -5Repository: PinHouse/PinHouse_BE Length of output: 155 🏁 Script executed: # Search for the file more broadly
find . -name "HomeNoticeListResponse.java" -type fRepository: PinHouse/PinHouse_BE Length of output: 157 🏁 Script executed: # List files in the home/application/dto directory
fd -t f . "src/main/java/com/pinHouse/server/platform/home/application/dto"Repository: PinHouse/PinHouse_BE Length of output: 803 🏁 Script executed: # Read the HomeNoticeListResponse.java file
cat -n src/main/java/com/pinHouse/server/platform/home/application/dto/HomeNoticeListResponse.javaRepository: PinHouse/PinHouse_BE Length of output: 1035 🏁 Script executed: # Search for where HomeNoticeListResponse is instantiated or built
rg "HomeNoticeListResponse" --type java -A 3 -B 1Repository: PinHouse/PinHouse_BE Length of output: 13096 🏁 Script executed: # Look at the HomeService implementation more carefully
rg -A 20 "getDeadlineApproachingNotices" src/main/java/com/pinHouse/server/platform/home/application/service/HomeService.java | head -50Repository: PinHouse/PinHouse_BE Length of output: 964 🏁 Script executed: # Also check the getRecommendedNoticesByDiagnosis method
rg -A 30 "getRecommendedNoticesByDiagnosis" src/main/java/com/pinHouse/server/platform/home/application/service/HomeService.java | grep -A 10 "HomeNoticeListResponse.builder"Repository: PinHouse/PinHouse_BE Length of output: 359 🏁 Script executed: # Get the exact line where title is set to null in HomeService
rg -n "\.title\(null\)" src/main/java/com/pinHouse/server/platform/home/application/service/HomeService.javaRepository: PinHouse/PinHouse_BE Length of output: 92 🏁 Script executed: # Also check all title assignments
rg -n "\.title\(" src/main/java/com/pinHouse/server/platform/home/application/service/HomeService.javaRepository: PinHouse/PinHouse_BE Length of output: 205 🏁 Script executed: # Get the full context around line 120 where title is set to null
sed -n '110,130p' src/main/java/com/pinHouse/server/platform/home/application/service/HomeService.javaRepository: PinHouse/PinHouse_BE Length of output: 800 🏁 Script executed: # Check if there are any other annotations or constraints on the title field in the DTO
cat -n src/main/java/com/pinHouse/server/platform/home/application/dto/HomeNoticeListResponse.java | sed -n '14,18p'Repository: PinHouse/PinHouse_BE Length of output: 225
수정 사항- `@Schema`(description = "목록 설명/출처", example = "진단 기반 추천")
+ `@Schema`(description = "목록 설명/출처", example = "진단 기반 추천", nullable = true)
String title,📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| @Schema(description = "공고 목록") | ||||||||||
| List<HomeNoticeResponse> content, | ||||||||||
|
|
||||||||||
|
|
||||||||||
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.
🧩 Analysis chain
🌐 Web query:
latest AWS SDK for Java v2 BOM version 2024 2025💡 Result:
Do you mean (A) the current/latest AWS SDK for Java v2 BOM version as of today (Jan 18, 2026), or (B) the latest BOM released in 2024 and the latest released in 2025?
🌐 Web query:
AWS SDK v2 2.21.0 security CVE vulnerabilities advisories💡 Result:
Summary — AWS SDK for Java (v2) 2.21.0: known security advisories affecting that release
Maven listings for multiple 2.21.0 artifacts (s3, sts, sdk-core, apache-client, auth) show known CVEs in dependencies that affect that BOM/artifact set, including (as reported on Maven Repository): CVE-2024-47554, CVE-2023-41329, CVE-2025-48924 and others. See artifact pages for details per module. [1][2][3]
There is an open GitHub issue noting Netty dependency CVE-2023-44487 (HTTP/2 “rapid reset”) and discussion about upgrading Netty in aws-sdk-java-v2 releases; users should check whether your 2.21.0 runtime pulls an affected Netty version. [4]
Recommendation
Sources
If you want, I can:
🌐 Web query:
AWS SDK v2 compatibility Spring Boot 3.4.3💡 Result:
Short answer: Yes — AWS SDK for Java v2 is compatible with Spring Boot 3.4.3. Spring Cloud AWS 3.x is built on AWS SDK v2 and targets Spring Boot 3.x, so using SDK v2 (or Spring Cloud AWS 3.x which depends on it) is the recommended approach. [1][2]
Notes / pointers:
Sources:
AWS SDK BOM 버전 2.21.0은 여러 보안 취약점이 있어 즉시 업그레이드가 필요합니다.
버전 2.21.0은 다음을 포함하여 여러 알려진 CVE의 영향을 받습니다: CVE-2024-47554, CVE-2023-41329, CVE-2025-48924, CVE-2023-44487 (Netty HTTP/2). 버전 2.33.x 이상으로 업그레이드한 후 의존성 취약점 스캐너(OWASP Dependency-Check, Snyk, GitHub Dependabot)로 재검증하세요. Spring Boot 3.4.3과의 호환성은 문제없습니다.
🤖 Prompt for AI Agents