Skip to content

Commit 2b3cb66

Browse files
authored
배치 스케줄러 푸시 연동 (#20)
* feat: wip 배치 스케줄러 <-> 푸시 연동 * feat: 푸시 배치 연동 * chore: 코드 정리 * chore: 코드 정리 * chore: 코드 정리
1 parent c5724c4 commit 2b3cb66

File tree

42 files changed

+398
-266
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+398
-266
lines changed

docker/docker-compose.prod.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ services:
3636
- "3307:3306"
3737
volumes:
3838
- mysql_data:/var/lib/mysql
39-
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
4039
command:
4140
- --character-set-server=utf8mb4
4241
- --collation-server=utf8mb4_unicode_ci

docker/init.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ CREATE TABLE IF NOT EXISTS gathering
2525
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
2626
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
2727
deleted_at TIMESTAMP NULL,
28+
last_pushed_at TIMESTAMP NULL,
2829

2930
INDEX idx_deleted_at (deleted_at),
3031

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
rootProject.name = "tuk-server"
22

3-
include("tuk-api", "tuk-batch")
3+
include("tuk-api", "tuk-batch", "tuk-contract")

tuk-api/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ jib {
3030
}
3131

3232
dependencies {
33+
implementation(project(":tuk-contract"))
34+
3335
implementation("org.springframework.boot:spring-boot-starter-web")
3436
implementation("org.springframework.boot:spring-boot-starter-actuator")
3537
implementation("org.springframework.boot:spring-boot-starter-data-jpa")

tuk-api/src/main/kotlin/nexters/tuk/application/device/DeviceService.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,22 @@ class DeviceService(
2020
memberId: Long,
2121
command: DeviceCommand.UpdateDeviceToken,
2222
): DeviceResponse.UpdateDeviceToken {
23-
require(command.deviceInfo.deviceToken != null) { "디바이스 토큰은 필수 정보입니다." }
23+
val deviceToken = command.deviceInfo.deviceToken ?: throw IllegalArgumentException("디바이스 토큰은 필수 정보입니다.")
2424

2525
val device = deviceRepository.findByDeviceIdAndMemberId(
2626
deviceId = command.deviceInfo.deviceId,
2727
memberId = memberId
2828
)?.let { device ->
2929
device.updateDeviceToken(
30-
newDeviceToken = command.deviceInfo.deviceToken,
30+
newDeviceToken = deviceToken,
3131
newAppVersion = command.deviceInfo.appVersion,
3232
newOsVersion = command.deviceInfo.osVersion,
3333
)
3434
device
3535
} ?: deviceRepository.save(
3636
Device.new(
3737
deviceId = command.deviceInfo.deviceType,
38-
deviceToken = command.deviceInfo.deviceToken,
38+
deviceToken = deviceToken,
3939
appVersion = command.deviceInfo.appVersion,
4040
osVersion = command.deviceInfo.osVersion,
4141
memberId = memberId
@@ -45,7 +45,7 @@ class DeviceService(
4545
return DeviceResponse.UpdateDeviceToken(
4646
memberId = device.memberId,
4747
deviceId = device.deviceId,
48-
deviceToken = device.deviceToken,
48+
deviceToken = deviceToken,
4949
updatedAt = device.updatedAt
5050
)
5151
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package nexters.tuk.application.device.dto.request
22

3-
import nexters.tuk.contract.device.TukDeviceInfo
3+
import nexters.tuk.contract.device.TukClientInfo
44

55
class DeviceCommand {
66
data class UpdateDeviceToken(
7-
val deviceInfo: TukDeviceInfo,
7+
val deviceInfo: TukClientInfo,
88
)
99
}

tuk-api/src/main/kotlin/nexters/tuk/application/push/PushSender.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ package nexters.tuk.application.push
22

33
import nexters.tuk.application.push.dto.request.PushCommand
44

5+
@JvmInline
6+
value class DeviceToken(val token: String)
7+
58
interface PushSender {
69
fun send(
7-
recipients: List<PushCommand.PushRecipient>,
10+
deviceTokens: List<DeviceToken>,
811
message: PushCommand.MessagePayload,
912
)
1013
}
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
package nexters.tuk.application.push
22

33
import nexters.tuk.application.push.dto.request.PushCommand
4-
import nexters.tuk.application.push.dto.response.PushResponse
4+
import nexters.tuk.domain.device.DeviceRepository
55
import org.slf4j.LoggerFactory
66
import org.springframework.stereotype.Service
77
import org.springframework.transaction.annotation.Transactional
88

99
@Service
1010
class PushService(
1111
private val pushSender: PushSender,
12+
private val deviceRepository: DeviceRepository,
1213
) {
1314
private val logger = LoggerFactory.getLogger(PushService::class.java)
1415

1516
@Transactional
1617
fun sendPush(command: PushCommand.Push) {
1718
logger.info("Sending bulk push notification. Recipients: ${command.recipients.size}")
19+
val memberIds = command.recipients.map { it.memberId }
20+
val deviceTokens = deviceRepository.findByMemberIdIn(memberIds)
21+
.mapNotNull { device -> device.deviceToken?.let { DeviceToken(it) } }
1822

1923
pushSender.send(
20-
recipients = command.recipients,
24+
deviceTokens = deviceTokens,
2125
message = command.message
2226
)
27+
logger.info("Sent push notification. Recipients: ${command.recipients.size}")
2328
}
2429
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package nexters.tuk.application.push
22

33
enum class PushType {
4+
// 모임 정기 푸시
45
GROUP_NOTIFICATION,
6+
// 초대장 푸시
57
INVITATION,
68
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
package nexters.tuk.application.push.dto.request
22

3+
import nexters.tuk.application.push.PushType
4+
35
class PushCommand {
46
data class Push(
57
val recipients: List<PushRecipient>,
68
val message: MessagePayload,
9+
val pushType: PushType,
710
)
811

912
data class MessagePayload(
1013
val title: String,
1114
val body: String,
1215
)
1316

14-
// FIXME: 디바이스 토큰이 아닌 memberId만 받아서 직접 토큰 조회후 발송하도록 책임 분리해도 좋을듯
1517
data class PushRecipient(
16-
val deviceToken: String,
17-
val memberId: Long? = null,
18+
val memberId: Long,
1819
)
1920
}

0 commit comments

Comments
 (0)