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
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.commerce.platform.core.application.out;

import com.commerce.platform.core.domain.aggreate.CardBinPromotion;

import java.util.List;

public interface CardBinPromotionOutPort {
List<CardBinPromotion> findActivePromotions();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.commerce.platform.core.domain.aggreate;

import com.commerce.platform.core.domain.enums.PayProvider;
import com.commerce.platform.core.domain.vo.ValidPeriod;
import com.commerce.platform.core.domain.vo.promotion.BasePromotionData;
import com.commerce.platform.infrastructure.persistence.converter.PromotionDataConverter;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

import java.time.LocalDateTime;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "card_bin_promotion")
@Entity
public class CardBinPromotion {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "card_bin", nullable = false)
private String cardBin;

@Column(name = "card_name", nullable = false)
private String cardName;

@Enumerated(EnumType.STRING)
@Column(name = "pay_provider", nullable = false)
private PayProvider payProvider;

/**
* JSON 프로모션 데이터
* - Converter에서 임시 타입으로 변환
* - 조회 후 PromotionDataPostProcessor에서 PayProvider에 맞게 재변환
*/
@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "promotion_data", nullable = false, columnDefinition = "json")
Copy link
Collaborator

Choose a reason for hiding this comment

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

json으로 저장한다는건, 안에 있는 내용을 특별히 들여다 볼 필요는 없다는 것과 같은 의미인건가요? 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

카드사에서 내려준 프로모션 정보는 json으로 관리하고

그 기반으로 사용자에게 혜택정보 제공을 위한 별도 컬럼으로 분리했습니다(카드사마다 관리파라미터가 다르다고 가정했습니다)

현재로서는 json 정보가 위 시점 이후로는 다루지 않고 있습니다.

사실은.. 저번 멘토링때 카드사별로 카드빈객체를 관리한다는 말씀에 db는 json, 서버에서는 각 객체를 정의해둔 상태입니다.

단순 기록용으로만 남게된다면 json컬럼은 삭제하는게 맞을 거 같습니다!

🤔혹시 결제 요청 시에 프로모션에 맞는 키값(?) 이 필요하나요?

@Convert(converter = PromotionDataConverter.class)
private BasePromotionData promotionData;

@Column(name = "is_active", nullable = false)
private boolean isActive = true;

@Embedded
private ValidPeriod validPeriod;

@Column(name = "last_updated_at", nullable = false)
private LocalDateTime lastUpdatedAt;

@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;

@Builder
public CardBinPromotion(
String cardBin,
String cardName,
PayProvider payProvider,
BasePromotionData promotionData,
ValidPeriod validPeriod
) {
this.cardBin = cardBin;
this.cardName = cardName;
this.payProvider = payProvider;
this.promotionData = promotionData;
this.validPeriod = validPeriod;
this.isActive = true;
}

@PrePersist
protected void onCreate() {
this.createdAt = LocalDateTime.now();
this.lastUpdatedAt = LocalDateTime.now();
}

@PreUpdate
protected void onUpdate() {
this.lastUpdatedAt = LocalDateTime.now();
}

public void activate() {
this.isActive = true;
}

