d543fb5585
Единственный канал создания тикета — кнопка "Поддержка" в Telegram-боте: переводит юзера в разовый режим ожидания (awaiting_support_message), следующее свободное сообщение становится тикетом/ответом в уже открытый (случайный текст мимо кнопки по-прежнему игнорируется бота). Саппорты отвечают из веб-админки, ответ уходит юзеру обратно в тот же Telegram-чат. Новая роль support видит только раздел тикетов (support_access_guard) — создаётся только Owner'ом. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
42 lines
2.5 KiB
SQL
42 lines
2.5 KiB
SQL
-- =====================================================================
|
|
-- ТЕХПОДДЕРЖКА: роль Support + тикеты через Telegram-бота
|
|
-- =====================================================================
|
|
-- Единственный канал связи с поддержкой — бот (см. src/bot.rs). Кнопка
|
|
-- "Поддержка" переводит юзера в разовый режим ожидания сообщения
|
|
-- (awaiting_support_message), сбрасывается сразу после получения текста —
|
|
-- случайное сообщение мимо кнопки тикет не создаёт.
|
|
ALTER TABLE users DROP CONSTRAINT IF EXISTS users_role_check;
|
|
ALTER TABLE users
|
|
ADD CONSTRAINT users_role_check
|
|
CHECK (role IN ('user', 'owner', 'moderator', 'partner', 'support', 'admin'));
|
|
|
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS awaiting_support_message BOOLEAN NOT NULL DEFAULT FALSE;
|
|
|
|
CREATE TABLE IF NOT EXISTS support_tickets (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'closed')),
|
|
-- Информационно: кто последним ответил. Не enforced-назначение — любой
|
|
-- staff/support видит и отвечает на любой тикет.
|
|
assigned_to UUID REFERENCES users(id),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_support_tickets_status ON support_tickets(status, updated_at DESC);
|
|
-- Быстро найти "есть ли уже открытый тикет у юзера" — частичный индекс,
|
|
-- т.к. это единственный поиск по user_id, который реально нужен в горячем пути.
|
|
CREATE INDEX IF NOT EXISTS idx_support_tickets_user_open ON support_tickets(user_id)
|
|
WHERE status = 'open';
|
|
|
|
CREATE TABLE IF NOT EXISTS support_messages (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
ticket_id UUID NOT NULL REFERENCES support_tickets(id) ON DELETE CASCADE,
|
|
sender_role VARCHAR(10) NOT NULL CHECK (sender_role IN ('user', 'staff')),
|
|
sender_user_id UUID REFERENCES users(id),
|
|
body TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_support_messages_ticket ON support_messages(ticket_id, created_at);
|