feat(android): Room foundation — AppDatabase + TypeConverters + Gradle plugin

M8 phase 4.1. Pre-flight research (per the feedback_m8_preflight_research
rule) found two needed adjustments to the original plan:

  1. Room 2.6.1 -> 2.8.4. Room 2.6.1 (Oct 2023) predates Kotlin 2.0
     mainstream; Room 2.7+ explicitly supports Kotlin 2.0+ and KSP2.
     Room 2.8.4 is current stable; minSdk 23 (we're at 26) and AGP 8.4+
     (we're on 9), both compatible.
  2. Use the androidx.room Gradle plugin's `room { schemaDirectory(...) }`
     block instead of the legacy `ksp { arg("room.schemaLocation", ...) }`
     pattern. Cleaner schema-export plumbing in Room 2.7+. Audit-deferred
     item; trigger condition (first Room entity) met here.

Files:
  - cache/db/AppDatabase.kt — @Database stub, schemaVersion 1
  - cache/db/TypeConverters.kt — Instant <-> Long, CacheSource enum
  - cache/db/DatabaseModule.kt — Hilt-provided AppDatabase singleton
  - cache/db/entities/SyncMetadataEntity.kt — pulled forward from
    Task 4.2 slice 7 to satisfy Room's "needs >=1 entity" compile check;
    its consumer (SyncController) lands in Phase 12.4
  - cache/db/dao/SyncMetadataDao.kt — minimal observe/get/upsert
  - libs.versions.toml — Room 2.8.4, androidx-room plugin alias
  - app/build.gradle.kts — apply androidx.room plugin, add room {}
    block, drop ksp room.schemaLocation arg

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-22 13:22:11 -04:00
parent 4cbbdbfef9
commit a10079e8ef
7 changed files with 155 additions and 6 deletions
+12 -5
View File
@@ -7,6 +7,7 @@ plugins {
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.ksp)
alias(libs.plugins.androidx.room)
alias(libs.plugins.hilt)
alias(libs.plugins.ktlint)
alias(libs.plugins.detekt)
@@ -24,13 +25,12 @@ android {
versionName = "0.1.0-native"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { useSupportLibrary = true }
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
arg("room.incremental", "true")
}
}
// Room schema export is handled by the androidx.room Gradle plugin via
// the room {} block below — replaces the legacy
// `ksp { arg("room.schemaLocation", ...) }` pattern in Room 2.7+.
signingConfigs {
create("release") {
val keystorePath: String? = System.getenv("ANDROID_KEYSTORE_PATH")
@@ -89,6 +89,13 @@ kotlin {
}
}
// Room schema export — generated JSON dumps live under android/app/schemas/
// for migration-test fixtures. Replaces the legacy
// `ksp { arg("room.schemaLocation", ...) }` arg-passing.
room {
schemaDirectory("$projectDir/schemas")
}
detekt {
toolVersion = libs.versions.detekt.get()
config.setFrom(files("$rootDir/config/detekt.yml"))