forked from boos/BoosAPI
fix: stabilize Codex continuation and proxy retry recovery / 修复 Codex 续传与代理重试稳定性 (#257)
* wip: preserve local changes before upstream merge * Improve proxy routing stability and add stable-first strategy * Sync explicit-group routing strategy to eligible source routes * Fix proxy retry and runtime health review issues * fix: make proxy channel retry attempts configurable * fix: harden proxy retry recovery and bookkeeping * fix: address pr 257 review comments --------- Co-authored-by: Cita <juricek.chen@gmail.com>
This commit is contained in:
@@ -99,4 +99,42 @@ describe('Sub2ApiAdapter subscription summary parsing', () => {
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves explicit zero activeCount from summary payload', async () => {
|
||||
const adapter = new MockSub2ApiAdapter({
|
||||
'/api/v1/auth/me': {
|
||||
code: 0,
|
||||
message: 'success',
|
||||
data: { id: 1, username: 'demo', email: 'demo@example.com', balance: 8.5 },
|
||||
},
|
||||
'/api/v1/subscriptions/summary': {
|
||||
code: 0,
|
||||
message: 'success',
|
||||
data: {
|
||||
active_count: 0,
|
||||
total_used_usd: 0,
|
||||
subscriptions: [
|
||||
{
|
||||
id: 11,
|
||||
group_name: 'Expired',
|
||||
status: 'expired',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const balance = await adapter.getBalance('https://sub2api.example.com', 'jwt-token');
|
||||
expect(balance.subscriptionSummary).toEqual({
|
||||
activeCount: 0,
|
||||
totalUsedUsd: 0,
|
||||
subscriptions: [
|
||||
{
|
||||
id: 11,
|
||||
groupName: 'Expired',
|
||||
status: 'expired',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -37,6 +37,15 @@ export class Sub2ApiAdapter extends BasePlatformAdapter {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private parseNonNegativeInteger(raw: unknown): number | undefined {
|
||||
if (typeof raw === 'number' && Number.isFinite(raw) && raw >= 0) return Math.trunc(raw);
|
||||
if (typeof raw === 'string') {
|
||||
const parsed = Number.parseInt(raw.trim(), 10);
|
||||
if (!Number.isNaN(parsed) && parsed >= 0) return parsed;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private parseNonNegativeNumber(raw: unknown): number | undefined {
|
||||
if (typeof raw === 'number' && Number.isFinite(raw) && raw >= 0) {
|
||||
return this.roundCurrency(raw);
|
||||
@@ -178,7 +187,7 @@ export class Sub2ApiAdapter extends BasePlatformAdapter {
|
||||
? payload as Record<string, unknown>
|
||||
: {};
|
||||
const subscriptions = this.parseSubscriptionItems(payload);
|
||||
const activeCount = this.parsePositiveInteger(body.active_count ?? body.activeCount);
|
||||
const activeCount = this.parseNonNegativeInteger(body.active_count ?? body.activeCount);
|
||||
const totalUsedUsd = this.parseNonNegativeNumber(body.total_used_usd ?? body.totalUsedUsd);
|
||||
const inferredUsedUsd = subscriptions.reduce((sum, item) => sum + (item.monthlyUsedUsd || 0), 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user