fix(auth-files): invalidate quota cache on mutations

This commit is contained in:
Supra4E8C
2026-07-30 03:37:35 +08:00
parent 3c8eba3027
commit 966a2918d5
3 changed files with 51 additions and 1 deletions
+7 -1
View File
@@ -29,6 +29,7 @@ import { OAuthModelAliasCard } from '@/features/authFiles/components/OAuthModelA
import { ProviderTabs } from '@/features/authFiles/components/ProviderTabs';
import { VaultHeader } from '@/features/authFiles/components/VaultHeader';
import { VaultPulse } from '@/features/authFiles/components/VaultPulse';
import { invalidateAuthFileDerivedCaches } from '@/features/authFiles/cacheInvalidation';
import { useAuthFilesData } from '@/features/authFiles/hooks/useAuthFilesData';
import { useAuthFilesModels } from '@/features/authFiles/hooks/useAuthFilesModels';
import { useAuthFilesOauth } from '@/features/authFiles/hooks/useAuthFilesOauth';
@@ -110,6 +111,11 @@ export function AuthFilesPage() {
invalidateModels,
} = useAuthFilesModels();
const invalidateDerivedCaches = useCallback(
(names?: string[]) => invalidateAuthFileDerivedCaches(invalidateModels, names),
[invalidateModels]
);
const {
files,
selectedFiles,
@@ -139,7 +145,7 @@ export function AuthFilesPage() {
batchDownload,
batchSetStatus,
batchDelete,
} = useAuthFilesData({ onFilesMutated: invalidateModels });
} = useAuthFilesData({ onFilesMutated: invalidateDerivedCaches });
const statusBarCache = useAuthFilesStatusBarCache(files);
@@ -0,0 +1,12 @@
import { useQuotaStore } from '@/stores/useQuotaStore';
type ModelsInvalidator = (names?: string[]) => void;
/** Invalidate every cache whose contents depend on an auth file's credentials. */
export const invalidateAuthFileDerivedCaches = (
invalidateModels: ModelsInvalidator,
names?: string[]
): void => {
invalidateModels(names);
useQuotaStore.getState().clearQuotaCache();
};
+32
View File
@@ -1,4 +1,5 @@
import { beforeEach, describe, expect, test } from 'bun:test';
import { invalidateAuthFileDerivedCaches } from '../src/features/authFiles/cacheInvalidation';
import {
captureQuotaCacheGeneration,
commitIfQuotaCacheCurrent,
@@ -35,4 +36,35 @@ describe('quota cache session isolation', () => {
).toBe(true);
expect(committed).toBe(true);
});
test('clears same-name quota and rejects an in-flight commit after auth mutation', () => {
const fileName = 'shared-codex.json';
useQuotaStore.getState().setCodexQuota({
[fileName]: {
status: 'success',
windows: [],
planType: 'account-a',
},
});
const accountARequest = captureQuotaCacheGeneration();
let invalidatedNames: string[] | undefined;
invalidateAuthFileDerivedCaches(
(names) => {
invalidatedNames = names;
},
[fileName]
);
expect(invalidatedNames).toEqual([fileName]);
expect(useQuotaStore.getState().codexQuota[fileName]).toBeUndefined();
let committed = false;
expect(
commitIfQuotaCacheCurrent(accountARequest, () => {
committed = true;
})
).toBe(false);
expect(committed).toBe(false);
});
});