axe/internal/db/migrations/0002_ticket_resolution.sql
2026-10-18 22:07:25 +03:00

45 lines
2.8 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 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);