-- ═══════════════════════════════════════════════════════════════════════════════ -- V2 schema — отдельные таблицы, не пересекаются с основным приложением -- ═══════════════════════════════════════════════════════════════════════════════ -- Компании (по W-номеру = client_id) CREATE TABLE IF NOT EXISTS v2_companies ( id SERIAL PRIMARY KEY, client_id VARCHAR(64) UNIQUE NOT NULL, -- WZ01112, WZ03709 ... name VARCHAR(255), -- название компании custom_limit INTEGER DEFAULT NULL -- NULL = использовать DEFAULT_LIMIT CHECK (custom_limit IS NULL OR custom_limit >= 0), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Записи белого списка (soft delete через deleted_at) CREATE TABLE IF NOT EXISTS v2_entries ( id SERIAL PRIMARY KEY, company_id INTEGER NOT NULL REFERENCES v2_companies(id) ON DELETE RESTRICT, value_cidr VARCHAR(18) NOT NULL -- формат: x.x.x.x/xx (CIDR или /32) CHECK (value_cidr ~ '^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$'), comment VARCHAR(255), created_by VARCHAR(255) NOT NULL, -- email создателя created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_by VARCHAR(255), updated_at TIMESTAMPTZ, deleted_by VARCHAR(255), deleted_at TIMESTAMPTZ ); -- Уникальность: в одной компании не может быть двух активных записей с одинаковым CIDR CREATE UNIQUE INDEX IF NOT EXISTS uq_v2_entries_active_cidr ON v2_entries(company_id, value_cidr) WHERE deleted_at IS NULL; -- Быстрый список активных записей компании CREATE INDEX IF NOT EXISTS idx_v2_entries_active ON v2_entries(company_id, created_at DESC) WHERE deleted_at IS NULL; -- Аудит (неизменяемый журнал) CREATE TABLE IF NOT EXISTS v2_audit ( id SERIAL PRIMARY KEY, user_email VARCHAR(255) NOT NULL, -- кто совершил действие company_id INTEGER NOT NULL, -- в какой компании action VARCHAR(32) NOT NULL -- CREATE, UPDATE, DELETE CHECK (action IN ('CREATE','UPDATE','DELETE')), old_value TEXT, -- предыдущий CIDR (для UPDATE) new_value TEXT, -- новый CIDR entry_id INTEGER, -- id записи в v2_entries impersonated_by VARCHAR(255), -- кто реально (если имперсонация) created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_v2_audit_company_time ON v2_audit(company_id, created_at DESC);