feat(backup): add ConversationCache Room DB (entity, DAO, database)
This commit is contained in:
parent
230e7f6201
commit
ab59e7e5c9
|
|
@ -0,0 +1,24 @@
|
||||||
|
package app.closer.data.local
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import app.closer.data.local.entity.ConversationCacheEntity
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface ConversationCacheDao {
|
||||||
|
|
||||||
|
/** Idempotent restore: re-restoring the same message id replaces (latest-wins). */
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
suspend fun upsertAll(rows: List<ConversationCacheEntity>)
|
||||||
|
|
||||||
|
@Query("SELECT * FROM conversation_cache WHERE conversationId = :conversationId ORDER BY createdAt ASC")
|
||||||
|
suspend fun forConversation(conversationId: String): List<ConversationCacheEntity>
|
||||||
|
|
||||||
|
@Query("SELECT COUNT(*) FROM conversation_cache")
|
||||||
|
suspend fun count(): Int
|
||||||
|
|
||||||
|
@Query("DELETE FROM conversation_cache")
|
||||||
|
suspend fun clear()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package app.closer.data.local
|
||||||
|
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
|
import app.closer.data.local.entity.ConversationCacheEntity
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Separate Room DB for the restored conversation cache — kept apart from the asset-backed [AppDatabase]
|
||||||
|
* (the prepopulated question bank) so backup/restore never risks that DB's asset schema hash.
|
||||||
|
*/
|
||||||
|
@Database(entities = [ConversationCacheEntity::class], version = 1, exportSchema = false)
|
||||||
|
abstract class ConversationCacheDatabase : RoomDatabase() {
|
||||||
|
abstract fun conversationCacheDao(): ConversationCacheDao
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package app.closer.data.local.entity
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A restored/backed-up message in the local durable conversation cache. Keyed by the Firestore
|
||||||
|
* message id so restore is idempotent (upsert = latest-wins on re-restore). `encText` keeps the
|
||||||
|
* `enc:v1:` body verbatim; `reactionsJson` is a small JSON object of uid→emoji. This store is the
|
||||||
|
* source of truth for restored history and the foundation for the later Option-B switch.
|
||||||
|
*/
|
||||||
|
@Entity(tableName = "conversation_cache")
|
||||||
|
data class ConversationCacheEntity(
|
||||||
|
@PrimaryKey val messageId: String,
|
||||||
|
val conversationId: String,
|
||||||
|
val conversationType: String,
|
||||||
|
val authorUserId: String,
|
||||||
|
val type: String,
|
||||||
|
val encText: String?,
|
||||||
|
val mediaUrl: String?,
|
||||||
|
val durationMs: Long?,
|
||||||
|
val createdAt: Long,
|
||||||
|
val deleted: Boolean,
|
||||||
|
val reactionsJson: String
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue