From 08136377ea489d3cc076fdbc32b894128a2f067f Mon Sep 17 00:00:00 2001 From: Amir Rajabi Date: Thu, 20 Aug 2026 13:35:02 +0330 Subject: [PATCH] Store additional device metadata --- .../nilin/opex/api/core/inout/auth/Device.kt | 14 +++++-- .../nilin/opex/api/core/inout/auth/Session.kt | 3 ++ .../kotlin/co/nilin/opex/auth/data/Device.kt | 14 +++++-- .../co/nilin/opex/auth/data/LoginEvent.kt | 10 ++++- .../kotlin/co/nilin/opex/auth/data/Session.kt | 6 ++- .../nilin/opex/auth/service/LoginService.kt | 27 +++++++++---- .../opex/auth/service/RegisterService.kt | 29 +++++++++----- .../co/nilin/opex/device/core/data/Device.kt | 10 +++-- .../nilin/opex/device/core/data/LoginEvent.kt | 9 ++++- .../nilin/opex/device/core/data/Platform.kt | 5 +++ .../core/service/UserSessionDeviceService.kt | 17 +++++--- .../ports/postgres/impl/DeviceManagerImpl.kt | 8 +++- .../ports/postgres/model/DeviceModel.kt | 39 ++++++++++++++----- .../device/ports/postgres/utils/Convertor.kt | 14 ++++++- .../V4__add_new_columns_for_device.sql | 6 +++ docker-compose.local.yml | 3 ++ 16 files changed, 162 insertions(+), 52 deletions(-) create mode 100644 device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/Platform.kt create mode 100644 device-management/device-management-ports/device-management-postgres/src/main/resources/db/migration/V4__add_new_columns_for_device.sql diff --git a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/inout/auth/Device.kt b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/inout/auth/Device.kt index 7162681b9..d65e471f9 100644 --- a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/inout/auth/Device.kt +++ b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/inout/auth/Device.kt @@ -1,8 +1,14 @@ package co.nilin.opex.api.core.inout.auth open class Device { - var deviceUuid: String?=null - var appVersion: String?=null - var osVersion: String?=null - var os: Os?=null + var appVersion: String? = null + var os: Os? = null + var osVersion: String? = null + var brand: String? = null + var model: String? = null + var platform: Platform? = null + var agent: String? = null + var pushToken: String? = null + var deviceUuid: String? = null + var buildNumber: Int? = null } \ No newline at end of file diff --git a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/inout/auth/Session.kt b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/inout/auth/Session.kt index 19b255363..8cbc2f891 100644 --- a/api/api-core/src/main/kotlin/co/nilin/opex/api/core/inout/auth/Session.kt +++ b/api/api-core/src/main/kotlin/co/nilin/opex/api/core/inout/auth/Session.kt @@ -25,3 +25,6 @@ enum class SessionStatus { enum class Os { ANDROID, IOS, MOBILE_WEB, DESKTOP_WEB } +enum class Platform { + WEB_APP, WEB_DESKTOP, ANDROID_NATIVE_APP, IOS_NATIVE_APP, WEB_ADMIN_DESKTOP +} diff --git a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/Device.kt b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/Device.kt index a588d5030..8d7f83284 100644 --- a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/Device.kt +++ b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/Device.kt @@ -1,8 +1,14 @@ package co.nilin.opex.auth.data open class Device { - var deviceUuid: String?=null - var appVersion: String?=null - var osVersion: String?=null - var os: Os?=null + var appVersion: String? = null + var os: Os? = null + var osVersion: String? = null + var brand: String? = null + var model: String? = null + var platform: Platform? = null + var agent: String? = null + var pushToken: String? = null + var deviceUuid: String? = null + var buildNumber: Int? = null } \ No newline at end of file diff --git a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/LoginEvent.kt b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/LoginEvent.kt index 5949762d5..e7a7298f1 100644 --- a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/LoginEvent.kt +++ b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/LoginEvent.kt @@ -4,10 +4,16 @@ import java.time.LocalDateTime data class LoginEvent( val uuid: String, - val sessionId: String?, val deviceUuid: String?, val appVersion: String?, val osVersion: String?, - val expireDate: LocalDateTime, + val pushToken: String?, val os: Os?, + val brand: String?, + val model: String?, + val platform: Platform?, + val agent: String?, + val buildNumber: Int?, + val sessionId: String, + val expireDate: LocalDateTime ) : AuthEvent() \ No newline at end of file diff --git a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/Session.kt b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/Session.kt index bf37da982..85ef22570 100644 --- a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/Session.kt +++ b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/data/Session.kt @@ -13,7 +13,7 @@ data class Sessions( val sessionStatus: SessionStatus?, val sessionCreateDate: LocalDateTime?, val sessionExpireDate: LocalDateTime?, - var isCurrentSession: Boolean?=false + var isCurrentSession: Boolean? = false ) enum class SessionStatus { @@ -25,3 +25,7 @@ enum class SessionStatus { enum class Os { ANDROID, IOS, MOBILE_WEB, DESKTOP_WEB } + +enum class Platform { + WEB_APP, WEB_DESKTOP, ANDROID_NATIVE_APP, IOS_NATIVE_APP, WEB_ADMIN_DESKTOP +} diff --git a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/service/LoginService.kt b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/service/LoginService.kt index 585c516d3..8fee1d3f1 100644 --- a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/service/LoginService.kt +++ b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/service/LoginService.kt @@ -211,16 +211,27 @@ class LoginService( return TokenResponse(token, null, null) } - private fun sendLoginEvent(userId: String, sessionState: String?, request: Device, expiresIn: Int) { + private fun sendLoginEvent( + userId: String, + sessionState: String?, + request: Device, + expiresIn: Int + ) { authEventProducer.send( LoginEvent( - userId, - sessionState, - request.deviceUuid, - request.appVersion, - request.osVersion, - LocalDateTime.now().plusSeconds(expiresIn.toLong()), - request.os + uuid = userId, + deviceUuid = request.deviceUuid, + appVersion = request.appVersion, + osVersion = request.osVersion, + pushToken = request.pushToken, + os = request.os, + brand = request.brand, + model = request.model, + platform = request.platform, + agent = request.agent, + buildNumber = request.buildNumber, + sessionId = sessionState ?: "", + expireDate = LocalDateTime.now().plusSeconds(expiresIn.toLong()) ) ) } diff --git a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/service/RegisterService.kt b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/service/RegisterService.kt index fa3ce1506..ab773bc32 100644 --- a/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/service/RegisterService.kt +++ b/auth-gateway/auth-gateway-app/src/main/kotlin/co/nilin/opex/auth/service/RegisterService.kt @@ -42,7 +42,7 @@ class RegisterService( isUserDuplicate(username) val otpType = username.type.otpType val otpReceiver = OTPReceiver(request.username, otpType) - val res = otpProxy.requestOTP(request.username, listOf(otpReceiver),OTPAction.REGISTER) + val res = otpProxy.requestOTP(request.username, listOf(otpReceiver), OTPAction.REGISTER) return TempOtpResponse(res.otp, otpReceiver) } @@ -107,16 +107,27 @@ class RegisterService( keycloakProxy.linkGoogleIdentity(userId, email, googleUserId) } - private fun sendLoginEvent(userId: String, sessionState: String?, request: Device, expiresIn: Int) { + private fun sendLoginEvent( + userId: String, + sessionState: String?, + request: Device, + expiresIn: Int + ) { authProducer.send( LoginEvent( - userId, - sessionState, - request.deviceUuid, - request.appVersion, - request.osVersion, - LocalDateTime.now().plusSeconds(expiresIn.toLong()), - request.os + uuid = userId, + deviceUuid = request.deviceUuid, + appVersion = request.appVersion, + osVersion = request.osVersion, + pushToken = request.pushToken, + os = request.os, + brand = request.brand, + model = request.model, + platform = request.platform, + agent = request.agent, + buildNumber = request.buildNumber, + sessionId = sessionState ?: "", + expireDate = LocalDateTime.now().plusSeconds(expiresIn.toLong()) ) ) } diff --git a/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/Device.kt b/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/Device.kt index cf990ba48..853578727 100644 --- a/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/Device.kt +++ b/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/Device.kt @@ -9,8 +9,12 @@ data class Device( val os: Os? = null, val osVersion: String? = null, val appVersion: String? = null, + val brand: String? = null, + val model: String? = null, + val platform: Platform? = null, + val agent: String? = null, val pushToken: String? = null, - val createDate: LocalDateTime?= LocalDateTime.now(), - val lastUpdateDate: LocalDateTime?= LocalDateTime.now() - + val buildNumber: Int? = null, + val createDate: LocalDateTime? = LocalDateTime.now(), + val lastUpdateDate: LocalDateTime? = LocalDateTime.now() ) diff --git a/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/LoginEvent.kt b/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/LoginEvent.kt index 3eb017fc5..d5f9afbb8 100644 --- a/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/LoginEvent.kt +++ b/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/LoginEvent.kt @@ -10,7 +10,12 @@ data class LoginEvent( val osVersion: String?, val pushToken: String?, val os: Os?, + val brand: String?, + val model: String?, + val platform: Platform?, + val agent: String?, + val buildNumber: Int?, val sessionId: String, - val expireDate: LocalDateTime, - ) : SessionEvent() + val expireDate: LocalDateTime +) : SessionEvent() diff --git a/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/Platform.kt b/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/Platform.kt new file mode 100644 index 000000000..c8d651b9b --- /dev/null +++ b/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/data/Platform.kt @@ -0,0 +1,5 @@ +package co.nilin.opex.device.core.data + +enum class Platform { + WEB_APP, WEB_DESKTOP, ANDROID_NATIVE_APP, IOS_NATIVE_APP, WEB_ADMIN_DESKTOP +} \ No newline at end of file diff --git a/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/service/UserSessionDeviceService.kt b/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/service/UserSessionDeviceService.kt index bd28282a4..a0089ef5d 100644 --- a/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/service/UserSessionDeviceService.kt +++ b/device-management/device-management-core/src/main/kotlin/co/nilin/opex/device/core/service/UserSessionDeviceService.kt @@ -16,7 +16,7 @@ class UserSessionDeviceService( ) { suspend fun getUserSessionsWithDevices(sessionsRequest: SessionsRequest): List { - return sessionPersister.fetchUserDeviceSession( sessionsRequest) + return sessionPersister.fetchUserDeviceSession(sessionsRequest) } @Transactional @@ -24,11 +24,16 @@ class UserSessionDeviceService( val device = with(loginEvent) { devicePersister.upsertDevice( Device( - deviceUuid = this.deviceUuid ?: UUID.randomUUID().toString(), - os = this.os, - osVersion = this.osVersion, - appVersion = this.appVersion, - pushToken = this.pushToken, + deviceUuid = deviceUuid ?: UUID.randomUUID().toString(), + os = os, + osVersion = osVersion, + appVersion = appVersion, + brand = brand, + model = model, + platform = platform, + agent = agent, + pushToken = pushToken, + buildNumber = buildNumber ) ) } diff --git a/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/impl/DeviceManagerImpl.kt b/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/impl/DeviceManagerImpl.kt index 545b72c93..c7be7853d 100644 --- a/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/impl/DeviceManagerImpl.kt +++ b/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/impl/DeviceManagerImpl.kt @@ -6,9 +6,8 @@ import co.nilin.opex.device.core.spi.DevicePersister import co.nilin.opex.device.ports.postgres.dao.DeviceRepository import co.nilin.opex.device.ports.postgres.utils.toDto import co.nilin.opex.device.ports.postgres.utils.toModel - -import kotlinx.coroutines.reactive.awaitFirstOrNull import kotlinx.coroutines.reactive.awaitFirst +import kotlinx.coroutines.reactive.awaitFirstOrNull import org.slf4j.LoggerFactory import org.springframework.stereotype.Component import java.time.LocalDateTime @@ -29,7 +28,12 @@ class DeviceManagerImpl( os = device.os, osVersion = device.osVersion, appVersion = device.appVersion, + brand = device.brand, + model = device.model, + platform = device.platform, + agent = device.agent, pushToken = device.pushToken, + buildNumber = device.buildNumber, lastUpdateDate = now ) ).awaitFirst() diff --git a/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/model/DeviceModel.kt b/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/model/DeviceModel.kt index 53405eba3..ac3e5f29f 100644 --- a/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/model/DeviceModel.kt +++ b/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/model/DeviceModel.kt @@ -1,6 +1,7 @@ package co.nilin.opex.device.ports.postgres.model import co.nilin.opex.device.core.data.Os +import co.nilin.opex.device.core.data.Platform import org.springframework.data.annotation.Id import org.springframework.data.annotation.Version import org.springframework.data.relational.core.mapping.Column @@ -10,13 +11,33 @@ import java.time.LocalDateTime @Table(name = "devices") data class DeviceModel( - @Id val id: Long?=null, - @Column("device_uuid") val deviceUuid: String, - @Column("os") val os: Os?, - @Column("os_version") val osVersion: String?, - @Column("app_version") val appVersion: String?, - @Column("push_token") val pushToken: String?, - @Column("create_date") val creteDate: LocalDateTime? = LocalDateTime.now(), - @Column("last_update_date") val lastUpdateDate: LocalDateTime? = LocalDateTime.now(), - @Column @Version var version: Long? = null + @Id + val id: Long? = null, + @Column("device_uuid") + val deviceUuid: String, + @Column("os") + val os: Os?, + @Column("os_version") + val osVersion: String?, + @Column("app_version") + val appVersion: String?, + @Column("brand") + val brand: String?, + @Column("model") + val model: String?, + @Column("platform") + val platform: Platform?, + @Column("agent") + val agent: String?, + @Column("push_token") + val pushToken: String?, + @Column("build_number") + val buildNumber: Int?, + @Column("create_date") + val createDate: LocalDateTime? = LocalDateTime.now(), + @Column("last_update_date") + val lastUpdateDate: LocalDateTime? = LocalDateTime.now(), + @Version + @Column("version") + var version: Long? = null ) diff --git a/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/utils/Convertor.kt b/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/utils/Convertor.kt index e7f17a17f..994330041 100644 --- a/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/utils/Convertor.kt +++ b/device-management/device-management-ports/device-management-postgres/src/main/kotlin/co/nilin/opex/device/ports/postgres/utils/Convertor.kt @@ -15,8 +15,13 @@ fun Device.toModel(): DeviceModel { os = os, osVersion = osVersion, appVersion = appVersion, + brand = brand, + model = model, + platform = platform, + agent = agent, pushToken = pushToken, - creteDate = createDate ?: LocalDateTime.now(), + buildNumber = buildNumber, + createDate = createDate ?: LocalDateTime.now(), lastUpdateDate = lastUpdateDate ?: LocalDateTime.now() ) } @@ -28,8 +33,13 @@ fun DeviceModel.toDto(): Device { os = os, osVersion = osVersion, appVersion = appVersion, + brand = brand, + model = model, + platform = platform, + agent = agent, pushToken = pushToken, - createDate = creteDate, + buildNumber = buildNumber, + createDate = createDate, lastUpdateDate = lastUpdateDate ) } diff --git a/device-management/device-management-ports/device-management-postgres/src/main/resources/db/migration/V4__add_new_columns_for_device.sql b/device-management/device-management-ports/device-management-postgres/src/main/resources/db/migration/V4__add_new_columns_for_device.sql new file mode 100644 index 000000000..f175f4843 --- /dev/null +++ b/device-management/device-management-ports/device-management-postgres/src/main/resources/db/migration/V4__add_new_columns_for_device.sql @@ -0,0 +1,6 @@ +ALTER TABLE devices + ADD COLUMN IF NOT EXISTS brand VARCHAR(100), + ADD COLUMN IF NOT EXISTS model VARCHAR(100), + ADD COLUMN IF NOT EXISTS platform VARCHAR(50), + ADD COLUMN IF NOT EXISTS agent VARCHAR(255), + ADD COLUMN IF NOT EXISTS build_number INTEGER; \ No newline at end of file diff --git a/docker-compose.local.yml b/docker-compose.local.yml index bcc4ed564..dd5fe5c31 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -63,6 +63,9 @@ services: postgres-profile: ports: - "5440:5432" + postgres-device-management: + ports: + - "5441:5432" accountant: ports: - "127.0.0.1:8089:8080"