내가 맡은 부분은 주문하기, 주문 확인, 주문에 대한 요청 관리(배달시작 or 배달 완료 or 취소)이다. 주문은 각 사용자마다 소지하고 있는 포인트로 주문하고, 가게 사장님은 배달이 완료되면 포인트를 지급받으며 매출액이 오른다.
이 중에서 포인트 관련한 부분을 구현한 방법은 다음과 같다.
규칙 ) 모든 사용자는 사장님이 될 수 있고, 사용자 한 명당 가게는 한 개만 가능하다.
모든 사용자에게는 포인트 테이블이 주어진다. 포인트 테이블에는 포인트와 매출액 컬럼이 존재한다.
주문 요청과 동시에 포인트를 차감한다. 트랜잭션을 사용하여 주문 테이블과 주문 정보 테이블에 데이터가 들어가 주문이 정상적으로 접수되면 포인트를 차감하도록 한다.
주문의 상태가 '배달 완료'로 변경되면 주문 정보에 있는 금액 만큼 가게 사장님에게 포인트가 지급되고, 지급된 포인트만큼 매출액이 증가한다.
단, 가게 정보에는 소유자의 정보가 들어있어 본인의 가게에 본인이 주문하여 완료된 주문은 매출로 인정되지 않는다. 즉, 본인 가게에서 본인이 주문하면 매출액이 증가하지 않는다.
이와 같은 로직으로 트랜잭션을 이용하여 구현하였다.
대충 코드는 아래와 같다.
updatedOrder = await this.prisma.$transaction(async (tx) => {
const order = await tx.orders.update({
where: { orderId: +orderId },
data: {
status: status,
},
});
const point = await tx.point.findFirst({
where: { userId: +userId },
});
let updatedPoint;
if (userId === order.userId) {
updatedPoint = await tx.point.update({
where: { userId: +userId },
data: {
money: point.money + order.totalPrice,
},
});
} else {
updatedPoint = await tx.point.update({
where: { userId: +userId },
data: {
money: point.money + order.totalPrice,
salesAmount: point.salesAmount + order.totalPrice,
},
});
}
return { order, updatedPoint };
});
}
주문의 상태는 다양하게 들어올 수 있는데
위는 배달 완료 요청을 했을 경우의 코드이다.
코드 구현은 어렵지 않은데 테스트 코드가 참 오래걸렸다 ..
그래도 계속 테스트 코드와 정면승부를 하다보니,
점점 시간도 엄청 단축되고, 이해가 되기 시작했다.
내일은 웹 소켓에 도전해봐야겠다.