From f83315baba58ed63b65cdd588e43a9ef8eaab4d6 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Wed, 20 May 2026 15:23:18 -0300 Subject: [PATCH] agenda: popover watch acompanha transicao virtual->materializada Bug do "Usar sumiu apos revogar antecipacao": o watch sincronizava eventoSelecionado por id, mas quando virtual era materializada (antecipar/Usar/Realizada flow) o id mudava de rec::rule::date pra uuid real. Watch nao achava match -> popover ficava preso na versao virtual stale -> botoes refletiam estado antigo. Fix: lookup em 2 etapas: 1) match por id (caso comum) 2) match por recurrence_id+recurrence_date quando nao acha (caso virtual->materializada). Pega a versao real correspondente aquela data. Estado final do teste C12 do user: status=realizado, saldo 3/4, 1 pending + 5 cancelled (audit trail de varios ciclos antecipar/ revogar). Funcionalmente OK; com o fix, retestes ficam mais limpos. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/layout/melissa/MelissaLayout.vue | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/layout/melissa/MelissaLayout.vue b/src/layout/melissa/MelissaLayout.vue index 0eed595..a005406 100644 --- a/src/layout/melissa/MelissaLayout.vue +++ b/src/layout/melissa/MelissaLayout.vue @@ -669,12 +669,24 @@ function fecharEvento() { // Sem isso, eventoSelecionado.value é snapshot do clique e não acompanha // updates do _paymentStateMap pós refetch (caso típico: revogar/antecipar // pagamento — record muda mas popover continuava mostrando estado antigo). -// Watch dispara apenas quando o ev correspondente aparece novo no eventos -// computed (paymentState atualizado pelo bulk-load). +// Lookup em 2 etapas: +// 1) match por id (caso comum — evento real persistente) +// 2) match por recurrence_id+recurrence_date (caso virtual → materializada: +// id muda de `rec::rule::date` pra uuid real após antecipar/Usar/etc). +// Sem o 2o lookup, popover ficava preso na versão virtual após o evento +// virar real — exemplo: revoguei antecipação, "Usar" não aparecia porque +// ev ainda era a versão virtual stale. watch(() => M.eventos.value, (novos) => { const sel = eventoSelecionado.value; if (!sel?.id) return; - const fresh = novos.find((e) => e.id === sel.id); + let fresh = novos.find((e) => e.id === sel.id); + if (!fresh && sel.recurrence_id && sel.recurrence_date) { + fresh = novos.find((e) => + !e.is_occurrence && + e.recurrence_id === sel.recurrence_id && + e.recurrence_date === sel.recurrence_date + ); + } if (fresh && fresh !== sel) { eventoSelecionado.value = fresh; }