mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-12 22:14:22 +00:00
fix(bar): keep is_default on cache-fallback rows
The collector cached each row before the default profile was resolved, so the cache-fallback path (getCachedNativeAccountRows) served the default account with is_default:false -- the UI then lost default ordering/tagging when /summary served from cache. Write the resolved default flag back onto the cached copy so the fallback stays consistent with a fresh collection.
This commit is contained in:
1 parent
f57eed8c34
commit
7b610f0e82
2 files changed
+50
-2
No files matched your search
@@ -669,6 +669,26 @@ function markDefault(row: BarSummaryRow, isDefault: boolean): BarSummaryRow {
|
|||||||
return { ...row, is_default: isDefault };
|
return { ...row, is_default: isDefault };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag the row with is_default AND write the flag back onto the cached copy. The
|
||||||
|
* collector caches a row before the default profile is known (the default is
|
||||||
|
* resolved in the enumerator), so without this the cache-fallback path
|
||||||
|
* (getCachedNativeAccountRows) would serve the default account with
|
||||||
|
* is_default:false and the UI would stop ordering/tagging it as the default.
|
||||||
|
*/
|
||||||
|
function markDefaultAndSyncCache(
|
||||||
|
map: Map<string, ProviderState>,
|
||||||
|
profile: string,
|
||||||
|
row: BarSummaryRow,
|
||||||
|
isDefault: boolean
|
||||||
|
): BarSummaryRow {
|
||||||
|
const state = map.get(profile);
|
||||||
|
if (state?.cachedRow) {
|
||||||
|
state.cachedRow = { ...state.cachedRow, is_default: isDefault };
|
||||||
|
}
|
||||||
|
return markDefault(row, isDefault);
|
||||||
|
}
|
||||||
|
|
||||||
async function collectClaudeRowForProfile(
|
async function collectClaudeRowForProfile(
|
||||||
profile: string,
|
profile: string,
|
||||||
deps: NativeQuotaDeps,
|
deps: NativeQuotaDeps,
|
||||||
@@ -1453,7 +1473,7 @@ async function getNativeAccountRowsMultiProfile(
|
|||||||
const isDefault = p === claudeDefault;
|
const isDefault = p === claudeDefault;
|
||||||
tasks.push(
|
tasks.push(
|
||||||
collectClaudeRowForProfile(p, deps, force)
|
collectClaudeRowForProfile(p, deps, force)
|
||||||
.then((r) => (r ? markDefault(r, isDefault) : null))
|
.then((r) => (r ? markDefaultAndSyncCache(claudeProfileStates, p, r, isDefault) : null))
|
||||||
.catch(() => null)
|
.catch(() => null)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1462,7 +1482,7 @@ async function getNativeAccountRowsMultiProfile(
|
|||||||
const isDefault = p === codexDefault;
|
const isDefault = p === codexDefault;
|
||||||
tasks.push(
|
tasks.push(
|
||||||
collectCodexRowForProfile(p, deps, force)
|
collectCodexRowForProfile(p, deps, force)
|
||||||
.then((r) => (r ? markDefault(r, isDefault) : null))
|
.then((r) => (r ? markDefaultAndSyncCache(codexProfileStates, p, r, isDefault) : null))
|
||||||
.catch(() => null)
|
.catch(() => null)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1306,4 +1306,32 @@ describe('review focus areas: reauth caching + codex local fallback', () => {
|
|||||||
expect(localCalls).toBe(1);
|
expect(localCalls).toBe(1);
|
||||||
expect(def?.quotaStatus).not.toBe('unsupported');
|
expect(def?.quotaStatus).not.toBe('unsupported');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('cache-fallback rows keep is_default for the default profile', async () => {
|
||||||
|
resetNativeQuotaState();
|
||||||
|
const clock = { now: 6_000_000 };
|
||||||
|
const deps = makeMultiProfileDeps({
|
||||||
|
clock,
|
||||||
|
claudeProfiles: ['work', 'ck'],
|
||||||
|
codexProfiles: ['default', 'ck'],
|
||||||
|
claudeDefault: 'work',
|
||||||
|
codexDefault: 'default',
|
||||||
|
credsForProfile: () => maxCreds(),
|
||||||
|
claudeFetch: async () => successQuota(),
|
||||||
|
codexNativeAuth: (p) => ({ accessToken: `t-${p}`, accountId: `id-${p}` }),
|
||||||
|
codexNetworkFetch: async () => codexSuccessQuota(),
|
||||||
|
});
|
||||||
|
|
||||||
|
await getNativeAccountRows(deps); // populate the per-profile caches
|
||||||
|
|
||||||
|
// The cache-fallback path must preserve is_default so the UI still orders and
|
||||||
|
// tags the default account when /summary serves from cache.
|
||||||
|
const cached = getCachedNativeAccountRows();
|
||||||
|
expect(cached.find((r) => r.surface === 'ccs' && r.profile === 'work')?.is_default).toBe(true);
|
||||||
|
expect(cached.find((r) => r.surface === 'ccsx' && r.profile === 'default')?.is_default).toBe(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(cached.find((r) => r.surface === 'ccs' && r.profile === 'ck')?.is_default).toBe(false);
|
||||||
|
expect(cached.find((r) => r.surface === 'ccsx' && r.profile === 'ck')?.is_default).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user