Skip to content

fix(marketing): corrige participantes ausentes no Meeting Showcase - #478

Merged
danielhe4rt merged 3 commits into
he4rt:4.xfrom
henrique-leme:story/477-meeting-showcase-participants
Aug 10, 2026
Merged

fix(marketing): corrige participantes ausentes no Meeting Showcase#478
danielhe4rt merged 3 commits into
he4rt:4.xfrom
henrique-leme:story/477-meeting-showcase-participants

Conversation

@henrique-leme

@henrique-leme henrique-leme commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Contexto

O Meeting Showcase podia encontrar a mensagem no período informado e ainda assim não identificar corretamente o participante. Isso acontecia porque os dados do Discord chegam em formatos diferentes e a tela só tratava parte deles.

Também existia um corte no último minuto escolhido. Ao informar 23:40 como horário final, por exemplo, mensagens enviadas depois de 23:40:00 ficavam fora da consulta.

Este PR corrige a leitura e exibição dos participantes que já foram ingeridos. O fluxo de ingestão das mensagens não foi alterado.

Alterações

  • Suporte aos formatos de metadata na raiz, em metadata.user e em metadata.author
  • Fallback para o usuário vinculado quando a identidade não possui metadata suficiente
  • Inclusão de identidades desconectadas que ainda possuem mensagens históricas
  • Inclusão de todo o último minuto selecionado no filtro de período
  • Testes cobrindo os formatos de metadata, fallback de usuário, identidade desconectada e mensagens dentro e fora do limite final

Plano de Testes

  • Rector nos arquivos alterados sem sugestões
  • Pint completo aprovado
  • PHPStan completo sem erros
  • Testes de Marketing com 8 testes e 69 assertions
  • Teste da importação de metadata.author com 1 teste e 4 assertions
  • Testes da persistência de mensagens com 3 testes e 9 assertions
  • Validação local da tela com participantes nos diferentes formatos de metadata

A suíte completa local executou 933 testes. Foram 931 aprovados e 2 falhas preexistentes em MergeDuplicateDiscordProfilesTest, causadas pelo tratamento de caminho absoluto do Windows no parâmetro --pairs-file. Esses testes ficam fora dos arquivos e do fluxo alterado neste PR. O CI em Linux fará a validação completa novamente.


Issues Relacionadas

Closes #477

@henrique-leme
henrique-leme requested a review from a team August 10, 2026 02:03
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Meeting Showcase participant loading now includes messages through the selected minute’s final second. External identities include soft-deleted records and linked users. Discord participant extraction supports root metadata, metadata.user, and metadata.author, with linked-user fallbacks. Feature tests cover participant fields, avatars, message counts, missing metadata, deleted identities, and end-minute filtering.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed As alterações atendem aos requisitos da issue #477, incluindo metadata, fallback, identidades desconectadas, limite final e testes.
Out of Scope Changes check ✅ Passed As alterações estão limitadas ao carregamento de participantes, ao filtro de período e aos testes correspondentes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed O título descreve de forma clara a correção principal da identificação de participantes no Meeting Showcase.
Description check ✅ Passed A descrição cobre contexto, alterações, testes executados, falhas preexistentes e issue relacionada.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
app-modules/panel-admin/tests/Feature/Marketing/MeetingShowcasePageTest.php (1)

135-155: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the exclusion side of the boundary.

The test proves inclusion at 23:40:59. It does not prove exclusion at 23:41:00. A future change to endOfMinute() (for example endOfHour()) would still pass.

