Skip to content

fix(journey): gatilho por evento sem ids obrigatórios e filtros usáveis (CRM-519) - #371

Merged
gomessguii merged 3 commits into
developfrom
fix/CRM-519-gatilho-evento-sem-ids-obrigatorios
Sep 6, 2026
Merged

gomessguii merged 3 commits into
developfrom
fix/CRM-519-gatilho-evento-sem-ids-obrigatorios

Conversation

@nickoliveira23

@nickoliveira23 nickoliveira23 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • O gatilho por evento de jornada tratava os campos required do catálogo como inputs obrigatórios do usuário (asterisco em purchase_id, conversation_id, message_id). No catálogo, required é "o produtor sempre envia"; no evo-flow, as propriedades do gatilho são um filtro opcional por igualdade. O gatilho era inutilizável pela tela.
  • Todo campo do schema vira filtro opcional atrás de "+ Adicionar filtro", com remoção por linha e a dica de que sem filtro a jornada dispara em toda ocorrência. Ids de identidade, chaves internas (source, dumps), nomes que duplicam um id e campos date/object não são oferecidos. Linha legada persistida continua visível e removível.
  • Ids do CRM viram Select alimentado pelos services (funil, etapa dependente do funil, canal, etiqueta, agente, campanha, template). Conjuntos fechados viram Select via options no FieldSpec, com os valores que o CRM emite de fato (Channel::*, incoming/outgoing, sent/delivered/read/failed, contact_type, created_via, content_type).
  • Canal e tipo de canal são um filtro só: a lista de canais segue o tipo escolhido, o tipo some do picker quando há canal, e um par legado contraditório ganha aviso inline com o botão de remover.
  • Rótulo humano e ajuda para cada campo, e descrição de cada evento, nos 6 locales. Sem fallback para o texto em inglês do catálogo.
  • Troca de evento sem diálogo: mantém os filtros compatíveis (mesma chave e tipo), avisa quantos saíram e oferece Desfazer. Salvar fica desabilitado sem evento ou com personalizado sem nome, com a mensagem sob o campo.
  • Modal: sem separador colado no título, "Como a jornada começa", descrição como texto simples, um aviso e um título no modo personalizado, roda do mouse nos dropdowns (Popover modal dentro do Dialog).

Security

  • Só front: sem rota nova, sem mudança de contrato com o evo-flow (a forma persistida {path, operator: {type: 'Equals', value}} é a mesma).
  • Os selects usam os services já existentes da conta; nenhum dado novo é exposto.

Test plan

  • npx vitest run src/components/journey/nodes/trigger src/components/journey/shared src/lib/events-manifest src/i18n src/services/channels (488 passed, na branch rebaseada no develop atual)
  • npx tsc --noEmit e eslint nos arquivos tocados (limpos); vite build do shell OK
  • Tela (camada conta, Jornadas → nova jornada → gatilho por evento): sem asterisco; "Conversa criada" → "Tipo de canal" abre select e "Canal" lista os canais do tipo escolhido; "Contato criado" sem created_at/customAttributes/id, com E-mail, Telefone e Tipo de contato; troca de evento com filtro incompatível mostra "1 filtro removido…" com Desfazer; personalizado sem nome não salva e diz o motivo; roda do mouse rola os dropdowns.

Rodada 2 (review de 04/09)

  • Branch rebaseada no develop: só o test.yml conflitou (lanes de lista fechada), mantidos os dois lados.
  • purchase.approved entrou no develop pela PR feat(frontend): evento Compra aprovada no manifesto de eventos (CRM-316) #369 depois desta branch: descrição do evento nos 6 locales, outcome com options (created | already_in_pipeline) e rótulos, e 3 specs cobrindo o evento (ids escondidos, product texto livre e amount numérico, outcome select).
  • Lookups pedem o mesmo tamanho de página que os filtros do CRM já usam: etiquetas e canais 200, agentes 100, templates -1. O index de canais pagina, então InboxesService.list ganhou o parâmetro opcional; os outros chamadores seguem sem argumento.
  • Exceção declarada: product fica em texto livre. No purchase.approved ele é a string do produto que a plataforma de pagamento envia (virtu, hotmart, kiwify, cakto), não um Product do CRM; um dropdown de produtos do CRM geraria filtro que nunca casa.
  • Comentários que o diff tornou falsos corrigidos (diálogo de troca de evento, campos obrigatórios), justificativa verdadeira no eslint-disable, fragmento vazio removido, ajuda do tipo de canal e rótulo "Atribuído por" condizentes com selects.
  • Limite conhecido: conta com mais de 200 etiquetas ou 100 agentes ainda trunca a lista; busca no select fica para o card de UX.

