Problem
`lib/env.ts` (122 lines) is imported only for its startup-validation side effect (`import "@/lib/env"` in `app/layout.tsx:1`). Every exported helper it defines (`getDbUrl`, `getAppUrl`, `getQfClientId`, `getQfClientSecret`, `getQfAuthBase`, `getAiProvider`, `getAnthropicApiKey`, `getGeminiApiKey`, `getJwksUrl`, `getAdminQfIds`, `isProduction`, etc.) has zero callers anywhere in `app/`, `lib/`, or `store/` — confirmed via repo-wide grep. The actual call sites (`lib/infra/db.ts:5`, `lib/admin/admin-auth.ts:22`, `lib/ai/ai.ts:7,28,41-43`, `lib/auth/social-auth.ts:166-168,380`) all read `process.env.X` directly instead, duplicating the env var names and defaults `lib/env.ts` already encodes.
Impact
Two independent, drifting sources of truth for env var names/defaults exist side by side. For example, the `ANTHROPIC_MODEL` default `"claude-opus-4-7"` is hardcoded separately in both `lib/env.ts:97` and `lib/ai/ai.ts:28` — a future change to one is easily missed in the other. The module also gives a false impression of being the app's env access layer when in practice it's dead weight aside from validation.
Location
`lib/env.ts` (all getters), vs. direct `process.env` reads in `lib/infra/db.ts:5`, `lib/admin/admin-auth.ts:22`, `lib/ai/ai.ts:7,28,41-43`, `lib/auth/social-auth.ts:166-168,380`
Suggested fix
Either wire the real call sites through `lib/env.ts`'s getters so there's a single source of truth for env var names/defaults, or delete the unused getters and keep only the startup-validation logic that `layout.tsx` actually relies on.
Problem
`lib/env.ts` (122 lines) is imported only for its startup-validation side effect (`import "@/lib/env"` in `app/layout.tsx:1`). Every exported helper it defines (`getDbUrl`, `getAppUrl`, `getQfClientId`, `getQfClientSecret`, `getQfAuthBase`, `getAiProvider`, `getAnthropicApiKey`, `getGeminiApiKey`, `getJwksUrl`, `getAdminQfIds`, `isProduction`, etc.) has zero callers anywhere in `app/`, `lib/`, or `store/` — confirmed via repo-wide grep. The actual call sites (`lib/infra/db.ts:5`, `lib/admin/admin-auth.ts:22`, `lib/ai/ai.ts:7,28,41-43`, `lib/auth/social-auth.ts:166-168,380`) all read `process.env.X` directly instead, duplicating the env var names and defaults `lib/env.ts` already encodes.
Impact
Two independent, drifting sources of truth for env var names/defaults exist side by side. For example, the `ANTHROPIC_MODEL` default `"claude-opus-4-7"` is hardcoded separately in both `lib/env.ts:97` and `lib/ai/ai.ts:28` — a future change to one is easily missed in the other. The module also gives a false impression of being the app's env access layer when in practice it's dead weight aside from validation.
Location
`lib/env.ts` (all getters), vs. direct `process.env` reads in `lib/infra/db.ts:5`, `lib/admin/admin-auth.ts:22`, `lib/ai/ai.ts:7,28,41-43`, `lib/auth/social-auth.ts:166-168,380`
Suggested fix
Either wire the real call sites through `lib/env.ts`'s getters so there's a single source of truth for env var names/defaults, or delete the unused getters and keep only the startup-validation logic that `layout.tsx` actually relies on.