From a5a4a29a37df59f5a62a94042182639042a34bf7 Mon Sep 17 00:00:00 2001 From: San Kim Date: Sun, 12 Jan 2025 20:06:45 +0900 Subject: [PATCH] =?UTF-8?q?feat(connection)=20:=20=EC=BB=A4=EB=84=A5?= =?UTF-8?q?=EC=85=98=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/connection/entity/Connection.kt | 25 ++++++- .../domain/connection/entity/Participant.kt | 25 +++++++ .../connection/entity/ConnectionJpaEntity.kt | 65 +++++++++++++++++++ .../connection/entity/ParticipantJpaEntity.kt | 39 +++++++++++ .../db/migration/V3__init_connection.sql | 16 +++++ 5 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 domain/src/main/kotlin/com/threedays/domain/connection/entity/Participant.kt create mode 100644 infrastructure/persistence/src/main/kotlin/com/threedays/persistence/connection/entity/ConnectionJpaEntity.kt create mode 100644 infrastructure/persistence/src/main/kotlin/com/threedays/persistence/connection/entity/ParticipantJpaEntity.kt create mode 100644 infrastructure/persistence/src/main/resources/db/migration/V3__init_connection.sql diff --git a/domain/src/main/kotlin/com/threedays/domain/connection/entity/Connection.kt b/domain/src/main/kotlin/com/threedays/domain/connection/entity/Connection.kt index f66bead..fab0101 100644 --- a/domain/src/main/kotlin/com/threedays/domain/connection/entity/Connection.kt +++ b/domain/src/main/kotlin/com/threedays/domain/connection/entity/Connection.kt @@ -1,13 +1,34 @@ package com.threedays.domain.connection.entity +import com.threedays.domain.user.entity.User import com.threedays.support.common.base.domain.AggregateRoot import com.threedays.support.common.base.domain.UUIDTypeId -import java.util.UUID +import java.time.LocalDateTime +import java.util.* data class Connection( override val id: Id, -): AggregateRoot() { + val participant1: Participant, + val participant2: Participant, + val connectedAt: LocalDateTime, +) : AggregateRoot() { data class Id(override val value: UUID) : UUIDTypeId(value) + companion object { + + fun match( + user1: User.Id, + user2: User.Id + ): Connection { + return Connection( + id = UUIDTypeId.random(), + participant1 = Participant(user1), + participant2 = Participant(user2), + connectedAt = LocalDateTime.now() + ) + } + } + + } diff --git a/domain/src/main/kotlin/com/threedays/domain/connection/entity/Participant.kt b/domain/src/main/kotlin/com/threedays/domain/connection/entity/Participant.kt new file mode 100644 index 0000000..f1d1012 --- /dev/null +++ b/domain/src/main/kotlin/com/threedays/domain/connection/entity/Participant.kt @@ -0,0 +1,25 @@ +package com.threedays.domain.connection.entity + +import com.threedays.domain.user.entity.User +import com.threedays.support.common.base.domain.DomainEntity + +/** + * 매칭에 참여하는 유저 + * @param id: 유저의 ID + * @param connectionResponse: 매칭에 대한 응답 + */ +data class Participant( + override val id: User.Id, + val connectionResponse: ConnectionResponse = ConnectionResponse.NO_RESPONSE +) : DomainEntity() { + + /** + * 유저의 매칭에 대한 응답 + */ + enum class ConnectionResponse { + NO_RESPONSE, // 응답하지 않음 + KEEP_CONNECT, // 커넥션 유지 + DISCONNECT, // 연결 끊기 + } + +} diff --git a/infrastructure/persistence/src/main/kotlin/com/threedays/persistence/connection/entity/ConnectionJpaEntity.kt b/infrastructure/persistence/src/main/kotlin/com/threedays/persistence/connection/entity/ConnectionJpaEntity.kt new file mode 100644 index 0000000..6e5bcd4 --- /dev/null +++ b/infrastructure/persistence/src/main/kotlin/com/threedays/persistence/connection/entity/ConnectionJpaEntity.kt @@ -0,0 +1,65 @@ +package com.threedays.persistence.connection.entity + +import com.threedays.domain.connection.entity.Connection +import jakarta.persistence.CascadeType +import jakarta.persistence.Column +import jakarta.persistence.Entity +import jakarta.persistence.FetchType +import jakarta.persistence.Id +import jakarta.persistence.OneToOne +import jakarta.persistence.Table +import java.time.LocalDateTime +import java.util.* + +@Entity +@Table(name = "connection") +class ConnectionJpaEntity( + id: UUID, + participant1: ParticipantJpaEntity, + participant2: ParticipantJpaEntity, + connectedAt: LocalDateTime, +) { + + @Id + var id: UUID = id + private set + + @OneToOne( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + ) + var participant1: ParticipantJpaEntity = participant1 + private set + + @OneToOne( + fetch = FetchType.EAGER, + cascade = [CascadeType.ALL], + ) + var participant2: ParticipantJpaEntity = participant2 + private set + + @Column(name = "connected_at", nullable = false) + var connectedAt: LocalDateTime = connectedAt + private set + + fun toDomain(): Connection { + return Connection( + id = Connection.Id(id), + participant1 = participant1.toDomain(), + participant2 = participant2.toDomain(), + connectedAt = connectedAt + ) + } + + companion object { + + fun from(domain: Connection): ConnectionJpaEntity { + return ConnectionJpaEntity( + id = domain.id.value, + participant1 = ParticipantJpaEntity.from(domain.participant1), + participant2 = ParticipantJpaEntity.from(domain.participant2), + connectedAt = domain.connectedAt + ) + } + } +} diff --git a/infrastructure/persistence/src/main/kotlin/com/threedays/persistence/connection/entity/ParticipantJpaEntity.kt b/infrastructure/persistence/src/main/kotlin/com/threedays/persistence/connection/entity/ParticipantJpaEntity.kt new file mode 100644 index 0000000..cf442db --- /dev/null +++ b/infrastructure/persistence/src/main/kotlin/com/threedays/persistence/connection/entity/ParticipantJpaEntity.kt @@ -0,0 +1,39 @@ +package com.threedays.persistence.connection.entity + +import com.threedays.domain.connection.entity.Participant +import com.threedays.domain.user.entity.User +import jakarta.persistence.* +import java.util.* + +@Entity +@Table(name = "participant") +class ParticipantJpaEntity( + id: UUID, + connectionResponse: Participant.ConnectionResponse +) { + + @Id + var id: UUID = id + private set + + @Column(name = "connection_response", nullable = false) + @Enumerated(EnumType.STRING) + var connectionResponse: Participant.ConnectionResponse = connectionResponse + private set + + fun toDomain(): Participant { + return Participant( + id = User.Id(id), + connectionResponse = connectionResponse + ) + } + + companion object { + fun from(domain: Participant): ParticipantJpaEntity { + return ParticipantJpaEntity( + id = domain.id.value, + connectionResponse = domain.connectionResponse + ) + } + } +} diff --git a/infrastructure/persistence/src/main/resources/db/migration/V3__init_connection.sql b/infrastructure/persistence/src/main/resources/db/migration/V3__init_connection.sql new file mode 100644 index 0000000..bd545d0 --- /dev/null +++ b/infrastructure/persistence/src/main/resources/db/migration/V3__init_connection.sql @@ -0,0 +1,16 @@ +CREATE TABLE participant +( + id BINARY(16) PRIMARY KEY COMMENT '사용자 ID', + connection_response VARCHAR(20) NOT NULL COMMENT '연결 응답 (ACCEPTED, REJECTED, WAITING)' +); + +CREATE TABLE connection +( + id BINARY(16) PRIMARY KEY COMMENT '커넥션 ID', + participant1_id BINARY(16) NOT NULL COMMENT '참가자1 ID', + participant2_id BINARY(16) NOT NULL COMMENT '참가자2 ID', + connected_at DATETIME(6) NOT NULL COMMENT '커넥션 생성 일시', + + INDEX idx_connection_participant1_id (participant1_id), + INDEX idx_connection_participant2_id (participant2_id) +);