Skip to content

Commit e2d5195

Browse files
authored
Merge pull request #51 from hackathon-soa/refactor/#47
Refactor/#47 코드 구조개선 (에러개선, 컨버터 책임분리 등)
2 parents 565c89e + 1ca1b7d commit e2d5195

31 files changed

+224
-188
lines changed

src/main/java/hackathon/soa/config/AmazonConfig.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,6 @@ public class AmazonConfig {
4545
@Value("verification")
4646
private String verificationPath; // S3 내 테스트 관련 파일 저장 디렉토리 경로 (폴더명: tests)
4747

48-
//!! s3에 어떤 디렉토리를 만들고, 그안에 뭘 저장하고 싶다면!!
49-
//1. aws 콘솔에서 s3 디렉토리 생성
50-
//2. AmazonConfig에 private String ~~Path 변수 생성
51-
//3. AmazonS3Manager에 generate~~KeyName() 메서드 추가
52-
//4. 서비스 계층에서 사용.
53-
5448
/**
5549
* AWS 인증 정보를 설정하는 초기화 메서드.
5650
* Spring이 이 클래스를 생성한 후 자동으로 호출되며,
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package hackathon.soa.domain.course;
2+
3+
import hackathon.soa.common.apiPayload.code.status.ErrorStatus;
4+
import hackathon.soa.common.apiPayload.exception.CourseHandler;
5+
import hackathon.soa.domain.course.dto.CourseRequestDTO;
6+
import hackathon.soa.entity.*;
7+
import hackathon.soa.entity.enums.CourseStatus;
8+
import hackathon.soa.entity.enums.MovementType;
9+
import lombok.experimental.UtilityClass;
10+
11+
@UtilityClass
12+
public class CourseConverter {
13+
14+
public Course toCourseEntity(CourseRequestDTO.CreateCourseRequest request, Member member) {
15+
return Course.builder()
16+
.title(request.getTitle())
17+
.region(request.getRegion())
18+
.startTime(request.getStartTime())
19+
.endTime(request.getEndTime())
20+
.interests(request.getInterests())
21+
.specialNote(request.getSpecialNote())
22+
.preferredGender(request.getPreferredGender())
23+
.status(CourseStatus.IN_PROGRESS)
24+
.member(member)
25+
.build();
26+
}
27+
28+
public CourseSegment toCourseSegment(Course course, CourseRequestDTO.SegmentDTO dto, int order) {
29+
return CourseSegment.builder()
30+
.course(course)
31+
.segmentOrder(order)
32+
.startTime(dto.getStartTime())
33+
.endTime(dto.getEndTime())
34+
.build();
35+
}
36+
37+
public MoveSegment toMoveSegment(CourseSegment segment, String movementTypeStr, Double distance) {
38+
MovementType movementType;
39+
try {
40+
movementType = MovementType.valueOf(movementTypeStr);
41+
} catch (IllegalArgumentException e) {
42+
throw new CourseHandler(ErrorStatus.SEGMENT_DESERIALIZATION_ERROR);
43+
}
44+
45+
return MoveSegment.builder()
46+
.courseSegment(segment)
47+
.movementType(movementType)
48+
.movementDistanceKm(distance)
49+
.build();
50+
}
51+
52+
public StaySegment toStaySegment(CourseSegment segment, String name, String address) {
53+
return StaySegment.builder()
54+
.courseSegment(segment)
55+
.locationName(name)
56+
.locationAddress(address)
57+
.build();
58+
}
59+
60+
public CourseTravelStyle toCourseTravelStyle(Course course, TravelStyle travelStyle) {
61+
return CourseTravelStyle.builder()
62+
.course(course)
63+
.travelStyle(travelStyle)
64+
.build();
65+
}
66+
}

src/main/java/hackathon/soa/domain/course/CoursePlaceSearchService.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ public List<String> search(String query) {
3131
HttpHeaders headers = new HttpHeaders();
3232
headers.set("X-Naver-Client-Id", clientId);
3333
headers.set("X-Naver-Client-Secret", clientSecret);
34-
headers.set("User-Agent", "Mozilla/5.0"); // User-Agent도 추가
34+
headers.set("User-Agent", "Mozilla/5.0"); // User-Agent도 추가
3535

3636
HttpEntity<Void> entity = new HttpEntity<>(headers);
3737

38-
// 실제 디버깅용: 원시 응답 출력
38+
// 실제 디버깅용: 원시 응답 출력
3939
ResponseEntity<String> debugResponse = restTemplate.exchange(
4040
apiUrl,
4141
HttpMethod.GET,
@@ -46,7 +46,7 @@ public List<String> search(String query) {
4646
System.out.println("✅ Client ID: " + clientId);
4747
System.out.println("✅ 네이버 원시 응답: " + debugResponse.getBody());
4848

49-
// 실사용 로직: DTO 매핑용
49+
// 실사용 로직: DTO 매핑용
5050
ResponseEntity<NaverLocalResponse> response = restTemplate.exchange(
5151
apiUrl,
5252
HttpMethod.GET,
@@ -55,7 +55,7 @@ public List<String> search(String query) {
5555
);
5656

5757
if (response.getBody() == null || response.getBody().getItems() == null) {
58-
System.out.println("⚠️ 응답이 null이거나 items 없음");
58+
System.out.println("응답이 null이거나 items 없음");
5959
return List.of("검색 결과가 없습니다.");
6060
}
6161

src/main/java/hackathon/soa/domain/course/CourseService.java

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package hackathon.soa.domain.course;
22

3+
import hackathon.soa.common.apiPayload.code.status.ErrorStatus;
4+
import hackathon.soa.common.apiPayload.exception.CourseHandler;
35
import hackathon.soa.domain.course.dto.CourseRequestDTO;
46
import hackathon.soa.domain.course.repository.*;
57
import hackathon.soa.domain.member.MemberRepository;
@@ -10,7 +12,6 @@
1012
import lombok.RequiredArgsConstructor;
1113
import org.springframework.stereotype.Service;
1214
import org.springframework.transaction.annotation.Transactional;
13-
1415
import java.util.List;
1516

1617
@Service
@@ -26,22 +27,12 @@ public class CourseService {
2627
private final MemberRepository memberRepository;
2728

2829
@Transactional
29-
public Long createCourse(CourseRequestDTO.CreateCourseRequest request,Long userId) {
30+
public Long createCourse(CourseRequestDTO.CreateCourseRequest request, Long userId) {
3031
Member member = memberRepository.findById(userId)
31-
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 회원입니다: " + userId));
32+
.orElseThrow(() -> new CourseHandler(ErrorStatus.MEMBER_NOT_FOUND));
3233

3334
// 1. Course 생성
34-
Course course = Course.builder()
35-
.title(request.getTitle())
36-
.region(request.getRegion())
37-
.startTime(request.getStartTime())
38-
.endTime(request.getEndTime())
39-
.interests(request.getInterests())
40-
.specialNote(request.getSpecialNote())
41-
.preferredGender(request.getPreferredGender())
42-
.status(CourseStatus.IN_PROGRESS)
43-
.member(member)
44-
.build();
35+
Course course = CourseConverter.toCourseEntity(request, member);
4536
courseRepository.save(course);
4637

4738
// 2. 여행 테마 저장
@@ -51,39 +42,25 @@ public Long createCourse(CourseRequestDTO.CreateCourseRequest request,Long userI
5142
TravelStyle.builder().name(themeName).build()
5243
));
5344

54-
CourseTravelStyle courseTravelStyle = CourseTravelStyle.builder()
55-
.course(course)
56-
.travelStyle(travelStyle)
57-
.build();
58-
59-
courseTravelStyleRepository.save(courseTravelStyle);
45+
courseTravelStyleRepository.save(
46+
CourseConverter.toCourseTravelStyle(course, travelStyle)
47+
);
6048
}
6149

6250
// 3. Segment 저장
6351
int order = 0;
6452
for (CourseRequestDTO.SegmentDTO dto : request.getSegments()) {
65-
CourseSegment segment = CourseSegment.builder()
66-
.course(course)
67-
.segmentOrder(order++)
68-
.startTime(dto.getStartTime())
69-
.endTime(dto.getEndTime())
70-
.build();
53+
CourseSegment segment = CourseConverter.toCourseSegment(course, dto, order++);
7154
courseSegmentRepository.save(segment);
7255

7356
if (dto.isMoving()) {
74-
MoveSegment move = MoveSegment.builder()
75-
.courseSegment(segment)
76-
.movementType(MovementType.valueOf(dto.getMovementType()))
77-
.movementDistanceKm(dto.getMovementDistanceKm())
78-
.build();
79-
moveSegmentRepository.save(move);
57+
moveSegmentRepository.save(
58+
CourseConverter.toMoveSegment(segment, dto.getMovementType(), dto.getMovementDistanceKm())
59+
);
8060
} else {
81-
StaySegment stay = StaySegment.builder()
82-
.courseSegment(segment)
83-
.locationName(dto.getLocationName())
84-
.locationAddress(dto.getLocationAddress())
85-
.build();
86-
staySegmentRepository.save(stay);
61+
staySegmentRepository.save(
62+
CourseConverter.toStaySegment(segment, dto.getLocationName(), dto.getLocationAddress())
63+
);
8764
}
8865
}
8966

src/main/java/hackathon/soa/domain/course/dto/CourseRequestDTO.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package hackathon.soa.domain.course.dto;
22

3-
import hackathon.soa.entity.Gender;
3+
import hackathon.soa.entity.enums.Gender;
44
import lombok.AllArgsConstructor;
55
import lombok.Builder;
66
import lombok.Getter;

src/main/java/hackathon/soa/domain/home/dto/HomeResponseDTO.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package hackathon.soa.domain.home.dto;
22

3-
import hackathon.soa.entity.Gender;
43
import lombok.AllArgsConstructor;
54
import lombok.Builder;
65
import lombok.Getter;

src/main/java/hackathon/soa/domain/member/MemberConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package hackathon.soa.domain.member;
22

33
import hackathon.soa.domain.auth.dto.AuthRequestDTO;
4-
import hackathon.soa.entity.Gender;
4+
import hackathon.soa.entity.enums.Gender;
55
import hackathon.soa.entity.Member;
66
import org.springframework.security.crypto.password.PasswordEncoder;
77

src/main/java/hackathon/soa/domain/participation/ParticipationController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import hackathon.soa.common.JwtUser;
44
import hackathon.soa.common.apiPayload.ApiResponse;
5+
import hackathon.soa.entity.enums.SegmentParticipationStatus;
56
import hackathon.soa.domain.participation.dto.ParticipationResponseDTO;
67
import hackathon.soa.domain.search.dto.SearchResponseDTO;
78
import hackathon.soa.entity.SegmentParticipationStatus;
@@ -70,5 +71,4 @@ public ApiResponse<ParticipationResponseDTO.ApplicantsResponsesDTO> getApplicant
7071
return ApiResponse.onSuccess(result);
7172
}
7273

73-
7474
}
Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,41 @@
1-
package hackathon.soa.domain.participation;
2-
3-
import hackathon.soa.domain.participation.dto.ParticipationResponseDTO;
4-
import hackathon.soa.entity.Member;
5-
6-
import java.time.LocalDate;
7-
import java.time.Period;
8-
import java.time.format.DateTimeFormatter;
9-
import java.util.List;
10-
import java.util.stream.Collectors;
11-
12-
public class ParticipationConverter {
13-
public static ParticipationResponseDTO.ApplicantsResponseDTO toApplicantsResponseDTO(Member member, Integer age) {
14-
return ParticipationResponseDTO.ApplicantsResponseDTO.builder()
15-
.nickname(member.getNickname())
16-
.disabilityType(member.getDisabilityType())
17-
.temperature(member.getTemperature())
18-
.phoneNumber(member.getPhoneNumber())
19-
.gender(member.getGender().toString())
20-
.age(age)
21-
.volunteerHours(member.getVolunteerHours())
22-
.build();
23-
}
24-
25-
public static ParticipationResponseDTO.ApplicantsResponsesDTO toApplicantsResponsesDTO(List<ParticipationResponseDTO.ApplicantsResponseDTO> dtos) {
26-
return ParticipationResponseDTO.ApplicantsResponsesDTO.builder()
27-
.applicants(dtos)
28-
.build();
29-
}
30-
}
1+
package hackathon.soa.domain.participation;
2+
3+
import hackathon.soa.domain.participation.dto.ParticipationResponseDTO;
4+
import hackathon.soa.entity.Member;
5+
import hackathon.soa.entity.SegmentParticipation;
6+
import hackathon.soa.entity.StaySegment;
7+
import hackathon.soa.entity.enums.SegmentParticipationStatus;
8+
import lombok.experimental.UtilityClass;
9+
10+
import java.util.List;
11+
12+
@UtilityClass
13+
public class ParticipationConverter {
14+
15+
public SegmentParticipation toSegmentParticipation(Member member, StaySegment segment, SegmentParticipationStatus status) {
16+
return SegmentParticipation.builder()
17+
.member(member)
18+
.staySegment(segment)
19+
.status(status)
20+
.build();
21+
}
22+
23+
public ParticipationResponseDTO.ApplicantsResponseDTO toApplicantsResponseDTO(Member member, Integer age) {
24+
return ParticipationResponseDTO.ApplicantsResponseDTO.builder()
25+
.nickname(member.getNickname())
26+
.disabilityType(member.getDisabilityType())
27+
.temperature(member.getTemperature())
28+
.phoneNumber(member.getPhoneNumber())
29+
.gender(member.getGender().toString())
30+
.age(age)
31+
.volunteerHours(member.getVolunteerHours())
32+
.build();
33+
}
34+
35+
public ParticipationResponseDTO.ApplicantsResponsesDTO toApplicantsResponsesDTO(List<ParticipationResponseDTO.ApplicantsResponseDTO> dtos) {
36+
return ParticipationResponseDTO.ApplicantsResponsesDTO.builder()
37+
.applicants(dtos)
38+
.build();
39+
}
40+
}
41+

src/main/java/hackathon/soa/domain/participation/ParticipationService.java

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import hackathon.soa.domain.segment.repository.CourseSegmentRepository;
1010
import hackathon.soa.domain.segment.repository.StaySegmentRepository;
1111
import hackathon.soa.entity.*;
12+
import hackathon.soa.entity.enums.SegmentParticipationStatus;
1213
import jakarta.transaction.Transactional;
1314
import lombok.RequiredArgsConstructor;
1415
import org.springframework.stereotype.Service;
@@ -17,8 +18,6 @@
1718
import java.time.Period;
1819
import java.time.format.DateTimeFormatter;
1920
import java.util.List;
20-
import java.util.Optional;
21-
import java.util.stream.Collectors;
2221

2322
@Service
2423
@Transactional
@@ -36,14 +35,12 @@ public void registerStaySegment(Long memberId, Long segmentId) {
3635
.orElseThrow(() -> new AuthHandler(ErrorStatus.MEMBER_NOT_FOUND));
3736

3837
StaySegment segment = staySegmentRepository.findById(segmentId)
39-
.orElseThrow(() -> new GeneralException(ErrorStatus.NOT_FOUND_SEGMENT));
40-
41-
segmentParticipationRepository.save(
42-
SegmentParticipation.builder()
43-
.member(member)
44-
.staySegment(segment)
45-
.status(SegmentParticipationStatus.PENDING)
46-
.build());
38+
.orElseThrow(() -> new GeneralException(ErrorStatus.SEGMENT_NOT_FOUND)); // ❗ ErrorStatus 통일
39+
40+
SegmentParticipation participation = ParticipationConverter.toSegmentParticipation(
41+
member, segment, SegmentParticipationStatus.PENDING
42+
);
43+
segmentParticipationRepository.save(participation);
4744
}
4845

4946
public void registerEntireSegment(Long memberId, Long courseId) {
@@ -56,25 +53,18 @@ public void registerEntireSegment(Long memberId, Long courseId) {
5653
List<CourseSegment> courseSegments = courseSegmentRepository.findAllByCourse(course);
5754

5855
for (CourseSegment cs : courseSegments) {
59-
Optional<StaySegment> optionalStaySegment = staySegmentRepository.findByCourseSegmentId(cs.getId());
60-
61-
if (optionalStaySegment.isEmpty()) {
62-
continue;
63-
}
64-
StaySegment staySegment = optionalStaySegment.get();
65-
66-
segmentParticipationRepository.save(
67-
SegmentParticipation.builder()
68-
.member(member)
69-
.staySegment(staySegment)
70-
.status(SegmentParticipationStatus.PENDING)
71-
.build()
72-
);
56+
staySegmentRepository.findByCourseSegmentId(cs.getId()).ifPresent(staySegment -> {
57+
SegmentParticipation participation = ParticipationConverter.toSegmentParticipation(
58+
member, staySegment, SegmentParticipationStatus.PENDING
59+
);
60+
segmentParticipationRepository.save(participation);
61+
});
7362
}
7463
}
64+
7565
public void updateStatus(Long participationId, SegmentParticipationStatus status) {
7666
SegmentParticipation participation = segmentParticipationRepository.findById(participationId)
77-
.orElseThrow(() -> new GeneralException(ErrorStatus._INTERNAL_SERVER_ERROR));
67+
.orElseThrow(() -> new GeneralException(ErrorStatus.SEGMENT_NOT_FOUND)); // ❗ 더 구체적인 에러로 교체
7868

7969
participation.updateStatus(status);
8070
}
@@ -102,4 +92,5 @@ public ParticipationResponseDTO.ApplicantsResponsesDTO getApplicants (Long segme
10292

10393
return ParticipationConverter.toApplicantsResponsesDTO(dtos);
10494
}
95+
10596
}

0 commit comments

Comments
 (0)