Files
OmniRoute/src/shared/utils/connectionStatus.ts
Diego Rodrigues de Sa e Souza c46d35bcb4 fix(dashboard): hide disabled provider connections from combo builder (#6984)
* fix(dashboard): hide disabled provider connections from combo builder

The combos page's fetchData() only filtered available connections by
testStatus ("active"/"success"), so a connection the user had
explicitly disabled (isActive: false) could still show up in the
combo builder if it carried a stale testStatus from before it was
disabled.

Add filterActiveConnections() in src/shared/utils/connectionStatus.ts
and apply it ahead of the existing testStatus filter.

Co-authored-by: itolstov <attid0@gmail.com>
Inspired-by: https://github.com/decolua/9router/pull/2526

* chore(changelog): fragment for #6984

* fix(combos): keep combos page within frozen size cap

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* fix(combos): extract filterUsableConnections to shrink the combos god-file

The combos page only filtered provider connections on testStatus, so a
connection the user had explicitly disabled survived with a stale
"active"/"success" status. The isActive + testStatus gate now lives in
the shared connectionStatus util as filterUsableConnections(), which the
page calls in a single line.

This keeps src/app/(dashboard)/dashboard/combos/page.tsx BELOW its frozen
file-size cap (4653 vs 4655 congelado — the file shrinks by 2 lines vs the
release tip) without touching config/quality/file-size-baseline.json, as
the gate asks ("modularize/extraia (DRY) para encolher").

The regression test now exercises filterUsableConnections directly instead
of hand-mirroring the page's filter chain, so it guards the real code path.

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* fix(combos): drop nullish entries in filterActiveConnections

`connection?.isActive !== false` evaluated to true for null/undefined
entries, so nullish elements survived the filter. Callers read properties
off the result — filterUsableConnections() reads `connection.testStatus`
— which would throw "TypeError: Cannot read properties of null".

Guard with an explicit truthiness check. Covered by a test that fails
against the previous predicate.

Reported-by: gemini-code-assist
Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

---------

Co-authored-by: itolstov <attid0@gmail.com>
2026-07-17 10:39:18 -03:00

42 lines
1.6 KiB
TypeScript

/**
* Shared helpers for filtering/classifying provider connections by their
* active/disabled state, independent of their last test result.
*
* A connection can have `isActive: false` (explicitly disabled by the user)
* while still carrying a stale `testStatus` of "active"/"success" from
* before it was disabled — callers that only filter on `testStatus` will
* incorrectly keep serving disabled connections.
*/
export interface ConnectionActiveFlag {
isActive?: boolean;
[key: string]: unknown;
}
/**
* Filters out connections that have been explicitly disabled
* (`isActive === false`). Connections without an `isActive` field are
* treated as active for backward compatibility. Nullish entries are
* dropped so callers can safely read properties off the result.
*/
export function filterActiveConnections<T extends ConnectionActiveFlag>(
connections: T[] | null | undefined
): T[] {
if (!Array.isArray(connections)) return [];
return connections.filter((connection) => !!connection && connection.isActive !== false);
}
/**
* Filters connections down to the ones a builder UI can actually route to:
* enabled (`isActive !== false`) AND last tested healthy ("active"/"success").
* Both gates must be applied together — filtering on `testStatus` alone keeps
* disabled connections that carry a stale healthy status.
*/
export function filterUsableConnections<T extends ConnectionActiveFlag>(
connections: T[] | null | undefined
): T[] {
return filterActiveConnections(connections).filter(
(connection) => connection.testStatus === "active" || connection.testStatus === "success"
);
}