diff --git a/.github/workflows/edge-integration-all.yml b/.github/workflows/edge-integration-all.yml index 4393af6f8..3fbcb0313 100644 --- a/.github/workflows/edge-integration-all.yml +++ b/.github/workflows/edge-integration-all.yml @@ -108,9 +108,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 needs: edge-integration - if: > - vars.SUPABASE_URL != '' && - secrets.SUPABASE_SERVICE_ROLE_KEY != '' + # NOTA: `secrets` NÃO é permitido em `if:` de job (compila o workflow inteiro + # como inválido → startup_failure, 0 jobs). Gate só no `vars` (permitido) e a + # presença do secret é checada por step via `env`. + if: vars.SUPABASE_URL != '' + env: + SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }} steps: - uses: actions/checkout@v5 @@ -124,14 +127,14 @@ jobs: run: npm ci - name: Run fuzz tests against live Supabase + if: env.SUPABASE_SERVICE_ROLE_KEY != '' run: node scripts/fuzz-testing.mjs env: SUPABASE_URL: ${{ vars.SUPABASE_URL || secrets.VITE_SUPABASE_URL }} - SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }} FUZZ_CONCURRENCY: "3" - name: Run upload fuzz tests against live Supabase + if: env.SUPABASE_SERVICE_ROLE_KEY != '' run: node scripts/fuzz-edge-uploads.mjs env: SUPABASE_URL: ${{ vars.SUPABASE_URL || secrets.VITE_SUPABASE_URL }} - SUPABASE_SERVICE_ROLE_KEY: ${{ secrets.SUPABASE_SERVICE_ROLE_KEY }} diff --git a/supabase/functions/visual-search/index.ts b/supabase/functions/visual-search/index.ts index 2e61f2178..0b33bd080 100644 --- a/supabase/functions/visual-search/index.ts +++ b/supabase/functions/visual-search/index.ts @@ -6,6 +6,7 @@ import { z } from '../_shared/zod-validate.ts'; import { applyRateLimit, rateLimiters } from '../_shared/rate-limiter.ts'; import { runBotProtection } from '../_shared/bot-protection.ts'; import { getOrCreateRequestId } from '../_shared/request-id.ts'; +import { resolveCredential } from '../_shared/credentials.ts'; Deno.serve(async (req) => { const corsHeaders = getCorsHeaders(req); @@ -44,7 +45,9 @@ Deno.serve(async (req) => { // 1. Authentication & Config Validation currentStep = "config_validation"; const AI_LOVABLE_API_KEY = Deno.env.get("LOVABLE_API_KEY"); - const AI_HF_ACCESS_TOKEN = Deno.env.get("HF_ACCESS_TOKEN"); + // SSOT: HF_ACCESS_TOKEN resolvido via resolveCredential (DB-first → env fallback), + // não Deno.env.get direto — alinhado com ai-recommendations/elevenlabs e o audit de credenciais. + const { value: AI_HF_ACCESS_TOKEN } = await resolveCredential("HF_ACCESS_TOKEN"); if (!AI_LOVABLE_API_KEY && !AI_HF_ACCESS_TOKEN) { throw new Error("Configuração ausente: LOVABLE_API_KEY ou HF_ACCESS_TOKEN não configurados no backend.");