Files
OmniRoute/src/lib/providers/deprecatedProviderCleanup.ts
Bob.Hou 9adc2f87d0 fix(dashboard): list and purge leftover gemini-cli rows (#13197)
A catalog drop with no DELETE path is a real dead end for operators — no card, no route, no way out. Good that by-provider delete now bumps the proxy generation and purges synced models the way single-row delete already did, and that a cleanup error there does not turn a successful row delete into a 500.

---

Validated in one consolidated worktree cut from `release/v3.8.51`, boarded with the other 19 PRs of this batch. Two in-batch conflicts, both additive and resolved by keeping each side: the `ENVIRONMENT.md` table (#13035 + #13011) and the `chatHelpers.ts` import block (#12975 on the tip + #13017).

- `typecheck:core` clean; `check:dashboard-typecheck` OK (206 pre-existing, within baseline); `check:changelog-integrity` OK; `check:docs-counts` migrations ✓
- complexity 2816 / baseline 3218 and cognitive-complexity 1271 / baseline 1437 — both under baseline
- 531 of 532 focused assertions green across the batch's 46 test files
- `check-file-size` rebaselined for the batch's real growth (annotation `_rebaseline_2026_09_11_mergebatch_v3851_houminxi`, landed on #13038), attributed per PR

The single red is **not this batch**: `tests/unit/combo/quota-weighted-strategy.test.ts` → "A/B isolation: 7 hard-empty + 2 at 0.5% + 1 at 40%, floor=1" asserts an order between two connections of identical weight and flakes on the pure tip too — 2 failures in 4 runs at `origin/release/v3.8.51` with nothing from this batch applied.

⚠️ base-red inherited: #12732 — `Docs Gates`, `Merge integrity`, `No new ESLint warnings`, `Unit Tests fast-path` and `Fast Quality Gates` reproduce on the pure tip (provider count 356 vs the 358 the modules define, SKILL.md drift, and `open-sse/utils/stream.ts` at 3115 > frozen 3098, untouched here).

Thanks @HouMinXi — the live evidence on these (X500 logs, `storage.sqlite` state, real `/v1/models` probes, the 36-minute outage write-up) is what let a 20-PR batch be reviewed as a unit.
2026-09-11 19:28:05 -03:00

50 lines
1.3 KiB
TypeScript

import {
getDeprecationNotice,
isDeprecatedProvider,
} from "@omniroute/open-sse/services/tokenRefresh.ts";
export function isOrphanDeprecatedConnection(conn: { provider?: string | null }): boolean {
return isDeprecatedProvider(String(conn.provider || ""));
}
export type DeprecatedProviderLeftoverGroup = {
provider: string;
migrateTo: string;
reason: string;
connectionIds: string[];
names: string[];
};
export function listDeprecatedProviderLeftovers(
connections: Array<{
id: string;
provider?: string | null;
name?: string | null;
}>
): DeprecatedProviderLeftoverGroup[] {
const groups = new Map<string, DeprecatedProviderLeftoverGroup>();
for (const conn of connections) {
if (!isOrphanDeprecatedConnection(conn)) continue;
const provider = String(conn.provider || "");
const notice = getDeprecationNotice(provider);
if (!notice) continue;
let group = groups.get(provider);
if (!group) {
group = {
provider,
migrateTo: notice.migrateTo,
reason: notice.reason,
connectionIds: [],
names: [],
};
groups.set(provider, group);
}
group.connectionIds.push(conn.id);
group.names.push(typeof conn.name === "string" ? conn.name : "");
}
return [...groups.values()].filter((group) => group.connectionIds.length > 0);
}