Skip to content
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

Feat/#29/매칭 취소,매칭 성공 로직 완성 #32

Open
wants to merge 63 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
3469ba7
fix: application local yml 들여쓰기 수정
soyesenna Jan 13, 2025
021e85c
feat: EnableJpaAuditing 추가
soyesenna Jan 13, 2025
959419d
feat: 매칭 취소 관련 이벤트 토픽 DTO 추가
soyesenna Jan 13, 2025
1cd28fe
feat: 매칭 취소 관련 enum 필드 추가
soyesenna Jan 13, 2025
67e5985
feat: Member entity에 방장 확인 메서드 추가
soyesenna Jan 13, 2025
ad3faba
feat: 매칭 취소 엔드포인트 추가
soyesenna Jan 13, 2025
61af188
feat: MatchingRoom 엔티티에 매칭 취소 관련 로직 추가
soyesenna Jan 13, 2025
871b065
feat: kafka consumer, producer 매칭 취소 관련 설정 추가
soyesenna Jan 13, 2025
6b6b5c0
feat: 매칭 취소 관련 비즈니스 로직 구현
soyesenna Jan 13, 2025
05dc9dc
feat: 매칭 취소 관련 kafka consumer, producer 로직 구현
soyesenna Jan 13, 2025
51de6b4
feat: 매칭 취소 이벤트 발행 로직 구현
soyesenna Jan 13, 2025
00bb278
feat: MemberNotInMatchingRoom 예외 추가
soyesenna Jan 13, 2025
c34a82c
feat: MemberAlreadyJoined 예외 추가
soyesenna Jan 13, 2025
c454d92
feat: Member ChargingInfo에 매칭 취소 로직 추가
soyesenna Jan 13, 2025
d5c389d
feat: MemberMatchingRoomChargingInfoRepository.findByMembersAndMatchi…
soyesenna Jan 13, 2025
541fc94
docs: .gitigonre에 docker compose yml 추가
soyesenna Jan 13, 2025
e4be019
feat: 매칭 취소 요청 시 sse 구독여부 확인 로직 추가
soyesenna Jan 13, 2025
115a3ff
feat: 매칭 완료 topic 추가
soyesenna Jan 13, 2025
69c3573
feat: 매칭 완료 producer config 추가
soyesenna Jan 13, 2025
e13ae21
feat: 매칭 완료 consumer config 추가
soyesenna Jan 13, 2025
4bf3e15
feat: MatchRoom 완료 이벤트 DTO에 builder 추가
soyesenna Jan 13, 2025
f534c13
feat: 매칭 방 상태에서 PROCESS 제거
soyesenna Jan 13, 2025
005163e
feat: 매칭 방 엔티티에 매칭 완료 로직 추가
soyesenna Jan 13, 2025
4ef71d2
feat: 매칭 방 완료 이벤트 발행 producer 추가
soyesenna Jan 13, 2025
c98f161
feat: 매칭 방 완료 비즈니스 로직 구현
soyesenna Jan 13, 2025
3de9118
feat: 매칭 방 완료 이벤트 구독 consumer 추가
soyesenna Jan 13, 2025
d6b4817
feat: 매칭 관련 토픽 DTO에 정적 펙터리 메서드 추가
soyesenna Jan 13, 2025
440d91a
refactor: 매칭 이벤트 DTO 생성 정적 펙터리 메서드로 생성하도록 수정
soyesenna Jan 13, 2025
5acae17
refacrtor: 엔티티와의 통일성을 위해 hostId -> roomMasterId 로 이름변경
soyesenna Jan 13, 2025
6df1e8c
refactor: 엔티티들에 정적 펙터리 메서드 추가
soyesenna Jan 13, 2025
6424e86
refactor: 엔티티 생성을 정적 펙토리 메서드로 하도록 수정
soyesenna Jan 13, 2025
cd4c568
refactor: consumer의 hostMemberId -> roomMasterId 로 변경
soyesenna Jan 13, 2025
f3e97b4
fix: 매칭 성공 이벤트에서 매칭 취소 이벤트를 발행하던 오류 수정
soyesenna Jan 13, 2025
a2d7000
refactor: 예외들에 정적 변수 추가
soyesenna Jan 13, 2025
93ee46b
refactor: 오타 수정
soyesenna Jan 13, 2025
e9faac6
refactor: 매칭 방 생성 메서드 createMatcingRoom으로 이름 변경 및 리턴 타입 void로 수정
soyesenna Jan 13, 2025
242b7e2
feat: MemberAlreadyLeftMatchingRoom 예외 추가
soyesenna Jan 13, 2025
f9aeea4
feat: 매칭 방이 다 찼는지 확인 책임 MatchingRoom 엔티티로 이전
soyesenna Jan 13, 2025
56dc901
feat: 멤버가 매칭 방에 들어온 적 있는지 확인 여부 로직 추가
soyesenna Jan 13, 2025
2b31cdb
refactor: 멤버가 참여한 매칭방을 조회할때 PaymentStatus도 확인하도록 수정
soyesenna Jan 13, 2025
8e212b7
refactor: MatchingRoomService 코드 정리 및 리펙터링
soyesenna Jan 13, 2025
25b6d01
feat: 컨트롤러가 current member id를 필요로하지만 파라미터로 받지 않았을 때 던질 예외 추가
soyesenna Jan 13, 2025
c79b747
feat: SSE 구독 여부 확인 로직 AOP로 분리
soyesenna Jan 13, 2025
4c2ce2c
refactor: SSE 구독 여부 확인 어노테이션 컨트롤러에 적용
soyesenna Jan 13, 2025
a1e1171
feat: 자동 매칭 취소, 매칭 방 매칭 완료 Topic 객체 bean 등록
soyesenna Jan 13, 2025
8f3c4c8
refactor: kafka template, kafka producer factory config 클래스 분리
soyesenna Jan 13, 2025
3c36c2c
refactor: 개행 수정
soyesenna Jan 13, 2025
a3f8abb
refactor: producer, kafka template, topic 동적으로 생성하도록 수정하기 위해 기존 설정 클래…
soyesenna Jan 13, 2025
b0af0fe
feat: NotDefienedKafkaTemplateException 추가
soyesenna Jan 13, 2025
952d355
feat: 매칭 이벤트가 구현해야하는 인터페이스 추가
soyesenna Jan 13, 2025
d3a3b29
feat: 기존 매칭 관련 이벤트들이 MatchingEvent를 구현하도록 수정
soyesenna Jan 13, 2025
12cf905
feat: Kafka 빈들을 동적으로 등록하기 위한 suffix 정의
soyesenna Jan 13, 2025
b20683f
feat: kafka 빈들을 동적으로 등록하기위한 유틸 클래스 정의
soyesenna Jan 13, 2025
342227e
feat: 기본 kafka producer, kafka template을 생성하는 클래스 추가
soyesenna Jan 13, 2025
6886e2d
fix: MemberMatchingRoomChargingInfoRepository 메서드 오타 수정
soyesenna Jan 13, 2025
6b999ac
feat: 동적으로 kafka template, producer, topic을 생성하는 registrar 클래스 구현
soyesenna Jan 13, 2025
2d7f2ae
feat: 매칭 이벤트를 생성해주는 팩토리 클래스 구현
soyesenna Jan 13, 2025
e09ad24
refactor: 동적으로 정의된 빈을 사용하도록 기존 서비스 로직 수정
soyesenna Jan 13, 2025
857ae25
refactor: sse 구독 여부를 확인하는 AOP 로직에서 어노테이션 정보를 꺼내오기위해 Method 객체 사용하도록 수정
soyesenna Jan 13, 2025
c0996ea
refactor: 필요 없는 로그 삭제 및 접근 제어자 설정
soyesenna Jan 14, 2025
d93eb15
chore: dev yml 설정
soyesenna Jan 14, 2025
06e76bc
Merge branch 'dev' into feat/#29/매칭-취소,매칭-성공-로직-완성
soyesenna Jan 14, 2025
eb59131
fix: 설정 오타 수정 및 registarar에 컴포넌트 어노테이션 추가
soyesenna Jan 16, 2025
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: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ out/
.vscode/

