Add unified DataManager as single source of truth for all app data

- Create DataManager.kt with StateFlows for all cached data:
  - Authentication (token, user)
  - Residences, tasks, documents, contractors
  - Subscription status and upgrade triggers
  - All lookup data (residence types, task categories, etc.)
  - Theme preferences and state metadata

- Add PersistenceManager with platform-specific implementations:
  - Android: SharedPreferences
  - iOS: NSUserDefaults
  - JVM: Properties file
  - WasmJS: localStorage

- Migrate APILayer to update DataManager on every API response
- Update Kotlin ViewModels to use DataManager for token access
- Deprecate LookupsRepository (delegates to DataManager)
- Create iOS DataManagerObservable Swift wrapper for SwiftUI
- Update iOS auth flow to use DataManager.isAuthenticated()

Data flow: User Action → API Call → DataManager Updated → All Screens React

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-03 00:21:24 -06:00
parent b79fda8aee
commit cf0cd1cda2
17 changed files with 1721 additions and 489 deletions

View File

@@ -0,0 +1,65 @@
package com.example.casera.data
import java.io.File
import java.util.Properties
/**
* JVM/Desktop implementation of PersistenceManager using Properties file.
*/
actual class PersistenceManager {
private val properties = Properties()
private val storageFile: File
init {
val userHome = System.getProperty("user.home")
val appDir = File(userHome, ".casera")
if (!appDir.exists()) {
appDir.mkdirs()
}
storageFile = File(appDir, "data.properties")
loadProperties()
}
private fun loadProperties() {
if (storageFile.exists()) {
try {
storageFile.inputStream().use { properties.load(it) }
} catch (e: Exception) {
// Ignore load errors
}
}
}
private fun saveProperties() {
try {
storageFile.outputStream().use { properties.store(it, "Casera Data Manager") }
} catch (e: Exception) {
// Ignore save errors
}
}
actual fun save(key: String, value: String) {
properties.setProperty(key, value)
saveProperties()
}
actual fun load(key: String): String? {
return properties.getProperty(key)
}
actual fun remove(key: String) {
properties.remove(key)
saveProperties()
}
actual fun clear() {
properties.clear()
saveProperties()
}
companion object {
private val instance by lazy { PersistenceManager() }
fun getInstance(): PersistenceManager = instance
}
}