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) <noreply@anthropic.com>
This commit is contained in:
Leonardo
2026-05-20 15:23:18 -03:00
parent 7d2a405d05
commit f83315baba
+15 -3
View File
@@ -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;
}