Feature Flag Local Cache
Component Detail
Description
A short-lived in-memory and persistent cache layer for feature flag data that reduces redundant Supabase reads. Stores the resolved flag map per organization with a configurable TTL and invalidates automatically when the TTL expires or the organization context switches.
feature-flag-cache
Summaries
The Feature Flag Local Cache is a critical performance and resilience component that ensures users experience fast, consistent app behavior regardless of network conditions. By storing feature flag decisions locally, the app avoids repeated database round-trips that would increase latency and cloud infrastructure costs at scale. More importantly, it enables the app to function correctly during offline or degraded network scenarios, reducing churn risk from poor connectivity experiences. For multi-organization enterprise customers who switch context frequently, the per-organization keying ensures each tenant's configuration is immediately available, supporting a seamless experience that directly impacts customer satisfaction scores and contract renewals.
The Feature Flag Local Cache is low complexity but has two distinct storage layers—in-memory and persistent (local storage)—that each require separate testing strategies. The TTL mechanism must be validated for edge cases such as the app being suspended mid-TTL and resumed later. The persistent layer (`persist` / `loadPersisted`) requires a local storage library (e.g., SharedPreferences or Hive) to be established as a project dependency, which should be confirmed early to avoid late-stage dependency conflicts. Cache invalidation on organization context switch must be explicitly tested in integration scenarios involving account switching.
This component has no network dependency, so it is low deployment risk and can be developed in parallel with the repository.
FeatureFlagCache maintains two storage layers: a `Map
`loadPersisted` is called at cold-start before the first network fetch to populate in-memory state. `invalidate` removes the in-memory entry only; `invalidateAll` clears both memory and persistent store. Keep TTL configurable via a constructor parameter to simplify testing with zero-second TTLs.
Responsibilities
- Store resolved flag maps in memory keyed by organization ID
- Enforce TTL expiry and return stale-flag indicator when cache is outdated
- Persist last-known flags to local storage for offline startup
- Invalidate cache on organization switch or explicit refresh
Interfaces
get(String organizationId) → CachedFlags?
set(String organizationId, List<FeatureFlag> flags)
isExpired(String organizationId) → bool
invalidate(String organizationId)
invalidateAll()
persist(String organizationId, List<FeatureFlag> flags) → Future<void>
loadPersisted(String organizationId) → Future<List<FeatureFlag>?>
Relationships
Dependents (2)
Components that depend on this component
Related Data Entities (1)
Data entities managed by this component