-
Notifications
You must be signed in to change notification settings - Fork 8
feat: 어드민 국가 crud 추가 #656
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
base: develop
Are you sure you want to change the base?
feat: 어드민 국가 crud 추가 #656
Changes from all commits
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,59 @@ | ||
| package com.example.solidconnection.admin.location.country.controller; | ||
|
|
||
| import com.example.solidconnection.admin.location.country.dto.AdminCountryCreateRequest; | ||
| import com.example.solidconnection.admin.location.country.dto.AdminCountryResponse; | ||
| import com.example.solidconnection.admin.location.country.dto.AdminCountryUpdateRequest; | ||
| import com.example.solidconnection.admin.location.country.service.AdminCountryService; | ||
| import jakarta.validation.Valid; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.DeleteMapping; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.PathVariable; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.PutMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @RequiredArgsConstructor | ||
| @RequestMapping("/admin/countries") | ||
| @RestController | ||
| public class AdminCountryController { | ||
|
|
||
| private final AdminCountryService adminCountryService; | ||
|
|
||
| @GetMapping | ||
| public ResponseEntity<List<AdminCountryResponse>> getAllCountries() { | ||
| List<AdminCountryResponse> responses = adminCountryService.getAllCountries(); | ||
| return ResponseEntity.ok(responses); | ||
| } | ||
|
|
||
| @PostMapping | ||
| public ResponseEntity<AdminCountryResponse> createCountry( | ||
| @Valid @RequestBody AdminCountryCreateRequest request | ||
| ) { | ||
| AdminCountryResponse response = adminCountryService.createCountry(request); | ||
| return ResponseEntity.status(HttpStatus.CREATED).body(response); | ||
| } | ||
|
|
||
| @PutMapping("/{code}") | ||
| public ResponseEntity<AdminCountryResponse> updateCountry( | ||
| @PathVariable String code, | ||
| @Valid @RequestBody AdminCountryUpdateRequest request | ||
| ) { | ||
| AdminCountryResponse response = adminCountryService.updateCountry(code, request); | ||
| return ResponseEntity.ok(response); | ||
| } | ||
|
|
||
| @DeleteMapping("/{code}") | ||
| public ResponseEntity<Void> deleteCountry( | ||
| @PathVariable String code | ||
| ) { | ||
| adminCountryService.deleteCountry(code); | ||
| return ResponseEntity.noContent().build(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.example.solidconnection.admin.location.country.dto; | ||
|
|
||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.Size; | ||
|
|
||
| public record AdminCountryCreateRequest( | ||
| @NotBlank(message = "국가 코드는 필수입니다") | ||
| @Size(min = 2, max = 2, message = "국가 코드는 2자여야 합니다") | ||
| String code, | ||
|
|
||
| @NotBlank(message = "한글 국가명은 필수입니다") | ||
| @Size(min = 1, max = 100, message = "한글 국가명은 1자 이상 100자 이하여야 합니다") | ||
| String koreanName, | ||
|
|
||
| @NotBlank(message = "지역 코드는 필수입니다") | ||
| @Size(min = 1, max = 10, message = "지역 코드는 1자 이상 10자 이하여야 합니다") | ||
| String regionCode | ||
| ) { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package com.example.solidconnection.admin.location.country.dto; | ||
|
|
||
| import com.example.solidconnection.location.country.domain.Country; | ||
|
|
||
| public record AdminCountryResponse( | ||
| String code, | ||
| String koreanName, | ||
| String regionCode | ||
| ) { | ||
|
|
||
| public static AdminCountryResponse from(Country country) { | ||
| return new AdminCountryResponse( | ||
| country.getCode(), | ||
| country.getKoreanName(), | ||
| country.getRegionCode() | ||
| ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.example.solidconnection.admin.location.country.dto; | ||
|
|
||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.Size; | ||
|
|
||
| public record AdminCountryUpdateRequest( | ||
| @NotBlank(message = "한글 국가명은 필수입니다") | ||
| @Size(min = 1, max = 100, message = "한글 국가명은 1자 이상 100자 이하여야 합니다") | ||
| String koreanName, | ||
|
|
||
| @NotBlank(message = "지역 코드는 필수입니다") | ||
| @Size(min = 1, max = 10, message = "지역 코드는 1자 이상 10자 이하여야 합니다") | ||
| String regionCode | ||
| ) { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| package com.example.solidconnection.admin.location.country.service; | ||
|
|
||
| import com.example.solidconnection.admin.location.country.dto.AdminCountryCreateRequest; | ||
| import com.example.solidconnection.admin.location.country.dto.AdminCountryResponse; | ||
| import com.example.solidconnection.admin.location.country.dto.AdminCountryUpdateRequest; | ||
| import com.example.solidconnection.common.exception.CustomException; | ||
| import com.example.solidconnection.common.exception.ErrorCode; | ||
| import com.example.solidconnection.location.country.domain.Country; | ||
| import com.example.solidconnection.location.country.repository.CountryRepository; | ||
| import com.example.solidconnection.location.region.repository.RegionRepository; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import java.util.List; | ||
|
Member
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. 마찬가지로 리포매팅 해주세요 ! |
||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class AdminCountryService { | ||
|
|
||
| private final CountryRepository countryRepository; | ||
| private final RegionRepository regionRepository; | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public List<AdminCountryResponse> getAllCountries() { | ||
| return countryRepository.findAll() | ||
| .stream() | ||
| .map(AdminCountryResponse::from) | ||
| .toList(); | ||
| } | ||
|
|
||
| @Transactional | ||
| public AdminCountryResponse createCountry(AdminCountryCreateRequest request) { | ||
| validateCodeNotExists(request.code()); | ||
| validateKoreanNameNotExists(request.koreanName()); | ||
| validateRegionCodeExists(request.regionCode()); | ||
|
|
||
| Country country = new Country(request.code(), request.koreanName(), request.regionCode()); | ||
| Country savedCountry = countryRepository.save(country); | ||
|
|
||
| return AdminCountryResponse.from(savedCountry); | ||
| } | ||
|
|
||
| private void validateCodeNotExists(String code) { | ||
| countryRepository.findByCode(code) | ||
| .ifPresent(country -> { | ||
| throw new CustomException(ErrorCode.COUNTRY_ALREADY_EXISTS); | ||
| }); | ||
| } | ||
|
|
||
| private void validateKoreanNameNotExists(String koreanName) { | ||
| countryRepository.findAllByKoreanNameIn(List.of(koreanName)) | ||
| .stream() | ||
| .findFirst() | ||
| .ifPresent(country -> { | ||
| throw new CustomException(ErrorCode.COUNTRY_ALREADY_EXISTS); | ||
|
Member
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. 현재 단일 조회임에도 |
||
| }); | ||
| } | ||
|
|
||
| private void validateRegionCodeExists(String regionCode) { | ||
| if (regionCode != null) { | ||
| regionRepository.findById(regionCode) | ||
| .orElseThrow(() -> new CustomException(ErrorCode.REGION_NOT_FOUND)); | ||
| } | ||
| } | ||
|
|
||
| @Transactional | ||
| public AdminCountryResponse updateCountry(String code, AdminCountryUpdateRequest request) { | ||
| Country country = countryRepository.findByCode(code) | ||
| .orElseThrow(() -> new CustomException(ErrorCode.COUNTRY_NOT_FOUND)); | ||
|
|
||
| validateKoreanNameNotDuplicated(request.koreanName(), code); | ||
| validateRegionCodeExists(request.regionCode()); | ||
|
|
||
| country.updateKoreanName(request.koreanName()); | ||
| country.updateRegionCode(request.regionCode()); | ||
|
|
||
| return AdminCountryResponse.from(country); | ||
| } | ||
|
|
||
| private void validateKoreanNameNotDuplicated(String koreanName, String excludeCode) { | ||
| countryRepository.findAllByKoreanNameIn(List.of(koreanName)) | ||
|
Member
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. 여기도 마찬가지로 단일 조회 메서드를 사용하면 좋을 거 같아요 |
||
| .stream() | ||
| .findFirst() | ||
| .ifPresent(existingCountry -> { | ||
| if (!existingCountry.getCode().equals(excludeCode)) { | ||
| throw new CustomException(ErrorCode.COUNTRY_ALREADY_EXISTS); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| @Transactional | ||
| public void deleteCountry(String code) { | ||
| Country country = countryRepository.findByCode(code) | ||
| .orElseThrow(() -> new CustomException(ErrorCode.COUNTRY_NOT_FOUND)); | ||
|
|
||
| countryRepository.delete(country); | ||
| } | ||
|
Comment on lines
+92
to
+98
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: #!/bin/bash
# 1. Country를 참조하는 엔티티 찾기
echo "=== Country 참조 엔티티 검색 ==="
rg -n 'private Country|@ManyToOne.*Country|@JoinColumn.*country' --type=java -g '!*Test*' | head -20
# 2. AdminCountryService의 전체 구조 확인
echo -e "\n=== AdminCountryService 구조 ==="
rg -n 'class AdminCountryService|public void|private' src/main/java/com/example/solidconnection/admin/location/country/service/AdminCountryService.java | head -30
# 3. 예외 처리 패턴 확인
echo -e "\n=== DataIntegrityViolationException 처리 ==="
rg -n 'DataIntegrityViolationException|catch.*Exception' --type=java -g '!*Test*' | grep -i country
# 4. HOST_UNIVERSITY_HAS_REFERENCES 사용 위치
echo -e "\n=== HOST_UNIVERSITY_HAS_REFERENCES 검색 ==="
rg -n 'HOST_UNIVERSITY_HAS_REFERENCES' --type=javaRepository: solid-connection/solid-connect-server Length of output: 1845 🏁 Script executed: #!/bin/bash
# 1. HostUniversity 엔티티의 Country 관계 설정 확인
echo "=== HostUniversity 엔티티 구조 ==="
sed -n '50,70p' src/main/java/com/example/solidconnection/university/domain/HostUniversity.java
# 2. AdminHostUniversityService의 deleteHostUniversity 메서드 구현
echo -e "\n=== AdminHostUniversityService deleteHostUniversity 메서드 ==="
rg -n 'public void deleteHostUniversity|private void validateHostUniversity' -A 15 src/main/java/com/example/solidconnection/admin/university/service/AdminHostUniversityService.java | head -50
# 3. Country 엔티티의 정의와 cascade 설정
echo -e "\n=== Country 엔티티 정의 ==="
cat -n src/main/java/com/example/solidconnection/common/domain/Country.java
# 4. UnivApplyInfo 또는 다른 엔티티에서 Country 참조 여부 확인
echo -e "\n=== UnivApplyInfo와 Country 관계 ==="
rg -n 'Country' src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java | head -10Repository: solid-connection/solid-connect-server Length of output: 1457 🏁 Script executed: #!/bin/bash
# 1. Country 엔티티 파일 위치 찾기
echo "=== Country 엔티티 파일 검색 ==="
find . -name 'Country.java' -type f | grep -v target | head -5
# 2. CountryRepository 메서드 확인
echo -e "\n=== CountryRepository 구조 ==="
cat -n src/main/java/com/example/solidconnection/common/repository/CountryRepository.java
# 3. HostUniversityRepository에서 Country 참조 확인 메서드
echo -e "\n=== HostUniversityRepository 메서드 ==="
rg -n 'existsByCountry|countByCountry|findByCountry' src/main/java/com/example/solidconnection/university/repository/HostUniversityRepository.java
# 4. AdminCountryService 전체 코드
echo -e "\n=== AdminCountryService 전체 ==="
cat -n src/main/java/com/example/solidconnection/admin/location/country/service/AdminCountryService.javaRepository: solid-connection/solid-connect-server Length of output: 5027 🏁 Script executed: #!/bin/bash
# 1. 모든 Repository 파일 찾기
echo "=== Repository 파일 위치 ==="
find . -name '*Repository.java' -path '*/repository/*' -type f | grep -E 'Country|HostUniversity'
# 2. Country 엔티티 구조
echo -e "\n=== Country 엔티티 ==="
cat -n src/main/java/com/example/solidconnection/location/country/domain/Country.java
# 3. HostUniversityRepository 내용
echo -e "\n=== HostUniversityRepository 메서드들 ==="
rg -n 'interface HostUniversityRepository|boolean exists|List<' src/main/java/com/example/solidconnection/university/repository/HostUniversityRepository.javaRepository: solid-connection/solid-connect-server Length of output: 1971 🏁 Script executed: #!/bin/bash
# 1. HostUniversityRepository 전체 내용
echo "=== HostUniversityRepository 전체 ==="
cat -n src/main/java/com/example/solidconnection/university/repository/HostUniversityRepository.java
# 2. CountryRepository 전체 내용
echo -e "\n=== CountryRepository 전체 ==="
cat -n src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java
# 3. HostUniversityFilterRepository에서 Country 관련 메서드
echo -e "\n=== HostUniversityFilterRepository ==="
rg -n 'Country|country' src/main/java/com/example/solidconnection/university/repository/custom/HostUniversityFilterRepository.javaRepository: solid-connection/solid-connect-server Length of output: 2275 🏁 Script executed: #!/bin/bash
# HostUniversityFilterRepository 전체 내용
echo "=== HostUniversityFilterRepository 전체 ==="
cat -n src/main/java/com/example/solidconnection/university/repository/custom/HostUniversityFilterRepository.javaRepository: solid-connection/solid-connect-server Length of output: 690 Country 삭제 시 참조 무결성 검증을 추가하세요. HostUniversity가 Country를 참조하고 있으므로, 삭제 전 다음 사항을 처리해야 합니다:
🤖 Prompt for AI Agents |
||
| } | ||
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.
import문 순서 관련해서 한 번 리포매팅 해주세요 !