P0.1: extract IDataManager interface + LocalDataManager ambient

Adds a narrow IDataManager contract covering the 5 DataManager members
referenced from ui/screens/** (currentUser, residences, totalSummary,
featureBenefits, subscription) and a staticCompositionLocalOf ambient
(LocalDataManager) that defaults to the DataManager singleton.

No screen call-sites change in this commit — screens migrate in P0.2.
ViewModels, APILayer, and PersistenceManager continue to depend on the
concrete DataManager singleton directly; the interface is deliberately
scoped to the screen surface the parity-gallery needs to substitute.

Includes IDataManagerTest (DataManager is IDataManager) and
LocalDataManagerTest (ambient val is exposed + default type-checks to the
real singleton). runComposeUiTest intentionally avoided — consistent with
ThemeSelectionScreenTest's convention, since commonTest composition
runtime is flaky on iosSimulator.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey T
2026-04-18 19:06:16 -05:00
parent bb4cbd58c3
commit 98b775d335
5 changed files with 125 additions and 6 deletions

View File

@@ -32,7 +32,7 @@ import kotlin.time.ExperimentalTime
* Data Flow:
* User Action → API Call → Server Response → DataManager Updated → All Screens React
*/
object DataManager {
object DataManager : IDataManager {
// ==================== CACHE CONFIGURATION ====================
@@ -107,7 +107,7 @@ object DataManager {
val authToken: StateFlow<String?> = _authToken.asStateFlow()
private val _currentUser = MutableStateFlow<User?>(null)
val currentUser: StateFlow<User?> = _currentUser.asStateFlow()
override val currentUser: StateFlow<User?> = _currentUser.asStateFlow()
// ==================== APP PREFERENCES ====================
@@ -122,13 +122,13 @@ object DataManager {
// ==================== RESIDENCES ====================
private val _residences = MutableStateFlow<List<Residence>>(emptyList())
val residences: StateFlow<List<Residence>> = _residences.asStateFlow()
override val residences: StateFlow<List<Residence>> = _residences.asStateFlow()
private val _myResidences = MutableStateFlow<MyResidencesResponse?>(null)
val myResidences: StateFlow<MyResidencesResponse?> = _myResidences.asStateFlow()
private val _totalSummary = MutableStateFlow<TotalSummary?>(null)
val totalSummary: StateFlow<TotalSummary?> = _totalSummary.asStateFlow()
override val totalSummary: StateFlow<TotalSummary?> = _totalSummary.asStateFlow()
private val _residenceSummaries = MutableStateFlow<Map<Int, ResidenceSummaryResponse>>(emptyMap())
val residenceSummaries: StateFlow<Map<Int, ResidenceSummaryResponse>> = _residenceSummaries.asStateFlow()
@@ -158,13 +158,13 @@ object DataManager {
// ==================== SUBSCRIPTION ====================
private val _subscription = MutableStateFlow<SubscriptionStatus?>(null)
val subscription: StateFlow<SubscriptionStatus?> = _subscription.asStateFlow()
override val subscription: StateFlow<SubscriptionStatus?> = _subscription.asStateFlow()
private val _upgradeTriggers = MutableStateFlow<Map<String, UpgradeTriggerData>>(emptyMap())
val upgradeTriggers: StateFlow<Map<String, UpgradeTriggerData>> = _upgradeTriggers.asStateFlow()
private val _featureBenefits = MutableStateFlow<List<FeatureBenefit>>(emptyList())
val featureBenefits: StateFlow<List<FeatureBenefit>> = _featureBenefits.asStateFlow()
override val featureBenefits: StateFlow<List<FeatureBenefit>> = _featureBenefits.asStateFlow()
private val _promotions = MutableStateFlow<List<Promotion>>(emptyList())
val promotions: StateFlow<List<Promotion>> = _promotions.asStateFlow()