Skip to content

docs(audit): relatório exaustivo Frontend ↔ Banco de Dados (4 P0 críticos)#69

Merged
adm01-debug merged 1 commit into
mainfrom
claude/audit-frontend-db-2026-04-29
Apr 30, 2026
Merged

docs(audit): relatório exaustivo Frontend ↔ Banco de Dados (4 P0 críticos)#69
adm01-debug merged 1 commit into
mainfrom
claude/audit-frontend-db-2026-04-29

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

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-code da VPS Atomica, com:

  • 27 MCPs configurados (incluindo supabase em read-only)
  • Acesso completo ao filesystem de /workspace/repos/Promo_Gifts
  • Permissão bypassPermissions para automação
  • Tempo de execução: ~9 minutos
  • Saída: 31 KB de markdown estruturado

TL;DR — 4 achados CRÍTICOS (P0)

# Título Onde
C1 Policies "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 em quotes. migrations/20250102000000_gifts_production.sql:87-90
C2 audit_trail com policy SELECT USING (true) sem restrição de role — logs acessíveis a anônimos. migrations/20251228_audit_trail.sql:18
C3 order_items SELECT aberto para qualquer usuário autenticado — viola menor privilégio entre vendedores. migrations/20260305220938_*.sql:86
C4 useQuotes.ts carrega 500 quotes com select('*') no browser, incluindo PII (email/tel/CNPJ de clientes). src/hooks/useQuotes.ts

Conteúdo do relatório

6 seções cobrem:

  1. Inventário do acoplamento — 68 tabelas, 28 edge functions, 35 RPCs, 9 subscriptions Realtime, 7 buckets Storage, com arquivo:linha de cada chamador
  2. Consistência de tipos — 12 tabelas usadas no front sem definicao em types.ts, 52 tipos sem uso direto, divergencias coluna a coluna
  3. Segurança / RLS — 4 críticos, 5 atencoes, lista de tabelas com RLS bem configurado
  4. Padroes de acesso — 67% dos hooks useQuery sem staleTime, queryKey sem convencao de namespace, 6 .catch(() => {}) silenciando falhas, top 5 piores select('*')
  5. Estado do schema — 356 migrations totais, 25 nos ultimos 3 dias, ritmo elevado, indices possivelmente ausentes
  6. Achados priorizados — tabela final com 15 itens classificados P0/P1/P2/P3

Limitação conhecida

As ferramentas MCP Supabase execute_sql, list_tables, get_advisors, list_migrations falharam com Your 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:

  1. Verificar se o PAT do Supabase (supabase_pat no Swarm) tem permissão de read no projeto nmojwpihnslkssljowjh
  2. Se sim, atualizar o --read-only no MCP server pra um token de organização com database:read

Próximos passos sugeridos

Em ordem de prioridade:

  1. PR urgente — migration que faz DROP POLICY "Allow all" em products, categories, suppliers, quotes E aplica policies restritivas equivalentes (a intenção original em PRs subsequentes era restritiva, mas o DROP esquecido invalidou)
  2. PR urgente — reescrever useQuotes.ts removendo select('*') em listagens (selecionar apenas colunas não-PII)
  3. PR médio — escopar order_items por organização
  4. PR médio — regenerar types.ts com supabase gen types typescript --project-id nmojwpihnslkssljowjh
  5. PR baixo — padronizar staleTime e queryKey namespacing

Cada 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.

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
Copilot AI review requested due to automatic review settings April 29, 2026 13:11
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

Warning

Rate limit exceeded

@adm01-debug has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 46 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 890cd674-fda2-4726-b1fb-d0517d3fc028

📥 Commits

Reviewing files that changed from the base of the PR and between 9e3f79e and 05024ed.

📒 Files selected for processing (2)
  • docs/AUDIT_FRONTEND_DATABASE.md
  • docs/AUDIT_FRONTEND_DATABASE_summary.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/audit-frontend-db-2026-04-29

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.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 25 minutes and 46 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +15 to +19
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.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +16 to +56
**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` |
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
**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` |

Copilot uses AI. Check for mistakes.
| `commemorative-dates` | `useCommemorativeDates.ts:60` |
| `detect-new-device` | `useDeviceDetection.ts:94` |
| `dropbox-list` | `useDropboxFiles.ts:29,44` |
| `external-db-bridge` | `PublicFavoriteListPage.tsx:79` |
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
| `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)* |

Copilot uses AI. Check for mistakes.
Comment on lines +154 to +164
**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` |

Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
- **Edge functions invocadas:** 28 (de 86 deployadas)
- **RPCs chamados:** 35 únicos
- **Subscriptions Realtime:** 9 canais (6 arquivos)
- **Buckets Storage:** 7 buckets
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
- **Buckets Storage:** 7 buckets
- **Buckets Storage:** 6 buckets

Copilot uses AI. Check for mistakes.
@adm01-debug adm01-debug merged commit dc01a09 into main Apr 30, 2026
6 of 11 checks passed
@adm01-debug adm01-debug deleted the claude/audit-frontend-db-2026-04-29 branch May 9, 2026 21:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants