fix: finish review-driven single-source cleanup

This commit is contained in:
Cita
2026-03-23 11:26:01 +08:00
parent 29c9fcbd29
commit 328b492ab3
21 changed files with 926 additions and 320 deletions
@@ -0,0 +1,13 @@
import { readFileSync } from 'node:fs';
import { describe, expect, it } from 'vitest';
function readSource(relativePath: string): string {
return readFileSync(new URL(relativePath, import.meta.url), 'utf8');
}
describe('account token route architecture boundaries', () => {
it('keeps legacy token repair from forcing route rebuilds inline', () => {
const source = readSource('./accountTokens.ts');
expect(source).not.toContain('rebuildRoutes: true');
});
});
-1
View File
@@ -233,7 +233,6 @@ async function executeAccountTokenSync(row: AccountWithSiteRow): Promise<SyncExe
accountId,
preferredApiToken: row.accounts.apiToken,
defaultTokenSource: 'legacy',
rebuildRoutes: true,
});
if (convergence.defaultTokenId != null) {
return {
+7 -12
View File
@@ -3,8 +3,10 @@ import { db, schema, runtimeDbDialect } from '../../db/index.js';
import { and, eq, gte, lt, sql } from 'drizzle-orm';
import { refreshBalance } from '../../services/balanceService.js';
import { getAdapter } from '../../services/platforms/index.js';
import { rebuildTokenRoutesFromAvailability } from '../../services/modelService.js';
import { convergeAccountMutation } from '../../services/accountMutationWorkflow.js';
import {
convergeAccountMutation,
rebuildRoutesBestEffort,
} from '../../services/accountMutationWorkflow.js';
import {
getCredentialModeFromExtraConfig,
getProxyUrlFromExtraConfig,
@@ -1330,9 +1332,7 @@ export async function accountsRoutes(app: FastifyInstance) {
app.delete<{ Params: { id: string } }>('/api/accounts/:id', async (request) => {
const id = parseInt(request.params.id);
await db.delete(schema.accounts).where(eq(schema.accounts.id, id)).run();
try {
await rebuildTokenRoutesFromAvailability();
} catch { }
await rebuildRoutesBestEffort();
return { success: true };
});
@@ -1386,9 +1386,7 @@ export async function accountsRoutes(app: FastifyInstance) {
}
if (shouldRebuildRoutes) {
try {
await rebuildTokenRoutesFromAvailability();
} catch { }
await rebuildRoutesBestEffort();
}
return {
@@ -1596,10 +1594,7 @@ export async function accountsRoutes(app: FastifyInstance) {
}
}
});
try {
await rebuildTokenRoutesFromAvailability();
} catch { }
await rebuildRoutesBestEffort();
return { success: true };
} catch (err: any) {
@@ -92,6 +92,12 @@ describe('proxy route architecture boundaries', () => {
expect(source).not.toContain('normalizeContentText(');
});
it('keeps codex runtime header and prompt-cache derivation inside provider profiles', () => {
const source = readSource('./upstreamEndpoint.ts');
expect(source).not.toContain('buildCodexRuntimeHeaders(');
expect(source).not.toContain('shouldInjectDerivedPromptCacheKey');
});
it('keeps gemini runtime closure in transformer-owned helpers', () => {
const source = readSource('./gemini.ts');
const surfaceSource = readSource('../../proxy-core/surfaces/geminiSurface.ts');
@@ -139,6 +145,23 @@ describe('proxy route architecture boundaries', () => {
expect(surfaceSource).toContain('openAiResponsesTransformer.proxyStream.createSession(');
});
it('keeps oauth refresh recovery and success bookkeeping behind shared surface helpers', () => {
const chatSurfaceSource = readSource('../../proxy-core/surfaces/chatSurface.ts');
const responsesSurfaceSource = readSource('../../proxy-core/surfaces/openAiResponsesSurface.ts');
expect(chatSurfaceSource).toContain('trySurfaceOauthRefreshRecovery(');
expect(chatSurfaceSource).toContain('recordSurfaceSuccess(');
expect(chatSurfaceSource).not.toContain('refreshOauthAccessTokenSingleflight(');
expect(chatSurfaceSource).not.toContain('resolveProxyUsageWithSelfLogFallback(');
expect(chatSurfaceSource).not.toContain('resolveProxyLogBilling(');
expect(responsesSurfaceSource).toContain('trySurfaceOauthRefreshRecovery(');
expect(responsesSurfaceSource).toContain('recordSurfaceSuccess(');
expect(responsesSurfaceSource).not.toContain('refreshOauthAccessTokenSingleflight(');
expect(responsesSurfaceSource).not.toContain('resolveProxyUsageWithSelfLogFallback(');
expect(responsesSurfaceSource).not.toContain('resolveProxyLogBilling(');
});
it('keeps canonical transformer contracts imported from the transformer boundary only', () => {
const chatSource = readSource('./chat.ts');
const responsesSource = readSource('./responses.ts');
+9 -34
View File
@@ -29,10 +29,7 @@ import {
} from '../../transformers/shared/endpointCompatibility.js';
import {
buildClaudeRuntimeHeaders,
buildCodexRuntimeHeaders,
buildGeminiCliRuntimeHeaders,
buildGeminiCliUserAgent,
getInputHeader,
headerValueToString,
} from '../../proxy-core/providers/headerUtils.js';
export {
@@ -1234,7 +1231,10 @@ export function buildUpstreamEndpointRequest(input: {
);
const configuredResponsesBody = applyConfiguredPayloadRules(body);
if (providerProfile?.id === 'codex') {
if (sitePlatform === 'codex') {
if (providerProfile?.id !== 'codex') {
throw new Error(`missing codex provider profile for platform: ${sitePlatform}`);
}
return providerProfile.prepareRequest({
endpoint: 'responses',
modelName: input.modelName,
@@ -1254,39 +1254,14 @@ export function buildUpstreamEndpointRequest(input: {
});
}
const headers = sitePlatform === 'codex'
? buildCodexRuntimeHeaders({
baseHeaders: {
...commonHeaders,
...responsesHeaders,
},
providerHeaders: input.providerHeaders,
explicitSessionId: asTrimmedString(input.codexExplicitSessionId) || null,
continuityKey: asTrimmedString(input.codexSessionCacheKey) || null,
})
: ensureStreamAcceptHeader({
...commonHeaders,
...responsesHeaders,
}, input.stream);
const codexSessionId = sitePlatform === 'codex'
? (getInputHeader(headers, 'session_id') || getInputHeader(headers, 'session-id'))
: null;
const shouldInjectDerivedPromptCacheKey = sitePlatform === 'codex'
&& !!codexSessionId
&& !asTrimmedString((configuredResponsesBody as Record<string, unknown>).prompt_cache_key)
&& !asTrimmedString(input.codexExplicitSessionId)
&& !!asTrimmedString(input.codexSessionCacheKey);
const runtimeBody = shouldInjectDerivedPromptCacheKey
? {
...configuredResponsesBody,
prompt_cache_key: codexSessionId,
}
: configuredResponsesBody;
const headers = ensureStreamAcceptHeader({
...commonHeaders,
...responsesHeaders,
}, input.stream);
return {
path: resolveEndpointPath('responses'),
headers,
body: runtimeBody,
body: configuredResponsesBody,
runtime,
};
}