P0: IDataManager coverage gaps — contractorDetail/documentDetail/taskCompletions/contractorsByResidence
Adds 4 new StateFlow members to IDataManager + DataManager + InMemoryDataManager + FixtureDataManager: - contractorDetail: Map<Int, Contractor> — cached detail fetches - documentDetail: Map<Int, Document> - taskCompletions: Map<Int, List<TaskCompletionResponse>> - contractorsByResidence: Map<Int, List<ContractorSummary>> APILayer now writes to these on successful detail/per-residence fetches: - getTaskCompletions -> setTaskCompletions - getDocument -> setDocumentDetail - getContractor -> setContractorDetail - getContractorsByResidence -> setContractorsForResidence Fixture populated() seeds contractorDetail + contractorsByResidence. Populated taskCompletions is empty (Fixtures doesn't define any completions yet). Foundation for P1 — VMs can now derive every read-state from DataManager reactively instead of owning independent MutableStateFlow fields. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -141,6 +141,9 @@ object DataManager : IDataManager {
|
||||
private val _tasksByResidence = MutableStateFlow<Map<Int, TaskColumnsResponse>>(emptyMap())
|
||||
override val tasksByResidence: StateFlow<Map<Int, TaskColumnsResponse>> = _tasksByResidence.asStateFlow()
|
||||
|
||||
private val _taskCompletions = MutableStateFlow<Map<Int, List<com.tt.honeyDue.models.TaskCompletionResponse>>>(emptyMap())
|
||||
override val taskCompletions: StateFlow<Map<Int, List<com.tt.honeyDue.models.TaskCompletionResponse>>> = _taskCompletions.asStateFlow()
|
||||
|
||||
// ==================== DOCUMENTS ====================
|
||||
|
||||
private val _documents = MutableStateFlow<List<Document>>(emptyList())
|
||||
@@ -149,12 +152,21 @@ object DataManager : IDataManager {
|
||||
private val _documentsByResidence = MutableStateFlow<Map<Int, List<Document>>>(emptyMap())
|
||||
override val documentsByResidence: StateFlow<Map<Int, List<Document>>> = _documentsByResidence.asStateFlow()
|
||||
|
||||
private val _documentDetail = MutableStateFlow<Map<Int, Document>>(emptyMap())
|
||||
override val documentDetail: StateFlow<Map<Int, Document>> = _documentDetail.asStateFlow()
|
||||
|
||||
// ==================== CONTRACTORS ====================
|
||||
// Stores ContractorSummary for list views (lighter weight than full Contractor)
|
||||
|
||||
private val _contractors = MutableStateFlow<List<ContractorSummary>>(emptyList())
|
||||
override val contractors: StateFlow<List<ContractorSummary>> = _contractors.asStateFlow()
|
||||
|
||||
private val _contractorsByResidence = MutableStateFlow<Map<Int, List<ContractorSummary>>>(emptyMap())
|
||||
override val contractorsByResidence: StateFlow<Map<Int, List<ContractorSummary>>> = _contractorsByResidence.asStateFlow()
|
||||
|
||||
private val _contractorDetail = MutableStateFlow<Map<Int, com.tt.honeyDue.models.Contractor>>(emptyMap())
|
||||
override val contractorDetail: StateFlow<Map<Int, com.tt.honeyDue.models.Contractor>> = _contractorDetail.asStateFlow()
|
||||
|
||||
// ==================== SUBSCRIPTION ====================
|
||||
|
||||
private val _subscription = MutableStateFlow<SubscriptionStatus?>(null)
|
||||
@@ -451,6 +463,11 @@ object DataManager : IDataManager {
|
||||
persistToDisk()
|
||||
}
|
||||
|
||||
/** Populate the per-task completion cache (used by TaskViewModel's derived flow). */
|
||||
fun setTaskCompletions(taskId: Int, completions: List<com.tt.honeyDue.models.TaskCompletionResponse>) {
|
||||
_taskCompletions.value = _taskCompletions.value + (taskId to completions)
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter cached allTasks by residence ID to avoid separate API call.
|
||||
* Returns null if allTasks not cached.
|
||||
@@ -557,6 +574,12 @@ object DataManager : IDataManager {
|
||||
persistToDisk()
|
||||
}
|
||||
|
||||
/** Populate the per-document detail cache (used by DocumentViewModel's derived flow). */
|
||||
fun setDocumentDetail(document: Document) {
|
||||
val id = document.id ?: return
|
||||
_documentDetail.value = _documentDetail.value + (id to document)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new document to the cache.
|
||||
* Caches affected: _documents, _documentsByResidence[residenceId]
|
||||
@@ -606,6 +629,16 @@ object DataManager : IDataManager {
|
||||
persistToDisk()
|
||||
}
|
||||
|
||||
/** Populate the per-residence contractor cache. */
|
||||
fun setContractorsForResidence(residenceId: Int, contractors: List<ContractorSummary>) {
|
||||
_contractorsByResidence.value = _contractorsByResidence.value + (residenceId to contractors)
|
||||
}
|
||||
|
||||
/** Populate the per-contractor detail cache (used by ContractorViewModel's derived flow). */
|
||||
fun setContractorDetail(contractor: com.tt.honeyDue.models.Contractor) {
|
||||
_contractorDetail.value = _contractorDetail.value + (contractor.id to contractor)
|
||||
}
|
||||
|
||||
fun addContractor(contractor: ContractorSummary) {
|
||||
_contractors.value = _contractors.value + contractor
|
||||
persistToDisk()
|
||||
|
||||
@@ -65,16 +65,28 @@ interface IDataManager {
|
||||
/** Kanban board cache keyed by residence id. */
|
||||
val tasksByResidence: StateFlow<Map<Int, TaskColumnsResponse>>
|
||||
|
||||
/** Task completions keyed by task id. Populated by APILayer.getTaskCompletions. */
|
||||
val taskCompletions: StateFlow<Map<Int, List<com.tt.honeyDue.models.TaskCompletionResponse>>>
|
||||
|
||||
// ==================== DOCUMENTS ====================
|
||||
|
||||
val documents: StateFlow<List<Document>>
|
||||
|
||||
val documentsByResidence: StateFlow<Map<Int, List<Document>>>
|
||||
|
||||
/** Document detail (full Document with user+images) cached by id. Populated by APILayer.getDocument. */
|
||||
val documentDetail: StateFlow<Map<Int, Document>>
|
||||
|
||||
// ==================== CONTRACTORS ====================
|
||||
|
||||
val contractors: StateFlow<List<ContractorSummary>>
|
||||
|
||||
/** Contractor list per residence id (from residence-scoped fetches). */
|
||||
val contractorsByResidence: StateFlow<Map<Int, List<ContractorSummary>>>
|
||||
|
||||
/** Contractor detail (full Contractor with user association) cached by id. Populated by APILayer.getContractor. */
|
||||
val contractorDetail: StateFlow<Map<Int, com.tt.honeyDue.models.Contractor>>
|
||||
|
||||
// ==================== SUBSCRIPTION ====================
|
||||
|
||||
/** Observed by [com.tt.honeyDue.ui.screens.ProfileScreen]. */
|
||||
|
||||
Reference in New Issue
Block a user