-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
290 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
src/main/java/com/testcar/car/domains/track/TrackController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package com.testcar.car.domains.track; | ||
|
||
|
||
import com.testcar.car.common.annotation.RoleAllowed; | ||
import com.testcar.car.domains.member.Role; | ||
import com.testcar.car.domains.track.model.RegisterTrackRequest; | ||
import com.testcar.car.domains.track.model.TrackResponse; | ||
import com.testcar.car.domains.track.model.vo.TrackFilterCondition; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import jakarta.validation.Valid; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PatchMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
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; | ||
|
||
@RestController | ||
@RequestMapping("/tracks") | ||
@RequiredArgsConstructor | ||
public class TrackController { | ||
private final TrackService trackService; | ||
|
||
@GetMapping | ||
@RoleAllowed(role = Role.USER) | ||
@Operation(summary = "[시험장 관리] 시험장 조회", description = "시험장을 조건에 맞게 조회합니다.") | ||
public List<TrackResponse> getTracksByCondition(TrackFilterCondition condition) { | ||
final List<Track> tracks = trackService.findAllByCondition(condition); | ||
return tracks.stream().map(TrackResponse::from).toList(); | ||
} | ||
|
||
@GetMapping("/{trackId}") | ||
@RoleAllowed(role = Role.USER) | ||
@Operation(summary = "[시험장 관리] 시험장 상세 정보", description = "시험장 상세 정보를 가져옵니다.") | ||
public TrackResponse getTrackById(@PathVariable Long trackId) { | ||
final Track track = trackService.findById(trackId); | ||
return TrackResponse.from(track); | ||
} | ||
|
||
@PostMapping("/register") | ||
@RoleAllowed(role = Role.ADMIN) | ||
@Operation(summary = "[시험장 관리] 시험장 등록", description = "(관리자) 새로운 시험장을 등록합니다.") | ||
public TrackResponse register(@Valid @RequestBody RegisterTrackRequest request) { | ||
final Track track = trackService.register(request); | ||
return TrackResponse.from(track); | ||
} | ||
|
||
@PatchMapping("/{trackId}") | ||
@RoleAllowed(role = Role.ADMIN) | ||
@Operation(summary = "[시험장 관리] 시험장 정보 수정", description = "(관리자) 시험장 정보를 수정합니다.") | ||
public TrackResponse update( | ||
@PathVariable Long trackId, @Valid @RequestBody RegisterTrackRequest request) { | ||
final Track track = trackService.updateById(trackId, request); | ||
return TrackResponse.from(track); | ||
} | ||
|
||
@DeleteMapping("/{trackId}") | ||
@RoleAllowed(role = Role.ADMIN) | ||
@Operation(summary = "[시험장 관리] 시험장 삭제", description = "(관리자) 시험장을 삭제합니다.") | ||
public TrackResponse delete(@PathVariable Long trackId) { | ||
final Track track = trackService.deleteById(trackId); | ||
return TrackResponse.from(track); | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
src/main/java/com/testcar/car/domains/track/TrackService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.testcar.car.domains.track; | ||
|
||
|
||
import com.testcar.car.common.exception.BadRequestException; | ||
import com.testcar.car.common.exception.NotFoundException; | ||
import com.testcar.car.domains.track.exception.ErrorCode; | ||
import com.testcar.car.domains.track.model.RegisterTrackRequest; | ||
import com.testcar.car.domains.track.model.vo.TrackFilterCondition; | ||
import com.testcar.car.domains.track.repository.TrackRepository; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@Transactional | ||
@RequiredArgsConstructor | ||
public class TrackService { | ||
private final TrackRepository trackRepository; | ||
|
||
/** 시험장을 id로 조회합니다. */ | ||
public Track findById(Long id) { | ||
return trackRepository | ||
.findByIdAndDeletedFalse(id) | ||
.orElseThrow(() -> new NotFoundException(ErrorCode.TRACK_NOT_FOUND)); | ||
} | ||
|
||
/** 시험장을 id로 조회합니다. */ | ||
public List<Track> findAllByCondition(TrackFilterCondition condition) { | ||
return trackRepository.findAllByCondition(condition); | ||
} | ||
|
||
/** 새로운 시험장을 등록합니다. */ | ||
public Track register(RegisterTrackRequest request) { | ||
final Track car = createEntity(request); | ||
return trackRepository.save(car); | ||
} | ||
|
||
/** 시험장 정보를 업데이트 합니다. */ | ||
public Track updateById(Long trackId, RegisterTrackRequest request) { | ||
Track track = this.findById(trackId); | ||
final Track updateTrack = this.createEntity(request); | ||
track.update(updateTrack); | ||
return trackRepository.save(track); | ||
} | ||
|
||
/** 시험장을 삭제 처리 합니다. (soft delete) */ | ||
public Track deleteById(Long trackId) { | ||
final Track car = this.findById(trackId); | ||
car.delete(); | ||
return trackRepository.save(car); | ||
} | ||
|
||
/** 영속되지 않은 시험장 엔티티를 생성합니다. */ | ||
private Track createEntity(RegisterTrackRequest request) { | ||
validateNameNotDuplicated(request.getName()); | ||
return Track.builder().name(request.getName()).location(request.getLocation()).build(); | ||
} | ||
|
||
/** 시험장명 중복을 검사합니다. */ | ||
private void validateNameNotDuplicated(String name) { | ||
if (trackRepository.existsByNameAndDeletedFalse(name)) { | ||
throw new BadRequestException(ErrorCode.DUPLICATED_TRACK_NAME); | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/testcar/car/domains/track/exception/ErrorCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.testcar.car.domains.track.exception; | ||
|
||
|
||
import com.testcar.car.common.exception.BaseErrorCode; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum ErrorCode implements BaseErrorCode { | ||
TRACK_NOT_FOUND("TRK001", "해당 시험장을 찾을 수 없습니다."), | ||
DUPLICATED_TRACK_NAME("TRK002", "중복된 시험장명입니다."), | ||
; | ||
private final String code; | ||
private final String message; | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/testcar/car/domains/track/model/RegisterTrackRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.testcar.car.domains.track.model; | ||
|
||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import jakarta.validation.constraints.NotBlank; | ||
import lombok.Getter; | ||
import org.hibernate.validator.constraints.Length; | ||
|
||
@Getter | ||
public class RegisterTrackRequest { | ||
@NotBlank | ||
@Length(max = 20) | ||
@Schema(description = "시험장명", example = "서산주행시험장") | ||
private String name; | ||
|
||
@NotBlank | ||
@Schema(description = "위치", example = "충청남도 서산시 부석면") | ||
private String location; | ||
} |
40 changes: 40 additions & 0 deletions
40
src/main/java/com/testcar/car/domains/track/model/TrackResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.testcar.car.domains.track.model; | ||
|
||
|
||
import com.testcar.car.domains.track.Track; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@Builder | ||
public class TrackResponse { | ||
@Schema(description = "시험장 ID", example = "1") | ||
private Long id; | ||
|
||
@Schema(description = "시험명", example = "서산주행시험장") | ||
private String name; | ||
|
||
@Schema(description = "위치", example = "충청남도 서산시 부석면") | ||
private String location; | ||
|
||
@Schema(description = "경도", example = "132.123123") | ||
private Double longitude; | ||
|
||
@Schema(description = "위도", example = "37.123123") | ||
private Double latitude; | ||
|
||
@Schema(description = "시험장 특성", example = "평지") | ||
private String description; | ||
|
||
public static TrackResponse from(Track track) { | ||
return TrackResponse.builder() | ||
.id(track.getId()) | ||
.name(track.getName()) | ||
.location(track.getLocation()) | ||
.longitude(track.getLongitude()) | ||
.latitude(track.getLatitude()) | ||
.description(track.getDescription()) | ||
.build(); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/testcar/car/domains/track/model/vo/TrackFilterCondition.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.testcar.car.domains.track.model.vo; | ||
|
||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
@Getter | ||
@Setter | ||
public class TrackFilterCondition { | ||
@Schema(description = "시험장명", example = "null") | ||
private String name; | ||
|
||
@Schema(description = "위치", example = "null") | ||
private String location; | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/testcar/car/domains/track/repository/TrackCustomRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.testcar.car.domains.track.repository; | ||
|
||
|
||
import com.testcar.car.domains.track.Track; | ||
import com.testcar.car.domains.track.model.vo.TrackFilterCondition; | ||
import java.util.List; | ||
|
||
public interface TrackCustomRepository { | ||
List<Track> findAllByCondition(TrackFilterCondition condition); | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/java/com/testcar/car/domains/track/repository/TrackCustomRepositoryImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.testcar.car.domains.track.repository; | ||
|
||
import static com.testcar.car.domains.track.QTrack.track; | ||
|
||
import com.querydsl.core.types.dsl.BooleanExpression; | ||
import com.querydsl.jpa.impl.JPAQueryFactory; | ||
import com.testcar.car.common.entity.BaseQueryDslRepository; | ||
import com.testcar.car.domains.track.Track; | ||
import com.testcar.car.domains.track.model.vo.TrackFilterCondition; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@RequiredArgsConstructor | ||
public class TrackCustomRepositoryImpl implements TrackCustomRepository, BaseQueryDslRepository { | ||
private final JPAQueryFactory jpaQueryFactory; | ||
|
||
@Override | ||
public List<Track> findAllByCondition(TrackFilterCondition condition) { | ||
return jpaQueryFactory | ||
.selectFrom(track) | ||
.where( | ||
notDeleted(track), | ||
trackNameContainsOrNull(condition.getName()), | ||
locationContainsOrNull(condition.getLocation())) | ||
.orderBy(track.name.asc()) | ||
.fetch(); | ||
} | ||
|
||
private BooleanExpression trackNameContainsOrNull(String name) { | ||
return (name == null) ? null : track.name.contains(name); | ||
} | ||
|
||
private BooleanExpression locationContainsOrNull(String location) { | ||
return (location == null) ? null : track.location.contains(location); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/testcar/car/domains/track/repository/TrackRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.testcar.car.domains.track.repository; | ||
|
||
|
||
import com.testcar.car.domains.track.Track; | ||
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface TrackRepository extends JpaRepository<Track, Long>, TrackCustomRepository { | ||
Optional<Track> findByIdAndDeletedFalse(Long id); | ||
|
||
boolean existsByNameAndDeletedFalse(String name); | ||
} |