[TIL] ํ๋ก์ ํธ 18์ผ์ฐจ.. ์ฌ๋ ์๋ฆผ ๋ง๋ฌด๋ฆฌํ๊ธฐ!!
๐ ์ค๋์ ์ด๋ค ํ๋ฃจ์์ง..
์ฐ์ ์ฌ๊ณ ๊ฐ์ ์คํจ ๊ด๋ จ Slack ์๋ฆผ์ ๋ง๋ฌด๋ฆฌํ๋ค!
// ์ฌ๊ณ ๊ฐ์ ์คํจ ์๋ฆผ ๋ฉ์์ง ์์ฑ
public String formatInventoryDecreaseFailureMessage(Long orderId, String memberName, String productId, String productName, String reason, LocalDateTime time) {
Map<String, Object> payload = getPayload();
List<Object> blocks = new ArrayList<>();
blocks.add(Map.of(
"type", "header",
"text", Map.of("type", "plain_text", "text", "โ ์ฌ๊ณ ๊ฐ์ ์คํจ ์๋ฆผ")
));
blocks.add(Map.of(
"type", "section",
"fields", List.of(
markdownField("*์ฃผ๋ฌธ ID:*", orderId.toString()),
markdownField("*ํ์๋ช
:*", memberName)
)
));
blocks.add(Map.of(
"type", "section",
"fields", List.of(
markdownField("*์ํ ID:*", productId),
markdownField("*์ํ๋ช
:*", productName)
)
));
blocks.add(Map.of(
"type", "section",
"text", markdownField("*\uD83D\uDD0D ์ฌ์ :*", reason)
));
blocks.add(Map.of(
"type", "context",
"elements", List.of(
Map.of("type", "mrkdwn", "text", "\uD83D\uDD52 *์๊ฐ:* " + time.format(formatter))
)
));
payload.put("blocks", blocks);
return JsonHelper.toJson(payload);
}
public void sendInventoryDecreaseFailureAlert(Long orderId, String memberName, String productId, String productName, String reason) {
String message = slackFormatter.formatInventoryDecreaseFailureMessage(orderId, memberName, productId, productName, reason, LocalDateTime.now());
sendPayload(message);
}
@Transactional
public void decreaseProductOptionCombinationInventory(Long orderId) {
List<OrderItem> orderItemList = orderItemRepository.findAllByOrderId(orderId);
for (OrderItem orderItem : orderItemList) {
Long productOptionCombinationId = orderItem.getProductOptionCombination().getId();
Integer quantity = orderItem.getQuantity();
ProductOptionCombination productOptionCombination = productOptionCombinationRepository
.findByIdWithPessimisticLock(productOptionCombinationId)
.orElseThrow(() -> new NotFoundException(ErrorCode.PRODUCT_OPTION_COMBINATION_NOT_FOUND));
if (productOptionCombination.getInventory() < quantity) {
slackNotifier.sendInventoryDecreaseFailureAlert(
orderId,
orderItem.getOrder().getMember().getName(),
productOptionCombination.getProduct().getId().toString(),
productOptionCombination.getProduct().getName(),
ErrorCode.PRODUCT_OPTION_COMBINATION_OUT_OF_INVENTORY.getMessage());
throw new ConflictException(ErrorCode.PRODUCT_OPTION_COMBINATION_OUT_OF_INVENTORY);
}
productOptionCombination.decreaseInventory(quantity);
}
}
์ ์์ ์ผ๋ก ์๋ฆผ ๋ฉ์์ง๊ฐ ๋์ฐฉํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค!
๊ทธ๋ค์์ผ๋ก๋ ๋ฐฐ์ก ์์ฑ ์ฑ๊ณตํ์ ๋ Slack ์๋ฆผ ๋ฉ์์ง๊ฐ ๋์ฐฉํ ์ ์๋๋ก ๊ตฌํํ๋ค.
// ๋ฐฐ์ก ์์ฑ ์ฑ๊ณต ์๋ฆผ ๋ฉ์์ง ์์ฑ
public String formatDeliveryCreateMessage(Long orderId, String memberName, String phoneNumber, String receiver, String receiverPhone, String address, String detailAddress, LocalDateTime time) {
Map<String, Object> payload = getPayload();
List<Object> blocks = new ArrayList<>();
blocks.add(Map.of(
"type", "header",
"text", Map.of("type", "plain_text", "text", "โ
๋ฐฐ์ก ์์ฑ ์ฑ๊ณต ์๋ฆผ")
));
blocks.add(Map.of(
"type", "section",
"fields", List.of(
markdownField("*์ฃผ๋ฌธ ID:*", orderId.toString())
)
));
blocks.add(Map.of(
"type", "section",
"fields", List.of(
markdownField("*ํ์๋ช
:*", memberName),
markdownField("*์ฐ๋ฝ์ฒ:*", phoneNumber)
)
));
blocks.add(Map.of(
"type", "section",
"fields", List.of(
markdownField("*์๋ น์ธ:*", receiver),
markdownField("*์๋ น์ธ ์ฐ๋ฝ์ฒ:*", receiverPhone),
markdownField("*์ฃผ์:*", address),
markdownField("*์์ธ์ฃผ์:*", detailAddress)
)
));
blocks.add(Map.of(
"type", "section",
"fields", List.of(
markdownField("*์ํ:*", "๋ฐฐ์ก ์์ฑ ์๋ฃ โ
")
)
));
blocks.add(Map.of(
"type", "context",
"elements", List.of(
Map.of("type", "mrkdwn", "text", "\uD83D\uDCE6 ๋ฐฐ์ก ์ ๋ณด๊ฐ ์ ์์ ์ผ๋ก ๋ฑ๋ก๋์์ต๋๋ค.\n"),
Map.of("type", "mrkdwn", "text", "\uD83D\uDD52 *์๊ฐ:* " + time.format(formatter))
)
));
payload.put("blocks", blocks);
return JsonHelper.toJson(payload);
}
public void sendDeliveryCreateAlert(Long orderId, String memberName, String phoneNumber, String receiver, String receiverPhone, String address, String detailAddress) {
String message = slackFormatter.formatDeliveryCreateMessage(orderId, memberName, phoneNumber, receiver, receiverPhone, address, detailAddress, LocalDateTime.now());
sendPayload(message);
}
@Transactional
public CreateDeliveryResponse createDelivery(CreateDeliveryRequest request) {
if (!orderRepository.existsById(request.orderId())) {
throw new NotFoundException(ErrorCode.ORDER_NOT_FOUND);
}
if (!sellerRepository.existsById(request.sellerId())) {
throw new NotFoundException(ErrorCode.SELLER_NOT_FOUND);
}
if (!senderRepository.existsById(request.senderId())) {
throw new NotFoundException(ErrorCode.SENDER_NOT_FOUND);
}
if (!addressRepository.existsById(request.addressId())) {
throw new NotFoundException(ErrorCode.ADDRESS_NOT_FOUND);
}
Order order = orderRepository.getReferenceById(request.orderId());
Seller seller = sellerRepository.getReferenceById(request.sellerId());
Sender sender = senderRepository.getReferenceById(request.senderId());
Address address = addressRepository.findById(request.addressId())
.orElseThrow(() -> new NotFoundException(ErrorCode.ADDRESS_NOT_FOUND));
Delivery delivery = Delivery.of(order, seller, sender, address, request.deliveryRequest());
deliveryRepository.save(delivery);
slackNotifier.sendDeliveryCreateAlert(
request.orderId(),
delivery.getOrder().getMember().getName(),
delivery.getOrder().getMember().getPhoneNumber(),
delivery.getReceiverName(),
delivery.getReceiverPhone(),
delivery.getReceiverAddress(),
delivery.getReceiverDetailAddress());
return CreateDeliveryResponse.from(delivery);
}
์ด๋ ๊ฒ ํ๋ฉด Slack ์๋ฆผ ๋ฉ์์ง๊ฐ ์ด๋ป๊ฒ ์ค๋๋?!
๋ง์ง๋ง์ผ๋ก ๋ฐฐ์ก ์์ฑ ์คํจํ์ ๋ ๊ด๋ จํด์ Slack ์๋ฆผ์ ๊ณ ๋ฏผํ๋ค.
์ ๋ณด ํ์ ์์ด ์์ธ ๊ด๋ จ ๋ด์ฉ๋ง ๋ฉ์์ง๋ก ๋ณด์ฌ์ฃผ๋ฉด ๋๋ค๊ณ ์๊ฐํ๊ณ , ๊ทธ๋ ๊ฒ ๊ตฌํํ์ง๋ง ์ ์ ์คํํด์ ํ
์คํธํด ๋ณด๋ Kafka์ ์ฌ์๋๋ก ์ธํด์ ๋ฉ์์ง๊ฐ ์ฌ์๋ ํ์๋งํผ ์ ์ก๋๋ ๊ฒ์ด์๋ค......
๊ทธ๋์ ์ฌ์๋ํ์ง ์๊ณ Slack ์๋ฆผ ๋ฉ์์ง ํ ๋ฒ๋ง ์ ์กํ ์ ์๋๋ก ์์ ํ๊ณ ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ฉ์์ง๊ฐ ํ ๋ฒ๋ง ์ ์ก๋๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค.
๐๏ธ ๋ด์ผ์ ๋ญ ํ์ง?!
โ๏ธ ํ๋ก์ ํธ ๊ณ ๋ํ
โ๏ธ ๋ก์ง ๋ด ๋ฌธ์ ์ ์์
โ๏ธ TIL ์์ฑํ๊ธฐ