Split out of #28's audit loop.
#28 made every datastore cache touch outage-tolerant (reads treat cache failure as a miss, mutations swallow-and-log, read-throughs use a capture-guard that keeps domain exceptions intact). TableSchemaService::getPrimaryColumnsForTable() / getUniqueColumns() still call CacheableService::getWithCache() bare, and the datastore write paths reach them via maybeThrowForDuplicateUniqueFields() — so a throwing cache backend has one remaining hop that can break create/update flows.
Fix shape: apply the same guarded read-through (serve the loaded value when only the post-load store failed; load directly when the probe broke; propagate fallback exceptions).
🤖 Generated with Claude Code
Split out of #28's audit loop.
#28 made every datastore cache touch outage-tolerant (reads treat cache failure as a miss, mutations swallow-and-log, read-throughs use a capture-guard that keeps domain exceptions intact).
TableSchemaService::getPrimaryColumnsForTable()/getUniqueColumns()still callCacheableService::getWithCache()bare, and the datastore write paths reach them viamaybeThrowForDuplicateUniqueFields()— so a throwing cache backend has one remaining hop that can break create/update flows.Fix shape: apply the same guarded read-through (serve the loaded value when only the post-load store failed; load directly when the probe broke; propagate fallback exceptions).
🤖 Generated with Claude Code