From 8cd29d15e2edcfbf6a5feae83f306cd349a815c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B2=A0=EB=89=B4?= Date: Sat, 6 Sep 2025 21:48:39 +0900 Subject: [PATCH 1/5] feat: add utm source parameters for tracking users source --- .../src/main/resources/templates/matching-template.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/infrastructure/src/main/resources/templates/matching-template.html b/infrastructure/src/main/resources/templates/matching-template.html index 8170ed9d..24446d75 100644 --- a/infrastructure/src/main/resources/templates/matching-template.html +++ b/infrastructure/src/main/resources/templates/matching-template.html @@ -47,7 +47,9 @@

- + + From dd2c14d2c0e261d3146b9a30cb192734746a7e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B2=A0=EB=89=B4?= Date: Sat, 6 Sep 2025 22:10:44 +0900 Subject: [PATCH 2/5] feature: delegate application layer to add utm sources to meet the clean architecture --- .../usecase/member/email/SendMatchingEmailUseCase.kt | 7 +++++-- .../src/main/kotlin/com/dobby/util/UtmLinkUtils.kt | 11 +++++++++++ .../test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt | 4 ++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 application/src/main/kotlin/com/dobby/util/UtmLinkUtils.kt create mode 100644 application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt diff --git a/application/src/main/kotlin/com/dobby/usecase/member/email/SendMatchingEmailUseCase.kt b/application/src/main/kotlin/com/dobby/usecase/member/email/SendMatchingEmailUseCase.kt index 101e74a3..57a9baec 100644 --- a/application/src/main/kotlin/com/dobby/usecase/member/email/SendMatchingEmailUseCase.kt +++ b/application/src/main/kotlin/com/dobby/usecase/member/email/SendMatchingEmailUseCase.kt @@ -11,6 +11,7 @@ import com.dobby.model.experiment.ExperimentPost import com.dobby.usecase.UseCase import com.dobby.util.EmailUtils import com.dobby.util.RetryUtils +import com.dobby.util.UtmLinkUtils import java.time.LocalDate import java.time.LocalDateTime import java.time.format.DateTimeFormatter @@ -70,13 +71,15 @@ class SendMatchingEmailUseCase( return groupedPosts.flatMap { (place, posts) -> val sortedPosts = posts.sortedBy { it.createdAt } sortedPosts.mapIndexed { index, post -> - val postUrl = urlGeneratorGateway.getExperimentPostUrl(post.id) + val baseUrl = urlGeneratorGateway.getExperimentPostUrl(post.id) + val postUrlWithUtm = UtmLinkUtils.add(baseUrl) + mapOf( "title" to post.title, "place" to if (index == 0) place else "", "uploadDate" to LocalDate.now().toString(), "reward" to post.reward, - "postUrl" to postUrl + "postUrl" to postUrlWithUtm ) } } diff --git a/application/src/main/kotlin/com/dobby/util/UtmLinkUtils.kt b/application/src/main/kotlin/com/dobby/util/UtmLinkUtils.kt new file mode 100644 index 00000000..91e7336c --- /dev/null +++ b/application/src/main/kotlin/com/dobby/util/UtmLinkUtils.kt @@ -0,0 +1,11 @@ +package com.dobby.util + +object UtmLinkUtils { + private const val EMAIL_UTM = "utm_source=email&utm_medium=daily" + + fun add(url: String, utm: String = EMAIL_UTM) : String { + if (url.contains("utm_source=") || url.contains("utm_medium=")) return url + val sep = if (url.contains("?")) "&" else "?" + return url + sep + utm + } +} diff --git a/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt b/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt new file mode 100644 index 00000000..5bf106de --- /dev/null +++ b/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt @@ -0,0 +1,4 @@ +package com.dobby.util + +class UtmLinkUtilsTest { +} From 7c8be0db5f251fa0c6fe679cc93f6c864336bc5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B2=A0=EB=89=B4?= Date: Sat, 6 Sep 2025 22:11:22 +0900 Subject: [PATCH 3/5] test: add unit test to combinate domain rules --- .../kotlin/com/dobby/util/UtmLinkUtilsTest.kt | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt b/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt index 5bf106de..c1afc68e 100644 --- a/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt +++ b/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt @@ -1,4 +1,35 @@ package com.dobby.util -class UtmLinkUtilsTest { -} +import io.kotest.core.spec.style.BehaviorSpec +import io.kotest.matchers.shouldBe + +class UtmLinkUtilsTest : BehaviorSpec ({ + + given("메일 트래킹 정책(utm_source=email&utm_medium=daily)") { + `when`("원본 쿼리스트링이 없는 URL이면") { + val url = "https://gradmeet.co.kr/post/123" + then("UTM이 ?로 시작하여 붙는다") { + UtmLinkUtils.add(url) shouldBe + "https://gradmeet.co.kr/post/123?utm_source=email&utm_medium=daily" + } + } + + + `when`("이미 쿼리스트링이 있는 URL이면") { + val url = "https://gradmeet.co.kr/post/123?param=test" + then("UTM이 &로 붙는다") { + UtmLinkUtils.add(url) shouldBe + "https://gradmeet.co.kr/post/123?param=test&utm_source=email&utm_medium=daily" + } + } + + `when`("이미 동일한 UTM이 붙어 있는 URL이면") { + val url = "https://gradmeet.co.kr/321?utm_source=email&utm_medium=daily" + then("중복 추가하지 않는다") { + UtmLinkUtils.add(url) shouldBe + "https://gradmeet.co.kr/321?utm_source=email&utm_medium=daily" + } + } + } + +}) From 7af4eec5e7e6a319b81e78c4c09c139e3cee7ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B2=A0=EB=89=B4?= Date: Sat, 6 Sep 2025 22:11:41 +0900 Subject: [PATCH 4/5] feature: rollback infrastructure area layer --- .../src/main/resources/templates/matching-template.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/infrastructure/src/main/resources/templates/matching-template.html b/infrastructure/src/main/resources/templates/matching-template.html index 24446d75..8170ed9d 100644 --- a/infrastructure/src/main/resources/templates/matching-template.html +++ b/infrastructure/src/main/resources/templates/matching-template.html @@ -47,9 +47,7 @@

- - +

From 1196c4cc7c8fa54f20c728e473709c3968838e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B2=A0=EB=89=B4?= Date: Sat, 6 Sep 2025 22:20:21 +0900 Subject: [PATCH 5/5] fix: fix space to meet the ktlintFormat logic --- application/src/main/kotlin/com/dobby/util/UtmLinkUtils.kt | 2 +- .../src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/application/src/main/kotlin/com/dobby/util/UtmLinkUtils.kt b/application/src/main/kotlin/com/dobby/util/UtmLinkUtils.kt index 91e7336c..6ad45cd6 100644 --- a/application/src/main/kotlin/com/dobby/util/UtmLinkUtils.kt +++ b/application/src/main/kotlin/com/dobby/util/UtmLinkUtils.kt @@ -3,7 +3,7 @@ package com.dobby.util object UtmLinkUtils { private const val EMAIL_UTM = "utm_source=email&utm_medium=daily" - fun add(url: String, utm: String = EMAIL_UTM) : String { + fun add(url: String, utm: String = EMAIL_UTM): String { if (url.contains("utm_source=") || url.contains("utm_medium=")) return url val sep = if (url.contains("?")) "&" else "?" return url + sep + utm diff --git a/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt b/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt index c1afc68e..f0f9ebd5 100644 --- a/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt +++ b/application/src/test/kotlin/com/dobby/util/UtmLinkUtilsTest.kt @@ -3,7 +3,7 @@ package com.dobby.util import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe -class UtmLinkUtilsTest : BehaviorSpec ({ +class UtmLinkUtilsTest : BehaviorSpec({ given("메일 트래킹 정책(utm_source=email&utm_medium=daily)") { `when`("원본 쿼리스트링이 없는 URL이면") { @@ -14,7 +14,6 @@ class UtmLinkUtilsTest : BehaviorSpec ({ } } - `when`("이미 쿼리스트링이 있는 URL이면") { val url = "https://gradmeet.co.kr/post/123?param=test" then("UTM이 &로 붙는다") { @@ -31,5 +30,4 @@ class UtmLinkUtilsTest : BehaviorSpec ({ } } } - })