feat(config): introduce CredentialResolver interface for test-friendly DI#1012
feat(config): introduce CredentialResolver interface for test-friendly DI#1012
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
nhopeatall
left a comment
There was a problem hiding this comment.
Summary
LGTM — Clean refactoring that extracts credential resolution into a proper interface/implementation pattern with dependency injection support for tests. The behavioral equivalence with the previous resolveFromEnvOrDb helper is maintained, CI is fully green, and the new tests provide solid coverage.
Notes
Minor behavioral nuance (not blocking): EnvCredentialResolver.resolve() uses process.env[key] ?? null, which would return an empty string "" if an env var exists but is empty. The old code used process.env[envKey] ? ... : notFoundValue, which treated empty strings as "not found" and returned null. This only affects getIntegrationCredentialOrNull and getOrgCredential in worker context with empty-string env vars — an edge case that shouldn't occur in practice since credentials are always non-empty values populated by the router. Not worth changing, just documenting for awareness.
The rest of the changes are straightforward:
- Interface + two implementations (
DbCredentialResolver,EnvCredentialResolver) correctly encapsulate the two resolution strategies getResolver()auto-selects the right implementation based on context, matching the original branching logicsetCredentialResolver()provides clean test DI withoutprocess.envmanipulation- The early
!envKeyguard ingetIntegrationCredentialproduces the same error as the old code path (wheredbLookupreturnednull→ throw) - All existing public function signatures are preserved
🕵️ claude-code · claude-opus-4-6 · run details
Summary
CredentialResolverinterface withresolve(projectId, key)andresolveAll(projectId)methodsDbCredentialResolver(production, reads from DB via existing repository calls) andEnvCredentialResolver(worker context, reads fromprocess.env+CASCADE_CREDENTIAL_KEYS)setCredentialResolver()for test-friendly dependency injection — no moreprocess.envmanipulation in testsgetIntegrationCredential,getIntegrationCredentialOrNull,getOrgCredential,getAllProjectCredentials) preserved as thin wrappers overgetResolver()Technical Details
The
getResolver()helper auto-selects the right implementation:CASCADE_CREDENTIAL_KEYSset →EnvCredentialResolver(worker context)DbCredentialResolver(router/dashboard/test context)setCredentialResolver(mockResolver)before tests, thensetCredentialResolver(null)inafterEachto restore auto-selectionTest plan
tests/unit/config/provider.test.tscontinue to pass unchangedsetCredentialResolver,DbCredentialResolver.resolve()/resolveAll(),EnvCredentialResolver.resolve()/resolveAll()Card
https://trello.com/c/69c19856a71e27354a2b3ccc
🤖 Generated with Claude Code
🕵️ claude-code · claude-sonnet-4-6 · run details