Миграции: JS-строки, транзакции, _migrations таблица. Без fs/path. Версия 0.1.23
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ipwhitelist",
|
"name": "ipwhitelist",
|
||||||
"version": "0.1.22",
|
"version": "0.1.23",
|
||||||
"description": "IP WhiteList microservice for cloud provider",
|
"description": "IP WhiteList microservice for cloud provider",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
// ═══════════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
version: '0.1.22',
|
version: '0.1.23',
|
||||||
|
|
||||||
// ── Среда ─────────────────────────────────────────────────────────────────
|
// ── Среда ─────────────────────────────────────────────────────────────────
|
||||||
// APP_ENV=test → тестовый стенд (жёлтый баннер в UI, можно включать тестовый API)
|
// APP_ENV=test → тестовый стенд (жёлтый баннер в UI, можно включать тестовый API)
|
||||||
|
|||||||
+56
-3
@@ -1,11 +1,29 @@
|
|||||||
// ═══════════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════════
|
||||||
// V2 — инициализация схемы БД
|
// V2 — инициализация схемы БД + миграции
|
||||||
//
|
//
|
||||||
// ЭТО: CREATE TABLE IF NOT EXISTS — безопасный повторный запуск.
|
// ЭТО: CREATE TABLE IF NOT EXISTS (идемпотентно) + applyMigrations().
|
||||||
// НИКАКИХ ALTER, миграций, DO$$ блоков. Только создание таблиц.
|
// ЗАЧЕМ: приложение само создаёт таблицы и применяет новые миграции при старте.
|
||||||
|
//
|
||||||
|
// МИГРАЦИИ: встроенные SQL-строки, не из файлов.
|
||||||
|
// Каждая в транзакции (BEGIN/COMMIT), ошибка логируется и пропускается.
|
||||||
|
// Без fs, path, process.exit.
|
||||||
// ═══════════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
// ── Миграции (упорядочены, выполняются один раз) ──────────────────────────────
|
||||||
|
const MIGRATIONS = [
|
||||||
|
{
|
||||||
|
name: '001_add_impersonated_by',
|
||||||
|
sql: `ALTER TABLE audit_log ADD COLUMN IF NOT EXISTS impersonated_by VARCHAR(255) DEFAULT NULL`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '002_add_audit_restore',
|
||||||
|
sql: `ALTER TABLE audit_log DROP CONSTRAINT IF EXISTS audit_log_action_check;
|
||||||
|
ALTER TABLE audit_log ADD CONSTRAINT audit_log_action_check CHECK (action IN ('CREATE','UPDATE','DELETE','RESTORE'))`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
async function ensureSchema(pool) {
|
async function ensureSchema(pool) {
|
||||||
|
// 1. Таблицы
|
||||||
await pool.query(`
|
await pool.query(`
|
||||||
CREATE TABLE IF NOT EXISTS companies (
|
CREATE TABLE IF NOT EXISTS companies (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
@@ -47,9 +65,44 @@ async function ensureSchema(pool) {
|
|||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_audit_log_company_time
|
CREATE INDEX IF NOT EXISTS idx_audit_log_company_time
|
||||||
ON audit_log(company_id, created_at DESC);
|
ON audit_log(company_id, created_at DESC);
|
||||||
|
|
||||||
|
-- Таблица учёта выполненных миграций
|
||||||
|
CREATE TABLE IF NOT EXISTS _migrations (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR(255) UNIQUE NOT NULL,
|
||||||
|
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
`);
|
`);
|
||||||
|
|
||||||
console.log('[db] Schema ensured');
|
console.log('[db] Schema ensured');
|
||||||
|
|
||||||
|
// 2. Миграции
|
||||||
|
await applyMigrations(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function applyMigrations(pool) {
|
||||||
|
try {
|
||||||
|
const done = new Set(
|
||||||
|
(await pool.query('SELECT name FROM _migrations')).rows.map(r => r.name)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const m of MIGRATIONS) {
|
||||||
|
if (done.has(m.name)) continue;
|
||||||
|
try {
|
||||||
|
await pool.query('BEGIN');
|
||||||
|
await pool.query(m.sql);
|
||||||
|
await pool.query('INSERT INTO _migrations (name) VALUES ($1)', [m.name]);
|
||||||
|
await pool.query('COMMIT');
|
||||||
|
console.log('[db] Migration applied:', m.name);
|
||||||
|
} catch (e) {
|
||||||
|
await pool.query('ROLLBACK').catch(() => {});
|
||||||
|
console.error('[db] Migration failed:', m.name, e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[db] applyMigrations error:', e.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { ensureSchema };
|
module.exports = { ensureSchema };
|
||||||
|
module.exports = { ensureSchema };
|
||||||
|
|||||||
Reference in New Issue
Block a user