require("dotenv").config({ quiet: true }); const fs = require("fs").promises; const path = require("path"); const { Pool } = require("pg"); const ROOT_DIR = path.join(__dirname, ".."); const SCHEMA_PATH = path.join(ROOT_DIR, "db", "schema.sql"); const getConfig = () => ({ host: process.env.DB_HOST, port: Number(process.env.DB_PORT || 5432), database: process.env.DB_DATABASE, user: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, ssl: process.env.DB_SSL === "1" ? { rejectUnauthorized: false } : false, }); const validateConfig = (config) => { const missing = ["host", "database", "user", "password"].filter((key) => !config[key]); if (missing.length) { throw new Error(`Missing PostgreSQL envs: ${missing.join(", ")}`); } }; const run = async () => { const config = getConfig(); validateConfig(config); const sql = await fs.readFile(SCHEMA_PATH, "utf-8"); const pool = new Pool(config); try { await pool.query("SELECT 1"); await pool.query(sql); console.log("Schema applied successfully."); } finally { await pool.end(); } }; run().catch((error) => { console.error("Failed to apply schema:", error.message); const msg = String(error.message || ""); if (error.code === "28P01" || /password authentication failed/i.test(msg)) { console.error( "\n[DB 인증 실패] .env의 DB_USERNAME·DB_PASSWORD가 PostgreSQL에 등록된 사용자·비밀번호와 일치하는지 확인하세요.", ); console.error( " (원격 DB면 관리자에게 계정을 확인하고, 로컬이면 `sudo -u postgres psql`에서 \\password 사용자명 으로 비밀번호를 맞추세요.)", ); } else if (/ECONNREFUSED|ENOTFOUND/i.test(msg) || error.code === "ECONNREFUSED") { console.error("\n[DB 연결 불가] DB_HOST·DB_PORT가 맞는지, 방화벽·PostgreSQL listen_addresses를 확인하세요."); } else if (error.code === "28000" || /role .* does not exist/i.test(msg)) { console.error( "\n[DB 사용자 없음] .env의 DB_USERNAME에 해당하는 PostgreSQL 역할(role)이 서버에 없습니다.", ); console.error( " 슈퍼유저로 접속해 CREATE ROLE ... LOGIN PASSWORD '...'; 및 GRANT를 실행하거나, db/bootstrap-role.sql.example을 참고하세요.", ); } process.exit(1); });