Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config-submodule
Original file line number Diff line number Diff line change
Expand Up @@ -446,11 +446,12 @@ public boolean existsChatRoom(Long ownerId, Long buyerId, Long propertyId) {
return existing != null;
}

@Override
public Long findExistingChatRoom(Long ownerId, Long buyerId, Long propertyId) {
ChatRoom existingRoom = chatRoomMapper.findByUserAndHome(ownerId, buyerId, propertyId);
return existingRoom.getChatRoomId();
}
@Override
public Long findExistingChatRoom(Long ownerId, Long buyerId, Long propertyId) {
ChatRoom existingRoom = chatRoomMapper.findByUserAndHome(ownerId, buyerId, propertyId);
return existingRoom.getChatRoomId();
}

/** {@inheritDoc} */
@Override
public List<Map<String, Object>> getChatMediaFiles(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,6 @@ List<Map<String, Object>> getChatMediaFiles(
* @param userId 거절하는 사용자 ID (소유자여야 함)
*/
void rejectContractRequest(Long chatRoomId, Long userId);
Long findExistingChatRoom(Long ownerId, Long buyerId, Long propertyId);

Long findExistingChatRoom(Long ownerId, Long buyerId, Long propertyId);
}
251 changes: 127 additions & 124 deletions src/main/java/org/scoula/domain/chat/service/ContractChatServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,22 +133,23 @@ public void AiMessage(Long contractChatId, String content) {
contractChatMapper.updateLastMessage(contractChatId, content);
messagingTemplate.convertAndSend("/topic/contract-chat/" + contractChatId, aiMessage);
}
public void AiMessageNext(Long contractChatId, String content) {
final Long ai = 9997L;

ContractChatDocument aiMessage =
ContractChatDocument.builder()
.contractChatId(contractChatId.toString())
.senderId(ai)
.receiverId(null)
.content(content)
.sendTime(LocalDateTime.now().toString())
.build();

contractChatMessageRepository.saveMessage(aiMessage);
contractChatMapper.updateLastMessage(contractChatId, content);
messagingTemplate.convertAndSend("/topic/contract-chat/" + contractChatId, aiMessage);
}

public void AiMessageNext(Long contractChatId, String content) {
final Long ai = 9997L;

ContractChatDocument aiMessage =
ContractChatDocument.builder()
.contractChatId(contractChatId.toString())
.senderId(ai)
.receiverId(null)
.content(content)
.sendTime(LocalDateTime.now().toString())
.build();

contractChatMessageRepository.saveMessage(aiMessage);
contractChatMapper.updateLastMessage(contractChatId, content);
messagingTemplate.convertAndSend("/topic/contract-chat/" + contractChatId, aiMessage);
}

public void AiMessageBtn(Long contractChatId, String content) {
final Long ai = 9998L;
Expand Down Expand Up @@ -280,14 +281,11 @@ public boolean setEndPointAndExport(Long contractChatId, Long userId, Long order

String result = sb.toString();

SpecialContractFixDocument improveClauseRequest =
updateRecentData(contractChatId, order, result);
ClauseImproveResponseDto improveClauseResponse = getAiClauseImprove(improveClauseRequest);


SpecialContractFixDocument improveClauseRequest =
updateRecentData(contractChatId, order, result);
ClauseImproveResponseDto improveClauseResponse =
getAiClauseImprove(improveClauseRequest);

updateSpecialClause(contractChatId, improveClauseResponse);
updateSpecialClause(contractChatId, improveClauseResponse);

Comment on lines +284 to 289
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

order 파라미터 유효성 검증 누락

현재 order에 대한 null/범위(예: 1..6) 검증이 없어 잘못된 조항 업데이트/AI 요청이 가능해집니다. 유효성 검증을 추가하고 실패 시 명확한 예외를 반환하세요.

적용 예시:

-          SpecialContractFixDocument improveClauseRequest =
-                  updateRecentData(contractChatId, order, result);
+          if (order == null || order < 1 || order > 6) {
+              throw new IllegalArgumentException("유효하지 않은 특약 order: " + order);
+          }
+          SpecialContractFixDocument improveClauseRequest =
+                  updateRecentData(contractChatId, order, result);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
SpecialContractFixDocument improveClauseRequest =
updateRecentData(contractChatId, order, result);
ClauseImproveResponseDto improveClauseResponse = getAiClauseImprove(improveClauseRequest);
SpecialContractFixDocument improveClauseRequest =
updateRecentData(contractChatId, order, result);
ClauseImproveResponseDto improveClauseResponse =
getAiClauseImprove(improveClauseRequest);
updateSpecialClause(contractChatId, improveClauseResponse);
updateSpecialClause(contractChatId, improveClauseResponse);
if (order == null || order < 1 || order > 6) {
throw new IllegalArgumentException("유효하지 않은 특약 order: " + order);
}
SpecialContractFixDocument improveClauseRequest =
updateRecentData(contractChatId, order, result);
ClauseImproveResponseDto improveClauseResponse = getAiClauseImprove(improveClauseRequest);
updateSpecialClause(contractChatId, improveClauseResponse);
🤖 Prompt for AI Agents
In src/main/java/org/scoula/domain/chat/service/ContractChatServiceImpl.java
around lines 284-289, the method uses the order parameter without validation
which allows null or out-of-range values to proceed and trigger incorrect
updates/AI requests; add a precondition check that order is not null and within
the valid range (e.g., 1..6) before calling updateRecentData/getAiClauseImprove,
and if the check fails throw a clear, specific runtime exception (for example
IllegalArgumentException or a domain-specific exception) with a descriptive
message so callers receive an immediate, understandable error rather than
proceeding with invalid input.

checkAndIncrementRoundIfComplete(contractChatId);
return true;
Expand Down Expand Up @@ -632,7 +630,6 @@ public void createNextRoundSpecialContractDocument(
.orElseThrow(
() -> new IllegalArgumentException("현재 라운드의 특약 문서를 찾을 수 없습니다"));


Long newRound = currentRound + 1;
log.info("새 라운드: {} → {}", currentRound, newRound);

Expand Down Expand Up @@ -1581,107 +1578,113 @@ private List<Long> findRejectedOrders(
return rejectedOrders;
}

@Override
@Transactional
public FinalSpecialContractDocument saveFinalSpecialContract(Long contractChatId) {
ContractChat contractChat = contractChatMapper.findByContractChatId(contractChatId);
ContractChat.ContractStatus currentStatus = contractChat.getStatus();

boolean isThirdRoundComplete = (currentStatus == ContractChat.ContractStatus.ROUND3);

List<FinalSpecialContractDocument.FinalClause> finalClauses = new ArrayList<>();

if (isThirdRoundComplete) {
log.info("=== 3회차 수정 완료 - 4라운드 데이터에서 최종 특약 생성 ===");

Optional<SpecialContractDocument> round4DocOpt =
specialContractMongoRepository
.findSpecialContractDocumentByContractChatIdAndRound(
contractChatId, 4L);

if (round4DocOpt.isPresent()) {
SpecialContractDocument round4Doc = round4DocOpt.get();

for (SpecialContractDocument.Clause clause : round4Doc.getClauses()) {
if (clause.getTitle() != null
&& !clause.getTitle().trim().isEmpty()
&& clause.getContent() != null
&& !clause.getContent().trim().isEmpty()) {

FinalSpecialContractDocument.FinalClause finalClause =
FinalSpecialContractDocument.FinalClause.builder()
.order(clause.getOrder())
.title(clause.getTitle())
.content(clause.getContent())
.build();

finalClauses.add(finalClause);
log.info("4라운드에서 특약 {}번 최종 저장: {}", clause.getOrder(), clause.getTitle());
}
}
}
} else {
log.info("=== 모든 특약 완료 - 완료된 특약들만 최종 저장 ===");

List<SpecialContractFixDocument> incompleteContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(
contractChatId, false);

if (!incompleteContracts.isEmpty()) {
throw new IllegalStateException(
"아직 완료되지 않은 특약이 " + incompleteContracts.size() + "개 있습니다.");
}

List<SpecialContractFixDocument> completedContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(
contractChatId, true);

if (completedContracts.isEmpty()) {
throw new IllegalStateException("완료된 특약이 없습니다.");
}

@Override
@Transactional
public FinalSpecialContractDocument saveFinalSpecialContract(Long contractChatId) {
ContractChat contractChat = contractChatMapper.findByContractChatId(contractChatId);
ContractChat.ContractStatus currentStatus = contractChat.getStatus();

boolean isThirdRoundComplete = (currentStatus == ContractChat.ContractStatus.ROUND3);

List<FinalSpecialContractDocument.FinalClause> finalClauses = new ArrayList<>();

if (isThirdRoundComplete) {
log.info("=== 3회차 수정 완료 - 4라운드 데이터에서 최종 특약 생성 ===");

Optional<SpecialContractDocument> round4DocOpt =
specialContractMongoRepository.findSpecialContractDocumentByContractChatIdAndRound(contractChatId, 4L);

if (round4DocOpt.isPresent()) {
SpecialContractDocument round4Doc = round4DocOpt.get();

for (SpecialContractDocument.Clause clause : round4Doc.getClauses()) {
if (clause.getTitle() != null && !clause.getTitle().trim().isEmpty() &&
clause.getContent() != null && !clause.getContent().trim().isEmpty()) {

FinalSpecialContractDocument.FinalClause finalClause =
FinalSpecialContractDocument.FinalClause.builder()
.order(clause.getOrder())
.title(clause.getTitle())
.content(clause.getContent())
.build();

finalClauses.add(finalClause);
log.info("4라운드에서 특약 {}번 최종 저장: {}", clause.getOrder(), clause.getTitle());
}
}
}
} else {
log.info("=== 모든 특약 완료 - 완료된 특약들만 최종 저장 ===");

List<SpecialContractFixDocument> incompleteContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(contractChatId, false);

if (!incompleteContracts.isEmpty()) {
throw new IllegalStateException(
"아직 완료되지 않은 특약이 " + incompleteContracts.size() + "개 있습니다.");
}

List<SpecialContractFixDocument> completedContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(contractChatId, true);

if (completedContracts.isEmpty()) {
throw new IllegalStateException("완료된 특약이 없습니다.");
}

for (SpecialContractFixDocument completedContract : completedContracts) {
Long order = completedContract.getOrder();

Optional<SpecialContractDocument> latestRoundDoc =
findLatestRoundForOrder(contractChatId, order);

if (latestRoundDoc.isPresent()) {
SpecialContractDocument doc = latestRoundDoc.get();

doc.getClauses().stream()
.filter(clause -> clause.getOrder().equals(order.intValue()))
.findFirst()
.ifPresent(
clause -> {
FinalSpecialContractDocument.FinalClause finalClause =
FinalSpecialContractDocument.FinalClause.builder()
.order(clause.getOrder())
.title(clause.getTitle())
.content(clause.getContent())
.build();

finalClauses.add(finalClause);
log.info(
"특약 {}번 최종 저장 완료 - sourceRound: {}",
order,
doc.getRound());
});
}
}
}

FinalSpecialContractDocument finalDocument =
FinalSpecialContractDocument.builder()
.contractChatId(contractChatId)
.totalFinalClauses(finalClauses.size())
.finalClauses(finalClauses)
.build();

FinalSpecialContractDocument savedDocument =
specialContractMongoRepository.saveFinalSpecialContract(finalDocument);

log.info("최종 특약 저장 완료 - 총 {}개 조항 (방식: {})",
finalClauses.size(),
isThirdRoundComplete ? "3회차 완료" : "모든 특약 완료");

return savedDocument;
}
for (SpecialContractFixDocument completedContract : completedContracts) {
Long order = completedContract.getOrder();

Optional<SpecialContractDocument> latestRoundDoc =
findLatestRoundForOrder(contractChatId, order);

if (latestRoundDoc.isPresent()) {
SpecialContractDocument doc = latestRoundDoc.get();

doc.getClauses().stream()
.filter(clause -> clause.getOrder().equals(order.intValue()))
.findFirst()
.ifPresent(
clause -> {
FinalSpecialContractDocument.FinalClause finalClause =
FinalSpecialContractDocument.FinalClause.builder()
.order(clause.getOrder())
.title(clause.getTitle())
.content(clause.getContent())
.build();

finalClauses.add(finalClause);
log.info(
"특약 {}번 최종 저장 완료 - sourceRound: {}",
order,
doc.getRound());
});
}
}
}

FinalSpecialContractDocument finalDocument =
FinalSpecialContractDocument.builder()
.contractChatId(contractChatId)
.totalFinalClauses(finalClauses.size())
.finalClauses(finalClauses)
.build();

FinalSpecialContractDocument savedDocument =
specialContractMongoRepository.saveFinalSpecialContract(finalDocument);

log.info(
"최종 특약 저장 완료 - 총 {}개 조항 (방식: {})",
finalClauses.size(),
isThirdRoundComplete ? "3회차 완료" : "모든 특약 완료");

return savedDocument;
}
Comment on lines +1581 to +1687
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

예외 타입 일관성 및 도메인 예외 사용

saveFinalSpecialContract에서 완료 조건 미충족 시 IllegalStateException을 던지고 있습니다. 서비스 계층 전반에서 BusinessException + 도메인 에러코드 패턴을 사용 중이므로 동일하게 맞추는 것이 좋습니다.

-              if (!incompleteContracts.isEmpty()) {
-                  throw new IllegalStateException(
-                          "아직 완료되지 않은 특약이 " + incompleteContracts.size() + "개 있습니다.");
-              }
+              if (!incompleteContracts.isEmpty()) {
+                  throw new BusinessException(
+                          ChatErrorCode.CONTRACT_END_REQUEST_INVALID,
+                          "아직 완료되지 않은 특약이 " + incompleteContracts.size() + "개 있습니다.");
+              }

필요 시 별도의 에러코드 추가를 고려하세요(예: CONTRACT_FINALIZE_INCOMPLETE).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Override
@Transactional
public FinalSpecialContractDocument saveFinalSpecialContract(Long contractChatId) {
ContractChat contractChat = contractChatMapper.findByContractChatId(contractChatId);
ContractChat.ContractStatus currentStatus = contractChat.getStatus();
boolean isThirdRoundComplete = (currentStatus == ContractChat.ContractStatus.ROUND3);
List<FinalSpecialContractDocument.FinalClause> finalClauses = new ArrayList<>();
if (isThirdRoundComplete) {
log.info("=== 3회차 수정 완료 - 4라운드 데이터에서 최종 특약 생성 ===");
Optional<SpecialContractDocument> round4DocOpt =
specialContractMongoRepository
.findSpecialContractDocumentByContractChatIdAndRound(
contractChatId, 4L);
if (round4DocOpt.isPresent()) {
SpecialContractDocument round4Doc = round4DocOpt.get();
for (SpecialContractDocument.Clause clause : round4Doc.getClauses()) {
if (clause.getTitle() != null
&& !clause.getTitle().trim().isEmpty()
&& clause.getContent() != null
&& !clause.getContent().trim().isEmpty()) {
FinalSpecialContractDocument.FinalClause finalClause =
FinalSpecialContractDocument.FinalClause.builder()
.order(clause.getOrder())
.title(clause.getTitle())
.content(clause.getContent())
.build();
finalClauses.add(finalClause);
log.info("4라운드에서 특약 {}번 최종 저장: {}", clause.getOrder(), clause.getTitle());
}
}
}
} else {
log.info("=== 모든 특약 완료 - 완료된 특약들만 최종 저장 ===");
List<SpecialContractFixDocument> incompleteContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(
contractChatId, false);
if (!incompleteContracts.isEmpty()) {
throw new IllegalStateException(
"아직 완료되지 않은 특약이 " + incompleteContracts.size() + "개 있습니다.");
}
List<SpecialContractFixDocument> completedContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(
contractChatId, true);
if (completedContracts.isEmpty()) {
throw new IllegalStateException("완료된 특약이 없습니다.");
}
@Override
@Transactional
public FinalSpecialContractDocument saveFinalSpecialContract(Long contractChatId) {
ContractChat contractChat = contractChatMapper.findByContractChatId(contractChatId);
ContractChat.ContractStatus currentStatus = contractChat.getStatus();
boolean isThirdRoundComplete = (currentStatus == ContractChat.ContractStatus.ROUND3);
List<FinalSpecialContractDocument.FinalClause> finalClauses = new ArrayList<>();
if (isThirdRoundComplete) {
log.info("=== 3회차 수정 완료 - 4라운드 데이터에서 최종 특약 생성 ===");
Optional<SpecialContractDocument> round4DocOpt =
specialContractMongoRepository.findSpecialContractDocumentByContractChatIdAndRound(contractChatId, 4L);
if (round4DocOpt.isPresent()) {
SpecialContractDocument round4Doc = round4DocOpt.get();
for (SpecialContractDocument.Clause clause : round4Doc.getClauses()) {
if (clause.getTitle() != null && !clause.getTitle().trim().isEmpty() &&
clause.getContent() != null && !clause.getContent().trim().isEmpty()) {
FinalSpecialContractDocument.FinalClause finalClause =
FinalSpecialContractDocument.FinalClause.builder()
.order(clause.getOrder())
.title(clause.getTitle())
.content(clause.getContent())
.build();
finalClauses.add(finalClause);
log.info("4라운드에서 특약 {}번 최종 저장: {}", clause.getOrder(), clause.getTitle());
}
}
}
} else {
log.info("=== 모든 특약 완료 - 완료된 특약들만 최종 저장 ===");
List<SpecialContractFixDocument> incompleteContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(contractChatId, false);
if (!incompleteContracts.isEmpty()) {
throw new IllegalStateException(
"아직 완료되지 않은 특약이 " + incompleteContracts.size() + "개 있습니다.");
}
List<SpecialContractFixDocument> completedContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(contractChatId, true);
if (completedContracts.isEmpty()) {
throw new IllegalStateException("완료된 특약이 없습니다.");
}
for (SpecialContractFixDocument completedContract : completedContracts) {
Long order = completedContract.getOrder();
Optional<SpecialContractDocument> latestRoundDoc =
findLatestRoundForOrder(contractChatId, order);
if (latestRoundDoc.isPresent()) {
SpecialContractDocument doc = latestRoundDoc.get();
doc.getClauses().stream()
.filter(clause -> clause.getOrder().equals(order.intValue()))
.findFirst()
.ifPresent(
clause -> {
FinalSpecialContractDocument.FinalClause finalClause =
FinalSpecialContractDocument.FinalClause.builder()
.order(clause.getOrder())
.title(clause.getTitle())
.content(clause.getContent())
.build();
finalClauses.add(finalClause);
log.info(
"특약 {}번 최종 저장 완료 - sourceRound: {}",
order,
doc.getRound());
});
}
}
}
FinalSpecialContractDocument finalDocument =
FinalSpecialContractDocument.builder()
.contractChatId(contractChatId)
.totalFinalClauses(finalClauses.size())
.finalClauses(finalClauses)
.build();
FinalSpecialContractDocument savedDocument =
specialContractMongoRepository.saveFinalSpecialContract(finalDocument);
log.info("최종 특약 저장 완료 - 총 {}개 조항 (방식: {})",
finalClauses.size(),
isThirdRoundComplete ? "3회차 완료" : "모든 특약 완료");
return savedDocument;
}
for (SpecialContractFixDocument completedContract : completedContracts) {
Long order = completedContract.getOrder();
Optional<SpecialContractDocument> latestRoundDoc =
findLatestRoundForOrder(contractChatId, order);
if (latestRoundDoc.isPresent()) {
SpecialContractDocument doc = latestRoundDoc.get();
doc.getClauses().stream()
.filter(clause -> clause.getOrder().equals(order.intValue()))
.findFirst()
.ifPresent(
clause -> {
FinalSpecialContractDocument.FinalClause finalClause =
FinalSpecialContractDocument.FinalClause.builder()
.order(clause.getOrder())
.title(clause.getTitle())
.content(clause.getContent())
.build();
finalClauses.add(finalClause);
log.info(
"특약 {}번 최종 저장 완료 - sourceRound: {}",
order,
doc.getRound());
});
}
}
}
FinalSpecialContractDocument finalDocument =
FinalSpecialContractDocument.builder()
.contractChatId(contractChatId)
.totalFinalClauses(finalClauses.size())
.finalClauses(finalClauses)
.build();
FinalSpecialContractDocument savedDocument =
specialContractMongoRepository.saveFinalSpecialContract(finalDocument);
log.info(
"최종 특약 저장 완료 - 총 {}개 조항 (방식: {})",
finalClauses.size(),
isThirdRoundComplete ? "3회차 완료" : "모든 특약 완료");
return savedDocument;
}
// 기존: 완료되지 않은 특약이 있으면 IllegalStateException
List<SpecialContractFixDocument> incompleteContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(
contractChatId, false);
- if (!incompleteContracts.isEmpty()) {
- throw new IllegalStateException(
- "아직 완료되지 않은 특약이 " + incompleteContracts.size() + "개 있습니다.");
- }
+ if (!incompleteContracts.isEmpty()) {
+ throw new BusinessException(
+ ChatErrorCode.CONTRACT_END_REQUEST_INVALID,
+ "아직 완료되지 않은 특약이 " + incompleteContracts.size() + "개 있습니다.");
+ }
List<SpecialContractFixDocument> completedContracts =
specialContractMongoRepository.findByContractChatIdAndIsPassed(
contractChatId, true);
🤖 Prompt for AI Agents
In src/main/java/org/scoula/domain/chat/service/ContractChatServiceImpl.java
around lines 1581-1687, replace the two IllegalStateException throws used when
unfinished or no completed special contracts are detected with the application's
BusinessException pattern using a domain error code (e.g.,
CONTRACT_FINALIZE_INCOMPLETE for "아직 완료되지 않은 특약..." and
CONTRACT_FINALIZE_NO_COMPLETED for "완료된 특약이 없습니다."). Create or reuse appropriate
ErrorCode enum entries if missing, construct BusinessException instances with
the new error code and a clear message (include the incomplete count for the
first case), and ensure imports and tests are updated accordingly so the service
follows the existing domain exception convention.


private Optional<SpecialContractDocument> findLatestRoundForOrder(
Long contractChatId, Long order) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.scoula.domain.contract.controller;

import org.scoula.domain.contract.dto.*;
import org.scoula.global.auth.dto.CustomUserDetails;
import org.scoula.global.common.dto.ApiResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(tags = "계약서 API", description = "계약서 : 정보확인 / 금액 조율 / 적법성 확인")
public interface ContractController {

// step 0
@ApiOperation(value = "임차인 대기 메세지", notes = "step0의 AI 메세지")
ResponseEntity<ApiResponse<Void>> standByContract(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);

// step 1 (init)
@ApiOperation(value = "계약서 몽고DB에 저장", notes = "계약서에 필요한 항목들을 가져와서 몽고 DB에 계약서 만들기")
ResponseEntity<ApiResponse<Void>> saveContractMongo(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);

// step 1 : start
@ApiOperation(value = "계약서 전체 조회", notes = "계약서 가져오기")
ResponseEntity<ApiResponse<ContractDTO>> getContract(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);

@ApiOperation(value = "정보조회 다음 단계로 넘어가기 Message", notes = "정보조회 마지막 단계에서 다음 단계로 넘어가기 Message")
ResponseEntity<ApiResponse<Void>> getContractNext(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);

// step 1 : finish
@ApiOperation(value = "다음 단계로 넘어가기", notes = "다음 단계 여부(true/false)를 받아서 다음 단계로 넘어가기")
ResponseEntity<ApiResponse<Boolean>> nextStep(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody NextStepDTO dto);

@ApiOperation(value = "금액 조회", notes = "금액을 조율하기 위해 금액을 조회")
ResponseEntity<ApiResponse<PaymentDTO>> getDepositPrice(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);

@ApiOperation(value = "금액 요청", notes = "임대인이 금액을 요청")
ResponseEntity<ApiResponse<Void>> saveDepositPrice(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody PaymentDTO dto);

@ApiOperation(value = "금액 거절 ", notes = "임차인이 금액을 거절")
ResponseEntity<ApiResponse<Void>> deleteDepositPrice(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);

@ApiOperation(value = "금액 수락", notes = "임대인과 임차인 모두 동의")
ResponseEntity<ApiResponse<Void>> updateDepositPrice(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);

@ApiOperation(value = "AI 적법성 확인 from 몽고DB", notes = "몽고DB에 있는 계약서를 AI로 보내고, 적법성 받기")
ResponseEntity<ApiResponse<LegalityDTO>> getLegality(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);

@ApiOperation(value = "특약을 계약서 DB에 저장 FROM 몽고DB", notes = "특약 테이블에 있는걸 계약서로 가져오기")
ResponseEntity<ApiResponse<Void>> saveSpecialContract(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);

@ApiOperation(value = "바뀐 특약 수정 from 몽고DB", notes = "적법성 검사 후 수정된 특약으로 변경")
ResponseEntity<ApiResponse<Void>> updateSpecialContract(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestBody SpecialContractUpdateDTO dto);

@ApiOperation(value = "적법성 검사 후 다음단계로 넘어가기", notes = "적법성 검사 후 AI 메세지를 보낸다")
ResponseEntity<ApiResponse<Void>> sendStep4(
@PathVariable Long contractChatId,
@AuthenticationPrincipal CustomUserDetails userDetails);
}
Loading
Loading