docs(audit): relatório exaustivo Frontend ↔ Banco de Dados (4 P0 críticos)#69
Conversation
Auditoria gerada via Claude Code no container claude-code da VPS, cruzando código do front (React/TS) com 356 migrations Supabase locais. ESCOPO - 68 tabelas inventariadas com mapeamento de chamadores - 28 edge functions invocadas catalogadas - 35 RPCs catalogados - 9 subscriptions Realtime + 7 buckets Storage - Análise de RLS, tipos, padrões de query, histórico de migrations ACHADOS - 4 CRÍTICOS (P0): policies Allow-all em products/categories/suppliers/quotes; PII em listagem de quotes; order_items aberto para qualquer auth; audit_trail anônimo - 7 ATENÇÃO (P1/P2): 12 tabelas sem types.ts; secrets em Realtime; staleTime ausente em 67% dos hooks - 4 INFO (P3): types mortos, queryKey sem namespace, ritmo de migrations, índices Não contém mudanças de código — apenas documentação e diagnóstico. Gerado por: claude-sonnet-4-6 | duração: ~9min | leitura via MCP supabase
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 25 minutes and 46 seconds.Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 05024edb4b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| 1. **Migração urgente:** Criar migration que execute `DROP POLICY "Allow all"` nas tabelas `products`, `categories`, `suppliers` e `quotes`. Essas 4 tabelas têm policy `FOR ALL USING (true)` ativa desde `20250102000000_gifts_production.sql` que **nunca foi removida**, permitindo acesso anônimo total (leitura e escrita) — incluindo PII de clientes em `quotes`. | ||
|
|
||
| 2. **Regenerar types.ts:** Executar `supabase gen types typescript --project-id nmojwpihnslkssljowjh` para cobrir as 12 tabelas sem tipos. | ||
|
|
||
| 3. **Restringir `order_items`:** Trocar `USING (true)` por filtro baseado em organização/usuário. |
There was a problem hiding this comment.
Add
audit_trail fix to immediate-action checklist
The executive summary says there are 4 critical findings, but the Ação imediata necessária list contains only three actions and does not include remediation for the critical audit_trail anonymous SELECT exposure described in the full report. Teams that execute only this checklist can leave a P0 issue unresolved even after completing all listed urgent items.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Adds a documentation-only technical audit report describing the coupling between the React/TS frontend and the Supabase database, with prioritized security and code-quality findings.
Changes:
- Adds an executive summary for the audit report.
- Adds the full audit report covering inventory, type consistency, RLS/security findings, access patterns, schema state, and prioritized actions.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| docs/AUDIT_FRONTEND_DATABASE_summary.md | Executive summary of the frontend↔DB audit and immediate action items. |
| docs/AUDIT_FRONTEND_DATABASE.md | Full audit report with detailed inventories, RLS findings, and prioritized recommendations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| **Total: 68 tabelas únicas** (combinando aspas simples e duplas nos chamadores) | ||
|
|
||
| | # | Tabela | # | Tabela | | ||
| |---|--------|---|--------| | ||
| | 1 | `access_blocked_log` | 35 | `mcp_api_keys` | | ||
| | 2 | `access_security_settings` | 36 | `mockup_prompt_configs` | | ||
| | 3 | `admin_audit_log` | 37 | `mockup_prompt_history` | | ||
| | 4 | `art_file_attachments` | 38 | `notifications` | | ||
| | 5 | `audit_log` | 39 | `optimization_queue` | | ||
| | 6 | `bot_detection_log` | 40 | `order_items` | | ||
| | 7 | `cart_templates` | 41 | `orders` | | ||
| | 8 | `category_icons` | 42 | `outbound_webhooks` | | ||
| | 9 | `city_whitelist` | 43 | `permissions` | | ||
| | 10 | `collection_items` | 44 | `personalization_simulations` | | ||
| | 11 | `collection_items_trash` | 45 | `personalization_techniques` | | ||
| | 12 | `collections` | 46 | `product_components` | | ||
| | 13 | `component_media` | 47 | `product_group_members` | | ||
| | 14 | `custom_kits` | 48 | `product_groups` | | ||
| | 15 | `expert_conversations` | 49 | `product_views` | | ||
| | 16 | `external_connections` | 50 | `products` | | ||
| | 17 | `favorite_items` | 51 | `profiles` | | ||
| | 18 | `favorite_items_trash` | 52 | `query_telemetry` | | ||
| | 19 | `favorite_lists` | 53 | `quote_approval_tokens` | | ||
| | 20 | `generated_mockups` | 54 | `quote_comments` | | ||
| | 21 | `inbound_webhook_endpoints` | 55 | `quote_history` | | ||
| | 22 | `ip_access_control` | 56 | `quote_item_personalizations` | | ||
| | 23 | `ip_whitelist` | 57 | `quote_items` | | ||
| | 24 | `kit_collaborators` | 58 | `quote_templates` | | ||
| | 25 | `kit_comments` | 59 | `quotes` | | ||
| | 26 | `kit_templates` | 60 | `request_rate_limits` | | ||
| | 27 | `kit_variants` | 61 | `role_permissions` | | ||
| | 28 | `login_attempts` | 62 | `roles` | | ||
| | 29 | `magic_up_brand_kits` | 63 | `sales_goals` | | ||
| | 30 | `magic_up_campaigns` | 64 | `search_analytics` | | ||
| | 31 | `magic_up_generations` | 65 | `secret_rotation_log` | | ||
| | 32 | `magic_up_generations` | 66 | `seller_cart_items` | | ||
| | 33 | `magic_up_prompt_configs` | 67 | `user_passkeys` | | ||
| | 34 | `magic_up_prompt_history` | 68 | `video_variant_links` | | ||
| | | | 69 | `voice_command_logs` | | ||
| | | | 70 | `webhook_deliveries` | | ||
| | | | 71 | `workspace_notifications` | |
There was a problem hiding this comment.
A seção afirma “Total: 68 tabelas únicas”, mas a tabela listada vai até 71 itens e contém duplicata explícita (magic_up_generations aparece duas vezes). Isso deixa o inventário inconsistente (e as linhas 69–71 ficam com as duas primeiras colunas vazias). Ajustar para que (a) a lista reflita apenas as tabelas únicas e (b) a contagem e a numeração batam com o conteúdo apresentado (idealmente regenerando/deduplicando a saída).
| **Total: 68 tabelas únicas** (combinando aspas simples e duplas nos chamadores) | |
| | # | Tabela | # | Tabela | | |
| |---|--------|---|--------| | |
| | 1 | `access_blocked_log` | 35 | `mcp_api_keys` | | |
| | 2 | `access_security_settings` | 36 | `mockup_prompt_configs` | | |
| | 3 | `admin_audit_log` | 37 | `mockup_prompt_history` | | |
| | 4 | `art_file_attachments` | 38 | `notifications` | | |
| | 5 | `audit_log` | 39 | `optimization_queue` | | |
| | 6 | `bot_detection_log` | 40 | `order_items` | | |
| | 7 | `cart_templates` | 41 | `orders` | | |
| | 8 | `category_icons` | 42 | `outbound_webhooks` | | |
| | 9 | `city_whitelist` | 43 | `permissions` | | |
| | 10 | `collection_items` | 44 | `personalization_simulations` | | |
| | 11 | `collection_items_trash` | 45 | `personalization_techniques` | | |
| | 12 | `collections` | 46 | `product_components` | | |
| | 13 | `component_media` | 47 | `product_group_members` | | |
| | 14 | `custom_kits` | 48 | `product_groups` | | |
| | 15 | `expert_conversations` | 49 | `product_views` | | |
| | 16 | `external_connections` | 50 | `products` | | |
| | 17 | `favorite_items` | 51 | `profiles` | | |
| | 18 | `favorite_items_trash` | 52 | `query_telemetry` | | |
| | 19 | `favorite_lists` | 53 | `quote_approval_tokens` | | |
| | 20 | `generated_mockups` | 54 | `quote_comments` | | |
| | 21 | `inbound_webhook_endpoints` | 55 | `quote_history` | | |
| | 22 | `ip_access_control` | 56 | `quote_item_personalizations` | | |
| | 23 | `ip_whitelist` | 57 | `quote_items` | | |
| | 24 | `kit_collaborators` | 58 | `quote_templates` | | |
| | 25 | `kit_comments` | 59 | `quotes` | | |
| | 26 | `kit_templates` | 60 | `request_rate_limits` | | |
| | 27 | `kit_variants` | 61 | `role_permissions` | | |
| | 28 | `login_attempts` | 62 | `roles` | | |
| | 29 | `magic_up_brand_kits` | 63 | `sales_goals` | | |
| | 30 | `magic_up_campaigns` | 64 | `search_analytics` | | |
| | 31 | `magic_up_generations` | 65 | `secret_rotation_log` | | |
| | 32 | `magic_up_generations` | 66 | `seller_cart_items` | | |
| | 33 | `magic_up_prompt_configs` | 67 | `user_passkeys` | | |
| | 34 | `magic_up_prompt_history` | 68 | `video_variant_links` | | |
| | | | 69 | `voice_command_logs` | | |
| | | | 70 | `webhook_deliveries` | | |
| | | | 71 | `workspace_notifications` | | |
| **Total: 70 tabelas únicas** (combinando aspas simples e duplas nos chamadores) | |
| | # | Tabela | # | Tabela | | |
| |---|--------|---|--------| | |
| | 1 | `access_blocked_log` | 36 | `mockup_prompt_history` | | |
| | 2 | `access_security_settings` | 37 | `notifications` | | |
| | 3 | `admin_audit_log` | 38 | `optimization_queue` | | |
| | 4 | `art_file_attachments` | 39 | `order_items` | | |
| | 5 | `audit_log` | 40 | `orders` | | |
| | 6 | `bot_detection_log` | 41 | `outbound_webhooks` | | |
| | 7 | `cart_templates` | 42 | `permissions` | | |
| | 8 | `category_icons` | 43 | `personalization_simulations` | | |
| | 9 | `city_whitelist` | 44 | `personalization_techniques` | | |
| | 10 | `collection_items` | 45 | `product_components` | | |
| | 11 | `collection_items_trash` | 46 | `product_group_members` | | |
| | 12 | `collections` | 47 | `product_groups` | | |
| | 13 | `component_media` | 48 | `product_views` | | |
| | 14 | `custom_kits` | 49 | `products` | | |
| | 15 | `expert_conversations` | 50 | `profiles` | | |
| | 16 | `external_connections` | 51 | `query_telemetry` | | |
| | 17 | `favorite_items` | 52 | `quote_approval_tokens` | | |
| | 18 | `favorite_items_trash` | 53 | `quote_comments` | | |
| | 19 | `favorite_lists` | 54 | `quote_history` | | |
| | 20 | `generated_mockups` | 55 | `quote_item_personalizations` | | |
| | 21 | `inbound_webhook_endpoints` | 56 | `quote_items` | | |
| | 22 | `ip_access_control` | 57 | `quote_templates` | | |
| | 23 | `ip_whitelist` | 58 | `quotes` | | |
| | 24 | `kit_collaborators` | 59 | `request_rate_limits` | | |
| | 25 | `kit_comments` | 60 | `role_permissions` | | |
| | 26 | `kit_templates` | 61 | `roles` | | |
| | 27 | `kit_variants` | 62 | `sales_goals` | | |
| | 28 | `login_attempts` | 63 | `search_analytics` | | |
| | 29 | `magic_up_brand_kits` | 64 | `secret_rotation_log` | | |
| | 30 | `magic_up_campaigns` | 65 | `seller_cart_items` | | |
| | 31 | `magic_up_generations` | 66 | `user_passkeys` | | |
| | 32 | `magic_up_prompt_configs` | 67 | `video_variant_links` | | |
| | 33 | `magic_up_prompt_history` | 68 | `voice_command_logs` | | |
| | 34 | `mcp_api_keys` | 69 | `webhook_deliveries` | | |
| | 35 | `mockup_prompt_configs` | 70 | `workspace_notifications` | |
| | `commemorative-dates` | `useCommemorativeDates.ts:60` | | ||
| | `detect-new-device` | `useDeviceDetection.ts:94` | | ||
| | `dropbox-list` | `useDropboxFiles.ts:29,44` | | ||
| | `external-db-bridge` | `PublicFavoriteListPage.tsx:79` | |
There was a problem hiding this comment.
A tabela de Edge Functions tem uma entrada duplicada para external-db-bridge (aparece em duas linhas). Isso pode inflar/invalidar a contagem de “28 invocadas” e dificulta leitura. Consolidar em uma única linha (unindo a lista de arquivos/linhas) e garantir que os totais reflitam entradas únicas.
| | `external-db-bridge` | `PublicFavoriteListPage.tsx:79` | | |
| | `external-db-bridge` | `PublicFavoriteListPage.tsx:79` *(entrada consolidada; manter nesta única linha e agregar aqui quaisquer outras referências da mesma função que existam no restante da tabela)* | |
| **Total: 7 buckets acessados** | ||
|
|
||
| | Bucket | Operações | Arquivo(s) | | ||
| |---|---|---| | ||
| | `art-files` | `getPublicUrl` | `QuoteBitrixSync.ts:84`, `QuoteActionHandlers.ts:110` | | ||
| | `supplier-logos` | `upload`, `getPublicUrl` | `useSuppliersManager.ts:327,329`, `useNewSupplierForm.ts:171,173` | | ||
| | `personalization-images` | `upload`, `getPublicUrl`, `remove` | `useProductImageGallery.ts:173,175,182`, `ImageUploadButton.tsx:119` | | ||
| | `avatars` | `upload`, `getPublicUrl` | `useUserManagement.ts:148,150` | | ||
| | `product-videos` | `upload`, `getPublicUrl` | `useProductVideoGallery.ts:152,154,161,163,318,320` | | ||
| | `mockup-art-files` | `remove` | `ArtFileUpload.tsx:124,153` | | ||
|
|
There was a problem hiding this comment.
A seção diz “Total: 7 buckets acessados”, mas a tabela lista 6 buckets (art-files, supplier-logos, personalization-images, avatars, product-videos, mockup-art-files). Pelo código do front-end, também só aparecem esses 6 buckets (não há 7º bucket em src/** via supabase.storage.from(...)). Corrigir o total para 6 ou adicionar explicitamente o bucket faltante com o respectivo uso/arquivo.
| - **Edge functions invocadas:** 28 (de 86 deployadas) | ||
| - **RPCs chamados:** 35 únicos | ||
| - **Subscriptions Realtime:** 9 canais (6 arquivos) | ||
| - **Buckets Storage:** 7 buckets |
There was a problem hiding this comment.
No inventário resumido, consta “Buckets Storage: 7 buckets”, mas o relatório detalhado (seção 1.5) lista apenas 6 buckets e o código do front-end também referencia só 6 via supabase.storage.from(...). Ajustar esse número para manter consistência com o restante do documento.
| - **Buckets Storage:** 7 buckets | |
| - **Buckets Storage:** 6 buckets |
O que é este PR
Apenas documentação. Adiciona o relatório completo de uma auditoria técnica exaustiva do acoplamento entre o frontend (React/TS) e o banco Supabase do projeto.
Não contém mudanças de código — é leitura. Os fixes virarão em PRs separados, priorizados pela severidade dos achados.
Como foi gerado
Via Claude Code (claude-sonnet-4-6) rodando no container
claude-codeda VPS Atomica, com:supabaseem read-only)/workspace/repos/Promo_GiftsbypassPermissionspara automaçãoTL;DR — 4 achados CRÍTICOS (P0)
"Allow all" FOR ALL USING (true)em products / categories / suppliers / quotes — nunca removidas desde a migration de 2025-01-02. Qualquer anônimo pode SELECT/INSERT/UPDATE/DELETE incluindo PII de clientes emquotes.migrations/20250102000000_gifts_production.sql:87-90audit_trailcom policy SELECTUSING (true)sem restrição de role — logs acessíveis a anônimos.migrations/20251228_audit_trail.sql:18order_itemsSELECT aberto para qualquer usuário autenticado — viola menor privilégio entre vendedores.migrations/20260305220938_*.sql:86useQuotes.tscarrega 500 quotes comselect('*')no browser, incluindo PII (email/tel/CNPJ de clientes).src/hooks/useQuotes.tsConteúdo do relatório
6 seções cobrem:
types.ts, 52 tipos sem uso direto, divergencias coluna a colunauseQuerysemstaleTime, queryKey sem convencao de namespace, 6.catch(() => {})silenciando falhas, top 5 pioresselect('*')Limitação conhecida
As ferramentas MCP Supabase
execute_sql,list_tables,get_advisors,list_migrationsfalharam comYour account does not have the necessary privileges. Toda a análise de banco foi feita sobre as 356 migrations locais — o estado live do banco pode divergir.Ações para destravar futuras auditorias com banco live:
supabase_patno Swarm) tem permissão de read no projetonmojwpihnslkssljowjh--read-onlyno MCP server pra um token de organização comdatabase:readPróximos passos sugeridos
Em ordem de prioridade:
DROP POLICY "Allow all"emproducts,categories,suppliers,quotesE aplica policies restritivas equivalentes (a intenção original em PRs subsequentes era restritiva, mas oDROPesquecido invalidou)useQuotes.tsremovendoselect('*')em listagens (selecionar apenas colunas não-PII)order_itemspor organizaçãotypes.tscomsupabase gen types typescript --project-id nmojwpihnslkssljowjhstaleTimeequeryKeynamespacingCada um desses pode ser delegado de volta ao Claude Code do container, com este relatório servindo de spec.
🤖 Relatorio gerado por Claude Code (claude-sonnet-4-6) | Orquestracao: Claude Opus 4.7 via Portainer MCP | Sem intervenção manual.