Voltar

Relatório de Auditoria Técnica

PRD 01 — O pescador de ofertas

Versão 1.0 · 06/11/2026

A. Arquitetura Encontrada

Stack: React 18 + Vite + Tailwind CSS + shadcn/ui, rodando na plataforma Base44 (BaaS).

Estrutura de pastas:

  • src/pages/ → 12 páginas (Home, OfferDetail, Dashboard, Blog, BlogDetail, BlogDashboard, About, PrivacyPolicy, TermsOfUse, Login, Register, ForgotPassword, ResetPassword)
  • src/components/ → Componentes UI (Hero, OfferCard, OfferModal, OfferMarquee, SearchBar, Filters, BotSection, Layout, dashboard/*, blog/*)
  • base44/entities/ → 6 entidades (Offer, Click, Lead, BlogPost, CommentReply, BotState)
  • base44/functions/ → 11 funções backend
  • base44/shared/ → 3 módulos compartilhados (offerUtils, shopeeAffiliateApi, marketplaceScraper)
  • base44/workflows/ → 6 workflows

Autenticação: Base44 Auth nativa (AuthProvider, ProtectedRoute). Usuários admin têm acesso ao Dashboard e BlogAdmin. Login via email/senha + Google OAuth. Rotas públicas não exigem login.

Navegação: React Router com Layout como wrapper (header + footer + Outlet). Navegação responsiva (mobile e desktop).

B. Banco de Dados

1. Entidade Offer (núcleo do catálogo)

Finalidade: Armazena todas as ofertas/produtos curados.

Campos principais: title, slug, description, detailed_description, image_url, additional_images, price_original, price_current, discount_percent, rating, review_count, niche (13 categorias), marketplace (shopee/amazon/mercadolivre), affiliate_url, social_caption, is_featured, is_expired, stock_status, click_count, post_status, post_priority, instagram_media_id.

Relacionamentos: Referenciada por Click.offer_id e CommentReply.offer_id.

Status: ✅ Preservar. Expansível — campos podem ser adicionados sem quebrar nada.

2. Entidade Click (rastreamento de cliques)

Finalidade: Registra cliques em links de afiliado.

Campos: offer_id, offer_title, lead_id, origem (enum: homepage, instagram, tiktok, facebook, direct, organic).

Status: ✅ Preservar. Expansível — faltam campos para PRD 02 (session_id, visitor_id, utm_*).

3. Entidade Lead (captura de leads)

Finalidade: Captura de leads e interessados.

Campos: name, email, preferred_niches (array), origem, status (pending, converted).

Status: ✅ Preservar. Expansível.

4. Entidade BlogPost (conteúdo)

Finalidade: Artigos do blog (prévias, unboxings, comparações).

Campos: title, slug, excerpt, content (HTML), cover_image, media_type, video_url, category, author, tags, is_published, views.

Status: ✅ Preservar.

5. Entidade CommentReply (Instagram)

Finalidade: Registra respostas enviadas a comentários do Instagram (evitar duplicidade).

Campos: comment_id, offer_id, media_id, username, comment_text, reply_text.

Status: ✅ Preservar.

6. Entidade BotState (estado do bot)

Finalidade: Estado simples do bot (chave/valor numérico).

Campos: key, value.

Status: ✅ Preservar.

7. Entidade User (sistema — built-in)

Finalidade: Usuários da plataforma. Apenas admins acessam o painel.

Status: ✅ Preservar (read-only, gerenciado pela plataforma).

C. Catálogo — Como os produtos entram

Existem 3 fluxos de entrada de produtos:

Fluxo 1: Sincronização automática via API Shopee (primário)

Função: syncOffersFromShopeeAPI → chama fetchShopeeProductOffers (GraphQL productOfferV2).

Como funciona: Busca 50 ofertas da Shopee Affiliate API, filtra por desconto maior que 0, verifica duplicidade por affiliate_url e title, cria registros com dados reais.

Fluxo 2: Sincronização via IA com web search (secundário)

Função: syncOffersFromWeb → usa InvokeLLM (gemini_3_flash + web search) para encontrar ofertas da Shopee e Amazon, depois faz scraping real, fallback para imagem gerada por IA.

Fluxo 3: Importação manual por URL

Função: importOfferFromUrl → admin cola URL de produto, resolve short links, extrai itemId/shopId, busca dados reais via API Shopee, se não encontrar, fallback para LLM + scraping.

CampoShopee APILLM/ScrapingDisponível?
ID externo (itemId)✅❌Parcial
Nome✅✅✅
Imagem✅ (real)Scraping/AI✅
Categoria (niche)DetectadaLLM✅
Preço atual✅✅✅
Preço originalCalculadoLLM✅
Desconto %✅LLM✅
Link afiliado✅ (API)Scraping+tag✅
Vendedor (shopName)✅❌Parcial
Avaliação (ratingStar)✅LLM✅
Qtd vendida (sales)✅❌Parcial
Comissão (commissionRate)✅ (não salvo)❌Disponível mas não salvo
DisponibilidadeDefaultDefaultNão real

D. Afiliados — Como os links funcionam

Shopee

  • Onde é gerado: O link chega pronto pela API (offerLink do productOfferV2).
  • Transformação: Nenhuma — o link da API já contém o tracking.
  • Sub-ID / Tracking ID: Não implementado.
  • Saída do usuário: Direta — window.open sem redirecionamento interno.

Amazon

  • Onde é gerado: URL do produto do scraper (ASIN) ou LLM.
  • Transformação: buildAffiliateUrl injeta tag=fishnet0f-20 (hardcoded).
  • ID de afiliado: fishnet0f-20 (Amazon Associates).
  • Saída do usuário: Direta — window.open.

Mercado Livre

  • Status: Enum existe mas não há integração ativa (conta suspensa). Aparece no rodapé mas não no catálogo.

Registro de clique

  • Sim, existe: Ao clicar em "Comprar", cria um registro Click com offer_id, offer_title e origem.
  • Origem registrada: homepage (OfferModal), direct (OfferDetail). Outros valores do enum existem mas não são populados.

E. APIs — Integrações existentes

IntegraçãoTipoEstadoFunção
Shopee Affiliate APIGraphQL + SHA256✅ FuncionandoshopeeAffiliateApi.ts
Instagram Graph APIOAuth Connector✅ AutorizadopostToInstagram, replyToComments
WhatsAppLink direto✅ FuncionandoCompartilhamento e reservas
Amazon ScraperHTTP scraping⚠️ FrágilmarketplaceScraper.ts
InvokeLLM (Gemini)Base44 Integration✅ FuncionandoWeb search + legendas
GenerateImageBase44 Integration✅ FuncionandoImagens de fallback

Secrets configurados: SITE_URL, SHOPEE_AFFILIATE_APP_ID, SHOPEE_AFFILIATE_SECRET, WORKFLOW_SECRET, HEYGEN_API_KEY.

F. Analytics

RecursoStatus
Google Analytics 4❌ NÃO IMPLEMENTADO
Google Tag Manager❌ NÃO IMPLEMENTADO
Meta Pixel❌ NÃO IMPLEMENTADO
Eventos personalizados⚠️ PARCIAL — Click.create + analytics.track
Tracking interno⚠️ PARCIAL — entidade Click sem session/visitor
Cookies❌ NÃO IMPLEMENTADO
Session ID❌ NÃO IMPLEMENTADO
Visitor ID❌ NÃO IMPLEMENTADO
UTM❌ NÃO IMPLEMENTADO — não parseados
Logs de clique⚠️ PARCIAL — sem contexto de sessão

G. Tracking — Capacidade atual

NívelStatusObservação
Origem⚠️ ParcialClick.origem é hardcoded
Visitante❌ Não existeSem visitor_id
Sessão❌ Não existeSem session_id
Campanha❌ Não existeSem campaign_id, UTM não parseado
Produto✅ ExisteClick.offer_id
Clique✅ ExisteEntidade Click + Offer.click_count
Redirecionamento❌ DiretoSem redirecionamento interno

Resumo: O sistema registra que produto foi clicado, mas não quem clicou, de onde veio, nem em qual sessão/campanha.

H. Dados de Marketplace para Tendências

CampoMarketplaceAPI/OrigemPossibilidade
Qtd vendida (sales)ShopeeproductOfferV2.sales⚠️ Disponível — não armazenado
Comissão (commissionRate)ShopeeproductOfferV2.commissionRate⚠️ Disponível — não armazenado
Avaliação (ratingStar)ShopeeproductOfferV2.ratingStar✅ Já armazenado em rating
Desconto %ShopeepriceDiscountRate✅ Já armazenado
Preço atualShopeepriceMin✅ Já armazenado
Ranking/popularidadeShopeesortType (2=Sales)✅ Via ordenação
Hot ProductsAliExpressAPI (futuro)🔜 Disponível se integrar
Amazon sales/rankingAmazonNão via scraping❌ Não disponível

Oportunidade: A API Shopee fornece sales e commissionRate que poderiam ser armazenados mas não estão sendo salvos. Adicionar esses campos permitiria análise de tendência no PRD 08.

I. Segurança

ItemStatus
API Keys no front-end✅ Nenhuma — todas em secrets
Tokens expostos✅ Nenhum token no front-end
Secrets no front-end✅ Nenhum — via secrets.get()
Endpoints administrativos✅ Protegidos — verificam admin
Acesso público a dados admin✅ ProtectedRoute
Credenciais hardcoded⚠️ Amazon tag fishnet0f-20 hardcoded
RLS (Row-Level Security)⚠️ Não configurado nas entidades

J. Performance

ItemStatusObservação
Consultas desnecessárias⚠️Home: 100 ofertas + 3 posts (2 chamadas)
Carregamento do catálogo✅Lista 100 ofertas — razoável
Imagens⚠️Usa img nativo, não Image otimizado
Busca⚠️Client-side em memória — não escala
Sitemap✅Gerado dinamicamente via getSitemap

K. Alterações Realizadas

Nenhuma alteração foi feita no código. Este PRD é exclusivamente de auditoria e levantamento. A aplicação permanece exatamente como estava.

L. Testes de Regressão

Como nenhuma alteração foi feita, não há risco de regressão. A arquitetura foi apenas lida, não modificada. Funcionalidades intactas:

✅ Home (catálogo, busca, filtros, marquee, blog)

✅ OfferDetail (SEO, JSON-LD, cliques, similares)

✅ Dashboard (3 abas)

✅ Sincronização Shopee API

✅ Sincronização via IA

✅ Importação manual por URL

✅ Instagram posting

✅ Blog (listagem, detalhe, admin)

✅ Atendimento via WhatsApp

✅ SEO (sitemap, meta tags, JSON-LD)

✅ Login/Admin (ProtectedRoute)

M. Recomendação para PRD 02

Estruturas existentes que o PRD 02 deverá reutilizar:

  1. Entidade Click — já existe. Expandir (não recriar) adicionando: session_id, visitor_id, utm_source, utm_medium, utm_campaign, utm_content, utm_term, referrer, landing_page.
  2. Entidade Lead — já captura origem. Manter como está.
  3. Componente Layout — ponto ideal para injetar tracking de sessão/visitante.
  4. OfferModal.handleBuy e OfferDetail.handleBuy — pontos onde o clique já é registrado. Expandir para incluir session_id/visitor_id/UTM.
  5. index.html — local para adicionar Meta Pixel e GA4 no PRD 06.

Novas estruturas que o PRD 02 precisará criar:

  • Entidade Session — nova, não existe equivalente.
  • Entidade Visitor — nova, não existe equivalente.
  • Entidade Campaign — nova, não existe equivalente.
  • Entidade Event — nova, estrutura genérica para eventos.
  • Hook useTracking ou módulo src/lib/tracking.js — para inicializar visitor_id (localStorage) + session_id (sessionStorage) + parse de UTM.

Recomendação técnica:

O PRD 02 deve seguir a prioridade REUTILIZAR → EXPANDIR → CRIAR: reutilizar entidade Click e handlers de clique existentes; expandir Click com novos campos; criar entidades Session, Visitor, Campaign, Event (não existem equivalentes).

Status do PRD 01: ✅ Concluído · Aguardando aprovação para iniciar o PRD 02