Fora do escopo

  • Aba Avançado (EventAdvancedConfig + VariableMapping): não foi tocada; estouro horizontal, caixa fixa e copy ficam para cards próprios.
  • Chaves ainda em texto livre por não terem conjunto verificado no CRM: activity_type, changeType, resolved_by_type, reason.
  • Select de lookup com valor persistido que já não existe na lista mostra o placeholder e mantém o valor gravado (só exibição).

Changed Files

  • src/components/journey/shared/EventPropertiesForm/{EventPropertiesForm.tsx,filterFields.ts,filterFields.spec.ts,EventPropertiesForm.spec.tsx,EventPropertiesForm.stories.tsx}
  • src/components/journey/shared/EventSelector/EventSelector.tsx
  • src/components/journey/nodes/trigger/{JourneyTriggerPanel.tsx,JourneyTriggerPanel.spec.tsx}
  • src/components/journey/nodes/trigger/components/{EventBasicConfig.tsx,EventBasicConfig.spec.tsx,EventConfiguration.tsx,EventConfiguration.spec.tsx,EventConfiguration.both-contexts.spec.tsx,TriggerDescription.tsx}
  • src/lib/events-manifest/{catalog.ts,types.ts,index.ts,event-properties-bridge.ts,event-properties-bridge.spec.ts}
  • src/services/channels/inboxesService.ts
  • src/i18n/locales/{pt,pt-BR,en,es,fr,it}/{events.json,journey.json}, src/i18n/locales/_lib/allowlist.ts, src/i18n/locales/journey-parity.spec.ts
  • .github/workflows/test.yml

Linked Issue

  • CRM-519

🤖 Generated with Claude Code

https://claude.ai/code/session_01JxYjUwr2vV69kYddiXJHRo

Summary by Sourcery

Make journey event triggers usable with optional, localized, and CRM-aware filters while preserving compatibility with existing saved configurations.

New Features:

  • Offer event-trigger properties as optional equality filters with add/remove controls and guidance for unfiltered triggers.
  • Provide CRM-backed selects and closed-set options for supported filter values, including dependent pipeline stages and channel-aware inbox selection.
  • Localize event descriptions, field labels, help text, and option labels across all supported locales.

Bug Fixes:

  • Stop treating catalog-producer-required fields and event identity IDs as user-required trigger inputs.
  • Prevent incompatible filters from remaining after event changes by retaining compatible filters and offering inline Undo for removed filters.
  • Prevent incomplete event configurations from being saved and improve dropdown scrolling within the trigger dialog.

Enhancements:

  • Hide timestamps, objects, internal fields, and redundant display names from the filter picker while preserving legacy persisted filters for removal.
  • Add inline warnings for contradictory legacy channel and inbox filters and retain the existing persisted filter contract.
  • Extend lookup loading to request appropriate page sizes for complete CRM select options.

CI:

  • Expand the focused CI test gate to cover event filter, trigger configuration, and locale parity regressions.

Documentation:

  • Update component guidance to describe optional event filters and CRM-backed filter controls.

Tests:

  • Replace required-field validation coverage with tests for optional filters, event switching, lookup selects, closed-set options, localization parity, legacy filters, and lookup pagination.

Chores:

  • Remove obsolete required-property validation and event-switch confirmation-dialog behavior.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @nickoliveira23, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 3 days by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Reviewer's Guide

Replaces unusable required event-trigger inputs with optional, localized equality filters, adds CRM-backed and enum selects with channel-aware behavior, improves event switching and save validation, and strengthens regression and i18n contract coverage without changing the persisted evo-flow contract.

Sequence diagram for switching event filters with Undo

sequenceDiagram
    participant User
    participant EventBasicConfig
    participant EventPropertiesForm
    participant JourneyTriggerPanel

    User->>EventBasicConfig: Select new event
    EventBasicConfig->>EventPropertiesForm: preserveCompatibleValues
    EventPropertiesForm-->>EventBasicConfig: Compatible filters
    EventBasicConfig->>EventBasicConfig: onEventPropertiesChange
    EventBasicConfig-->>User: Show dropped-filter status and Undo
    alt User selects Undo
        User->>EventBasicConfig: handleUndoSwitch
        EventBasicConfig->>EventBasicConfig: onEventNameChange
        EventBasicConfig->>EventBasicConfig: onEventPropertiesChange
        EventBasicConfig-->>User: Restore prior event and filters
    else User edits a filter
        User->>EventBasicConfig: Edit filter
        EventBasicConfig->>EventBasicConfig: Clear dropped-filter status
    end
