import 'server-only' /** * 환경변수 검증·export 단일 진입점. * * 값은 실제로 필요해지는 시점(함수 호출 시)에만 읽고 검증한다 — 모듈 최상단에서 즉시 검증하면 * `force-dynamic` 라우트라도 `next build`의 페이지 데이터 수집 단계에서 이 모듈이 먼저 로드되어 * 운영 배포 전 로컬 빌드가 SESSION_SECRET 미설정만으로 실패할 수 있기 때문이다. * 대신 각 접근자 함수 자체가 "호출 시점" fail-fast를 보장한다 — 기본값 폴백은 없다. */ function readRequiredEnv(key: string): string { const value = process.env[key]; if (!value) { throw new Error( `환경변수 ${key}가 설정되지 않았습니다. 배포 환경에 값을 주입하세요.` ); } return value; } /** 세션 토큰 서명에 사용하는 HMAC 시크릿. 누락 시 즉시 throw(fail-fast). */ export function getSessionSecret(): string { return readRequiredEnv('SESSION_SECRET'); } /** 백엔드(edupay-backend) API 오리진. 누락 시 즉시 throw(fail-fast, 기본값 폴백 없음). */ export function getApiBaseUrl(): string { return readRequiredEnv('EDUPAY_API_BASE_URL'); } /** * 개발용 백엔드 accessToken. * * 관리자 로그인 연동(별도 작업)이 끝나면 토큰은 세션에서 나오고 이 함수는 삭제 대상이다. * 그 전까지 보호된 백엔드 API를 실제 데이터로 확인할 수 있게 하는 임시 우회로이며, * 운영에서는 키가 있더라도 읽지 않는다(fail-closed) — 개발용 토큰이 배포에 섞여 들어가도 * 운영 트래픽이 그 토큰으로 백엔드를 호출하는 일이 없어야 하기 때문이다. */ export function getDevApiAccessToken(): string | null { if (process.env.NODE_ENV === 'production') { return null; } return process.env.EDUPAY_API_ACCESS_TOKEN || null; } export type MockAdminCredentials = { loginId: string; password: string; }; /** * mock 관리자 시드 계정. 운영 환경(.env.production)에는 키를 두지 않아 * 누락 시 null을 반환 — mock 로그인이 항상 실패하도록(fail-closed) 한다. */ export function getMockAdminCredentials(): MockAdminCredentials | null { const loginId = process.env.MOCK_ADMIN_LOGIN_ID; const password = process.env.MOCK_ADMIN_PASSWORD; if (!loginId || !password) { return null; } return { loginId, password }; }