feat(chat-talk-room): Room Database 설정 및 Entity 생성
refactor(chat-talk-room): 패키지 chat.room → chat.talk.room 마이그레이션 및 DI 모듈 분리 왜: 기능 영역 명확화(talk) 및 DI 책임 분리로 유지보수성과 확장성을 높이기 위함 무엇: - 모델/응답/enum 파일들을 chat.room → chat.talk.room 으로 이동 - Room DB 패키지를 chat.room.db → chat.talk.room.db 로 이동 - AppDatabase 클래스명을 역할에 맞게 ChatMessageDatabase로 변경 문서: - docs/chat-talk-room-package-migration-and-di-module.md 추가 - docs/chat-room-room-database.md 내용 클래스명/경로 갱신
This commit is contained in:
		@@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * 보이스온 - 채팅방 캐릭터 정보 모델
 | 
					 * 보이스온 - 채팅방 캐릭터 정보 모델
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package kr.co.vividnext.sodalive.chat.room
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.annotation.Keep
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
import com.google.gson.annotations.SerializedName
 | 
					import com.google.gson.annotations.SerializedName
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * 보이스온 - 채팅 메시지 모델 (서버 응답 기반)
 | 
					 * 보이스온 - 채팅 메시지 모델 (서버 응답 기반)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package kr.co.vividnext.sodalive.chat.room
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.annotation.Keep
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
import com.google.gson.annotations.SerializedName
 | 
					import com.google.gson.annotations.SerializedName
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * 보이스온 - 채팅 메시지 매핑 유틸리티
 | 
					 * 보이스온 - 채팅 메시지 매핑 유틸리티
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package kr.co.vividnext.sodalive.chat.room
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.annotation.Keep
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * 보이스온 - 점진적 메시지 로딩 응답 모델
 | 
					 * 보이스온 - 점진적 메시지 로딩 응답 모델
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package kr.co.vividnext.sodalive.chat.room
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.annotation.Keep
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
import com.google.gson.annotations.SerializedName
 | 
					import com.google.gson.annotations.SerializedName
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * 보이스온 - 통합 채팅방 입장 응답 모델
 | 
					 * 보이스온 - 통합 채팅방 입장 응답 모델
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package kr.co.vividnext.sodalive.chat.room
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.annotation.Keep
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
import com.google.gson.annotations.SerializedName
 | 
					import com.google.gson.annotations.SerializedName
 | 
				
			||||||
