Skip to content

Commit 91a6415

Browse files
committed
#19 feat(ContractService): 계약 리뷰 작섵 기능 구현
feat(Review): 양방향 관계 설정 feat(ContractReviewService): 계약 리뷰 추가 기능 ContractService로부터 분리 feat(Review): 별점 1~5 만 가능하도록 검증 기능추가 feat(ContractReviewService): 정상종료 되도록 변경
1 parent 676443d commit 91a6415

15 files changed

+135
-9
lines changed

build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ repositories {
2626
dependencies {
2727
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
2828
implementation 'org.springframework.boot:spring-boot-starter-web'
29+
implementation 'org.springframework.boot:spring-boot-starter-validation'
2930
compileOnly 'org.projectlombok:lombok'
3031
// runtimeOnly 'com.mysql:mysql-connector-j'
3132
runtimeOnly 'com.h2database:h2'
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package com.example.api.contracts;
22

33
import com.example.api.domain.Contract;
4+
import java.util.Optional;
45
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.data.jpa.repository.Query;
7+
import org.springframework.data.repository.query.Param;
8+
import org.springframework.stereotype.Repository;
59

10+
@Repository
611
interface ContractRepository extends JpaRepository<Contract, Long> {
712
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.example.api.contracts;
2+
3+
import com.example.api.contracts.dto.AddContractReviewCommand;
4+
import com.example.api.domain.Contract;
5+
import com.example.api.domain.Review;
6+
import com.example.api.exception.BusinessException;
7+
import com.example.api.exception.ErrorCode;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.stereotype.Service;
10+
import org.springframework.transaction.annotation.Transactional;
11+
import org.springframework.validation.annotation.Validated;
12+
13+
@Service
14+
@RequiredArgsConstructor
15+
public class ContractReviewService {
16+
private final ReviewRepository reviewRepository;
17+
private final ContractRepository contractRepository;
18+
private final ReviewMapper reviewMapper;
19+
20+
@Transactional
21+
public void addContractReview(@Validated final AddContractReviewCommand addContractReviewCommand) {
22+
final Contract contract = contractRepository.findById(addContractReviewCommand.contractId())
23+
.orElseThrow(() -> new BusinessException(ErrorCode.CONTRACT_EXCEPTION));
24+
if (contract.isContractSucceeded()) {
25+
final Review contractReview = reviewMapper.createReview(addContractReviewCommand);
26+
contract.addReview(contractReview);
27+
reviewRepository.save(contractReview);
28+
return;
29+
}
30+
throw new BusinessException("계약이 완료되지 않았습니다.", ErrorCode.CONTRACT_EXCEPTION);
31+
}
32+
}

src/main/java/com/example/api/contracts/ContractService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import com.example.api.contracts.dto.AcceptContractCommand;
44
import com.example.api.contracts.dto.AcceptSuggestCommand;
5-
import com.example.api.contracts.dto.UpdateContractConditionCommand;
65
import com.example.api.contracts.dto.QueryAllSuggestsForMeCommand;
76
import com.example.api.contracts.dto.SuggestedBusinessResponse;
7+
import com.example.api.contracts.dto.UpdateContractConditionCommand;
88
import com.example.api.contracts.update.UpdateContractConditionManager;
99
import com.example.api.domain.Contract;
1010
import com.example.api.domain.OfferEmployment;

src/main/java/com/example/api/contracts/OfferRepository.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import org.springframework.data.jpa.repository.Query;
88
import org.springframework.data.repository.query.Param;
99

10-
public interface OfferRepository extends JpaRepository<OfferEmployment, Long> {
10+
interface OfferRepository extends JpaRepository<OfferEmployment, Long> {
1111
@Query("SELECT new com.example.api.contracts.dto.SuggestedBusinessResponse(offer.business.businessId, offer.suggestStartTime, offer.suggestEndTime, offer.suggestHourlyPay, offer.suggestReaded, offer.suggestSucceeded) "
1212
+ "FROM OfferEmployment offer "
1313
+ "WHERE offer.employee.employeeId = :employeeId")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.example.api.contracts;
2+
3+
import com.example.api.contracts.dto.AddContractReviewCommand;
4+
import com.example.api.domain.Review;
5+
import org.springframework.stereotype.Service;
6+
7+
@Service
8+
class ReviewMapper {
9+
public Review createReview(final AddContractReviewCommand reviewCommand) {
10+
return new Review(reviewCommand.starPoint(), reviewCommand.reviewContent());
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.example.api.contracts;
2+
3+
import com.example.api.domain.Review;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.stereotype.Repository;
6+
7+
@Repository
8+
interface ReviewRepository extends JpaRepository<Review, Long> {
9+
}

src/main/java/com/example/api/contracts/controller/ContractController.java

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.example.api.contracts.ContractService;
44
import com.example.api.contracts.dto.AcceptContractCommand;
55
import com.example.api.contracts.dto.AcceptSuggestCommand;
6+
import com.example.api.contracts.dto.AddContractReviewCommand;
7+
import com.example.api.contracts.dto.AddContractReviewRequest;
68
import com.example.api.contracts.dto.QueryAllSuggestsForMeCommand;
79
import com.example.api.contracts.dto.SuggestedBusinessResponse;
810
import com.example.api.contracts.dto.UpdateContractConditionCommand;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.example.api.contracts.controller;
2+
3+
import com.example.api.contracts.ContractReviewService;
4+
import com.example.api.contracts.dto.AddContractReviewCommand;
5+
import com.example.api.contracts.dto.AddContractReviewRequest;
6+
import lombok.RequiredArgsConstructor;
7+
import org.springframework.http.ResponseEntity;
8+
import org.springframework.web.bind.annotation.PathVariable;
9+
import org.springframework.web.bind.annotation.PostMapping;
10+
import org.springframework.web.bind.annotation.RequestBody;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
@RestController
14+
@RequiredArgsConstructor
15+
class ContractReviewController {
16+
private final ContractReviewService contractReviewService;
17+
18+
@PostMapping("/api/v1/contracts/{contractId}/reviews")
19+
public ResponseEntity<?> addContractReview(
20+
@PathVariable(required = true) final Long contractId,
21+
@RequestBody final AddContractReviewRequest addContractReviewRequest
22+
) {
23+
final AddContractReviewCommand addReviewCommand = addContractReviewRequest.toCommand(contractId);
24+
contractReviewService.addContractReview(addReviewCommand);
25+
return ResponseEntity.ok(null);
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.example.api.contracts.dto;
22

3-
import org.springframework.lang.NonNull;
3+
import jakarta.validation.constraints.NotNull;
44

55
public record AcceptContractCommand(
6-
@NonNull
6+
@NotNull
77
Long contractId
88
) {
99
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.example.api.contracts.dto;
2+
3+
import org.hibernate.validator.constraints.Range;
4+
import org.springframework.lang.NonNull;
5+
6+
public record AddContractReviewCommand(
7+
@NonNull
8+
Long contractId,
9+
String reviewContent,
10+
@NonNull
11+
@Range(min = 0L, max = 5L)
12+
Integer starPoint
13+
) {
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.example.api.contracts.dto;
2+
3+
public record AddContractReviewRequest(
4+
String reviewContent,
5+
Integer starPoint
6+
) {
7+
public AddContractReviewCommand toCommand(final Long contractId) {
8+
return new AddContractReviewCommand(contractId, reviewContent, starPoint);
9+
}
10+
}

src/main/java/com/example/api/domain/Contract.java

+8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public class Contract extends BaseEntity {
2525
private int contractHourlyPay;
2626
@Column(name = "CONTRACT_SUCCEDED", columnDefinition = "boolean DEFAULT false")
2727
private boolean contractSucceeded;
28+
@OneToOne
29+
@JoinColumn(name = "REVIEW_ID")
30+
private Review review;
2831

2932
public Contract(
3033
final OfferEmployment offerEmployment,
@@ -59,5 +62,10 @@ public boolean isValidContractRangeTime() {
5962
public void succeed() {
6063
this.contractSucceeded = true;
6164
}
65+
66+
public void addReview(final Review review) {
67+
this.review = review;
68+
review.setContract(this);
69+
}
6270
}
6371

src/main/java/com/example/api/domain/Review.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,22 @@
1010
@Getter
1111
@Setter
1212
@Table(name = "REVIEW")
13-
@AllArgsConstructor
1413
@NoArgsConstructor
1514
public class Review extends BaseEntity {
1615

1716
@Id
1817
@GeneratedValue(strategy = GenerationType.IDENTITY)
19-
private Long suggestId;
20-
18+
private Long reviewId;
19+
@OneToOne(mappedBy = "review")
20+
private Contract contract;
2121
@Column(name = "REVIEW_STAR_POINT")
2222
private int reviewStarPoint;
23-
2423
@Column(name = "REVIEW_CONTENT")
2524
private String reviewContent;
25+
26+
public Review(final int reviewStarPoint, final String reviewContent) {
27+
this.reviewStarPoint = reviewStarPoint;
28+
this.reviewContent = reviewContent;
29+
}
2630
}
2731

src/main/java/com/example/api/exception/ErrorCode.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
@Getter
77
public enum ErrorCode {
8-
SERVER_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "-000", "서버 에러");
8+
SERVER_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "-000", "서버 에러"),
9+
10+
CONTRACT_EXCEPTION(HttpStatus.BAD_REQUEST, "-400", "계약 정보 에러");
911

1012
private final HttpStatus httpStatus;
1113
private final String errorCode;

0 commit comments

Comments
 (0)