public void deactivate() {
this.isActive = false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.commerce.platform.core.domain.vo.promotion;

/**
* 카드사별 프로모션 데이터 인터페이스
* PayProvider 값에 따라 구현체로 역직렬화됨
*/
public interface BasePromotionData {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.commerce.platform.core.domain.vo.promotion;

import lombok.Builder;

@Builder
public record BcPromotionData(
String bc_target,
String bc_payType,
String bc_card_name,
String bc_content,
String bc_condition
) implements BasePromotionData {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.commerce.platform.core.domain.vo.promotion;

import lombok.Builder;

@Builder
public record HanaPromotionData(
String hana_target,
String hana_payType,
String hana_card_name,
String hana_content,
String hana_condition
) implements BasePromotionData {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.commerce.platform.core.domain.vo.promotion;

import lombok.Builder;

@Builder
public record HyundaiPromotionData(
String hyundai_target,
String hyundai_payType,
String hyundai_card_name,
String hyundai_content,
String hyundai_condition
) implements BasePromotionData {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.commerce.platform.core.domain.vo.promotion;

import lombok.Builder;

@Builder
public record KbPromotionData(
String kb_target,
String kb_payType,
String kb_card_name,
String kb_content,
String kb_condition
) implements BasePromotionData {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.commerce.platform.core.domain.vo.promotion;

import lombok.Builder;

@Builder
public record LottePromotionData(
String lotte_target,
String lotte_payType,
String lotte_card_name,
String lotte_content,
String lotte_condition
) implements BasePromotionData {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.commerce.platform.core.domain.vo.promotion;

import lombok.Builder;

@Builder
public record NhPromotionData(
String nh_target,
String nh_payType,
String nh_card_name,
String nh_content,
String nh_condition
) implements BasePromotionData {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.commerce.platform.core.domain.vo.promotion;

import lombok.Builder;

@Builder
public record SamsungPromotionData(
String samsung_target,
String samsung_payType,
String samsung_card_name,
String samsung_content,
String samsung_condition
) implements BasePromotionData {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.commerce.platform.core.domain.vo.promotion;

import lombok.Builder;

@Builder
public record ShinhanPromotionData(
String shinhan_target,
String shinhan_payType,
String shinhan_card_name,
String shinhan_content,
String shinhan_condition
) implements BasePromotionData {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.commerce.platform.infrastructure.adaptor;

import com.commerce.platform.core.application.out.CardBinPromotionOutPort;
import com.commerce.platform.core.domain.aggreate.CardBinPromotion;
import com.commerce.platform.infrastructure.persistence.CardBinPromotionRepository;
import com.commerce.platform.infrastructure.persistence.processor.PromotionDataPostProcessor;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import java.util.List;

/**
* promotionData 후처리
* CardBinPromotion 반환
*/
@Log4j2
@RequiredArgsConstructor
@Component
public class CardBinPromotionAdaptor implements CardBinPromotionOutPort {

private final CardBinPromotionRepository repository;
private final PromotionDataPostProcessor postProcessor;

public List<CardBinPromotion> findActivePromotions() {
List<CardBinPromotion> results = repository.findAllByActive();
results.forEach(postProcessor::process);
return results;
}

public CardBinPromotion save(CardBinPromotion entity) {
CardBinPromotion saved = repository.save(entity);
postProcessor.process(saved);
return saved;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.commerce.platform.infrastructure.persistence;

import com.commerce.platform.core.domain.aggreate.CardBinPromotion;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface CardBinPromotionRepository extends JpaRepository<CardBinPromotion, Long> {

/**
* 활성화된 카드 BIN 조회
*/
@Query("""
SELECT c FROM CardBinPromotion c
WHERE c.isActive = true
AND CURRENT_DATE BETWEEN c.validPeriod.frDt AND c.validPeriod.toDt
""")
List<CardBinPromotion> findAllByActive();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.commerce.platform.infrastructure.persistence.converter;

import com.commerce.platform.core.domain.vo.promotion.BasePromotionData;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import lombok.extern.log4j.Log4j2;

/**
* BasePromotionData <-> JSON String 변환 Converter
*/
@Log4j2
@Converter
public class PromotionDataConverter implements AttributeConverter<BasePromotionData, String> {

private static final ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

@Override
public String convertToDatabaseColumn(BasePromotionData attribute) {
if (attribute == null) return null;

try {
return objectMapper.writeValueAsString(attribute);
} catch (JsonProcessingException e) {
throw new IllegalStateException("프로모션 데이터 직렬화 실패", e);
}
}

@Override
public BasePromotionData convertToEntityAttribute(String dbData) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

요 부분이 기대가 되는군요 😎

if (dbData == null || dbData.isBlank()) return null;

// 임시 객체 JsonPromotionData 반환
return new JsonPromotionData(dbData);
}

/**
* JSON String을 보관하는 임시 래퍼 클래스
*/
public record JsonPromotionData(String jsonData)
implements BasePromotionData {}
}
Loading
Loading