♻️ Proposed additional case
test('it excludes messages sent after the selected end minute', function (): void {
    $identity = ExternalIdentity::factory()->create([
        'provider' => IdentityProvider::Discord,
        'external_account_id' => '445',
        'metadata' => ['username' => 'too-late-user'],
    ]);

    Message::factory()->create([
        'external_identity_id' => $identity->id,
        'channel_id' => 'meeting-channel',
        'sent_at' => Date::parse('2026-08-03 23:41:00', 'America/Sao_Paulo')->utc(),
    ]);

    livewire(MeetingShowcasePage::class)
        ->set('channelId', 'meeting-channel')
        ->set('startDate', '2026-08-03T22:00')
        ->set('endDate', '2026-08-03T23:40')
        ->call('loadParticipants')
        ->assertSet('participants', []);
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app-modules/panel-admin/tests/Feature/Marketing/MeetingShowcasePageTest.php`
around lines 135 - 155, Add a complementary test near “it includes messages sent
during the selected end minute” that creates a message at 23:41:00, uses the
same selected end time of 23:40, calls loadParticipants, and asserts
participants is empty, verifying messages after the selected minute are
excluded.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app-modules/panel-admin/tests/Feature/Marketing/MeetingShowcasePageTest.php`:
- Around line 135-155: Add a complementary test near “it includes messages sent
during the selected end minute” that creates a message at 23:41:00, uses the
same selected end time of 23:40, calls loadParticipants, and asserts
participants is empty, verifying messages after the selected minute are
excluded.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5919169c-5521-4c90-8ada-41b0e78cbb57

📥 Commits

Reviewing files that changed from the base of the PR and between de3efd4 and a9f4ce3.

📒 Files selected for processing (2)
  • app-modules/panel-admin/src/Marketing/Pages/MeetingShowcasePage.php
  • app-modules/panel-admin/tests/Feature/Marketing/MeetingShowcasePageTest.php

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app-modules/panel-admin/tests/Feature/Marketing/MeetingShowcasePageTest.php (1)

109-132: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Assert aggregated message totals.

This test creates one message per identity and never checks total_messages. It would pass if repeated messages were counted incorrectly. Add a second message for one identity and assert its total_messages value.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app-modules/panel-admin/tests/Feature/Marketing/MeetingShowcasePageTest.php`
around lines 109 - 132, Update the participant aggregation assertions in
MeetingShowcasePageTest so the fixture includes a second message for one
identity, then assert that identity’s total_messages equals 2 while retaining
the existing participant count and identity assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@app-modules/panel-admin/tests/Feature/Marketing/MeetingShowcasePageTest.php`:
- Around line 109-132: Update the participant aggregation assertions in
MeetingShowcasePageTest so the fixture includes a second message for one
identity, then assert that identity’s total_messages equals 2 while retaining
the existing participant count and identity assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: dd763ae2-8d97-441e-a839-9eacb6e1d9b5

📥 Commits

Reviewing files that changed from the base of the PR and between a9f4ce3 and cdfb503.

📒 Files selected for processing (1)
  • app-modules/panel-admin/tests/Feature/Marketing/MeetingShowcasePageTest.php

Comment thread app-modules/panel-admin/src/Marketing/Pages/MeetingShowcasePage.php

@guisaliba guisaliba 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.

LGTM! mas tive a mesma dúvida do Nadachi.

@sirelves

sirelves commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

@Luisnadachi @guisaliba fui atrás dessa do author vs user, porque a resposta muda o que a linha 107 significa.

são o mesmo objeto: os dois são o User da API do Discord, mesmo schema (id, username, global_name, avatar). o que muda é de qual payload cada um foi arrancado. são três caminhos criando ExternalIdentity e cada um salva o payload cru do jeito que recebeu, o OAuth do site achata username/email/avatar na raiz do metadata, o import de perfil salva o $profile inteiro (e no profile o usuário vem embrulhado numa chave user), e o import de mensagem salva ['author' => $dto->authorRaw], que é o author do objeto Message. mesma pessoa, três embalagens.

e o que acho que tava por trás da dúvida: os dois nunca aparecem juntos no mesmo registro. o ImportDiscordProfileAction usa updateOrCreate com o metadata no array de update, então substitui o metadata inteiro toda vez que roda. o import de mensagem só escreve metadata no createIdentity, quando a identidade ainda nem existe. quem toca por último manda, e o perfil sempre ganha porque é o único que dá update. se a identidade nasceu de uma mensagem e o perfil for importado depois, o author some e vira user.

por isso o user ?? author não desempata nada. não existe registro com os dois, não tem risco de pegar a fonte errada. o ?? aqui não é defensivo, é a união de três produtores.

fora do escopo desse PR, mas esse sobrescrito me incomodou: quem logou com Discord no site tem email no metadata e perde ele se o perfil for importado depois. vou abrir issue pra normalizar na ingestão, aí a tela lê um formato só em vez de adivinhar três.

@buzinei-bibi buzinei-bibi 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.

lgtm

@hefeus

hefeus commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

LGTM

@danielhe4rt
danielhe4rt merged commit 65f9fcd into he4rt:4.x Aug 10, 2026
9 checks passed
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.

fix(marketing): participantes da reunião não aparecem corretamente no Meeting Showcase

7 participants