src/main/resources/.env

docker-compose.yml
2 changes: 2 additions & 0 deletions src/main/java/com/gachtaxi/GachtaxiApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableMongoAuditing
@EnableJpaAuditing
public class GachtaxiApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.gachtaxi.domain.matching.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SseSubscribeRequired {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.gachtaxi.domain.matching.aop;

import com.gachtaxi.domain.matching.common.controller.ResponseMessage;
import com.gachtaxi.domain.matching.common.exception.ControllerNotHasCurrentMemberIdException;
import com.gachtaxi.domain.matching.common.service.AutoMatchingService;
import com.gachtaxi.global.auth.jwt.annotation.CurrentMemberId;
import com.gachtaxi.global.common.response.ApiResponse;
import java.lang.reflect.Parameter;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

@Aspect
@Component
@RequiredArgsConstructor
public class SseSubscribeRequiredAop {

private final AutoMatchingService autoMatchingService;

@Around("@annotation(com.gachtaxi.domain.matching.aop.SseSubscribeRequired)")
public Object checkSseSubscribe(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
Long memberId = null;
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
Parameter[] parameters = signature.getMethod().getParameters();

for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
if (parameter.getType().equals(Long.class) && parameter.isAnnotationPresent(
CurrentMemberId.class)) {
memberId = (Long) proceedingJoinPoint.getArgs()[i];
break;
}
}
Comment on lines +24 to +37
Copy link
Member

Choose a reason for hiding this comment

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

SseSubscribeRequired 어노테이션을 활용해서 AOP 방식으로 체크를 해주는 로직은 한번도 보지못하였는데 코드도 클린해지고 중복 처리에도 용이한거 같습니다 많이 배웠습니다
제가 이해한 바가 맞다면 해당 어노테이션은 SSE 구독 여부를 확인하기 위한 어노테이션으로 사용자가 SSE에 구독되어 있는지 확인해주는 걸로 이해했는데 맞을까요 ??
또한 저희가 컨트롤러 수준에서 구독 여부만 확인해주면 되지만, 이 로직을 추가하면 테스트의 복잡성이 증가할 수도 있겠다는 생각이 들었는데, 기존 방식에서 AOP 방식을 도입한 주영님의 의견도 궁금합니다

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

SSE 구독이 되어있지 않으면 서비스 로직 자체가 실행되면 안된다고 판단해서 컨트롤러 수준에서 구독이 안되어있으면 튕겨내는 식으로 구현했습니다. 이때 구독 여부 확인 로직 자체는 단위 테스트가 필요 없다고 생각합니다.
단위 테스트에서는 비즈니스 로직만을 검증하므로 서비스 로직 단위 테스트시에는 구독이 무조건 되어있다고 가정하고 테스트를 진행할 것이기 때문입니다.(구독이 안되어있으면 서비스 로직 자체가 실행 안되므로)
통합 테스트에서는 구독 여부 확인도 테스트해야하지만, 구독이 안되어있으면 서비스 로직 자체가 실행이 안되도록 설계했으므로
구독 x -> 컨트롤러에서 튕겨나가는지 검증(서비스 로직이 실행 안되는걸 검증)
구독 o -> 서비스 로직이 정상적으로 실행되는지 검증

즉, SSE 구독 여부 확인과 서비스 로직을 완전히 분리해 놓은 설계가 되므로 테스트의 복잡성 또한 낮아질 것으로 생각됩니다.


if (memberId == null) {
throw new ControllerNotHasCurrentMemberIdException();
}

if (!this.autoMatchingService.isSseSubscribed(memberId)) {
return ApiResponse.response(
HttpStatus.BAD_REQUEST,
ResponseMessage.NOT_SUBSCRIBED_SSE.getMessage()
);
}

return proceedingJoinPoint.proceed();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.gachtaxi.domain.matching.common.controller;

import com.gachtaxi.domain.matching.aop.SseSubscribeRequired;
import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingCancelledRequest;
import com.gachtaxi.domain.matching.common.dto.request.AutoMatchingPostRequest;
import com.gachtaxi.domain.matching.common.dto.response.AutoMatchingPostResponse;
import com.gachtaxi.domain.matching.common.service.AutoMatchingService;
import com.gachtaxi.global.auth.jwt.annotation.CurrentMemberId;
import com.gachtaxi.global.common.response.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -15,6 +19,7 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/matching/auto")
Expand All @@ -23,31 +28,33 @@ public class AutoMatchingController {
private final AutoMatchingService autoMatchingService;

@GetMapping(value = "/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter subscribeSse(@RequestParam Long memberId) {
// TODO: 인가 로직 완성되면 해당 멤버의 아이디를 가져오도록 변경
// Long memberId = 1L;

public SseEmitter subscribeSse(@CurrentMemberId Long memberId) {
return this.autoMatchingService.handleSubscribe(memberId);
}

@PostMapping("/request")
@SseSubscribeRequired
public ApiResponse<AutoMatchingPostResponse> requestMatching(
@RequestParam Long memberId,
@CurrentMemberId Long memberId,
@RequestBody AutoMatchingPostRequest autoMatchingPostRequest
) {
// TODO: 인가 로직 완성되면 해당 멤버의 아이디를 가져오도록 변경
// Long memberId = 1L;
if (!this.autoMatchingService.isSseSubscribed(memberId)) {
return ApiResponse.response(
HttpStatus.BAD_REQUEST,
ResponseMessage.NOT_SUBSCRIBED_SSE.getMessage()
);
}

return ApiResponse.response(
HttpStatus.OK,
ResponseMessage.AUTO_MATCHING_REQUEST_ACCEPTED.getMessage(),
this.autoMatchingService.handlerAutoRequestMatching(memberId, autoMatchingPostRequest)
Comment on lines 42 to 44
Copy link
Member

Choose a reason for hiding this comment

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

HttpStatus나 ResponseMessage는 정적 경로 추가하면 좋을 거 같아요!

);
}

@PostMapping("/cancel")
@SseSubscribeRequired
public ApiResponse<AutoMatchingPostResponse> cancelMatching(
@CurrentMemberId Long memberId,
@RequestBody AutoMatchingCancelledRequest autoMatchingCancelledRequest
) {
return ApiResponse.response(
HttpStatus.OK,
ResponseMessage.AUTO_MATCHING_REQUEST_CANCELLED.getMessage(),
this.autoMatchingService.handlerAutoCancelMatching(memberId, autoMatchingCancelledRequest)
Copy link
Member

Choose a reason for hiding this comment

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

response 메서드 내에서 서비스의 반환값을 넣어주는 코드가 길어지니 가독성이 약간 아쉬운 것 같아요!

AutoMatchingPostResponse response = autoMatchingService.handlerAutoCancelMatching(memberId, autoMatchingCancelledRequest);
ApiResponse.response(OK, AUTO_MATCHING_REQUEST_CANCELLED.getMessage(), response);

위 처럼 명시적으로 나눠지면 보기가 더 편할 것 같아요!

);
Comment on lines +54 to +58
Copy link
Member

Choose a reason for hiding this comment

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

여기두요!

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public enum ResponseMessage {

// auto matching
AUTO_MATCHING_REQUEST_ACCEPTED("자동 매칭 요청 전송에 성공했습니다."),
NOT_SUBSCRIBED_SSE("SSE 구독 후 자동 매칭을 요청할 수 있습니다.");
NOT_SUBSCRIBED_SSE("SSE 구독 후 자동 매칭을 요청할 수 있습니다."),
AUTO_MATCHING_REQUEST_CANCELLED("자동 매칭 취소 요청 전송에 성공했습니다.");

private final String message;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@AllArgsConstructor
public enum AutoMatchingStatus {
REQUESTED("REQUESTED"),
REJECTED("REJECTED");

REJECTED("REJECTED"),
CANCELLED("CANCELLED");
private final String value;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.gachtaxi.domain.matching.common.dto.request;

public record AutoMatchingCancelledRequest(
Long roomId
) {

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gachtaxi.domain.matching.common.entity;

import com.gachtaxi.domain.matching.common.entity.enums.MatchingRoomStatus;
import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent;
import com.gachtaxi.domain.members.entity.Members;
import com.gachtaxi.global.common.entity.BaseEntity;
import jakarta.persistence.CascadeType;
Expand All @@ -18,10 +19,11 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Table(name = "matching_room")
@Builder
@Builder(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class MatchingRoom extends BaseEntity {
Expand All @@ -38,6 +40,8 @@ public class MatchingRoom extends BaseEntity {
private List<MemberMatchingRoomChargingInfo> memberMatchingRoomChargingInfo;

@ManyToOne(cascade = CascadeType.PERSIST, optional = false)
@Getter
@Setter
private Members roomMaster;

@Column(name = "title", nullable = false)
Expand All @@ -56,7 +60,35 @@ public class MatchingRoom extends BaseEntity {
@Enumerated(EnumType.STRING)
private MatchingRoomStatus matchingRoomStatus;

public boolean isActiveMatchingRoom() {
public boolean isActive() {
return this.matchingRoomStatus == MatchingRoomStatus.ACTIVE;
}

public void changeRoomMaster(Members members) {
this.setRoomMaster(members);
}

public void cancelMatchingRoom() {
this.matchingRoomStatus = MatchingRoomStatus.CANCELLED;
}

public void completeMatchingRoom() {
this.matchingRoomStatus = MatchingRoomStatus.COMPLETE;
}

public boolean isFull(int size) {
return size == totalCharge;
}

public static MatchingRoom activeOf(MatchRoomCreatedEvent matchRoomCreatedEvent, Members members, Route route) {
return MatchingRoom.builder()
.capacity(matchRoomCreatedEvent.maxCapacity())
.roomMaster(members)
.title(matchRoomCreatedEvent.title())
.description(matchRoomCreatedEvent.description())
.route(route)
.totalCharge(matchRoomCreatedEvent.expectedTotalCharge())
.matchingRoomStatus(MatchingRoomStatus.ACTIVE)
.build();
}
Comment on lines +83 to +93
Copy link
Member

@huncozyboy huncozyboy Jan 14, 2025

Choose a reason for hiding this comment

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

activeOf 메서드로 MatchRoomCreatedEvent, 태그, 멤버 등의 다양한 데이터를 사용해서 활성화된 방
즉, 객체를 생성해주는 걸로 이해했습니다
activeOf 메서드가 MatchingRoom 객체를 생성하는 것뿐만 아니라 태그 초기화, 방 상태 설정까지 너무 많은 책임을 가지게 되는 것은 아닌가 하는 생각이 있습니다. activeOf 메서드가 복잡해지게 되면 유지보수가 어려워지고 코드 테스트가 복잡해지지 않을까요 ??

매칭 부분에 책임 관리에 대한 부분은 저도 서비스 알고리즘을 현재 설계해보면서 고민이 많은 부분인데,
태그 초기화는 별도의 메서드나 유틸리티 클래스로 분리하여 처리하면 가독성과 재사용성이 증가할 수 있을거라고 생각했습니다
블랙리스트라던지 태그 검증 등의 로직 또한 별도 유틸리티 클래스로 추출해주는 방식을 생각했었는데 아래의 방식은 어떨까요 ??

public static List<MatchingRoomTagInfo> initializeTags(MatchRoomCreatedEvent event) {
    return event.getTags().stream()
        .map(tag -> MatchingRoomTagInfo.of(tag))
        .collect(Collectors.toList());
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

이 메서드는 "새로운 매칭방 생성" 이라는 역할만을 가지고 있는 메서드입니다.
태그 초기화는 다른 서비스 로직에서 처리하고, 블랙 리스트는 매칭 이벤트 서비스들의 책임이 아닌 알고리즘의 책임이라고 생각하여 넣지 않았습니다

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@
@Table(name = "matching_room_tag_info")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
@Builder(access = AccessLevel.PRIVATE)
public class MatchingRoomTagInfo extends BaseEntity {

@ManyToOne
private MatchingRoom matchingRoom;

@Enumerated(EnumType.STRING)
private Tags tags;

public static MatchingRoomTagInfo of(MatchingRoom matchingRoom, Tags tag) {
return MatchingRoomTagInfo.builder()
.matchingRoom(matchingRoom)
.tags(tag)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

Expand All @@ -26,10 +27,11 @@
)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
@Builder(access = AccessLevel.PRIVATE)
public class MemberMatchingRoomChargingInfo extends BaseEntity {

@ManyToOne(fetch = FetchType.LAZY)
@Getter
private Members members;

@ManyToOne(fetch = FetchType.LAZY)
Expand All @@ -40,5 +42,27 @@ public class MemberMatchingRoomChargingInfo extends BaseEntity {
private Integer charge;

@Enumerated(EnumType.STRING)
private PaymentStatus paymentStatus = PaymentStatus.NOT_PAYED;
private PaymentStatus paymentStatus;

public void leftMatchingRoom() {
this.paymentStatus = PaymentStatus.LEFT;
}

public boolean isAlreadyLeft() {
return this.paymentStatus == PaymentStatus.LEFT;
}

public MemberMatchingRoomChargingInfo joinMatchingRoom() {
this.paymentStatus = PaymentStatus.NOT_PAYED;
return this;
}

public static MemberMatchingRoomChargingInfo notPayedOf(MatchingRoom matchingRoom, Members members) {
return MemberMatchingRoomChargingInfo.builder()
.matchingRoom(matchingRoom)
.members(members)
.charge(matchingRoom.getTotalCharge())
.paymentStatus(PaymentStatus.NOT_PAYED)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.gachtaxi.domain.matching.common.entity;

import com.gachtaxi.domain.matching.event.dto.kafka_topic.MatchRoomCreatedEvent;
import com.gachtaxi.global.common.entity.BaseEntity;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
Expand All @@ -10,7 +11,7 @@

@Entity
@Table(name = "route")
@Builder
@Builder(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Route extends BaseEntity {
Expand All @@ -20,4 +21,13 @@ public class Route extends BaseEntity {

private String endLocationCoordinate;
private String endLocationName;

public static Route from(MatchRoomCreatedEvent matchRoomCreatedEvent) {
return Route.builder()
.startLocationCoordinate(matchRoomCreatedEvent.startPoint())
.startLocationName(matchRoomCreatedEvent.startName())
.endLocationCoordinate(matchRoomCreatedEvent.destinationPoint())
.endLocationName(matchRoomCreatedEvent.destinationName())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.gachtaxi.domain.matching.common.entity.enums;

public enum MatchingRoomStatus {
PROCESS, COMPLETE, CANCELED, ACTIVE
COMPLETE, CANCELLED, ACTIVE
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.gachtaxi.domain.matching.common.entity.enums;

public enum PaymentStatus {
PAYED, NOT_PAYED, FAILED
PAYED, NOT_PAYED, FAILED, LEFT
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.gachtaxi.domain.matching.common.exception;

import static com.gachtaxi.domain.matching.common.exception.ErrorMessage.CONTROLLER_NOT_HAS_CURRENT_MEMBER_ID;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;

import com.gachtaxi.global.common.exception.BaseException;

public class ControllerNotHasCurrentMemberIdException extends BaseException {

public ControllerNotHasCurrentMemberIdException() {
super(INTERNAL_SERVER_ERROR, CONTROLLER_NOT_HAS_CURRENT_MEMBER_ID.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
public enum ErrorMessage {

NO_SUCH_MATCHING_ROOM("해당 매칭 방이 존재하지 않습니다."),
NOT_ACTIVE_MATCHING_ROOM("열린 매칭 방이 아닙니다.");
NOT_ACTIVE_MATCHING_ROOM("열린 매칭 방이 아닙니다."),
MEMBER_NOT_IN_MATCHING_ROOM("해당 매칭 방에 참가한 멤버가 아닙니다."),
MEMBER_ALREADY_JOINED_MATCHING_ROOM("해당 맴버는 이미 매칭 방에 참가한 멤버입니다"),
MEMBER_ALREADY_LEFT_MATCHING_ROOM("해당 멤버는 이미 매칭 방에서 나간 멤버입니다."),
CONTROLLER_NOT_HAS_CURRENT_MEMBER_ID("해당 컨트롤러는 인가된 멤버 ID가 필요합니다."),
NOT_DEFINED_KAFKA_TEMPLATE("해당 이벤트와 맞는 KafkaTemplate이 정의되지 않았습니다.");

private final String message;
}
Loading