Refactoring Opportunity
Summary
- File:
containers/api-proxy/server.js
- Current size: 1,284 lines
- Responsibilities identified: 6 distinct concerns in one file
Evidence
grep -n "^function" containers/api-proxy/server.js
97: function makeModelBodyTransform(provider)
137: function resetModelCacheState()
155: function resetKeyValidationState()
163: function isValidRequestId(id)
172: function checkRateLimit(req, res, provider, requestBytes) ← rate limiting subsystem
227: function proxyRequest(req, res, targetHost, ...) ← 200-line core proxy
428: function proxyWebSocket(req, socket, head, targetHost, ...) ← 145-line WebSocket proxy
574: function healthResponse()
596: function reflectEndpoints()
618: function handleManagementEndpoint(req, res) ← management API
646: function buildModelsJson()
670: function writeModelsJson(logDir)
729: function httpProbe(url, opts, timeoutMs)
772: function fetchJson(url, opts, timeoutMs)
830: function extractModelIds(json) ← model discovery subsystem
996: function _summarizeValidationFailures(mode)
1111: function createProviderServer(adapter) ← server factory
Six distinct responsibilities:
- HTTP forward proxy (
proxyRequest) — credential injection, header manipulation
- WebSocket proxy (
proxyWebSocket) — separate protocol handler
- Rate limiter (
checkRateLimit, reset functions) — per-provider request/byte limits
- Model discovery (
buildModelsJson, fetchJson, extractModelIds) — upstream model enumeration
- Management API (
handleManagementEndpoint, reflectEndpoints, healthResponse) — health/introspection
- Server factory (
createProviderServer) — wires everything together
Proposed Split
containers/api-proxy/
proxy-request.js — proxyRequest, proxyWebSocket (~350 lines)
rate-limiter.js — checkRateLimit, reset functions, state (~100 lines)
model-discovery.js — buildModelsJson, fetchJson, extractModelIds (~200 lines)
management.js — health, reflect, management endpoint handlers (~100 lines)
server.js — createProviderServer, adapter wiring, startup (~200 lines)
Effort Estimate
Medium — functions have clear boundaries but share module-level state (rate limit counters, model cache). State would need to be passed explicitly or encapsulated in classes/closures.
Benefits
proxyRequest is security-critical (credential injection path); isolation makes auditing easier
- Rate limiter can be unit-tested without spinning up a full HTTP server
- Model discovery failures are easier to diagnose when isolated
- Reduces the risk of accidental cross-concern changes
Detected by Refactoring Scanner workflow. Run date: 2026-05-05
Generated by Refactoring Opportunity Scanner · ● 350.4K · ◷
Refactoring Opportunity
Summary
containers/api-proxy/server.jsEvidence
grep -n "^function" containers/api-proxy/server.jsSix distinct responsibilities:
proxyRequest) — credential injection, header manipulationproxyWebSocket) — separate protocol handlercheckRateLimit, reset functions) — per-provider request/byte limitsbuildModelsJson,fetchJson,extractModelIds) — upstream model enumerationhandleManagementEndpoint,reflectEndpoints,healthResponse) — health/introspectioncreateProviderServer) — wires everything togetherProposed Split
Effort Estimate
Medium — functions have clear boundaries but share module-level state (rate limit counters, model cache). State would need to be passed explicitly or encapsulated in classes/closures.
Benefits
proxyRequestis security-critical (credential injection path); isolation makes auditing easierDetected by Refactoring Scanner workflow. Run date: 2026-05-05