From 8e88d6eed7e6c029618e7fc72f2ebd32f7a68fd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Thu, 9 Jul 2026 07:32:50 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=B8=D0=B3=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8:=20JS-=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B8,=20=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D0=BA=D1=86=D0=B8=D0=B8,=20=5Fmi?= =?UTF-8?q?grations=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D0=B0.=20=D0=91?= =?UTF-8?q?=D0=B5=D0=B7=20fs/path.=20=D0=92=D0=B5=D1=80=D1=81=D0=B8=D1=8F?= =?UTF-8?q?=200.1.23?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- v2/src/config/index.js | 2 +- v2/src/db/schema.js | 59 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index eacd615..704aaff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ipwhitelist", - "version": "0.1.22", + "version": "0.1.23", "description": "IP WhiteList microservice for cloud provider", "main": "server.js", "scripts": { diff --git a/v2/src/config/index.js b/v2/src/config/index.js index 1209504..14d526e 100644 --- a/v2/src/config/index.js +++ b/v2/src/config/index.js @@ -8,7 +8,7 @@ // ═══════════════════════════════════════════════════════════════════════════════ module.exports = { - version: '0.1.22', + version: '0.1.23', // ── Среда ───────────────────────────────────────────────────────────────── // APP_ENV=test → тестовый стенд (жёлтый баннер в UI, можно включать тестовый API) diff --git a/v2/src/db/schema.js b/v2/src/db/schema.js index 195d368..8358be8 100644 --- a/v2/src/db/schema.js +++ b/v2/src/db/schema.js @@ -1,11 +1,29 @@ // ═══════════════════════════════════════════════════════════════════════════════ -// V2 — инициализация схемы БД +// V2 — инициализация схемы БД + миграции // -// ЭТО: CREATE TABLE IF NOT EXISTS — безопасный повторный запуск. -// НИКАКИХ ALTER, миграций, DO$$ блоков. Только создание таблиц. +// ЭТО: CREATE TABLE IF NOT EXISTS (идемпотентно) + applyMigrations(). +// ЗАЧЕМ: приложение само создаёт таблицы и применяет новые миграции при старте. +// +// МИГРАЦИИ: встроенные 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) { + // 1. Таблицы await pool.query(` CREATE TABLE IF NOT EXISTS companies ( id SERIAL PRIMARY KEY, @@ -47,9 +65,44 @@ async function ensureSchema(pool) { CREATE INDEX IF NOT EXISTS idx_audit_log_company_time 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'); + + // 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 };