# HANDOFF — 2026-05-19 (C1-C6 ✅, próximo C7 — pacote upfront) Documento de continuidade. **Quando voltar, comece lendo esta página até o fim.** > **🎯 SE A FORÇA CAIR / SESSÃO PERDER CONTEXTO:** estamos na rodada de > testes manuais dos 13 cenários do doc viva > `src/docs/agenda-compromisso-financeiro-cenarios.html`. **C1-C6 ✅**. > Próximo passo: **Cenário 7** (Donald Winnicott · pacote UPFRONT · 4 × > R$ 200 = cobrança única de R$ 800). > **🟢 WORKING TREE LIMPO** após commit/push de 19/05 da manhã. Migration > nova (20260519000001) já rodada no DB local. Pronto pra próximo bloco. --- ## 🔴 PRÓXIMO PASSO IMEDIATO — Cenário 7 (Pacote UPFRONT) | Campo | Valor | |---|---| | Paciente | **Donald Winnicott** | | Frequência | **Semanal · 4 ocorrências** | | Serviço | qualquer (ex: Sessão particular R$ 200) | | Cobrança ao salvar | **Gerar cobrança** + estilo **"Pacote único (upfront)"** | | Total esperado | **R$ 800** (4 × 200) | **Esperado:** - 1 row em `recurrence_rules` + **1 row em `agenda_eventos`** (1ª materializada) - 1 row em `billing_contracts` (type=package, charging_style=upfront, total_sessions=4, package_price=800) - **1 row em `financial_records`** com amount=800, status=pending (cobrança ÚNICA do pacote, vencimento na 1ª sessão) - Agenda: 1ª com badge $ (R$ 800 a cobrar) + 3 virtuais limpas (cobertas pelo pacote) Após C7: C8 (saldo) → C9 (per_session) → C10-C13 (status change + edit cobrada). Quando todos passarem, replicar em **Rail** (`AgendaTerapeutaPage.vue`) e **Clínica** (`AgendaClinicaPage.vue`). --- ## 📦 O que foi feito em 18/05 ### Cenário 4 (Joyce · "Já recebi") ✅ - Testado e passou: toast "Cobrança paga R$ 180,00 recebido via PIX", record nasceu `paid + payment_method=pix + paid_at=now()`. ### Novo indicador: barra esquerda verde para sessão paga - Brainstorm de 6 opções; user escolheu #6 (3 canais visuais distintos por estado). - `MelissaAgenda.vue:395-419` — computa `isPaidSession` (sessão+paciente+não-virtual+`paymentState==='paid'`) e adiciona classe `ma-evt--paid` ao FC event (combina com `ma-evt--inactive-patient` se ambos). - `MelissaAgenda.vue:2325-2335` — CSS força `border-left-color: #10b981 !important` (emerald-500, 4px). `!important` necessário porque FC seta `borderColor` inline. Trata também list view (`.fc-list-event-dot`). - Doc HTML atualizado: legenda "Indicadores visuais" agora descreve **3 estados** (pendente / pago / neutro) com 3 mocks empilhados; estado-alvo do C4 reescrito mencionando a barra verde. - Decisão salva em `memory/project_agenda_payment_indicators.md`. ### Linha "Cobrança" no popover + Resumo do dialog - **Popover `MelissaEventoPanel`** — antes só mostrava amber "A receber R$ X" pra pendente. Agora cobre os 3 estados, com cor + ícone por variante: - `paid` → `pi-check-circle` verde, label **"Pago · R$ X,XX"** - `pending` → `pi-dollar` amber, label **"A receber R$ X (cobrança pendente)"** (mantido) - `none` → `pi-dollar` amber, label **"A cobrar R$ X"** ou **"Cobrança ainda não gerada"** (mantido) - CSS reescrito em 3 modificadores `.evento-row--pay-{paid|pending|none}` (com dark mode). - **Resumo lateral do `AgendaEventDialog`** — nova linha entre `pi-clock` e `pi-map-marker` em ambas as cópias (mobile inline + desktop floating). - Novo ref `sessionPaymentRecord` em `useAgendaEventLifecycle.js:104+` (sem guard de `occurrenceMode`, contrário ao `occFinancialRecord` que continua só pra Rail/Clínica). Loader `loadSessionPaymentRecord` chamado no mesmo lifecycle. - Computed `paymentSummary` em `AgendaEventDialog.vue:951+` retorna `{icon, cls, label}` pra 5 casos: paid (verde + paid_at), overdue (vermelho + due_date), pending (amber + due_date), sem cobrança c/ valor (neutro), sem cobrança s/ valor (neutro). - `@cobranca-atualizada` do `AgendaEventoFinanceiroPanel` agora também dispara `loadSessionPaymentRecord` pra a linha refrescar. - **Importante:** `occFinancialRecord` (que aciona lock-edit) NÃO foi tocado de propósito — esse é território da Fase 6/C13 (Edit cobrada). Manter dois refs separados evita ativar lock prematuro em Melissa. ### Preparação do C5 (Sándor + Unimed Nacional) — UX de convênio refinado (3 issues) User tentou rodar C5 e bateu em 3 problemas seguidos. Cada um virou um fix: 1. **Botão "Cadastrar" do procedimento navegava pra `/pages/notfound`** - Root cause: `goToConveniosConfig` em `AgendaEventDialog.vue` prefixava com `/therapist` ou `/admin`, mas `/configuracoes/*` é rota **raiz** sob `AppLayout` (sibling, não filho). Em Melissa, convênios mora dentro do próprio layout via `secao: 'cfg-convenios'` (sem URL própria). - Fix descartado: o user não queria sair da agenda. Em vez disso, criamos um quick-create inline (ver #2). `goToConveniosConfig` foi removida (dead code virou armadilha). 2. **Quick-create de procedimento inline (sem sair da agenda)** - Novo componente `InsurancePlanServiceQuickCreateDialog.vue` (modelo do `InsurancePlanQuickCreateDialog`). 2 campos: nome do procedimento + valor que o convênio paga. Insere em `insurance_plan_services` pro `insurance_plan_id` ativo. - Wiring em `useAgendaEventLifecycle.js`: novo `planServiceQuickDlgOpen` + `openPlanServiceQuickCreate()` + `onPlanServiceCreated(service)`. Após criar, recarrega `loadInsurancePlans` e **auto-seleciona** o novo procedimento **só quando nada estava selecionado antes** (preserva escolha quando user já tinha selecionado X e está só cadastrando Y pra próxima). - UI refatorada (`AgendaEventDialog.vue:3110+`): a caixa cinza com botão "Cadastrar" agora aparece **sempre** que um convênio está selecionado. Quando 0 procedimentos: **"Este convênio ainda não tem procedimentos cadastrados."** Quando 1+: **"Se quiser adicionar mais procedimentos a este convênio:"**. - `planServiceQuickDlgOpen` adicionado ao `anyChildDialogOpen` pra esconder o Resumo flutuante enquanto o quick-create está aberto. 3. **Botão "+ Novo convênio" faltando em `/melissa/cfg-convenios` (e na rota canônica também)** - Root cause: `ConfiguracoesConveniosPage.vue` tinha o form de "Novo convênio" condicionado a `addingNew === true`, mas **nenhum botão setava esse flag**. Empty state mandava "Clique em 'Novo convênio'" sem botão pra clicar. - Fix: toolbar simples no topo do template `