Loading

Flow diagram for configuring an event trigger with optional filters

flowchart TD
    A[Choose event] --> B{Canonical or custom?}
    B -->|Canonical| C[Show localized event description]
    C --> D[Add optional equality filter]
    D --> E{Filter type}
    E -->|CRM id| F[Load options from CRM service]
    E -->|Closed set| G[Show enum Select]
    E -->|Other supported field| H[Show value input]
    F --> I[Persist path and Equals value]
    G --> I
    H --> I
    C --> J[Save with no filters]
    B -->|Custom| K[Enter custom event name]
    K --> L{Name present?}
    L -->|Yes| M[Enable Save]
    L -->|No| N[Keep Save disabled]
Loading

File-Level Changes

Change Details Files
Reworked canonical event properties into optional equality filters instead of required user inputs.
  • Removed required-field validation and asterisk indicators.
  • Added an Add filter picker with per-row removal and legacy-row visibility.
  • Excluded event identity, internal, timestamp, and object fields from new filters while preserving persisted compatibility.
src/components/journey/shared/EventPropertiesForm/EventPropertiesForm.tsx
src/components/journey/shared/EventPropertiesForm/filterFields.ts
src/lib/events-manifest/event-properties-bridge.ts
src/components/journey/nodes/trigger/components/EventBasicConfig.tsx
src/components/journey/nodes/trigger/JourneyTriggerPanel.tsx
Added typed filter controls backed by CRM data and event-manifest value sets.
  • Added service-backed selects for pipelines, dependent stages, inboxes, labels, agents, campaigns, and templates.
  • Added enum options for CRM-emitted channel, message, contact, creation, status, and content values.
  • Combined inbox and channel type behavior, including narrowing, implied picker removal, and contradictory legacy warnings.
src/components/journey/shared/EventPropertiesForm/EventPropertiesForm.tsx
src/components/journey/shared/EventPropertiesForm/filterFields.ts
src/lib/events-manifest/catalog.ts
src/lib/events-manifest/types.ts
Improved event switching and trigger validity behavior.
  • Automatically retained compatible filters and removed incompatible ones without a dialog.
  • Added an inline removal notice with Undo that restores the previous event and filters.
  • Enabled saving for any selected canonical event without filters and gated saving for missing or unnamed custom events.
src/components/journey/nodes/trigger/components/EventBasicConfig.tsx
src/components/journey/nodes/trigger/JourneyTriggerPanel.tsx
src/components/journey/nodes/trigger/components/EventConfiguration.tsx
Localized event and filter presentation across all supported locales.
  • Added human labels, help text, option labels, event descriptions, and updated journey copy in six locales.
  • Added parity and filter-contract tests to prevent missing translations and unsupported field controls.
src/i18n/locales/en/events.json
src/i18n/locales/pt-BR/events.json
src/i18n/locales/pt/events.json
src/i18n/locales/es/events.json
src/i18n/locales/fr/events.json
src/i18n/locales/it/events.json
src/i18n/locales/journey-parity.spec.ts
src/components/journey/shared/EventPropertiesForm/filterFields.spec.ts
Refined trigger modal and dropdown interaction behavior.
  • Simplified trigger descriptions and modal headings/alerts.
  • Enabled modal popovers so nested event and filter dropdowns scroll correctly inside the dialog.
src/components/journey/nodes/trigger/components/TriggerDescription.tsx
src/components/journey/shared/EventSelector/EventSelector.tsx
src/components/journey/shared/EventPropertiesForm/EventPropertiesForm.tsx
Expanded regression coverage and CI execution for the new filter contract.
  • Updated journey trigger and event configuration tests for optional filters, switching, custom-event validation, and persisted shapes.
  • Added service mocks and tests for lookup loading, dependent stages, enums, filtering, removal, and legacy conflicts.
  • Included focused filter tests in the CI test command.
src/components/journey/shared/EventPropertiesForm/EventPropertiesForm.spec.tsx
src/components/journey/nodes/trigger/JourneyTriggerPanel.spec.tsx
src/components/journey/nodes/trigger/components/EventBasicConfig.spec.tsx
src/components/journey/nodes/trigger/components/EventConfiguration.spec.tsx
src/components/journey/nodes/trigger/components/EventConfiguration.both-contexts.spec.tsx
.github/workflows/test.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@nickoliveira23
nickoliveira23 force-pushed the fix/CRM-519-gatilho-evento-sem-ids-obrigatorios branch from 3c0adc0 to 8fe4646 Compare September 5, 2026 13:38
nickoliveira23 and others added 3 commits September 6, 2026 11:49
…is (CRM-519)

O formulário do gatilho lia `schema.required` do catálogo como "o usuário
precisa preencher" e pedia purchase_id, conversation_id, message_id com
asterisco. No catálogo, required significa "o produtor sempre envia"; no
evo-flow, as propriedades do gatilho são um filtro opcional por igualdade.

- Todo campo do schema é filtro opcional atrás de "+ Adicionar filtro",
  com remoção por linha. Ids de identidade, chaves internas, timestamps e
  objetos não são oferecidos; linha legada persistida continua visível e
  removível.
- Ids do CRM viram select (funil, etapa dependente do funil, canal,
  etiqueta, agente, campanha, template). Conjuntos fechados viram select
  via `options` no FieldSpec, com os valores que o CRM emite
  (Channel::*, incoming/outgoing, sent/delivered/read/failed...).
- Canal e tipo de canal são um filtro só: a lista de canais segue o tipo
  escolhido, o tipo some quando há canal, par legado contraditório ganha
  aviso inline.
- Rótulo, ajuda e descrição de evento em pt, pt-BR, en, es, fr e it; sem
  fallback para o texto em inglês do catálogo.
- Troca de evento sem diálogo: mantém os filtros compatíveis, avisa quantos
  saíram e oferece Desfazer.
- Salvar desabilitado sem evento ou com personalizado sem nome, com a
  mensagem sob o campo. `validateEventProperties` removida.
- Modal: sem separador colado no título, "Como a jornada começa",
  descrição como texto simples, um aviso e um título no modo
  personalizado, roda do mouse nos dropdowns (Popover modal).
- Spec de contrato do filtro (rótulo e ajuda em todo locale, select para
  uuid e conjunto fechado, nada de date/object) na lane do Vitest.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxYjUwr2vV69kYddiXJHRo
…ados e acabamento do review (CRM-519)

Rodada 2 do review. A branch foi rebaseada no develop, que trouxe o
purchase.approved (PR #369) depois de a rodada 1 nascer:

- events.purchase_approved.description nos 6 locales e `options` em
  `outcome` (created | already_in_pipeline) com rótulos, para a guarda
  de contrato ficar verde com o catálogo atual.
- Specs cobrindo purchase.approved: ids da compra e do card fora do
  picker, product em texto livre e amount numérico, outcome como select.
- Lookups pedem o mesmo tamanho de página que os filtros do CRM já usam
  (etiquetas e canais 200, agentes 100, templates -1); o index de canais
  pagina, então InboxesService.list ganha o parâmetro opcional.
- Comentários que o diff anterior tornou falsos corrigidos (diálogo de
  troca de evento e campos obrigatórios não existem mais); justificativa
  verdadeira no eslint-disable; fragmento vazio removido; ajuda do tipo
  de canal e rótulo de "Atribuído por" condizentes com selects.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxYjUwr2vV69kYddiXJHRo
… fixes (CRM-519)

Round 2 review findings.

- provider is a closed set of four adapters (virtu, hotmart, kiwify,
  cakto, registered in config/initializers/purchase_adapters.rb) and was
  the last offered key still rendering as free text. It gets `options`
  plus labels in the six locales, and its help stops reading as a
  "type it like this" hint now that it is a select.
- The contract guard only read a closed set off a `|` in the
  description, which is why provider slipped through: it now also reads
  a parenthesised comma list of three or more bare tokens.
- The campaign lookup still asked for the default page (25 in evo-flow),
  the one paginated endpoint the previous round left out.
- The page sizes had no guard at all; EventPropertiesForm.spec pins what
  each lookup sends, including the pipeline endpoints that take nothing.
- Event-config validity moves from `dirty` to `saveDisabled`, the
  NodeConfigModal prop documented for it. Same rendered state.
- Comments: the flag in JourneyTriggerPanel no longer reports
  "required-field validity" (nothing is required), and EventBasicConfig
  is no longer an "extracted verbatim" copy of EventConfiguration.
- CI lane takes EventBasicConfig.spec (switch notice and Undo) and
  journey-parity.spec, the only guard for the six-locale event-switch
  keys since i18n-parity skips journey.json.
@gomessguii
gomessguii force-pushed the fix/CRM-519-gatilho-evento-sem-ids-obrigatorios branch from 2d65f54 to f495054 Compare September 6, 2026 14:54
@gomessguii
gomessguii merged commit 6dc27d9 into develop Sep 6, 2026
7 checks passed
@gomessguii
gomessguii deleted the fix/CRM-519-gatilho-evento-sem-ids-obrigatorios branch September 6, 2026 15:00
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