axe/internal/db/migrations/0002_ticket_resolution.sql

45 lines
2.8 KiB
MySQL
Raw Normal View History

2026-10-18 19:07:25 +00:00
-- 0002_ticket_resolution — закрытие цикла заявки.
--
-- Семантика (см. README):
-- * confirm (клиент, из done) -> closed + confirmed_at — работа принята;
-- * reject (клиент, из done) -> rejected — НЕ финал, нужна доработка;
-- * cancel (клиент/админ) -> closed + cancel_reason — окончательный отказ/отмена.
-- Финал у заявки всегда один — статус 'closed'; исход различают
-- confirmed_at (принято клиентом) и cancel_reason (отменено/отклонено).
--
-- Как и в 0001, применённый файл редактировать нельзя: раннер хранит checksum.
-- ============ новые колонки ============
ALTER TABLE tickets ADD COLUMN IF NOT EXISTS reject_reason text;
ALTER TABLE tickets ADD COLUMN IF NOT EXISTS cancel_reason text;
ALTER TABLE tickets ADD COLUMN IF NOT EXISTS rejected_at timestamptz;
ALTER TABLE tickets ADD COLUMN IF NOT EXISTS closed_by uuid REFERENCES profiles (id);
ALTER TABLE tickets ADD COLUMN IF NOT EXISTS rework_count integer NOT NULL DEFAULT 0;
-- ============ ограничения ============
-- Было: (worker_id IS NULL) = (status = 'new').
-- Отмена заявки в статусе 'new' даёт 'closed' при worker_id = NULL,
-- поэтому «свободная ⇔ new» перестаёт работать. Новое правило:
-- мастер обязателен во всех статусах, кроме 'new' и закрытых.
ALTER TABLE tickets DROP CONSTRAINT IF EXISTS tickets_free_iff_new;
ALTER TABLE tickets ADD CONSTRAINT tickets_needs_worker
CHECK (status IN ('new', 'closed') OR worker_id IS NOT NULL);
-- Достигнутый статус обязан иметь свой таймстамп.
ALTER TABLE tickets DROP CONSTRAINT IF EXISTS tickets_rejected_time;
ALTER TABLE tickets ADD CONSTRAINT tickets_rejected_time
CHECK (status <> 'rejected' OR rejected_at IS NOT NULL);
-- Отклонение возможно только из 'done' и всегда с причиной:
-- мастер должен понимать, что переделывать.
ALTER TABLE tickets DROP CONSTRAINT IF EXISTS tickets_rejected_reason;
ALTER TABLE tickets ADD CONSTRAINT tickets_rejected_reason
CHECK (status <> 'rejected' OR (reject_reason IS NOT NULL AND done_at IS NOT NULL));
-- Закрытая заявка либо принята клиентом, либо отменена с указанием причины.
ALTER TABLE tickets DROP CONSTRAINT IF EXISTS tickets_closed_reason;
ALTER TABLE tickets ADD CONSTRAINT tickets_closed_reason
CHECK (status <> 'closed' OR confirmed_at IS NOT NULL OR cancel_reason IS NOT NULL);