-- Таблицы админки (Блок 4.1): шаблоны сообщений, история изменений и расписания. -- Схема bot.* уже создана миграцией V1. -- Тексты сообщений: источник правды для админки (бот подключается в 4.5). CREATE TABLE IF NOT EXISTS bot.message_templates ( key text PRIMARY KEY, text text NOT NULL, description text NOT NULL DEFAULT '', enabled boolean NOT NULL DEFAULT true, updated_at timestamptz NOT NULL DEFAULT now(), updated_by bigint ); COMMENT ON TABLE bot.message_templates IS 'Шаблоны сообщений бота (редактируются в админке)'; COMMENT ON COLUMN bot.message_templates.key IS 'Стабильный ключ шаблона (например, info.help)'; COMMENT ON COLUMN bot.message_templates.updated_by IS 'Telegram-ID администратора, последним изменившего текст'; -- История правок: старые значения и автор (аудит + откат). CREATE TABLE IF NOT EXISTS bot.message_template_history ( id bigserial PRIMARY KEY, key text NOT NULL REFERENCES bot.message_templates (key) ON DELETE CASCADE, old_text text, new_text text NOT NULL, editor_id bigint, changed_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_template_history_key_time ON bot.message_template_history (key, changed_at DESC); COMMENT ON TABLE bot.message_template_history IS 'История изменений шаблонов (кто, когда, старое и новое значение)'; -- Расписания рассылок: редактирует админка, исполняет бот (4.5). CREATE TABLE IF NOT EXISTS bot.schedules ( id bigserial PRIMARY KEY, template_key text NOT NULL REFERENCES bot.message_templates (key) ON DELETE RESTRICT, hour smallint NOT NULL CHECK (hour BETWEEN 0 AND 23), minute smallint NOT NULL CHECK (minute BETWEEN 0 AND 59), weekdays smallint[] NOT NULL DEFAULT '{}', timezone text NOT NULL DEFAULT 'Europe/Moscow', enabled boolean NOT NULL DEFAULT true, description text NOT NULL DEFAULT '', updated_at timestamptz NOT NULL DEFAULT now(), updated_by bigint ); COMMENT ON TABLE bot.schedules IS 'Расписания рассылок (исполняет бот, редактирует админка)'; COMMENT ON COLUMN bot.schedules.weekdays IS 'Дни недели 1..7 (ISO, 1 = понедельник); пусто — каждый день'; -- История изменений расписаний: снимок строки до и после правки. -- FK с SET NULL: история должна пережить удаление самого расписания. CREATE TABLE IF NOT EXISTS bot.schedules_history ( id bigserial PRIMARY KEY, schedule_id bigint REFERENCES bot.schedules (id) ON DELETE SET NULL, old_data jsonb, new_data jsonb, editor_id bigint, changed_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_schedules_history_schedule_time ON bot.schedules_history (schedule_id, changed_at DESC); COMMENT ON TABLE bot.schedules_history IS 'История изменений расписаний (аудит)';