From 56cbd1b75c0be4a3e4f009d35d05b35d94de8d34 Mon Sep 17 00:00:00 2001 From: byeong Date: Thu, 16 Apr 2026 19:15:04 +0900 Subject: [PATCH] =?UTF-8?q?fix(web):=20neon=20lazy=20init=20=ED=8C=A8?= =?UTF-8?q?=ED=84=B4=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/shared/db/index.ts | 25 ++++++++++++++++++++++--- apps/web/vitest.config.mts | 4 +--- apps/web/vitest.setup.ts | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 apps/web/vitest.setup.ts diff --git a/apps/web/src/shared/db/index.ts b/apps/web/src/shared/db/index.ts index 1be305d9..e24853e5 100644 --- a/apps/web/src/shared/db/index.ts +++ b/apps/web/src/shared/db/index.ts @@ -2,6 +2,25 @@ import { neon } from "@neondatabase/serverless"; import { drizzle } from "drizzle-orm/neon-http"; import * as scheme from "./scheme"; -// biome-ignore lint: 환경변수는 서버에서만 접근 가능하므로 안전하다. -const sql = neon(process.env.DATABASE_URL!); -export const db = drizzle({ client: sql, schema: scheme }); +// DB 인스턴스를 처음 사용할 때까지 초기화를 지연합니다. +// 모듈 import 시점에 neon()을 호출하면 환경변수가 아직 준비되지 않은 +// 환경(테스트, 일부 번들러)에서 에러가 발생하기 때문입니다. +type DB = ReturnType>; +let _db: DB | undefined; + +function getDb(): DB { + if (!_db) { + // biome-ignore lint: 환경변수는 서버에서만 접근 가능하므로 안전하다. + const sql = neon(process.env.DATABASE_URL!); + _db = drizzle({ client: sql, schema: scheme }); + } + return _db; +} + +// Proxy를 통해 db.query, db.insert 등 기존 호출부를 그대로 유지하면서 +// 실제 접근이 일어날 때 getDb()로 초기화를 트리거합니다. +export const db = new Proxy({} as DB, { + get(_, prop) { + return getDb()[prop as keyof DB]; + }, +}); diff --git a/apps/web/vitest.config.mts b/apps/web/vitest.config.mts index 531b0ded..829cedc3 100644 --- a/apps/web/vitest.config.mts +++ b/apps/web/vitest.config.mts @@ -6,8 +6,6 @@ export default defineConfig({ plugins: [tsconfigPaths(), react()], test: { environment: "jsdom", - env: { - DATABASE_URL: "postgresql://test:test@localhost:5432/test", - }, + setupFiles: ["./vitest.setup.ts"], }, }); diff --git a/apps/web/vitest.setup.ts b/apps/web/vitest.setup.ts new file mode 100644 index 00000000..b3e15d1f --- /dev/null +++ b/apps/web/vitest.setup.ts @@ -0,0 +1,15 @@ +import { vi } from "vitest"; + +// 테스트 환경(jsdom)에서는 실제 DB 연결이 없으므로 +// @/shared/db 모듈 전체를 가짜(mock)로 대체합니다. +// 각 테스트 파일에서 vi.mocked(db.insert).mockResolvedValue(...) 등으로 +// 원하는 반환값을 설정할 수 있습니다. +vi.mock("@/shared/db", () => ({ + db: { + query: {}, + insert: vi.fn(), + update: vi.fn(), + delete: vi.fn(), + select: vi.fn(), + }, +}));