Cache contractors at startup and filter by residence from cache

- Load contractors during initializeLookups() when authenticated
- Update getContractorsByResidence() to filter from cache instead of making network call
- Only fetch from API if cache is empty or stale

This eliminates the /contractors/by-residence/{id}/ call when visiting residences.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-13 23:38:43 -06:00
parent 33ee445aea
commit 4592c4493c

View File

@@ -151,8 +151,22 @@ object APILayer {
} else if (subscriptionStatusResult is ApiResult.Error) {
println("❌ Failed to fetch subscription status: ${subscriptionStatusResult.message}")
}
// Load contractors if cache is empty or stale
if (!DataManager.isCacheValid(DataManager.contractorsCacheTime)) {
println("🔄 Fetching contractors...")
val contractorsResult = contractorApi.getContractors(token, null, null, null, null)
if (contractorsResult is ApiResult.Success) {
println("✅ Contractors loaded: ${contractorsResult.data.size} contractors")
DataManager.setContractors(contractorsResult.data)
} else if (contractorsResult is ApiResult.Error) {
println("❌ Failed to fetch contractors: ${contractorsResult.message}")
}
} else {
println("⏭️ Skipping contractors (cache still valid)")
}
} else {
println("⏭️ Skipping subscription status (not authenticated)")
println("⏭️ Skipping subscription status and contractors (not authenticated)")
}
DataManager.markLookupsInitialized()
@@ -1019,9 +1033,30 @@ object APILayer {
return result
}
suspend fun getContractorsByResidence(residenceId: Int): ApiResult<List<ContractorSummary>> {
val token = getToken() ?: return ApiResult.Error("Not authenticated", 401)
return contractorApi.getContractorsByResidence(token, residenceId)
suspend fun getContractorsByResidence(residenceId: Int, forceRefresh: Boolean = false): ApiResult<List<ContractorSummary>> {
// Check cache first - filter contractors by residenceId
if (!forceRefresh && DataManager.isCacheValid(DataManager.contractorsCacheTime)) {
val cachedContractors = DataManager.contractors.value
val filtered = cachedContractors.filter { it.residenceId == residenceId }
return ApiResult.Success(filtered)
}
// If cache is empty or stale, fetch all contractors first to populate cache
if (DataManager.contractors.value.isEmpty() || !DataManager.isCacheValid(DataManager.contractorsCacheTime)) {
val token = getToken() ?: return ApiResult.Error("Not authenticated", 401)
val result = contractorApi.getContractors(token, null, null, null, null)
if (result is ApiResult.Success) {
DataManager.setContractors(result.data)
// Now filter from the fresh cache
val filtered = result.data.filter { it.residenceId == residenceId }
return ApiResult.Success(filtered)
}
return result as ApiResult<List<ContractorSummary>>
}
// Fallback: filter from cache
val filtered = DataManager.contractors.value.filter { it.residenceId == residenceId }
return ApiResult.Success(filtered)
}
// ==================== Task Template Operations ====================