Files
ai_platform/scripts/apply-schema.js

63 lines
2.3 KiB
JavaScript

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);
});