Releases: evolution-foundation/evo-ai-crm-community
v1.0.0-rc5
[v1.0.0-rc5] - 2026-05-27
Hardening of fresh-install plus a substantial expansion of the EvoFlow surface. Critical first-boot fixes (auth-service race on first start, EvoFlow event schema sanity) ship alongside new EvoFlow capability: a contact_events backfill worker, the proxied /contacts/:id/events endpoint with enrich, five new flow node types wired into automation rules, and Evolution Hub promoted into a usable Meta proxy (channel linking, legacy gate removed).
Highlights
- Fresh-install hardening — first-boot races and missing schema entries that affected clean installations are resolved; new deployments now come up cleanly without manual intervention.
- EvoFlow expansion —
contact_eventsbackfill worker, proxied events endpoint with enrich (EVO-1243), five new flow node types inActionService(EVO-1262), and Ruby-side event schema mirror with validator (EVO-1261). - Evolution Hub usable as a Meta proxy — inboxes can now be linked to an existing Hub channel and the legacy
EVOLUTION_HUB_URLgate is gone.
Added
- EVO-1243 — Proxied
/contacts/:id/eventsendpoint with enrich — exposes a contact's event stream from EvoFlow through the CRM, enriching each event with the additional context the UI needs. Includes a STI guard added during review hardening. - EVO-1261 — Ruby-side mirror of the EvoFlow event schema +
SchemaValidator—EVENT_SCHEMAis mirrored in Ruby and deep-frozen; the validator enforces strict UUID format, rejects empty strings, performs an eager schema check, and raises on unregistered event names. Backed by review iterations covering the cast ofinbox_id/assigned_by_idto:uuidin the fork. - EVO-1262 — Five new flow node types in automation rules —
ActionServiceis collapsed onto shared pipeline and message action handlers, and five new flow node types are wired through them. Ships with a parity harness, spec coverage, and a README describing the shared-handler contract. - EvoFlow
contact_eventsbackfill worker — backfills the newcontact_eventsdata set for installations that predate EvoFlow. Hardened across two review passes. - Evolution Hub — link inbox to an existing Hub channel — operators can now attach a CRM inbox to a pre-existing Evolution Hub channel rather than always provisioning a fresh one through the proxy.
- Notifications payload — sender name, avatar, preview and
last_activity_at— the notification payload now carries enough context for clients to render a rich list without an extra round-trip.
Changed
- EVO-1419 — Notifications scope tightened — inbox fan-out is no longer part of the EVO-1419 scope; the payload-enrichment work above is the remaining deliverable.
pipeline_task_*notification types are declared explicitly out of scope for this iteration. - WhatsApp Cloud send errors routed through
StatusUpdateService— send-time errors on WhatsApp Cloud now flow through the same status-update funnel as the other providers, keeping the message-status pipeline consistent. - Schema regenerated for
AddEvolutionHubMetaToChannels(EVO-1455) —schema.rbreflects the new Evolution Hub Meta columns onchannels.
Fixed
- EvoFlow — missing schema entries for 5 conversation events — closes gaps in the freshly mirrored event schema that surfaced during fresh-install smoke tests.
- Evolution Hub — legacy
EVOLUTION_HUB_URLgate removed — installations no longer need to set the legacy environment variable for Hub flows to activate; configuration is read from the canonical source. - Notifications — nil sender on assignment +
avatar_urllookup — assignment notifications no longer crash when the assigning user is nil, andavatar_urlis fetched defensively.
Notes for upgrade
- Run
db:migrateon upgrade — theAddEvolutionHubMetaToChannelsmigration adds the Evolution Hub Meta columns tochannels. - Fresh installs now boot cleanly when the auth service races with other services on first start; no manual workaround is required on new deployments.
- The EvoFlow
contact_eventsbackfill worker is safe to run on existing installations and is idempotent. Operators upgrading from rc4 should let it complete before relying on the new/contacts/:id/eventsendpoint. - No new required environment variables.
EVOLUTION_HUB_URLis no longer consulted; if you still have it set, you can remove it.
v1.0.0-rc3
[v1.0.0-rc3] - 2026-05-17
Release de estabilização — concentra correções de bugs em paridade de payload com Evolution Go (botões/listas), entrega de mídia outbound, hardening do endpoint Notificame verify, filtragem de secrets em logs Rails, bulk actions, escopo IDOR e diversas correções de automation rules. Também consolida a fundação do open-core via EXTENSION_POINTS.md + lib/evo_extension_points/ (módulos no-op), introduz catálogo de products com variantes + venda em pipeline, export/import de bundles de templates (EVO-1116) e endpoint para limpar configurações de admin por tipo.
Added
- Catálogo de Products — modelo completo de products com variantes, attach a agentes via tab dedicada e venda integrada ao pipeline (panel de vendas no item de pipeline).
- Template Bundles — export & import (EVO-1116) — exportação e importação de configuração via bundle ZIP. Permite empacotar inboxes, agentes, automation rules, canned responses e templates em um único arquivo portável entre instalações.
- EVO-1051 —
DELETEendpoint para limpar admin config por tipo — operador da instalação pode resetar configurações específicas (SMTP, Storage, etc.) sem ter de editar o banco. - EVO-1287 — CI guard-rail para o contrato
EvoExtensionPoints(#76) — workflow que falha o PR se módulos dolib/evo_extension_points/forem modificados sem revisão consciente. Garante que a Enterprise edition continue podendo injetar implementações sem precisar de fork. - EVO-1286 —
lib/evo_extension_points/com 5 módulos no-op (#75) — pontos de extensão declarados como módulos no-op, prontos para serem reabertos pela Enterprise. Contrato versionado emEXTENSION_POINTS.md. - EVO-1283 —
EXTENSION_POINTS.md(#73) — documento declarando 4 hooks versionados expostos pelo CRM como contrato público de extensão. - EVO-1058 — operador
attribute_changedem labels com dedup de dispatch (#56). Automation rules passam a reagir a mudanças de atribuição de label sem disparar duas vezes para o mesmo evento. - EVO-1057 — listeners para
conversation_resolvedeconversation_status_changed(#53). Amplia o vocabulário de triggers do automation rules para cobrir mudanças de status da conversa. - EVO-1011 — Bulk actions — collect de resultados por item e resposta com
success_ids/failed_ids, suporte a resolve em massa de conversas via checkbox. - Pipelines —
move_to_pipelineaction — automation rules ganham ação para mover conversa entre pipelines preservando o id do item. Inclui dedup depipeline_stage_updatedem janela de 5s por(rule, pipeline_item, stage)para evitar tempestade de eventos. - Inboxes — expansão de variáveis em message templates — variáveis ganham campos adicionais (
label,source,example,position,component) acessíveis no template. - Automation rule runs — gerenciamento + cleanup job — endpoint de API para consultar histórico de execução de regras + job de limpeza periódica.
- Action service — novos métodos
send_canned_responseesend_templatenoActionService(uso direto pelas automations). - Spec de regressão —
pipeline_item_specpara fluxo de auto-assign-and-move (EVO-1080) (#57). - Spec de regressão — Notificame verify endpoint (EVO-986).
- Spec de regressão — exclusão de contato com attachments (EVO-973) (#46).
- Spec de contrato —
Webhooks::Triggere endurecimento do spec de macros (EVO-1041).
Changed
- EVO-1113 — Consolidação de resolução de credenciais no
EvolutionConcern— antes a lógica estava espalhada por providers; agora um único concern centraliza o fallback per-field paraapi_url,admin_tokene demais credenciais Evolution. Reduz superfície de bug e facilita troca entre Evolution API e Evolution Go. - Docs padronizados para Evolution Foundation 2026 (README, LICENSE, NOTICE, TRADEMARKS).
- Docs (org) — URLs do GitHub atualizadas de
EvolutionAPIparaevolution-foundation. - Schema — comments atualizados em
automation_rule_run,roleeuser_role. - Schema — removidas tabelas e foreign keys não utilizadas.
Fixed
Mensageria — Evolution Go / Evolution API
- EVO-1115 — payload de buttons/lists para Evolution Go (#72) — formato corrigido para paridade com Evolution Go. Mensagens interativas (botões e listas) chegavam malformadas; agora seguem o schema esperado por ambos os providers.
- EVO-1151 — falha de entrega de mídia outbound (#70) — corrigido para Evolution API e Evolution Go. Anexos de outgoing não chegavam ao destinatário em determinados cenários de tamanho/codec.
- Mensagens duplicadas no incoming handler do Evolution Go — handler agora deduplica eventos antes de criar a conversa.
- Fallback de configuração Evolution —
api_urleadmin_tokenagora caem para oGlobalConfigquando a configuração por inbox está vazia.
Notificame / Webhooks
- EVO-986 — Notificame verify endpoint hardening — auth obrigatório, validação de payload, sem error leakage. Endpoint anterior expunha detalhes de erro úteis para enumeração.
- EVO-1041 — Macro webhook delivery failures — falhas em webhooks de macro agora são surfaceadas (antes ficavam silenciosas). Restrito o re-raise a
:macro_webhookpara evitar retry storm em outros tipos. Wired correto através deExecutionService→WebhookJob.
Automation rules
- EVO-1130 — Notificame attachment fallback_title (#69) — prefere
content[:fileName]quando disponível para gerar o título do anexo. - EVO-1049 — BMS/Resend delivery method (#66) — corrigida resolução do símbolo do delivery method para a classe correta.
- EVO-1011 — Bulk actions — fix das findings HIGH de review (round 2 e 3), spec de fixture com
pipeline_typeválido (EVO-1047). labelscondition — agora usaEXISTSsubquery (independente e NULL-safe), resolve UUIDs para títulos com fallback, e casa label em conversation OU contact.message_typefilter — aceita valores numéricos, não só keys de enum.apply_labelaction — resolve UUIDs para titles antes de tagear.pipeline_stage_updated— dedup em janela de 5s por(rule, pipeline_item, stage)evita disparo em rajada.- Cross-pipeline stage movement — bypass correto da validação
same-pipelinequando a action émove_to_pipeline. - Action templates —
send_templateusadeep_stringify_keys, parâmetros melhorados. MessageTemplateVariable— definido localmente para evitar quebra de build.- Diagnostic logging — adicionado em
move_to_pipelineepipeline_stage_updatedpara investigação de issues em produção.
Contacts / Pipeline
- EVO-1018 — Group contacts — distingue contatos de grupo WhatsApp de contatos reais de cliente; review feedback aplicado.
Mídia (EVO-999)
- HIGH review findings aplicadas para os fixes de mídia: fallback de
video file_type,fallback_titleem attachments, todos os caminhos de download cobertos.
Estabilidade
- Docker — bundler version — fixada durante installation para evitar build não-determinístico.
- EVO-1047 —
pipeline_item_specusapipeline_typeválido na fixture (antes quebrava o spec).
Security
- EVO-1111 — Filtragem de secrets nos logs Rails — campos sensíveis (
password,token,api_key, etc.) passam pelo filter parameters do Rails antes de chegar ao log. Antes era possível vazar credenciais em logs de erro/debug. - EVO-1084 — IDOR scope no
BulkActionsJob— escopo de account aplicado no job; antes era possível, com um ID válido de outra conta, manipular recursos cross-tenant. - EVO-986 — Notificame verify endpoint — auth obrigatório + validação fechada + sem error leakage (ver Fixed).
v1.0.0-rc2
Docker Image
docker pull evoapicloud/evo-ai-crm-community:1.0.0-rc2The Docker tag drops the leading
vfrom the git tag (v1.0.0-rc2→1.0.0-rc2).:latestalso tracks this release.
[v1.0.0-rc2] - 2026-05-05
Release de estabilização — concentra correções de 500 Internal Server Error em endpoints REST, fixes do fluxo Evolution Go, automation rules por stage, navegação card → conversation, performance de pipeline, migrations idempotentes para deploys em schemas drifted, RBAC de super_admin reconhecido como administrator em todos os bypasses, e signed URLs S3 para buckets privados em ambos os providers WhatsApp.
Added
- EVO-989 — Automation rules por stage: nova feature que permite configurar regras
trigger → actionpor estágio do pipeline. Triggers suportados:label_added,conversation_status_changed,custom_attribute_updated. Actions:move_to_stage,assign_agent,apply_label. Execução assíncrona via Sidekiq com loop prevention (Current.executed_by = :stage_automation). IncluiPipelines::StageAutomationService,PipelineStageAutomationListenere validação whitelist de payload no controller. (#44) - EVO-1007 backend —
PipelineItemSerializeragora expõeconversation.uuidna payload do pipeline para que o frontend possa navegar do card direto para/conversations/<uuid>. Mudança escopada (não tocaConversationSerializerglobal) para evitar regressão no chat. (#43) - EVO-1006 — busca e filtros adicionados ao kanban de pipeline (parte backend já estava na rc1, finalizada com
include_labelsna cadeia de serialização — #39). - EVO-987 — criação inline de label a partir do modal "Assign Label" (suporte backend).
Fixed
API REST — bugs que causavam 500
PATCH /api/v1/pipelines/:id/pipeline_items/:id/update_custom_fields:before_action :set_pipeline_itemnão cobria:update_custom_fields, então@pipeline_itemficavanile cada chamada levantavaNoMethodError. (#32)POST /api/v1/contacts/:id/companieslevantavaNoMethodError:validate :must_belong_to_same_accountdeclarado emContactCompanynão tinha implementação. Definido comono-op(Community é single-tenant). (#34)POST/DELETE /api/v1/contacts/:id/companiesretornavam 500 em violação de regra de negócio:error_response(code:, message:)com kwargs incompatíveis com a assinatura do helper (positional). Corrigido para retornar 400 com envelopeBUSINESS_RULE_VIOLATION. (#35)/api/v1/agents/*retornavam 500 /Unauthorized:current_userera passado como primeiro argumento posicional paraEvoAiCoreService.*_agent(a assinatura esperaparams/agent_data/agent_id); além disso,request.headersnunca era encaminhado, então oevo-corerecebia chamadas sem token Bearer. (#33) — follow-up registrado em #42 para replicar o fix nos demais controllers (apikeys,folders, etc).GET /api/v1/oauth/applications: retornava array JSON puro, mas o frontend espera o envelope padrão{ success, data, meta: { pagination } }. Tela/settings/integrations/oauth-appsquebrava comTypeError: Cannot read properties of undefined (reading 'pagination'). (#36)- EVO-1000 —
POST /api/v1/team_membersretornava 401 + body{"error":"Invalid User IDs"}para todo UUID válido (a validação faziaparams[:user_ids].map(&:to_i), mas o PK doUseré UUID — todos viravam0e nunca casavam). Resgate ajustado paraRecordInvalid/InvalidForeignKeycom 422 limpo. (#24)
Evolution Go (EvoGo) — fluxo WhatsApp
- Conversation routing — sem mais conversas duplicadas: quando o CRM enviava mensagem via EvoGo, o echo voltava como webhook com
IsFromMe: true, mas a busca de contato era por phone number — outgoing usa identificador LID (@lid), então nenhum match era encontrado e uma conversa nova era criada a cada envio. Lookup agora prioriza identifier LID e usa fallback para phone. (#22) - Sender type correto e contact lookup: outgoing eram salvos como
sender_type: Contactem vez deUser. Join de inbox no contact lookup também estava errado. Corrigido + reabertura de conversas pendentes ao chegar nova mensagem. (#22) - Mídia (imagem / áudio / vídeo) salva sem arquivo: 3 problemas distintos resolvidos juntos: (1)
ActiveStorage#after_commitnão disparava em Sidekiq → migrado paraActiveStorage::Blob.create_and_upload!síncrono; (2)mediaUrlaninhado emimageMessage/audioMessage/etc. agora é extraído viaextract_media_url; (3) EvoGo sem S3 manda mídia embase64inline — adicionado decode paraTempfile. (#22) - Áudio sem waveform / duração / PTT:
configure_audio_metadataeaudio_voice_note?estavam definidos duas vezes no mesmo módulo (Ruby usava silenciosamente a última definição, que era stub incompleta com keys erradas). Mergidas em definições únicas usando symbol keys. Também removidossave_message_and_notifyeattach_media_from_urlque eram dead code. (#22) - ActionCable — broadcast em token vazio:
account_tokenretornava""(string vazia) quando account era nil, e[account_token].compactdeixava passar a string vazia, causando broadcast em canal vazio. Função agora retornanil(verdadeiro nil) e aceita Hash + AR-object como input.ActionCableBroadcastJobtambém passou a tolerar payload com keys string ou symbol. (#22) - Mídia em bucket S3 privado retornava 404 no chat:
generate_direct_s3_urlmontava a URL pública diretamente (bucket.host/key), mas instalações que usam Cloudflare R2 ou S3 com ACL privada bloqueiam acesso público. Substituído porpresigned_url(signed URL com expiração curta) tanto nowhatsapp/providers/evolution_go_service.rb(commit316849d) quanto nowhatsapp/providers/evolution_service.rb(commitdaa9ee9— o caminho do Evolution API tradicional foi corrigido em seguida com a mesma lógica).
Listeners e dispatchers
ContactCompanyListener: eventos eram publicados viaWisper::Publishercomdata: { ... }, mas todos os listeners do projeto leem comoevent.data[:contact](esperando o wrapperEvents::BasedoSyncDispatcher). Resultado:undefined method 'data' for an instance of Hashno log + broadcastCONTACT_COMPANY_LINKEDnunca disparava. Migrado paraRails.configuration.dispatcher.dispatch(...)emLinkCompanyService,UnlinkCompanyService,Contact#add_companye#remove_company; listener toleraaccount: nilviasingle_tenant_account. (#37)- EVO-975 —
assign_to_default_pipelinena criação de conversa: removido:accountdo eager loading dopipelines_controller#fetch_pipeline(a associação não existe na edição community e geravaAssociationNotFoundError, impedindois_default: truede ser persistido), e adicionado logging detalhado para diagnosticar futuros problemas. (#26)
Performance e listas
- Pipeline chip na listagem de conversas só aparecia depois de tagear:
ConversationFinder#build_conversations_querymantinha o preload minimalista intencionalmente, sempipeline_items. Como oConversationSerializersó popula o blocopipelinesquando a associação está loaded, o frontend recebiapipelines: []e oConversationBadgescaía no branch "sem pipeline". Adicionadopipeline_items: [:pipeline, :pipeline_stage]ao preload — chip agora renderiza desde o primeiro load.
Serializers
- EVO-1010 —
TeamSerializeragora incluimembers_count(rodandoteam.team_members.countindexado porteam_id), corrigindo cards / linhas que mostravam0 membersmesmo com membros associados. (#25)
RBAC — super_admin reconhecido como administrator
Quando o evo-auth-service-community introduziu o role super_admin (ver changelog de auth nesta mesma release), as listas hardcoded do CRM continuavam apontando só para account_owner, então o operador da instalação aparecia sem privilégios em vários bypasses sutis (mailers de admin, finders de admin, helpers de permissão).
User#administrator?: passou a aceitar tantoaccount_ownerquantosuper_admin(app/models/concerns/user_attribute_helpers.rb). Antes filtros comoConversation.assignable_byretornavam vazio para super_admin, e a lista de conversas aparecia sem nada apesar do JWT estar válido.Role::ADMIN_ROLE_KEYS: nova constante centralizando%w[account_owner super_admin]. Adotada porAdministratorNotifications::BaseMailer#admin_emails(notificações de instalação) e por todo finder/scope que filtrava por role administrativo.- Effect: nenhum endpoint precisou ser alterado individualmente — a constante consolidou o que estava espalhado em quatro lugares (commit
5f1eed2).
Pipelines / Templates / Mensageria (do ciclo develop)
- EVO-974: aceita payload com filtros aninhados, suporta
pipeline_id/contact_id, equery_builderagora pareiarow + clausepara sobreviver a cláusulas vazias. - EVO-1002:
MessageTemplate#serializedespelhasettings.statusno top-level; criação de template roteia pelo provider sync (Meta) e não inverte maisactiveparafalseem sync de templatesPENDING/REJECTED. - EVO-1001: resolve UUIDs de labels ao tagear / renderizar conversas. (#14)
- EVO-1005:
pipeline_items#updatepersistepipeline_stage_id. (#27) - EVO-1006:
include_labelsagora atravessa toda a cadeia de serialização do pipeline. (#39) - EVO-984: fallback de credencial + webhook eager para Evolution Go. (#41)
- EVO-1055: novo endpoint
GET /api/v1/evolution/healthque faz proxy para${api_url}/do Evolution API e retorna o JSON upstream. O frontendEvolutionService.healthCheckdependia dessa rota para validar a URL configurada antes de criar um canal WhatsApp; sem ela, toda criação de canal Evolution API caía em 404 com "Health check falhou" e nenhum caminho adiante. Controller espelha o padrãoNet::HTTPde `authorizations_controller#check_server_s...
v1.0.0-rc1
What's Changed
- feat: Runtime Config — admin panel for system configurations by @gomessguii in #1
- fix(installation config): derive encryption key from secret_key_base when env var is unset by @gomessguii in #2
Full Changelog: https://github.com/EvolutionAPI/evo-ai-crm-community/commits/v1.0.0-rc1