Problem
TokenInterceptor loads tokens from FlutterSecureStorage for every intercepted request, including every protected API request. Secure storage is relatively expensive and platform-backed, so hot request paths should not depend on repeated keychain/secure-storage reads when the token is already known in memory.
Evidence
lib/core/dio/interceptors/token_interceptor.dart calls tokenLocalDataSource.getToken() inside onRequest.
- The interceptor then adds the access token to the
Authorization header for the request.
lib/data/data_sources/token_local_data_source.dart implements getToken() by reading from FlutterSecureStorage.
getToken() may perform the current iOS-options read and then a legacy-options fallback read, so a single protected request can trigger multiple secure-storage reads before network dispatch.
- Refresh flow also calls
getToken() again.
Proposed direction
Introduce an in-memory token cache owned by the token data source or a small token/session service:
- Populate the cache after sign-in, token refresh, and first successful secure-storage read.
- Update the cache whenever
storeTokens or storeAuthToken writes new token values.
- Clear the cache on
deleteToken and local sign-out.
- Keep secure storage as the persistence layer, but avoid reading it on every request once the cache is warm.
- Preserve the legacy-token migration behavior on first load.
Acceptance criteria
- Protected requests use cached access tokens after the first successful token load.
storeTokens, storeAuthToken, and refresh-token success update both secure storage and the in-memory value.
deleteToken clears both secure storage and the in-memory value.
- Missing-token behavior remains unchanged for protected and auth-exempt endpoints.
- Add unit coverage proving repeated protected requests do not repeatedly hit secure storage after the cache is warm.
Source: Codex codebase audit on 2026-06-28.
Problem
TokenInterceptorloads tokens fromFlutterSecureStoragefor every intercepted request, including every protected API request. Secure storage is relatively expensive and platform-backed, so hot request paths should not depend on repeated keychain/secure-storage reads when the token is already known in memory.Evidence
lib/core/dio/interceptors/token_interceptor.dartcallstokenLocalDataSource.getToken()insideonRequest.Authorizationheader for the request.lib/data/data_sources/token_local_data_source.dartimplementsgetToken()by reading fromFlutterSecureStorage.getToken()may perform the current iOS-options read and then a legacy-options fallback read, so a single protected request can trigger multiple secure-storage reads before network dispatch.getToken()again.Proposed direction
Introduce an in-memory token cache owned by the token data source or a small token/session service:
storeTokensorstoreAuthTokenwrites new token values.deleteTokenand local sign-out.Acceptance criteria
storeTokens,storeAuthToken, and refresh-token success update both secure storage and the in-memory value.deleteTokenclears both secure storage and the in-memory value.Source: Codex codebase audit on 2026-06-28.