mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 04:12:17 +03:00
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host. Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean. Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
70 lines
2.9 KiB
TypeScript
70 lines
2.9 KiB
TypeScript
/**
|
|
* db/proxyLogs.ts — Read queries over the `proxy_logs` table.
|
|
* Extracted from the /api/logs/export route handler.
|
|
*
|
|
* Hard Rule #5: routes must not embed raw SQL — these queries live here so the
|
|
* /api/logs/export route can delegate.
|
|
*
|
|
* NOTE: The SELECT * intentionally returns the historical `public_ip` column,
|
|
* NOT `clientIp`. This differs from GET /api/usage/proxy-logs which exposes
|
|
* the value as `clientIp`. Callers of the export endpoint should read
|
|
* `public_ip`. This inconsistency will be resolved in a future DB migration
|
|
* (#2880).
|
|
*
|
|
* Sliced out of #3500 (proxy_logs cluster, slice 4).
|
|
*/
|
|
|
|
import { getDbInstance } from "./core";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Queries
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Returns all proxy_logs rows with timestamp >= `since`, ordered by timestamp
|
|
* descending (most recent first).
|
|
*
|
|
* @param since - ISO-8601 timestamp lower bound, e.g. "2024-01-01T00:00:00.000Z".
|
|
*/
|
|
export function exportProxyLogsSince(since: string): Record<string, unknown>[] {
|
|
const db = getDbInstance();
|
|
const stmt = db.prepare(
|
|
"SELECT * FROM proxy_logs WHERE timestamp >= @since ORDER BY timestamp DESC"
|
|
);
|
|
return stmt.all({ since }) as Record<string, unknown>[];
|
|
}
|
|
|
|
// 24h window for "last known egress IP" lookups. This helper answers a
|
|
// different question from proxyEgress.ts (#10677): that module reports which
|
|
// connections share an egress IP *right now*, derived from their proxy config
|
|
// and a live probe (5 min cache), while the lock needs the IP a connection
|
|
// actually *left through* on its recent traffic — history, which only
|
|
// proxy_logs holds. Hence a local window constant rather than a dependency.
|
|
// Exported so callers can build `since` without duplicating the window.
|
|
export const EGRESS_IP_LOOKUP_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
|
|
/**
|
|
* Last non-null egress IP observed for a connection within the window, or
|
|
* null. Best-effort by design: egress_ip is only populated once the egress IP
|
|
* has been probed (cache TTL 5 min), so a cold cache yields null and the
|
|
* caller must fall back to today's behavior. Synchronous read (#10539 — no
|
|
* in-memory cache to go stale). The table has no index on connection_id
|
|
* (migration 134, YAGNI); the scan is bounded by the window via
|
|
* idx_pl_timestamp and this helper only runs at 429 frequency.
|
|
*/
|
|
export function getRecentEgressIpForConnection(
|
|
connectionId: string,
|
|
since: string
|
|
): { egressIp: string; at: string } | null {
|
|
const db = getDbInstance();
|
|
const row = db
|
|
.prepare(
|
|
`SELECT egress_ip, timestamp FROM proxy_logs
|
|
WHERE connection_id = ? AND egress_ip IS NOT NULL AND timestamp >= ?
|
|
ORDER BY timestamp DESC LIMIT 1`
|
|
)
|
|
.get(connectionId, since) as { egress_ip: string; timestamp: string } | undefined;
|
|
if (!row) return null;
|
|
return { egressIp: row.egress_ip, at: row.timestamp };
|
|
}
|