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