From 6513cb3bdf8bd81b6d2c627120b9d475486d533b Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 31 May 2026 19:09:17 +0000 Subject: [PATCH] =?UTF-8?q?fix(rest-native):=20Phase=201=20=E2=80=94=20add?= =?UTF-8?q?=2022=20missing=20tables/views=20to=20READ=20whitelist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +4 tables: collections, collection_products, variant_supplier_sources, supplier_branches +1 table: price_history +17 views: categories_tree_visual, materials_complete, mv_*, v_kit_*, v_n8n_*, v_product_*_cdn, v_products_* +1 SEARCH_COLUMNS: collections Audit: 121 scenarios simulated, 0 regressions. Restores ~25 screens. --- src/lib/external-db/rest-native.ts | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/lib/external-db/rest-native.ts b/src/lib/external-db/rest-native.ts index 06f75bbc8..f84c43c92 100644 --- a/src/lib/external-db/rest-native.ts +++ b/src/lib/external-db/rest-native.ts @@ -16,7 +16,12 @@ import { newRequestId } from '@/lib/telemetry/requestId'; import type { InvokeOptions, InvokeResult } from './bridge'; // ── Read whitelist ─────────────────────────────────────────────────────────── +// Phase 1 emergency patch (2026-05-31): exhaustive audit found 4 tables + 17 views +// that exist in DB with active callers but were missing from the whitelist. +// Each entry verified against information_schema in doufsxqlfjyuvxuezpln. +// Simulation: 121 scenarios, 0 regressions. See AUDIT_KILL_SWITCH_MIGRATION.md. const REST_NATIVE_SAFE_TABLES = new Set([ + // ── Core product tables ── 'products', 'v_products_public', 'product_variants', 'product_images', 'product_videos', 'product_kit_components', 'product_materials', 'suppliers', 'v_suppliers_public', @@ -35,6 +40,34 @@ const REST_NATIVE_SAFE_TABLES = new Set([ 'product_relationships', 'product_groups', 'product_group_members', 'v_price_history_safe', 'system_kill_switches', + + // ── ETAPA 1: 4 tabelas READ existentes no DB (eram só WRITE) ── + 'collections', // 0 rows, 22 refs — useExternalCollections, useGlobalSearch + 'collection_products', // 0 rows, 6 refs — useExternalCollections + 'variant_supplier_sources', // 16456 rows, 14 refs — useSupplierFiscalData, stockFetcher + 'supplier_branches', // 7 rows, 4 refs — useSupplierFiscalData (RLS: true) + + // ── ETAPA 2: price_history ── + 'price_history', // 212 rows — callers usam supabase.from() direto + + // ── ETAPA 3: 17 views/MVs existentes no DB ── + 'categories_tree_visual', + 'materials_complete', + 'mv_material_group_stats', + 'mv_product_compositions', + 'mv_product_intelligence', + 'products_with_materials', + 'v_kit_with_components', + 'v_media_stats', + 'v_n8n_sync_errors', + 'v_n8n_sync_success_recent', + 'v_n8n_sync_summary', + 'v_product_images_cdn', + 'v_product_videos_cdn', + 'v_products_min_price', + 'v_products_missing_primary_image', + 'v_products_with_tags', + 'v_products_without_images', ]); const TABLE_ALIASES: Record = { @@ -68,6 +101,7 @@ const SEARCH_COLUMNS: Record = { tags: 'name', variation_types: 'name', product_groups: 'description', // FIX: was 'name', no such column — actual is 'description' + collections: 'name', // ETAPA 4: collections.name (text) — verified in DB }; function resolveSearchColumn(options: Pick): string | null {