address comments

This commit is contained in:
ksmaze
2026-03-14 20:34:02 -07:00
parent ed3de8cca6
commit 0c7e600d41
2 changed files with 50 additions and 24 deletions
@@ -79,8 +79,8 @@ describe('accounts skipModelFetch behavior', () => {
}); });
expect(response.statusCode).toBe(200); expect(response.statusCode).toBe(200);
// getModels is called ONCE asynchronously by refreshModelsForAccount later in the flow // getModels should NOT be called when skipModelFetch is true
expect(getModelsMock).toHaveBeenCalledTimes(1); expect(getModelsMock).toHaveBeenCalledTimes(0);
const accounts = await db.select().from(schema.accounts).all(); const accounts = await db.select().from(schema.accounts).all();
expect(accounts).toHaveLength(1); expect(accounts).toHaveLength(1);
+33 -7
View File
@@ -1,5 +1,5 @@
import { FastifyInstance } from 'fastify'; import { FastifyInstance } from 'fastify';
import { db, schema } from '../../db/index.js'; import { db, schema, runtimeDbDialect } from '../../db/index.js';
import { and, eq, gte, lt, sql } from 'drizzle-orm'; import { and, eq, gte, lt, sql } from 'drizzle-orm';
import { refreshBalance } from '../../services/balanceService.js'; import { refreshBalance } from '../../services/balanceService.js';
import { getAdapter } from '../../services/platforms/index.js'; import { getAdapter } from '../../services/platforms/index.js';
@@ -979,7 +979,7 @@ export async function accountsRoutes(app: FastifyInstance) {
let verifiedModels: string[] = []; let verifiedModels: string[] = [];
if (credentialMode === 'apikey') { if (credentialMode === 'apikey') {
if (body.skipModelFetch) { if (body.skipModelFetch === true) {
tokenType = 'apikey'; tokenType = 'apikey';
accessToken = ''; accessToken = '';
if (!apiToken) apiToken = rawAccessToken; if (!apiToken) apiToken = rawAccessToken;
@@ -1104,10 +1104,14 @@ export async function accountsRoutes(app: FastifyInstance) {
if (tokenType === 'session') { if (tokenType === 'session') {
try { await refreshBalance(result.id); } catch { } try { await refreshBalance(result.id); } catch { }
} }
// Try to refresh models only if not skipping.
if (body.skipModelFetch !== true) {
try { try {
await refreshModelsForAccount(result.id); await refreshModelsForAccount(result.id);
await rebuildTokenRoutesFromAvailability(); await rebuildTokenRoutesFromAvailability();
} catch { } } catch { }
}
const account = await db.select().from(schema.accounts).where(eq(schema.accounts.id, result.id)).get(); const account = await db.select().from(schema.accounts).where(eq(schema.accounts.id, result.id)).get();
const finalCredentialMode = account ? resolveStoredCredentialMode(account) : resolvedCredentialMode; const finalCredentialMode = account ? resolveStoredCredentialMode(account) : resolvedCredentialMode;
@@ -1418,7 +1422,7 @@ export async function accountsRoutes(app: FastifyInstance) {
return reply.code(400).send({ message: '模型列表不能为空' }); return reply.code(400).send({ message: '模型列表不能为空' });
} }
const normalizedModels = models.map(m => String(m).trim()).filter(m => m.length > 0); const normalizedModels = Array.from(new Set(models.map(m => String(m).trim()).filter(m => m.length > 0)));
if (normalizedModels.length === 0) { if (normalizedModels.length === 0) {
return reply.code(400).send({ message: '模型列表不能为空' }); return reply.code(400).send({ message: '模型列表不能为空' });
} }
@@ -1433,19 +1437,19 @@ export async function accountsRoutes(app: FastifyInstance) {
try { try {
await db.transaction(async (tx) => { await db.transaction(async (tx) => {
const checkedAt = new Date().toISOString();
for (const modelName of normalizedModels) { for (const modelName of normalizedModels) {
if (runtimeDbDialect === 'mysql') {
const existing = await tx.select() const existing = await tx.select()
.from(schema.modelAvailability) .from(schema.modelAvailability)
.where(and(eq(schema.modelAvailability.accountId, accountId), eq(schema.modelAvailability.modelName, modelName))) .where(and(eq(schema.modelAvailability.accountId, accountId), eq(schema.modelAvailability.modelName, modelName)))
.get(); .get();
if (existing) { if (existing) {
if (!existing.available || !existing.isManual) {
await tx.update(schema.modelAvailability) await tx.update(schema.modelAvailability)
.set({ available: true, latencyMs: null, isManual: true, checkedAt: new Date().toISOString() }) .set({ available: true, latencyMs: null, isManual: true, checkedAt })
.where(eq(schema.modelAvailability.id, existing.id)) .where(eq(schema.modelAvailability.id, existing.id))
.run(); .run();
}
} else { } else {
await tx.insert(schema.modelAvailability).values({ await tx.insert(schema.modelAvailability).values({
accountId, accountId,
@@ -1453,9 +1457,31 @@ export async function accountsRoutes(app: FastifyInstance) {
available: true, available: true,
isManual: true, isManual: true,
latencyMs: null, latencyMs: null,
checkedAt: new Date().toISOString(), checkedAt,
}).run(); }).run();
} }
} else {
// SQLite / PostgreSQL path
await (tx.insert(schema.modelAvailability)
.values({
accountId,
modelName,
available: true,
isManual: true,
latencyMs: null,
checkedAt,
}) as any)
.onConflictDoUpdate({
target: [schema.modelAvailability.accountId, schema.modelAvailability.modelName],
set: {
available: true,
isManual: true,
latencyMs: null,
checkedAt,
},
})
.run();
}
} }
}); });