Centralize environment variable access through CONFIG - #3
Conversation
## Problem The codebase had inconsistent environment variable access patterns: - Direct `process.env` access in multiple files (llm_client.ts, groq tests, vitest.config.ts) - Tests manipulating `process.env` directly, causing side effects between tests - No single source of truth for environment configuration - Vitest config importing dotenv separately from the rest of the application This made the code harder to test, maintain, and reason about. Mock strategies were fragile and required manual process.env manipulation. ## Solution Centralized all environment variable access through the CONFIG object in config.ts: 1. **Added TEST.SCOPE configuration**: New `TEST_SCOPE` environment variable in CONFIG.TEST for controlling test execution scope 2. **Updated llm_client.ts**: Changed from `process.env.GROQ_API_KEY` to `CONFIG.GROQ.API_KEY` 3. **Updated groq integration tests**: Use CONFIG instead of direct process.env access 4. **Updated vitest.config.ts**: Import CONFIG instead of dotenv, use `CONFIG.TEST.SCOPE` instead of `process.env.TEST_SCOPE` 5. **Improved unit test mocking**: - groq-default unit test now mocks CONFIG module instead of manipulating process.env - reranker unit test uses vi.doMock to properly isolate CONFIG changes 6. **Updated groq provider JSDoc**: Example now shows CONFIG usage instead of process.env 7. **Removed obsolete comment**: Deleted incorrect comment about RerankerConfig in types.ts ## Benefits - **Single source of truth**: All environment variables accessed through CONFIG - **Better testability**: Tests mock CONFIG module instead of global process.env - **Type safety**: CONFIG provides typed access to all configuration - **Cleaner tests**: No more side effects from process.env manipulation - **Consistent patterns**: All files follow the same configuration access pattern - **Better documentation**: Examples and tests demonstrate the correct usage pattern ## Implementation Details - Used Vitest's `vi.doMock` for isolating CONFIG changes in tests that need different values - Maintained backward compatibility - all existing environment variables work the same way - Integration tests properly skip when GROQ_API_KEY is not available using CONFIG check - vitest.config.ts now imports CONFIG directly, eliminating duplicate dotenv loading ## Edge Cases Handled - Empty string API keys are treated as missing (falsy check remains) - Test scope defaults to "all" if not specified - Module isolation in unit tests prevents cross-test pollution 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Claude finished @stevekrenzel's task —— View job Code Review: Centralize environment variable access through CONFIGReview Tasks
SummaryThis PR successfully centralizes environment variable access through the CONFIG object. The implementation is solid and improves testability. However, there are a few areas where the code doesn't fully comply with the Intent library's strict engineering standards. 🟢 Strengths
🟡 Issues Found1. Missing Braces on If Statements (vitest.config.ts:33-42)Severity: High - Violates mandatory code style The ternary operator on lines 33-42 creates an implicit single-branch structure that should use braces: // Current (lines 33-42)
...(scope === "int"
? {}
: {
thresholds: {
lines: 100,
statements: 100,
functions: 100,
branches: 100,
},
}),Why this matters: While this is a ternary (not an if statement), the CLAUDE.md guidelines emphasize "Always use braces" to avoid single-line conditionals. This structure is functionally equivalent to a conditional branch and should be refactored for consistency. Suggested fix: Extract this logic into a helper function with explicit early returns: function getCoverageThresholds(scope: string) {
if (scope === "int") {
return {};
}
return {
thresholds: {
lines: 100,
statements: 100,
functions: 100,
branches: 100,
},
};
}
// Then in config:
coverage: {
...baseCoverageConfig,
...getCoverageThresholds(scope),
}2. Missing JSDoc Documentation (config.ts:7-23)Severity: Medium - Violates "Document Everything" principle The CONFIG object lacks JSDoc documentation explaining:
Suggested addition (before line 7): /**
* Global configuration object for Intent library.
*
* Centralizes all environment variable access with type-safe defaults.
* Values are loaded once at module initialization via dotenv/config.
*
* In tests, mock this module using vi.doMock() to override values:
*
* @example
* ```typescript
* vi.doMock("./config", () => ({
* CONFIG: {
* GROQ: { API_KEY: "test-key" },
* // ... rest of config
* },
* }));
* ```
*
* @see lib/config for the underlying config helpers
*/
export const CONFIG = {3. Missing JSDoc on TEST.SCOPE (config.ts:20-22)Severity: Low - New config property should be documented The new Suggested fix (before line 20): TEST: {
/** Test execution scope: "unit", "int", or "all" (default) */
SCOPE: string("TEST_SCOPE", { default: "all" }),
},4. Ternary Chain Could Be Simplified (vitest.config.ts:6-11)Severity: Low - Minor readability issue The nested ternary for Current (lines 6-11): const includePatterns =
scope === "unit"
? ["src/**/*.unit.test.ts"]
: scope === "int"
? ["src/**/*.int.test.ts"]
: ["src/**/*.unit.test.ts", "src/**/*.int.test.ts"];Suggested refactor: /**
* Get test file patterns based on scope.
*
* @param scope - Test scope from CONFIG
* @returns Array of glob patterns for test files
* @private
*/
function getTestPatterns(scope: string): string[] {
if (scope === "unit") {
return ["src/**/*.unit.test.ts"];
}
if (scope === "int") {
return ["src/**/*.int.test.ts"];
}
return ["src/**/*.unit.test.ts", "src/**/*.int.test.ts"];
}
const includePatterns = getTestPatterns(scope);This follows the "early returns with braces" pattern and makes the logic more testable. ✅ Code Quality Checklist
📝 Additional Observations
🎯 RecommendationApprove with minor revisions. The architectural change is excellent and the implementation is solid. The issues found are style/documentation violations that should be addressed to maintain the library's strict quality standards, but they don't affect functionality. Priority fixes:
The core change - centralizing CONFIG access - is implemented correctly and significantly improves the codebase. |
Problem
The codebase had inconsistent environment variable access patterns:
process.envaccess in multiple files (llm_client.ts, groq tests, vitest.config.ts)process.envdirectly, causing side effects between testsThis made the code harder to test, maintain, and reason about. Mock strategies were fragile and required manual process.env manipulation.
Solution
Centralized all environment variable access through the CONFIG object in config.ts:
TEST_SCOPEenvironment variable in CONFIG.TEST for controlling test execution scopeprocess.env.GROQ_API_KEYtoCONFIG.GROQ.API_KEYCONFIG.TEST.SCOPEinstead ofprocess.env.TEST_SCOPEBenefits
Implementation Details
vi.doMockfor isolating CONFIG changes in tests that need different valuesEdge Cases Handled
🤖 Generated with Claude Code