Hunter CRM - Technical Reference
Versão: 2.0 | Data: Março 2026 | Status: Production1. Visão Geral
Hunter CRM é um sistema completo de gestão comercial B2B desenvolvido para times de SDRs e Closers. O sistema gerencia todo o ciclo de vendas desde a captação de leads até o fechamento de negócios (deals).
1.1 Stack Tecnológica
1.2 Métricas do Codebase (Março 2026)
1.3 Repositório
/root/clawd/focus-hunt2. Arquitetura de Dados
2.1 Entidades Principais
``
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ LEADS │────▶│ DEALS │────▶│ CONTACTS │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ LEAD_LISTS │ │ PIPELINES │ │ ACCOUNTS │
└─────────────┘ │ (stages) │ └─────────────┘
└─────────────┘
`
2.2 Schema: Leads (Tabela Principal)
A tabela leads é o coração do sistema de prospecção.
`sql
leads {
-- Identificação
id: UUID (PK)
name: TEXT (required)
email: TEXT
phone: TEXT
-- Empresa
company_name: TEXT (required)
company_cnpj: TEXT
company_website: TEXT
company_industry: TEXT
company_size: TEXT -- '1-10', '11-50', '51-200', '201-500', '500+'
company_address: TEXT
company_city: TEXT
company_state: TEXT
-- Status e Fluxo
status: TEXT DEFAULT 'new' -- 'new', 'contacted', 'qualified', 'disqualified', 'converted'
status_changed_at: TIMESTAMP
priority: TEXT -- 'low', 'medium', 'high', 'urgent'
-- Atribuição
assigned_to: UUID → profiles.id
list_id: UUID → lead_lists.id
list_assigned_at: TIMESTAMP
list_first_contact_at: TIMESTAMP
list_sla_deadline: TIMESTAMP
list_row_number: INTEGER
-- Scoring
score: NUMERIC
demographic_score: NUMERIC
behavioral_score: NUMERIC
fit_score: NUMERIC
effective_score: NUMERIC
decay_multiplier: NUMERIC DEFAULT 1
score_breakdown: JSONB
score_updated_at: TIMESTAMP
skip_score_calculation: BOOLEAN DEFAULT FALSE
-- Qualificação/Desqualificação
qualification_notes: TEXT
disqualification_reason: TEXT
disqualification_reason_id: UUID
disqualification_notes: TEXT
rejection_reason: TEXT
rejected_at: TIMESTAMP
rejected_by: UUID
-- Recovery (Leads perdidos)
in_recovery_cadence: BOOLEAN DEFAULT FALSE
recovery_cadence_started_at: TIMESTAMP
recovery_assigned_to: UUID
recovery_notes: TEXT
-- Conversão
converted_at: TIMESTAMP
converted_to_contact_id: UUID → contacts.id
-- Agrupamento (Company Groups)
company_group_id: UUID → lead_company_groups.id
champion_of_group: BOOLEAN DEFAULT FALSE
is_manual_champion: BOOLEAN DEFAULT FALSE
-- Reuniões
scheduled_meeting_id: UUID
scheduled_with_user_id: UUID
-- UTM Tracking
utm_source: TEXT
utm_medium: TEXT
utm_campaign: TEXT
utm_term: TEXT
utm_content: TEXT
gclid: TEXT
fbclid: TEXT
msclkid: TEXT
landing_page_url: TEXT
referrer_url: TEXT
first_visit_at: TIMESTAMP
-- Relacionamentos
source_id: UUID → lead_sources.id
account_id: UUID → accounts.id
created_by: UUID → profiles.id
-- Metadata
custom_fields: JSONB
tags: TEXT[]
last_activity_at: TIMESTAMP
last_contact_at: TIMESTAMP
created_at: TIMESTAMP
updated_at: TIMESTAMP
}
`
2.3 Schema: Deals (Negócios)
A tabela deals gerencia todo o pipeline de vendas.
`sql
deals {
-- Identificação
id: UUID (PK)
title: TEXT (required)
company: TEXT (required)
company_cnpj: TEXT
-- Contato Principal
contact: TEXT (required)
contact_email: TEXT
contact_phone: TEXT
contact_position: TEXT
contact_notes: TEXT
contact_id: UUID → contacts.id
primary_contact_id: UUID → contacts.id
-- Pipeline
stage_id: UUID (required) → pipeline_stages.id
sub_status_id: UUID → deal_sub_statuses.id
position: INTEGER -- Ordenação no Kanban
days_in_current_stage: INTEGER
-- Valores
value: NUMERIC -- Valor total do deal
mrr: NUMERIC -- Monthly Recurring Revenue
list_value: NUMERIC
-- Probabilidade e Risco
win_probability: NUMERIC (0-100)
probability_breakdown: JSONB
probability_updated_at: TIMESTAMP
risk_level: TEXT -- 'low', 'medium', 'high', 'critical'
risk_factors: JSONB
-- Tipo de Deal
deal_type: TEXT DEFAULT 'new_business' -- 'new_business' | 'recovery'
recovery_source_deal_id: UUID → deals.id -- Se recovery, aponta para o deal original
recovery_context: TEXT
-- Financeiro/Contrato
billing_type: TEXT -- 'one_time', 'recurring', 'usage_based'
contract_duration_months: INTEGER
discount_percent: NUMERIC
discount_value: NUMERIC
installments: INTEGER
payment_method: TEXT
contract_link: TEXT
-- Discovery/Proposta
discovery_acceptance_status: TEXT -- 'pending', 'accepted', 'rejected'
discovery_call_link: TEXT
proposal_call_link: TEXT
-- Status
status: TEXT -- 'active', 'won', 'lost', 'archived'
is_active: BOOLEAN DEFAULT TRUE
won_at: TIMESTAMP
lost_at: TIMESTAMP
loss_reason_id: UUID → deal_loss_reasons.id
loss_notes: TEXT
-- Datas
expected_close_date: DATE
original_expected_close_date: DATE
close_date_change_count: INTEGER DEFAULT 0
next_contact_date: DATE
last_activity_at: TIMESTAMP
-- Atribuição
user_id: UUID (required) → profiles.id -- Closer responsável
sdr_id: UUID → profiles.id -- SDR que originou
squad_id_at_close: UUID → squads.id
visible_to: TEXT
-- UTM Tracking (herdado do lead)
utm_source, utm_medium, utm_campaign, utm_term, utm_content: TEXT
gclid, fbclid, msclkid: TEXT
landing_page_url, referrer_url: TEXT
first_visit_at: TIMESTAMP
-- Relacionamentos
lead_id: UUID → leads.id
account_id: UUID → accounts.id
product_id: UUID → products.id
source_id: UUID → lead_sources.id
-- Metadata
notes: TEXT
tags: TEXT
created_at: TIMESTAMP
updated_at: TIMESTAMP
}
`
2.4 Schema: Profiles (Usuários)
`sql
profiles {
id: UUID (PK) → auth.users.id
full_name: TEXT (required)
email: TEXT (required)
avatar_url: TEXT
contact_phone: TEXT
job_title: TEXT
email_signature: TEXT
functional_area: TEXT -- 'vendas', 'marketing', 'operações'
reports_to: UUID → profiles.id
is_active: BOOLEAN DEFAULT TRUE
theme_preference: TEXT DEFAULT 'system'
created_at: TIMESTAMP
updated_at: TIMESTAMP
}
`
2.5 Schema: User Roles (Permissões)
`sql
user_roles {
id: UUID (PK)
user_id: UUID (required) → profiles.id
role: app_role (required) -- Enum
created_at: TIMESTAMP
}
-- Enum app_role
'admin' -- Acesso total
'head_comercial' -- Head da área comercial
'lider_tribo' -- Líder de tribo
'lider_prospeccao'-- Líder de prospecção (SDRs)
'lider_closers' -- Líder de closers
'squad_leader' -- Líder de squad
'squad' -- Membro de squad
'closer' -- Closer
'sdr' -- SDR
'bdr' -- BDR
'leader' -- Líder genérico
`
2.6 Schema: Squads (Times)
`sql
squads {
id: UUID (PK)
name: TEXT (required)
description: TEXT
color: TEXT -- Hex color
functional_area: TEXT
matrix_type: TEXT
leader_id: UUID → profiles.id
is_active: BOOLEAN DEFAULT TRUE
created_at: TIMESTAMP
updated_at: TIMESTAMP
}
user_squads {
id: UUID (PK)
user_id: UUID (required) → profiles.id
squad_id: UUID (required) → squads.id
created_at: TIMESTAMP
}
`
2.7 Schema: Pipeline e Stages
`sql
pipelines {
id: UUID (PK)
name: TEXT (required)
description: TEXT
color: TEXT
is_active: BOOLEAN DEFAULT TRUE
created_at: TIMESTAMP
updated_at: TIMESTAMP
}
pipeline_stages {
id: UUID (PK)
pipeline_id: UUID (required) → pipelines.id
name: TEXT (required)
description: TEXT
order: INTEGER (required) -- Ordem no pipeline
color: TEXT
probability: NUMERIC -- Probabilidade padrão de ganho
is_active: BOOLEAN DEFAULT TRUE
created_at: TIMESTAMP
updated_at: TIMESTAMP
}
`
2.8 Schema: Activities (Atividades)
`sql
deal_activities {
id: UUID (PK)
deal_id: UUID (required) → deals.id
activity_type: TEXT (required)
-- 'call', 'email', 'meeting', 'whatsapp', 'task', 'note'
title: TEXT (required)
description: TEXT
scheduled_at: TIMESTAMP
completed_at: TIMESTAMP
completed_by: UUID → profiles.id
outcome: TEXT
call_disposition: TEXT
meeting_type: TEXT
no_show_count: INTEGER DEFAULT 0
reschedule_count: INTEGER DEFAULT 0
last_no_show_at: TIMESTAMP
last_reschedule_at: TIMESTAMP
cancellation_reason: TEXT
cancelled_at: TIMESTAMP
google_event_id: TEXT
google_event_link: TEXT
calendar_sync_enabled: BOOLEAN DEFAULT FALSE
assigned_users: UUID[]
auto_scheduled: BOOLEAN DEFAULT FALSE
automation_execution_id: UUID
created_by: UUID (required) → profiles.id
created_at: TIMESTAMP
updated_at: TIMESTAMP
}
lead_activities {
-- Mesma estrutura, mas para leads
lead_id: UUID (required) → leads.id
...
}
`
2.9 Schema: Lead Lists (Listas de Prospecção)
`sql
lead_lists {
id: UUID (PK)
name: TEXT (required)
description: TEXT
source_type: TEXT -- 'csv_upload', 'manual', 'api', 'form'
status: TEXT -- 'draft', 'processing', 'ready', 'distributed'
-- Importação
file_name: TEXT
file_size_bytes: INTEGER
total_rows: INTEGER
valid_count: INTEGER
error_count: INTEGER
duplicate_count: INTEGER
progress_percent: INTEGER
-- Distribuição
distributed_at: TIMESTAMP
distributed_by: UUID → profiles.id
distribution_rules: JSONB
scheduled_distribution_at: TIMESTAMP
scheduled_distribution_method: TEXT
scheduled_by: UUID
-- SLA
sla_hours: INTEGER
-- Rollback
can_rollback: BOOLEAN DEFAULT FALSE
rollback_expires_at: TIMESTAMP
rolled_back_at: TIMESTAMP
-- Metadata
created_by: UUID (required) → profiles.id
created_at: TIMESTAMP
updated_at: TIMESTAMP
}
lead_list_items {
id: UUID (PK)
list_id: UUID (required) → lead_lists.id
lead_id: UUID → leads.id
row_number: INTEGER (required)
raw_data: JSONB (required)
mapped_data: JSONB
validation_status: TEXT -- 'valid', 'error', 'duplicate'
validation_errors: JSONB
duplicate_of_id: UUID
duplicate_of_type: TEXT -- 'lead', 'contact', 'deal'
created_at: TIMESTAMP
}
`
3. Hierarquia e Permissões
3.1 Estrutura Organizacional
`
┌────────────────┐
│ Admin │
└───────┬────────┘
│
┌───────▼────────┐
│ Head Comercial │
└───────┬────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌────────▼────────┐ ┌──────▼──────┐ ┌───────▼───────┐
│ Líder Tribo │ │Líder Closers│ │Líder Prospecção│
└────────┬────────┘ └──────┬──────┘ └───────┬───────┘
│ │ │
Squads/Tribos Closers SDRs/BDRs
`
3.2 Regras de Visibilidade
3.3 Command Centers por Role
(/closer-command) (/squad-command) (/my-command)4. Fluxos de Negócio
4.1 Ciclo de Vida do Lead
`
┌─────────┐ ┌───────────┐ ┌────────────┐ ┌───────────┐
│ NEW │──▶│ CONTACTED │──▶│ QUALIFIED │──▶│ CONVERTED │
└─────────┘ └───────────┘ └────────────┘ └───────────┘
│ │
│ ▼
│ ┌──────────────┐
└───────▶│ DISQUALIFIED │
└──────────────┘
`
Status Possíveis:
: Lead recém criado/importado: Primeiro contato realizado: Lead qualificado, pronto para virar deal: Lead não qualificado (com motivo): Convertido em deal/contato4.2 Ciclo de Vida do Deal
`
Pipeline Stages (exemplo):
┌──────────────┐ ┌──────────┐ ┌─────────────┐ ┌───────┐
│ Qualificação │──▶│ Proposta │──▶│ Negociação │──▶│ Ganho │
└──────────────┘ └──────────┘ └─────────────┘ └───────┘
│ │ │
└────────────────┴───────────────┘
│
▼
┌─────────┐
│ Perdido │
└─────────┘
`
Status do Deal:
: Deal em andamento: Deal ganho (fechado): Deal perdido: Deal arquivado4.3 Sistema de Recovery
O sistema de Recovery permite reativar deals perdidos há 90+ dias.
Critérios de Elegibilidade:
1. status = 'lost'
2. lost_at há mais de 90 dias
3. Não existe deal ativo apontando para ele via recovery_source_deal_id
Campos de Recovery no Deal:
: 'new_business' ou 'recovery': ID do deal original perdido: Contexto/motivo da reativaçãoFluxo:
`
Deal Original (perdido 90+ dias)
│
▼
[Check Elegibilidade]
│
▼
Criar Recovery Deal
├── deal_type = 'recovery'
├── recovery_source_deal_id = original.id
└── recovery_context = "motivo"
`
Nota: Recovery deals podem gerar outros recovery deals (cadeia infinita).
4.4 Sistema de SLA
Campos no Lead:
: Prazo para primeiro contato: Data do primeiro contatoCampos na Lead List:
: Horas de SLA configuradasEdge Function: check-sla-expired
4.5 Sistema de Scoring
Tipos de Score:
: Score baseado em dados demográficos (cargo, empresa): Score baseado em comportamento (abertura de emails, cliques): Score de fit com ICP: Score efetivo (após decay)Decay (Decaimento):
: Fator de decaimento (0-1): Última vez que decay foi calculado5. Integrações
5.1 Google Calendar
Funcionalidades:
Edge Functions:
Campos nas Activities:
5.2 Gmail
Funcionalidades:
Edge Functions:
5.3 Mautic (Marketing Automation)
Funcionalidades:
Edge Functions:
5.4 WhatsApp (WAHA)
Funcionalidades:
Edge Functions:
5.5 Twilio VOIP
Funcionalidades:
Edge Functions:
5.6 GTM (Google Tag Manager)
Funcionalidades:
Edge Functions:
6. Edge Functions (Backend)
6.1 Lista Completa (67 funções)
7. Hooks Principais
7.1 Organização por Categoria
Leads (30+ hooks):
, useLead, useCreateLead, useUpdateLead, useDeleteLead, useLeadListMetrics, useLeadScoringRules, useLeadNotes, useLeadWatchers, useLeadPhones (multi-contact)Deals (25+ hooks):
, useDeal, useCreateDeal, useUpdateDeal, useArchivedDeals, useArchiveDeal, useDealStakeholders, useDealActivitiesPipeline (10 hooks):
, usePipelineStages, useAllPipelineStages, usePipelineMetricsAtividades (15 hooks):
, useActivityTracking, useActivityReminders, useActivityLiveFeed, useActivityStreakRanking & Performance (20 hooks):
, useCloserRanking, useTeamGoalsPerformance, useGoalProgress, useForecastCommand Centers (10 hooks):
, useCloserPipelineFunnel, useDealsInLimboAnalytics (15 hooks):
, useAgingAnalysis, useCallMetrics, useUserAnalyticsIntegrações (20 hooks):
, useCallTranscriptionSearch, useGlobalSearch, useCheckCalendarConflicts8. Contextos e Providers
8.1 AuthContext
`typescript
interface AuthContextType {
user: User | null;
profile: Profile | null;
roles: AppRole[];
isAdmin: boolean;
isLoading: boolean;
signIn: (email: string, password: string) => Promise`
8.2 ViewAsContext
Permite "ver como" outro usuário (para admins/líderes).
`typescript
interface ViewAsContextType {
viewAsUserId: string | null;
setViewAsUserId: (id: string | null) => void;
effectiveUserId: string; // viewAsUserId ou user.id
}
`
8.3 VoIPContext
Gerencia estado do sistema de VOIP.
`typescript
interface VoIPContextType {
isConnected: boolean;
currentCall: CallState | null;
initiateCall: (phone: string, dealId?: string) => Promise`
8.4 TimezoneContext
`typescript
interface TimezoneContextType {
timezone: string;
setTimezone: (tz: string) => void;
formatDate: (date: Date, format: string) => string;
}
`
9. Páginas e Rotas
9.1 Mapa de Rotas (36 páginas)
10. Fluxos de UI
10.1 Kanban de Deals
Componentes:
→ Container principal → Coluna por stage → Card do deal → Ações em massaFuncionalidades:
10.2 Action Bar
Ações disponíveis:
10.3 Deal Drawer
Seções:
10.4 Recovery Flow
1. Acessa lista de deals elegíveis (/recovery-candidates)
2. Seleciona deal para reativar
3. Modal de confirmação com contexto
4. Criação automática do recovery deal
5. Atribuição para closer disponível
11. Setup para Desenvolvimento
11.1 Requisitos
11.2 Variáveis de Ambiente
`env
VITE_SUPABASE_URL=https://xxx.supabase.co
VITE_SUPABASE_ANON_KEY=eyJxxxx
VITE_GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
VITE_TWILIO_ACCOUNT_SID=ACxxxx
`
11.3 Comandos
`bash
Instalar dependências
npm install
Desenvolvimento
npm run devBuild
npm run buildPreview do build
npm run previewType check
npm run typecheckLint
npm run lint `11.4 Estrutura de Diretórios
`
src/
├── components/ # Componentes React
│ ├── ui/ # Componentes base (shadcn)
│ ├── Layout/ # Header, Sidebar, etc
│ ├── Dashboard/ # Widgets do dashboard
│ ├── Leads/ # Componentes de leads
│ ├── Deals/ # Componentes de deals
│ └── ...
├── contexts/ # React Contexts
├── hooks/ # Custom hooks
├── integrations/ # Supabase client e types
├── lib/ # Utilidades
├── pages/ # Páginas/Routes
├── providers/ # Providers (QueryClient, etc)
├── types/ # TypeScript types
└── utils/ # Funções auxiliares
`11.5 Convenções de Código
Hooks: use prefix (ex: useDeals)
Componentes: PascalCase (ex: DealCard)
Arquivos: camelCase para hooks, PascalCase para componentes
Types: Interfaces com I prefix ou sufixo descritivo
Formatters: Usar lib/formatters.ts para formatação11.6 Padrões TanStack Query
`typescript
// Query padrão
const { data, isLoading, error } = useQuery({
queryKey: ['deals', filters],
queryFn: async () => {
const { data, error } = await supabase
.from('deals')
.select('*')
.eq('is_active', true);
if (error) throw error;
return data;
},
staleTime: 5 60 1000, // 5 minutos
});// Mutation padrão
const mutation = useMutation({
mutationFn: async (deal: CreateDealInput) => {
const { data, error } = await supabase
.from('deals')
.insert(deal)
.select()
.single();
if (error) throw error;
return data;
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['deals'] });
toast.success('Deal criado!');
},
});
`
12. Referências
12.1 Arquivos Importantes
Arquivo Descrição
|---------|-----------|
src/integrations/supabase/types.ts Types gerados do Supabase (9638 linhas)
src/types/accounts.ts Types de accounts, contacts, roles
src/hooks/useRecoveryDeals.ts Lógica de recovery
src/hooks/useCloserRanking.ts Ranking de closers
src/pages/CloserCommandCenter.tsx Dashboard de closers
src/pages/Negocios.tsx Kanban de deals
src/pages/Leads.tsx Gestão de leads 12.2 Documentação Adicional
Local: /root/clawd/apex/arcosscale/tools/hunter/DOCS/`
Documento gerado em Março 2026 | Hunter CRM v2.0