From 8ccf5d955dca5b7182f4fac5e1dcb4740d65b321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 10 Jul 2026 05:16:08 +0300 Subject: [PATCH] =?UTF-8?q?fix(supplier):=20=D0=BC=D0=B8=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20supplier=5Forder=5Fchecks=20=E2=80=94=20pg?= =?UTF-8?q?sql=5Fsupplier=20+=20=D0=B8=D0=BD=D0=BB=D0=B0=D0=B9=D0=BD-GRANT?= =?UTF-8?q?=20crm=5Fsupplier=5Fworker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit По rls-ревью: соседние SaaS-supplier-таблицы (supplier_sync_runs/deferred_sync) создаются через pgsql_supplier + GRANT SELECT,INSERT + USAGE на sequence для crm_supplier_worker в DO-блоке с IF EXISTS. Дефолтный Schema::create оставлял таблицу во владении crm_migrator без грантов → VerifySupplierOrderJob упал бы permission denied на боевом Managed PG. Приведено к паттерну + SaaS-коммент + CHECK status. Co-Authored-By: Claude Opus 4.8 (1M context) --- ...09_190000_create_supplier_order_checks.php | 63 ++++++++++++++----- docs/observer/STATUS.md | 6 +- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/app/database/migrations/2026_07_09_190000_create_supplier_order_checks.php b/app/database/migrations/2026_07_09_190000_create_supplier_order_checks.php index dd67ba51..f4cbacbe 100644 --- a/app/database/migrations/2026_07_09_190000_create_supplier_order_checks.php +++ b/app/database/migrations/2026_07_09_190000_create_supplier_order_checks.php @@ -3,32 +3,61 @@ declare(strict_types=1); use Illuminate\Database\Migrations\Migration; -use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\Schema; +use Illuminate\Support\Facades\DB; +/** + * supplier_order_checks — история итоговой проверки заказа у поставщика. + * + * VerifySupplierOrderJob после ночного прогона робота перечитывает живой кабинет + * поставщика и сверяет каждую нашу строку с формулой; результат + * (ok / mismatch / unable_to_verify + список расхождений) пишется сюда одной строкой. + * + * Системная таблица (как supplier_sync_runs / supplier_deferred_sync) — без RLS/ + * tenant_id, пишет supplier-flow джоб под crm_supplier_worker (BYPASSRLS), читает SaaS-admin. + * Создаётся через pgsql_supplier + инлайн-GRANT (guard IF EXISTS) — на проде миграции + * катит crm_migrator, поэтому дефолтные привилегии crm_supplier_worker не наследуются. + * + * Spec: docs/superpowers/specs/2026-07-09-supplier-order-verification-and-deadline-watch-design.md §6. + */ return new class extends Migration { public function up(): void { - Schema::create('supplier_order_checks', function (Blueprint $table): void { - $table->bigIncrements('id'); - $table->timestampTz('checked_at'); - $table->unsignedBigInteger('sync_run_id')->nullable(); - $table->integer('intended_rows')->default(0); - $table->integer('live_rows')->default(0); - $table->integer('mismatch_count')->default(0); - // ok | mismatch | unable_to_verify - $table->string('status', 32); - $table->jsonb('details')->nullable(); - $table->timestampTz('created_at')->useCurrent(); + $supplier = DB::connection('pgsql_supplier'); - $table->index('checked_at'); - $table->index('status'); - }); + $supplier->statement(<<<'SQL' + CREATE TABLE IF NOT EXISTS supplier_order_checks ( + id BIGSERIAL PRIMARY KEY, + checked_at TIMESTAMPTZ NOT NULL, + sync_run_id BIGINT, + intended_rows INTEGER NOT NULL DEFAULT 0, + live_rows INTEGER NOT NULL DEFAULT 0, + mismatch_count INTEGER NOT NULL DEFAULT 0, + status VARCHAR(32) NOT NULL + CHECK (status IN ('ok','mismatch','unable_to_verify')), + details JSONB, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + ) + SQL); + $supplier->statement('CREATE INDEX IF NOT EXISTS idx_supplier_order_checks_checked ON supplier_order_checks (checked_at DESC)'); + $supplier->statement('CREATE INDEX IF NOT EXISTS idx_supplier_order_checks_status ON supplier_order_checks (status)'); + + foreach (['crm_supplier_worker'] as $role) { + $supplier->statement(<<statement('DROP TABLE IF EXISTS supplier_order_checks CASCADE'); } }; diff --git a/docs/observer/STATUS.md b/docs/observer/STATUS.md index 29c08b98..9d7e9259 100644 --- a/docs/observer/STATUS.md +++ b/docs/observer/STATUS.md @@ -1,6 +1,6 @@ # Brain Status (auto-generated) -Last updated: 2026-07-10T01:43:47.562Z +Last updated: 2026-07-10T01:58:51.729Z | Контролёр | Состояние | Детали | |---|---|---| @@ -112,8 +112,8 @@ Episodes since last run: 542 / threshold: 10 | PID | Имя | CPU-время | Возраст | |---|---|---|---| -| 11216 | MsMpEng | 2.69ч | NaNч | -| 10400 | Code | 1.98ч | NaNч | +| 11216 | MsMpEng | 2.76ч | 0.0ч | +| 10400 | Code | 2.00ч | 0.0ч | ⚠️ Проверь, не «осиротевшие» ли это процессы от завершённых Claude-сессий.