마케팅 트래킹

- 복합키를 AUTO_INCREMENT의 단일키로 변경
- AppLaunch 트래킹 추가
This commit is contained in:
Klaus 2025-03-26 13:09:09 +09:00
parent ba9c71a4ec
commit c466ecb77c
7 changed files with 67 additions and 42 deletions

View File

@ -18,16 +18,16 @@ class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) {
endDate: LocalDateTime
): Int {
return queryFactory
.select(adTrackingHistory.id.pid)
.select(adTrackingHistory.pid)
.from(adTrackingHistory)
.where(
adTrackingHistory.id.createdAt.goe(startDate),
adTrackingHistory.id.createdAt.loe(endDate)
adTrackingHistory.createdAt.goe(startDate),
adTrackingHistory.createdAt.loe(endDate)
)
.groupBy(
getFormattedDate(adTrackingHistory.id.createdAt),
getFormattedDate(adTrackingHistory.createdAt),
adTrackingHistory.mediaGroup,
adTrackingHistory.id.pid,
adTrackingHistory.pid,
adTrackingHistory.pidName
)
.fetch()
@ -41,45 +41,45 @@ class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) {
limit: Long
): List<GetAdminAdStatisticsItem> {
val signUpCount = CaseBuilder()
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.SIGNUP))
.`when`(adTrackingHistory.type.eq(AdTrackingHistoryType.SIGNUP))
.then(1)
.otherwise(0)
.sum()
val loginCount = CaseBuilder()
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.LOGIN))
.`when`(adTrackingHistory.type.eq(AdTrackingHistoryType.LOGIN))
.then(1)
.otherwise(0)
.sum()
val firstPaymentCount = CaseBuilder()
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.FIRST_PAYMENT))
.`when`(adTrackingHistory.type.eq(AdTrackingHistoryType.FIRST_PAYMENT))
.then(1)
.otherwise(0)
.sum()
val firstPaymentTotalAmount = CaseBuilder()
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.FIRST_PAYMENT))
.`when`(adTrackingHistory.type.eq(AdTrackingHistoryType.FIRST_PAYMENT))
.then(adTrackingHistory.price)
.otherwise(Expressions.constant(0.0))
.sum()
val repeatPaymentCount = CaseBuilder()
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
.`when`(adTrackingHistory.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
.then(1)
.otherwise(0)
.sum()
val repeatPaymentTotalAmount = CaseBuilder()
.`when`(adTrackingHistory.id.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
.`when`(adTrackingHistory.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
.then(adTrackingHistory.price)
.otherwise(Expressions.constant(0.0))
.sum()
val allPaymentCount = CaseBuilder()
.`when`(
adTrackingHistory.id.type.eq(AdTrackingHistoryType.FIRST_PAYMENT)
.or(adTrackingHistory.id.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
adTrackingHistory.type.eq(AdTrackingHistoryType.FIRST_PAYMENT)
.or(adTrackingHistory.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
)
.then(1)
.otherwise(0)
@ -87,8 +87,8 @@ class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) {
val allPaymentTotalAmount = CaseBuilder()
.`when`(
adTrackingHistory.id.type.eq(AdTrackingHistoryType.FIRST_PAYMENT)
.or(adTrackingHistory.id.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
adTrackingHistory.type.eq(AdTrackingHistoryType.FIRST_PAYMENT)
.or(adTrackingHistory.type.eq(AdTrackingHistoryType.REPEAT_PAYMENT))
)
.then(adTrackingHistory.price)
.otherwise(Expressions.constant(0.0))
@ -97,9 +97,9 @@ class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) {
return queryFactory
.select(
QGetAdminAdStatisticsItem(
getFormattedDate(adTrackingHistory.id.createdAt),
getFormattedDate(adTrackingHistory.createdAt),
adTrackingHistory.mediaGroup,
adTrackingHistory.id.pid,
adTrackingHistory.pid,
adTrackingHistory.pidName,
loginCount,
signUpCount,
@ -113,16 +113,16 @@ class AdminAdStatisticsRepository(private val queryFactory: JPAQueryFactory) {
)
.from(adTrackingHistory)
.where(
adTrackingHistory.id.createdAt.goe(startDate),
adTrackingHistory.id.createdAt.loe(endDate)
adTrackingHistory.createdAt.goe(startDate),
adTrackingHistory.createdAt.loe(endDate)
)
.groupBy(
getFormattedDate(adTrackingHistory.id.createdAt),
getFormattedDate(adTrackingHistory.createdAt),
adTrackingHistory.mediaGroup,
adTrackingHistory.id.pid,
adTrackingHistory.pid,
adTrackingHistory.pidName
)
.orderBy(getFormattedDate(adTrackingHistory.id.createdAt).desc())
.orderBy(getFormattedDate(adTrackingHistory.createdAt).desc())
.offset(offset)
.limit(limit)
.fetch()

View File

@ -85,6 +85,7 @@ class SecurityConfig(
.antMatchers(HttpMethod.GET, "/live/room").permitAll()
.antMatchers(HttpMethod.GET, "/event").permitAll()
.antMatchers(HttpMethod.GET, "/live/recommend").permitAll()
.antMatchers("/ad-tracking/app-launch").permitAll()
.anyRequest().authenticated()
.and()
.build()

View File

@ -0,0 +1,3 @@
package kr.co.vividnext.sodalive.marketing
data class AdTrackingAppLaunchRequest(val pid: String)

View File

@ -0,0 +1,23 @@
package kr.co.vividnext.sodalive.marketing
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/ad-tracking")
class AdTrackingController(private val service: AdTrackingService) {
@PostMapping("/app-launch")
fun trackingAppLaunch(
@RequestBody request: AdTrackingAppLaunchRequest
) = run {
service.saveTrackingHistory(
pid = request.pid,
type = AdTrackingHistoryType.APP_LAUNCH,
memberId = 0,
price = null,
locale = null
)
}
}

View File

@ -1,22 +1,25 @@
package kr.co.vividnext.sodalive.marketing
import java.io.Serializable
import java.time.LocalDateTime
import javax.persistence.Embeddable
import javax.persistence.EmbeddedId
import javax.persistence.Entity
import javax.persistence.EnumType
import javax.persistence.Enumerated
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
import javax.persistence.PreUpdate
@Entity
data class AdTrackingHistory(
@EmbeddedId
val id: AdTrackingHistoryId,
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null,
val mediaGroup: String,
val pid: String,
val pidName: String,
val type: AdTrackingHistoryType,
val price: Double = 0.toDouble(),
val locale: String? = null,
val memberId: Long,
val createdAt: LocalDateTime = LocalDateTime.now(),
var updatedAt: LocalDateTime = LocalDateTime.now()
) {
@PreUpdate
@ -25,16 +28,10 @@ data class AdTrackingHistory(
}
}
@Embeddable
data class AdTrackingHistoryId(
val pid: String,
val memberId: Long,
@Enumerated(value = EnumType.STRING)
val type: AdTrackingHistoryType,
val createdAt: LocalDateTime = LocalDateTime.now()
) : Serializable
enum class AdTrackingHistoryType {
// 앱 실행
APP_LAUNCH,
// 회원가입
SIGNUP,

View File

@ -2,4 +2,4 @@ package kr.co.vividnext.sodalive.marketing
import org.springframework.data.jpa.repository.JpaRepository
interface AdTrackingRepository : JpaRepository<AdTrackingHistory, AdTrackingHistoryId>
interface AdTrackingRepository : JpaRepository<AdTrackingHistory, Long>

View File

@ -25,13 +25,14 @@ class AdTrackingService(
val mediaPartner = mediaPartnerRepository.findByPid(pid)
if (mediaPartner != null) {
val id = AdTrackingHistoryId(pid = pid, memberId = memberId, type = type)
val trackingHistory = AdTrackingHistory(
id = id,
mediaGroup = mediaPartner.mediaGroup,
pid = pid,
pidName = mediaPartner.pidName,
type = type,
price = price ?: 0.toDouble(),
locale = locale
locale = locale,
memberId = memberId
)
repository.save(trackingHistory)
}