<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

/**
 * Путь А (Managed PG): пересчёт hash-цепочки аудита без session_replication_role
 * (superuser-only, недоступен в управляемой базе Яндекса).
 *
 * audit_block_mutation() теперь пропускает мутацию при метке app.audit_rebuild='on'
 * И (superuser — для dev/test postgres) ИЛИ (членство в crm_migrator — покрывает
 * crm_supplier_worker, под которым AuditRebuildChain идёт на проде через pgsql_supplier).
 * Проверка членства защищена EXISTS-гардом, чтобы не падать на dev, где роли crm_* нет.
 *
 * Поведение append-only сохранено: без метки любой UPDATE/DELETE аудита запрещён.
 * См. docs/superpowers/findings/2026-06-26-db-migration/etap1-sandbox-results.md (шов C).
 */
return new class extends Migration
{
    public function up(): void
    {
        DB::unprepared(<<<'SQL'
        CREATE OR REPLACE FUNCTION public.audit_block_mutation()
        RETURNS trigger LANGUAGE plpgsql AS $function$
        BEGIN
          IF current_setting('app.audit_rebuild', true) = 'on' THEN
            -- dev/test: postgres superuser
            IF (SELECT rolsuper FROM pg_roles WHERE rolname = current_user) THEN
              RETURN COALESCE(NEW, OLD);
            END IF;
            -- managed: член crm_migrator (в т.ч. crm_supplier_worker)
            IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'crm_migrator') THEN
              IF pg_has_role(current_user, 'crm_migrator', 'MEMBER') THEN
                RETURN COALESCE(NEW, OLD);
              END IF;
            END IF;
          END IF;
          RAISE EXCEPTION 'audit log is append-only (table %): UPDATE/DELETE forbidden', TG_TABLE_NAME
              USING ERRCODE = 'check_violation';
        END;
        $function$;
        SQL);
    }

    public function down(): void
    {
        DB::unprepared(<<<'SQL'
        CREATE OR REPLACE FUNCTION public.audit_block_mutation()
        RETURNS trigger LANGUAGE plpgsql AS $function$
        BEGIN
            RAISE EXCEPTION 'audit log is append-only (table %): UPDATE/DELETE forbidden', TG_TABLE_NAME
                USING ERRCODE = 'check_violation';
        END;
        $function$;
        SQL);
    }
};