@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.talk.room.db.ChatMessageDatabase
 | 
				
			||||||
 | 
					import org.koin.android.ext.koin.androidContext
 | 
				
			||||||
 | 
					import org.koin.dsl.module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					val chatTalkRoomModule = module {
 | 
				
			||||||
 | 
					    // Database
 | 
				
			||||||
 | 
					    single { ChatMessageDatabase.getDatabase(androidContext()) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // DAO
 | 
				
			||||||
 | 
					    single { get<ChatMessageDatabase>().chatMessageDao() }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * 보이스온 - 채팅방 메시지 전송 상태 Enum
 | 
					 * 보이스온 - 채팅방 메시지 전송 상태 Enum
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package kr.co.vividnext.sodalive.chat.room
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.annotation.Keep
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * 보이스온 - 채팅방 메시지 타입 Enum
 | 
					 * 보이스온 - 채팅방 메시지 타입 Enum
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package kr.co.vividnext.sodalive.chat.room
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.annotation.Keep
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * 보이스온 - 채팅 메시지 모델 (서버 응답 전용 DTO)
 | 
					 * 보이스온 - 채팅 메시지 모델 (서버 응답 전용 DTO)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
package kr.co.vividnext.sodalive.chat.room
 | 
					package kr.co.vividnext.sodalive.chat.talk.room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.annotation.Keep
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
import com.google.gson.annotations.SerializedName
 | 
					import com.google.gson.annotations.SerializedName
 | 
				
			||||||
@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 보이스온 - 채팅 메시지 Room TypeConverters
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package kr.co.vividnext.sodalive.chat.talk.room.db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.room.TypeConverter
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.talk.room.MessageStatus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object ChatMessageConverters {
 | 
				
			||||||
 | 
					    @TypeConverter
 | 
				
			||||||
 | 
					    @JvmStatic
 | 
				
			||||||
 | 
					    fun fromStatus(value: MessageStatus?): String? = value?.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @TypeConverter
 | 
				
			||||||
 | 
					    @JvmStatic
 | 
				
			||||||
 | 
					    fun toStatus(value: String?): MessageStatus? = value?.let { MessageStatus.valueOf(it) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 보이스온 - 채팅 메시지 DAO
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package kr.co.vividnext.sodalive.chat.talk.room.db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
 | 
					import androidx.room.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Keep
 | 
				
			||||||
 | 
					@Dao
 | 
				
			||||||
 | 
					interface ChatMessageDao {
 | 
				
			||||||
 | 
					    @Query("SELECT * FROM chat_messages WHERE roomId = :roomId ORDER BY createdAt DESC LIMIT 20")
 | 
				
			||||||
 | 
					    suspend fun getRecentMessages(roomId: Long): List<ChatMessageEntity>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Insert(onConflict = OnConflictStrategy.REPLACE)
 | 
				
			||||||
 | 
					    suspend fun insertMessage(message: ChatMessageEntity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Insert(onConflict = OnConflictStrategy.REPLACE)
 | 
				
			||||||
 | 
					    suspend fun insertMessages(messages: List<ChatMessageEntity>)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Update
 | 
				
			||||||
 | 
					    suspend fun updateMessage(message: ChatMessageEntity)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Query("DELETE FROM chat_messages WHERE roomId = :roomId AND createdAt < :cutoffTime")
 | 
				
			||||||
 | 
					    suspend fun deleteOldMessages(roomId: Long, cutoffTime: Long)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Query("DELETE FROM chat_messages")
 | 
				
			||||||
 | 
					    suspend fun deleteAllMessages()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Query("SELECT DISTINCT roomId FROM chat_messages")
 | 
				
			||||||
 | 
					    suspend fun getAllRoomIds(): List<Long>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 보이스온 - 채팅방 Room Database (ChatMessage 테이블 포함)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package kr.co.vividnext.sodalive.chat.talk.room.db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.content.Context
 | 
				
			||||||
 | 
					import androidx.room.Database
 | 
				
			||||||
 | 
					import androidx.room.Room
 | 
				
			||||||
 | 
					import androidx.room.RoomDatabase
 | 
				
			||||||
 | 
					import androidx.room.TypeConverters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Database(
 | 
				
			||||||
 | 
					    entities = [ChatMessageEntity::class],
 | 
				
			||||||
 | 
					    version = 1,
 | 
				
			||||||
 | 
					    exportSchema = false
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					@TypeConverters(ChatMessageConverters::class)
 | 
				
			||||||
 | 
					abstract class ChatMessageDatabase : RoomDatabase() {
 | 
				
			||||||
 | 
					    abstract fun chatMessageDao(): ChatMessageDao
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					        @Volatile
 | 
				
			||||||
 | 
					        private var INSTANCE: ChatMessageDatabase? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fun getDatabase(context: Context): ChatMessageDatabase {
 | 
				
			||||||
 | 
					            return INSTANCE ?: synchronized(this) {
 | 
				
			||||||
 | 
					                val instance = Room.databaseBuilder(
 | 
				
			||||||
 | 
					                    context.applicationContext,
 | 
				
			||||||
 | 
					                    ChatMessageDatabase::class.java,
 | 
				
			||||||
 | 
					                    "chat_database"
 | 
				
			||||||
 | 
					                ).build()
 | 
				
			||||||
 | 
					                INSTANCE = instance
 | 
				
			||||||
 | 
					                instance
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 보이스온 - 채팅 메시지 Room Entity
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package kr.co.vividnext.sodalive.chat.talk.room.db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import androidx.annotation.Keep
 | 
				
			||||||
 | 
					import androidx.room.Entity
 | 
				
			||||||
 | 
					import androidx.room.PrimaryKey
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.talk.room.MessageStatus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Keep
 | 
				
			||||||
 | 
					@Entity(tableName = "chat_messages")
 | 
				
			||||||
 | 
					data class ChatMessageEntity(
 | 
				
			||||||
 | 
					    @PrimaryKey val messageId: Long,
 | 
				
			||||||
 | 
					    val roomId: Long,
 | 
				
			||||||
 | 
					    val message: String,
 | 
				
			||||||
 | 
					    val profileImageUrl: String,
 | 
				
			||||||
 | 
					    val mine: Boolean,
 | 
				
			||||||
 | 
					    val createdAt: Long,
 | 
				
			||||||
 | 
					    val status: MessageStatus = MessageStatus.SENT,
 | 
				
			||||||
 | 
					    val localId: String? = null
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
@@ -146,6 +146,7 @@ import kr.co.vividnext.sodalive.mypage.profile.tag.MemberTagApi
 | 
				
			|||||||
import kr.co.vividnext.sodalive.mypage.profile.tag.MemberTagRepository
 | 
					import kr.co.vividnext.sodalive.mypage.profile.tag.MemberTagRepository
 | 
				
			||||||
import kr.co.vividnext.sodalive.mypage.profile.tag.MemberTagViewModel
 | 
					import kr.co.vividnext.sodalive.mypage.profile.tag.MemberTagViewModel
 | 
				
			||||||
import kr.co.vividnext.sodalive.mypage.recent.recentContentModule
 | 
					import kr.co.vividnext.sodalive.mypage.recent.recentContentModule
 | 
				
			||||||
 | 
					import kr.co.vividnext.sodalive.chat.talk.room.chatTalkRoomModule
 | 
				
			||||||
import kr.co.vividnext.sodalive.mypage.service_center.FaqApi
 | 
					import kr.co.vividnext.sodalive.mypage.service_center.FaqApi
 | 
				
			||||||
import kr.co.vividnext.sodalive.mypage.service_center.FaqRepository
 | 
					import kr.co.vividnext.sodalive.mypage.service_center.FaqRepository
 | 
				
			||||||
import kr.co.vividnext.sodalive.mypage.service_center.ServiceCenterViewModel
 | 
					import kr.co.vividnext.sodalive.mypage.service_center.ServiceCenterViewModel
 | 
				
			||||||
@@ -410,6 +411,7 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
 | 
				
			|||||||
        viewModelModule,
 | 
					        viewModelModule,
 | 
				
			||||||
        repositoryModule,
 | 
					        repositoryModule,
 | 
				
			||||||
        recentContentModule,
 | 
					        recentContentModule,
 | 
				
			||||||
 | 
					        chatTalkRoomModule,
 | 
				
			||||||
        otherModule
 | 
					        otherModule
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user