Todas as mudanças notáveis deste projeto são documentadas neste arquivo.
O formato segue Keep a Changelog
e o projeto adota Semantic Versioning.
webhook_eventos e fila_jobs com índices para consulta rápida.Support/Queue (fachada) + FilaJobRepository com reserva atômica,Support/WebhookSignature — HMAC hex/base64 com prefixo opcionalX-Goog-Signature, Meta X-Hub-Signature-256).Services/WebhookService — valida assinatura, deduplica por ID externo,ProcessarWebhookJob.Jobs/ProcessarWebhookJob — cria leads a partir de webhooks (Google AdsServices/QueueWorker — processa lotes, aplica backoff e registra falhas.Controllers/WebhookController — endpoints públicos /webhooks/google/webhooks/meta (incluindo verificação hub.challenge).queue:work, queue:once, queue:status, queue:prune.AdminController::webhooks e fila + views correspondentesWebhooks e Fila na sidebar admin.CsrfMiddleware isenta rotas sob /webhooks/.config/webhooks.php e config/queue.php.docs/WEBHOOKS.md com endpoints, segurança, fluxo, worker e simulação.QueueTest, WebhookSignatureTest, WebhookServiceTest,QueueWorkerTest.Application::boot() inicializa Queue.docs/OPERACAO.md e docs/ROADMAP.md atualizados..env.example ganhou WEBHOOK_* e QUEUE_*.config/import.php com limites, aliases de cabeçalho e campos obrigatórios.Support/CsvImporter — detecção de separador, remoção de BOM, sniff de encodingServices/ImportService — sugestão automática de mapeamento, preview com contagemconfirmar() com upsert idempotente por(campanha_id, data).Controllers/ImportController — fluxo em etapas (upload → mapear → preview → confirmar),metricas/import com stepper visual e tabela de prévia./metricas.ADMIN).is_admin().storage/imports/ para arquivos temporários.CsvImporterTest e ImportServiceTest.partials/sidebar.php reescrito com agrupamento e bloco condicional de admin..env.example ganhou IMPORT_MAX_BYTES e IMPORT_MAX_ROWS.config/container.php registra ImportService e ImportController.alertas_enviados (deduplicação de alertas por chave).Support/Alerting — canal de alertas por e-mail com deduplicação e log de envios.Services/AlertService — chaves canônicas (erro.500, disco.baixo, backup.falhou,erros.500.lote, teste.manual) com textos padronizados.Support/Backup — verificação de integridade do último dump (descompacta, extraiApplication::renderServerError (silencioso em debug/testing).HealthController expandido com backup e alertas.AdminController + views admin/dashboard e admin/alertas (acesso restrito aadmin ou listados em ADMIN_USER_IDS).Config/AdminConfig — leitura de e-mails e IDs de admin.cache:clear, audit:prune, user:promote, backup:verify,alert:test, alert:list.json (logs/app.jsonl), sanitização de campos sensíveisdocs/OPERACAO.md — runbook do dia a dia.LoggerJsonTest, BackupVerifyTest, AlertingTest, AdminDashboardTest.config/logging.php inclui format e json_path..env.example ganhou ADMIN_EMAILS, ADMIN_USER_IDS, ALERT_* e LOG_FORMAT.docs/ROADMAP.md atualizado (Sprint 13 concluída + próximas sprints).Support/Csp com nonce por request; SecurityHeadersMiddleware aplica CSP estrita'unsafe-inline' só fora de produção).Support/Totp — TOTP RFC 6238 puro (secret base32, code, verify, backup codes, otpauth URI).Support/PasswordPolicy — mínimo 10 caracteres, bloqueio de senhas comuns e deTwoFactorService e TwoFactorRepository; 2FA opcional pós-login.TwoFactorController (setup, confirmação, desativação, regeneração de backup codes,PerfilController + views perfil/index e perfil/two-factor.AuditService + AuditRepository + tabela audit_log; hook opcional em BaseRepository$auditable = true) com mascaramento de campos sensíveis./cadastro e /resetar-senha/{token}.AuthService::alterarSenha() e uso de PasswordPolicy em registro/reset.docs/SEGURANCA.md.TotpTest, PasswordPolicyTest, CspTest, AuditServiceTest.AuthService::login() retorna '2fa_required' quando 2FA está ativo; sessão ficalayouts/app.php usa assets externos (/assets/css/app.css, /assets/js/app.js).security.php ganha seções csp, password e two_factor.config/container.php com todos os bindings de DI do projeto.Application::buildContainer() reduzido a executar o arquivo de configuração.tests/Support/TestCase.php — base para testes de feature com SQLite em memória,criarUsuario, criarCliente, criarCampanha, autenticar).tests/Support/HttpClient.php — simula requisições ao Router com sessão e CSRF.ClienteControllerTest (index, store, update, destroy, isolamento)CampanhaControllerTest (store, filtros, isolamento)DiagnosticoControllerTest (iniciar, responder, concluir)MetricaControllerTest (lançar, validação, export CSV)LeadControllerTest (pipeline, criar, mover, coluna AJAX, interação, export CSV)RelatorioControllerTest (gerar, exibir, recarregar snapshot)docs/TESTES.md — guia de testes, política de cobertura e CI..github/workflows/ci.yml — CI em PHP 8.1 e 8.2 (lint + PHPUnit).phpunit.xml atualizado com suíte Feature e <php><env> para testes.Application.php: DI movida para config/container.php.Support/Cache (driver arquivo, TTL por namespace, remember, forget,flushNamespace, prune).config/cache.php + variáveis .env (CACHE_ENABLED, CACHE_DRIVER, CACHE_PATH, CACHE_PREFIX).MetricaService::resumoUsuario/resumoCampanha e em todas asDashboardController.Cache::flushNamespace) nos writes de métricasSupport/Csv com BOM UTF-8, separador ;, floats em formato pt-BR e streaming.MetricaController::exportCsv (GET /metricas/export.csv?periodo=&campanha_id=).LeadController::exportCsv (GET /leads/export.csv?filtros…).GET /leads/coluna/{estagio}?offset=) + botão "Carregar mais".metricas (usuario_id, data) eleads (usuario_id, estagio, updated_at).asset_versioned() (hash de conteúdo em query string).cleanup estendido para limpar cache expirado.DashboardController agora depende de Support\Onboarding e usa cache curto (60s).MetricaService e LeadService invalidam cache nos writes.metricas/index.php e leads/index.php incluem botões de exportação.leads/index.php implementa "carregar mais" por coluna via AJAX.feedbacks (com contexto JSON) e eventos_uso (com sessão e IP).FeedbackRepository + FeedbackService (tipos bug/sugestão/dúvida/elogio;FeedbackController com widget universal, painel admin, resposta e endpoint de funil.EventoUsoRepository + EventoUsoService com eventos canônicos e prefixo outros.EventoUsoController com endpoint fire-and-forget (POST /events).feedbacks/widget.php).localStorage, disparado na primeira sessão.Support/Onboarding).EventoUsoService::registrarDoRequest.docs/ROADMAP.md com sprints concluídas e próximas.docs/FEEDBACK.md com fluxo de triagem e critérios de priorização.FeedbackServiceTest e EventoUsoServiceTest.DashboardController passa onboarding para a view.Dashboard/index.php inclui o card de primeiros passos (oculto quando 100%).partials/topbar.php adiciona botões de feedback e tour.partials/sidebar.php adiciona link de Feedbacks (admin) e Roadmap.security.php com headers, rate limiting e política de cookies.SecurityHeadersMiddleware aplicado globalmente (CSP, X-Frame-Options, HSTS em HTTPS, etc.).ThrottleMiddleware + RateLimiter (driver arquivo) para login e recuperação de senha.Logger com rotação por tamanho (logs/app.log + arquivos numerados).HealthController expandido (/health retorna DB, disco, mailer, PHP, logs).cleanup no bin/console para limpar rate-limit e cache antigos.bin/backup.sh com dump do MySQL (--single-transaction) e tar do storage/, com retenção de N dias.docs/DEPLOY.md, docs/SMOKE-TEST.md, docs/ONBOARDING.md..htaccess raiz e public/ com headers, compressão e cache de assets..env: RATE_LIMIT_PATH, BACKUP_PATH, BACKUP_KEEP_DAYS.RateLimiterTest (5 casos) e SecurityHeadersTest (4 casos).Application::boot() configura Logger antes de qualquer código executável.Application::logError() usa Logger::error() com contexto estruturado./login e /esqueci-senha agora têm ThrottleMiddleware.config/logging.php inclui política de rotação.leads e interacoes_lead com FKs, índices e timestamps de conversão/perda.LeadRepository (pipeline por estágio, paginação, resumo agregado, por cliente/campanha).InteracaoLeadRepository (por lead, tipos, checagem de posse).LeadService:LeadController com index (Kanban + tabela), create, store, show, edit, update,mover, interagir, excluirInteracao e destroy.leads/index (Kanban drag-and-drop com fallback de clique), leads/form eleads/show (detalhe + timeline de interações + mover estágio).campanhas/show (bloco "Leads gerados" com KPIs) eclientes/show (bloco "Leads" com valor em pipeline).LeadServiceTest cobrindo estágios, pipeline, interações, isolamento e conversão.CampanhaController::show() injeta leads da campanha.ClienteController::show() injeta leads do cliente.DashboardController recebe LeadService.LeadRepository, InteracaoLeadRepository, LeadService e LeadController.relatorios com snapshot JSON e FK para clientes/usuários.RelatorioRepository (paginação, por cliente, resumo, decode do snapshot).RelatorioService que consolida:atualizarSnapshot() recalcula.RelatorioController com index, novo, store, show, recarregar e destroy.relatorios/index, relatorios/novo e relatorios/show@media print oculta sidebar/topbar/açõesclientes/show (botão "Gerar relatório" + histórico).RelatorioServiceTest cobrindo geração, validações de período,ClienteController::show() injeta relatórios do cliente via container.DashboardController recebe RelatorioService.RelatorioRepository, RelatorioService e RelatorioController.metricas com UNIQUE (campanha_id, data) para evitar duplicidade.MetricaRepository com somas por campanha/usuário, série diária e top campanhas.MetricaService com:MetricaController com index, porCampanha, lancar, store e destroy.metricas/index, metricas/campanha e metricas/lancar.App\Support\Chart com gráfico de linha comparativo e sparkline (SVG puro).campanhas/show com mini-KPIs e sparkline de investimento.MetricaServiceTest cobrindo cálculos (CTR/CPL/CPA/ROAS), upsert,CampanhaController::show() injeta resumo e série de métricas.DashboardController recebe MetricaService e expõe 30 dias por padrão.MetricaRepository, MetricaService e MetricaController.planos_campanha e itens_plano com FKs e índices.PlanoCampanhaRepository (paginação com progresso embutido, resumo agregado,ItemPlanoRepository (itens por plano,PlanoCampanhaService:criarAPartirDoDiagnostico() gera plano com ~14 itens organizados em 6 categoriascriarManual() permite plano com itens passados linha a linha;marcarItem() atualiza progresso de forma idempotente;montarPlanoDeDiagnostico() exposto para testes.PlanoCampanhaController com index, create, store, gerarDoDiagnostico,show, edit, update, destroy, marcarItem.planejamento/index, planejamento/form e planejamento/show com barracampanhas/show com histórico de planos e botão "Gerar plano do diagnóstico".PlanoCampanhaServiceTest cobrindo geração automática, validações,CampanhaController::show() injeta planos via container.DashboardController recebe PlanoCampanhaService.PlanoCampanhaRepository, ItemPlanoRepository,PlanoCampanhaService e PlanoCampanhaController.perguntas_diagnostico, diagnosticos e respostas_diagnosticoperguntas_diagnostico_seeder com 8 perguntas basePerguntaDiagnosticoRepository (com decode automático do JSON de opções),DiagnosticoRepository (busca por usuário, por campanha, em-andamento e último concluído)RespostaDiagnosticoRepository (upsert idempotente por diagnóstico+pergunta).DiagnosticoService com motor de regras determinístico:iniciar() cria ou retoma diagnóstico em andamento;responder() valida valor e persiste pontos/recomendação/prioridade;concluir() valida completude e calcula score 0–100, classificaçãosaudavel/atencao/risco/critico) e problema principal (prioridade alta primeiro,recomendacoesPorPrioridade() agrupa recomendações em alta/média/baixa.DiagnosticoController com wizard (iniciar, responder, concluir, continuar, show).diagnostico/wizard.php com navegação por etapas, auto-avanço após resposta,diagnostico/relatorio.php com score circular SVG, classificação colorida,campanhas/show.php.Controller::rotuloOpcao() e DiagnosticoService::rotulo() para rótulos amigáveis.DiagnosticoServiceTest cobrindo motor de regras (score em extremos,CampanhaController::show() passa a injetar diagnósticos da campanha via container.bin/console seed agora suporta múltiplos seeders.canais com catálogo fixo (Google Ads, Meta Ads, TikTok Ads, Instagram, Outro)database/seeders/canais_seeder.php).campanhas com FKs para usuarios, clientes e canais.CanalRepository + CanalService (listagem, opções compactas, busca).CampanhaRepository com paginação, filtros combinados (busca, canal, cliente, status),CampanhaService com validação server-side (cliente pertence ao usuário, canal existe,CampanhaController completo (index com filtros, create, store, show, edit, update, destroy).AuthMiddleware.campanhas/index (filtros + paginação), campanhas/form (criar/editar) ecampanhas/show (detalhe com placeholder para métricas).seed no CLI (php bin/console seed [nome]).CanalServiceTest (4 casos) e CampanhaServiceTest (12 casos).DashboardController agora injeta CampanhaService.CanalRepository, CampanhaRepository, CanalService,CampanhaService e CampanhaController.DashboardController com dashboard real: KPIs (total, ativos, inativos, segmentos),ClienteRepository::resumoPorUsuario() e ClienteService::resumo() (agregações por status e segmento).Alert (App\Support\Alert) com API fluente (success/error/warning/info)render() idempotente, eliminando duplicação do partial flash.AlertTest (5 casos) e casos adicionais de ClienteServiceTest::resumo.data-label.layouts/app.php reescrito com menu mobile robusto e CSS de tabela responsiva.partials/flash.php simplificado: delega para Alert::render().layouts/auth.php usa Alert::render() diretamente.ClienteController e AuthController passam a usar Alert::* no lugar de Session::flash.AuthController::dashboard() removido (migrado para DashboardController)./dashboard agora aponta para DashboardController::index.DashboardController.layouts/app.php) com sidebar, topbar e identidade visual do protótipo.sidebar com navegação (Dashboard, Clientes) e logout em formulário POST+CSRF.topbar com Changelog/subChangelog dinâmicos e slot de ações.ClienteRepository com findByUsuarioId, existsByNome, paginateByUsuario e countByUsuario.ClienteService com validação server-side, unicidade por usuário (case-insensitive),usuario_id e mensagens de erro prontas para o usuário.ClienteController com index, create, store, show, edit, update, destroy.Pagination (helper + partial) com preservação de query string.clientes/index, clientes/form e clientes/show fiéis ao protótipo aprovado,AuthMiddleware, com CSRF global.ClienteRepository e ClienteService.AuthController::dashboard agora exibe contagem de clientes do usuário (placeholder até Sprint 2).ClienteServiceTest (16 casos) e PaginationTest (5 casos).log / smtp) controlados por MAIL_DRIVER.LogDriver grava mensagens formatadas em logs/email.log (útil em desenvolvimento).SmtpDriver envia via PHPMailer lendo credenciais de config/mail.php / .env.TokenService com tokens de uso único (random_bytes(32) + sha256), expiraçãoUsuarioRepository e TokenEmailRepository (herdam BaseRepository).AuthService: cadastro, confirmação por e-mail, login (bloqueado sem confirmaçãoiniciarResetSenha() (reenvia confirmação seresetarSenha().Session com start idempotente, flash messages, old input, errors e expiração por inatividade.Csrf (geração, campo, validação com hash_equals) e CsrfMiddleware aplicado globalmente.AuthMiddleware e GuestMiddleware.App\Kernel\Container).login, cadastro, esqueci-senha, resetar-senha,confirmar-sucesso) coerentes com o protótipo aprovado.old(), csrf_token(), csrf_field(), flash(), auth_user(), auth_check().LogDriverTest, TokenServiceTest, AuthServiceTest (fluxo completo).Database (PDO singleton, MySQL/SQLite, transações seguras).Migrator com suporte a up/down, batches, status, pending, rollback e fresh.usuarios, tokens_email (com FK e cascade) e clientes (com FK para usuarios).BaseRepository com find, findOrFail, findBy, all, where, count, exists,paginate, create, update, delete, deleteWhere e proteção via $fillable/$guarded.bin/console com comandos migrate, rollback [N], status, fresh --force e help.DatabaseTest, MigratorTest, BaseRepositoryTest.Request, Response, Route, Router.{id}), grupos (prefix, name, middleware),->name(), Router::url(), route()).MiddlewareInterface.404, 405 e 500 com views dedicadas e resposta JSONapplication/json.View renderer simples com setBasePath().Controller base com view(), json(), redirect(), back().route(), esc() e base_url()/asset() revisados para evitarURL_PATH está vazio.RequestTest, RouterTest) + phpunit.xml.logs/app.log a partir do Application::logError()..env via vlucas/phpdotenv (safeLoad).base_url() e asset() respeitando URL_BASE + URL_PATH (funciona em subpasta do htdocs).env(), base_url(), asset().app.php, database.php, mail.php, logging.php.logs/ (fora do versionamento).log / smtp) com suporte a logs/email.log..htaccess raiz redirecionando para /public e front controller em public/.htaccess..gitignore, .editorconfig.composer.json com dependências base (phpdotenv, PHPMailer, Monolog) e PHPUnit em dev.README.md, CONTEXTO_PROJETO.md.