agenda: Fase 5 (status change/edit cobrada) + indicadores visuais + UX convenio
DB
- drop agenda_excecoes (substituida por financial_exceptions + lock-edit
baseado em financial_records)
- financial_records.payment_link (Asaas + link compartilhavel)
- financial_exceptions.consume_on_miss (rotular nao-show consome ou nao)
- billing_contracts.charging_style (upfront/saldo/per_session)
Payment refactor
- paymentSettlement -> paymentMethod (string) + markPaidNow (bool).
Handler aplica payment_method sempre; status='paid'+paid_at apenas
quando markPaidNow=true && method != 'link'. Asaas (link) sempre
liquida via webhook, nunca nasce paid.
- create_financial_record_for_session com pos-RPC patch pra payment_method
e (opcional) status='paid' quando user marca "ja recebi".
Indicadores visuais (3 canais distintos por estado)
- Paid: barra esquerda emerald-500 4px na agenda (MelissaAgenda),
pi-check-circle no popover/Resumo.
- Pending: badge \$ amber canto direito (mantido); linha amber no popover/
Resumo "A receber R\$ X (cobranca pendente)".
- Neutro: sem badge nem barra (compromisso pessoal, bloqueio, ou
ocorrencia virtual de pacote upfront/saldo).
- Bulk-load de paymentState em _reloadRange etapa 4 (1 query unica em
financial_records mapeada por agenda_evento_id).
- AgendaEventDialog Resumo lateral ganha linha entre pi-clock e
pi-map-marker via novo sessionPaymentRecord (sem guard de
occurrenceMode, contrario ao occFinancialRecord que continua so pra
Rail/Clinica). 5 estados: paid+paid_at, overdue+venceu, pending+vence,
sem cobranca c/ valor, sem cobranca s/ valor.
UX de convenio
- InsurancePlanServiceQuickCreateDialog novo: cadastra procedimento
POR CIMA do AgendaEventDialog sem sair da agenda. Auto-seleciona
novo procedimento so quando nada estava selecionado antes.
- Caixa cinza "Cadastrar procedimento" sempre visivel quando convenio
selecionado, com copy variavel (0 procedimentos: chamada urgente;
1+: "se quiser adicionar mais").
- "+ Novo convenio" toolbar em ConfiguracoesConveniosPage (botao
estava faltando, empty state mandava clicar em botao inexistente).
- Hint contextual abaixo do card Sessao/Honorarios: convenio = "N da
guia eh opcional", gratuito = "sem cobranca", particular = sem hint.
Label "N da Guia" tambem ganhou "(opcional)" no service-picker dialog.
Bug fixes
- pickDbFields whitelist faltando 'modalidade' (useMelissaAgenda.js:74)
— sessoes avulsas eram salvas como presencial independente da
escolha visual. Adicionado.
- goToConveniosConfig removida — fazia router.push("/therapist/
configuracoes/convenios") mas /configuracoes/* eh rota raiz, nao
filha. Substituida pelo quick-create inline (#1).
- bloqueioCobrindo + dialogBlockOverlap passados via deps em
_buildHandlers (refs do useMelissaAgenda nao sao acessiveis no
escopo de _buildHandlers).
Fase 5 (status change + edit cobrada)
- AgendaStatusChangeConfirmDialog: confirm dialog quando user muda
status pra realizada/faltou/cancelado, com opcoes de markPaid ou
gerar cobranca conforme o caso.
- useAgendaBloqueios novo composable: extrai logica de bloqueios
cinza (background events) do MelissaAgenda.
Doc viva
- src/docs/agenda-compromisso-financeiro-cenarios.html: 13 cenarios
de teste manual. C1-C4 ja validados. Cada teste validado vira parte
da doc final pra area de ajuda (pos-Fase 9).
Wiki/handoff
- agenda-compromisso-fluxo e agenda-billing-pesquisa-mercado (decisoes
arquiteturais sobre billing).
- HANDOFF.md atualizado.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,142 @@ Chronological, append-only record of everything that's happened in this wiki.
|
||||
|
||||
---
|
||||
|
||||
## [2026-05-18 23:30] session | UX de convenio refinado (3 fixes) + hint contextual
|
||||
Touched: none (sem nova wiki page; tudo em codigo + HANDOFF)
|
||||
Detalhes: tarde inteira consumida em refinar UX de convenio antes do
|
||||
save real do C5. User bateu em 3 problemas seguidos:
|
||||
|
||||
1) Botao "Cadastrar" do procedimento navegava pra /pages/notfound.
|
||||
Root cause: goToConveniosConfig prefixava com /therapist|/admin mas
|
||||
/configuracoes/* eh rota raiz sob AppLayout (sibling, nao filho). Em
|
||||
Melissa, convenios mora via secao=cfg-convenios sem URL propria.
|
||||
Fix descartado: user nao queria sair da agenda. Criamos quick-create
|
||||
inline (#2). Removi goToConveniosConfig (dead code).
|
||||
|
||||
2) InsurancePlanServiceQuickCreateDialog (novo componente). Mesmo pattern
|
||||
do InsurancePlanQuickCreateDialog. 2 campos: nome + valor que o
|
||||
convenio paga. Wiring em useAgendaEventLifecycle: planServiceQuickDlgOpen
|
||||
+ openPlanServiceQuickCreate + onPlanServiceCreated. Apos criar:
|
||||
loadInsurancePlans + auto-seleciona SO se nada estava selecionado
|
||||
antes. UI refatorada: caixa cinza com botao "Cadastrar" SEMPRE
|
||||
visivel quando convenio selecionado, copy varia por contagem
|
||||
(0 procedimentos = chamada urgente; 1+ = "se quiser adicionar mais").
|
||||
|
||||
3) Botao "+ Novo convenio" faltando em ConfiguracoesConveniosPage.vue.
|
||||
addingNew=true sem botao pra setar. Empty state mandava clicar em
|
||||
botao inexistente. Fix: toolbar topo com Button label="Novo convenio"
|
||||
@click="addingNew = true". Empty state corrigida.
|
||||
|
||||
Hint contextual abaixo do card Sessao/Honorarios. User: "Nº da guia
|
||||
eh obrigatorio?" — consegui salvar sem. Tentativa 1: coloquei em
|
||||
v-if=occurrenceMode (errado, so Rail/Clinica). Tentativa 2: fluxo
|
||||
principal Melissa (linha 2305). Copy: convenio = "Nº da guia eh
|
||||
opcional…", gratuito = "Sessão gratuita…", particular = sem hint.
|
||||
Label "Nº da Guia" tambem ganhou "(opcional)".
|
||||
|
||||
PROXIMO: rodar de fato o save do C5 (Sandor + Unimed + R$ 95). Tudo
|
||||
preparado, agora eh testar end-to-end.
|
||||
|
||||
## [2026-05-18 21:45] session | Linha de cobranca no popover (3 estados) + Resumo do dialog
|
||||
Touched: none (sem nova wiki page)
|
||||
Detalhes: extensao do trabalho da sessao anterior (barra verde na agenda).
|
||||
User pediu pra popover mostrar tambem o estado pago, nao so pendente.
|
||||
Lembrava que "tinha algo assim mas talvez seja pra outra coisa" —
|
||||
verifiquei: occFinancialRecord existia mas com guard de occurrenceMode,
|
||||
servindo Fase 6 (lock-edit) em Rail/Clinica apenas. Decidi NAO unguardar
|
||||
pra nao ativar lock prematuro em Melissa (isso eh C13).
|
||||
|
||||
MelissaEventoPanel.vue: showPaymentRow agora cobre paid tambem; novo
|
||||
paymentVariant + paymentIcon (pi-check-circle quando pago, pi-dollar
|
||||
nos outros); paymentLabel inclui "Pago · R$ X,XX"; CSS com 3
|
||||
modificadores .evento-row--pay-{paid|pending|none} + dark mode.
|
||||
|
||||
AgendaEventDialog.vue + useAgendaEventLifecycle.js: novo ref
|
||||
sessionPaymentRecord (independente do occFinancialRecord). Loader sem
|
||||
guard, chamado no mesmo lifecycle. Computed paymentSummary cobre 5
|
||||
estados (paid + verde + paid_at, overdue + vermelho + venceu, pending
|
||||
+ amber + vence, sem cobranca c/ valor, sem cobranca s/ valor). Nova
|
||||
linha summary-row entre pi-clock e pi-map-marker em ambas as copias do
|
||||
Resumo (mobile inline + desktop floating). CSS com 4 classes
|
||||
.aed-pay-summary-row--{paid|pending|overdue|none}.
|
||||
|
||||
@cobranca-atualizada do AgendaEventoFinanceiroPanel agora tambem
|
||||
dispara loadSessionPaymentRecord pra a linha refrescar quando user
|
||||
marca pago pelo panel inline.
|
||||
|
||||
PROXIMO: cenario 5 (Sandor + Unimed Nacional, R$ 95, convenio).
|
||||
|
||||
## [2026-05-18 21:00] session | Cenario 4 OK + barra esquerda verde pra sessao paga
|
||||
Touched: none (decisao salva em memory/, doc HTML atualizado, sem nova wiki page)
|
||||
Detalhes: cenario 4 (Joyce R$180 PIX "Ja recebi") testado e passou — toast,
|
||||
record paid+pix+paid_at, badge $ removido. User pediu sinalizacao visual
|
||||
pra sessao paga "olhar e saber". Brainstorm de 6 opcoes (check verde
|
||||
canto, barra esquerda, fundo green-50, $ riscado, so popover, 3 canais
|
||||
combinados). User escolheu #6 — 3 canais visuais distintos:
|
||||
- pago: barra verde 4px borda esquerda (emerald-500)
|
||||
- pendente: badge $ amber canto direito (como antes)
|
||||
- neutro: nem um nem outro (sem cobranca / virtual)
|
||||
Implementado em MelissaAgenda.vue (classe ma-evt--paid via classNames,
|
||||
CSS forca border-left-color !important porque FC seta borderColor inline).
|
||||
Doc HTML legenda "Indicadores visuais" expandida pros 3 estados (3 mocks
|
||||
empilhados). Estado-alvo do C4 reescrito. Memoria persistida em
|
||||
memory/project_agenda_payment_indicators.md (decisao + onde aplicar quando
|
||||
replicar em Rail/Clinica). HANDOFF atualizado pra apontar C5 como
|
||||
proximo.
|
||||
|
||||
## [2026-05-17 02:30] session | Testes C1-C3 + payment refactor + indicadores visuais + fix modalidade
|
||||
Touched: agenda-compromisso-fluxo (implicit via HANDOFF.md, sem nova pagina)
|
||||
Detalhes: rodada de testes manuais dos cenarios do doc viva
|
||||
src/docs/agenda-compromisso-financeiro-cenarios.html. Cenarios 1, 2 e 3 ok.
|
||||
|
||||
CENARIO 1 (bloqueio):
|
||||
- Fix `bloqueioCobrindo is not defined` em onSelectTime — funcao mora no
|
||||
escopo de useMelissaAgenda mas onSelectTime esta em _buildHandlers.
|
||||
Passada via deps, mesmo padrao do _openStatusDialog.
|
||||
- Soft warn de bloqueio sobre slot agora vai DENTRO do dialog (Message
|
||||
warn no topo do step 1) em vez de toast atras do overlay. Novo ref
|
||||
dialogBlockOverlap no composable + nova prop blockOverlapWarning no
|
||||
AgendaEventDialog. Reset nos outros openers.
|
||||
- Doc HTML cenario 1 expandido em 1a (criar) + 1b (agendar sobre
|
||||
bloqueio), com mock visual da Message + comparacao agendador publico.
|
||||
|
||||
CENARIO 2 (avulsa sem cobranca):
|
||||
- Hint chargeMode fonte 0.72rem -> 0.8125rem.
|
||||
- Card Frequencia avulsa refeito: era empty state convidando configurar,
|
||||
agora renderiza como "selecionado" com .aed-pay-summary (Tipo: Avulsa
|
||||
/ Sessao unica, sem repeticao / botao Editar). Visual identico ao
|
||||
estado configurado de pacote.
|
||||
|
||||
CENARIO 3 (avulsa cobrar ao salvar):
|
||||
- Refactor paymentSettlement -> paymentMethod + markPaidNow. UI antiga
|
||||
misturava metodo e status num Select unico ("Ja recebi - PIX"). Agora
|
||||
2 controles: Select forma (sem prefixo "Ja recebi") + SelectButton
|
||||
status (pendente / ja recebi). SelectButton oculto quando metodo='link'.
|
||||
Wire em 3 camadas (Dialog -> useAgendaEventActions -> useMelissaAgenda
|
||||
handler avulsa + _createPackageContract).
|
||||
- Indicadores visuais de pagamento: bulk-load 1x em _reloadRange etapa 4
|
||||
(financial_records mapeado por agenda_evento_id -> paid|pending|none).
|
||||
normalizeForMelissa injeta paymentState + price. Badge $ amber 16px no
|
||||
canto superior direito do evento da agenda (so sessao+paciente+nao-
|
||||
virtual+!paid). Linha "A receber" amber abaixo do horario no popover
|
||||
(MelissaEventoPanel), texto adaptativo.
|
||||
- BUG FIX pickDbFields whitelist faltando 'modalidade' — todas as sessoes
|
||||
avulsas criadas no Melissa ate hoje foram salvas como presencial no DB
|
||||
independente da escolha visual. Adicionado ao allowed[]. Gotcha durador
|
||||
salvo em memory/project_pickdbfields_whitelist.md.
|
||||
|
||||
DOC HTML AMPLAMENTE ATUALIZADO:
|
||||
- Nova secao topo "★ Indicadores visuais de pagamento" com mocks (badge
|
||||
$ + linha popover) e link em violeta no TOC.
|
||||
- Caixa violeta "Indicadores visuais" em cada cenario relevante (C2-C9)
|
||||
descrevendo o que aparece em cada caso.
|
||||
- C4 ganhou caixa verde "estado-alvo" (sem badge, sem linha — pago).
|
||||
- Receitas dos C2-C4 atualizadas pros 3 controles novos.
|
||||
|
||||
PROXIMO: cenario 4 (Joyce, "Ja recebi (dar baixa)"). Apos passar, seguir
|
||||
ate C13. Quando todos passarem, replicar em AgendaTerapeutaPage (Rail) e
|
||||
AgendaClinicaPage (Clinica). HANDOFF.md reescrito com tudo.
|
||||
|
||||
## [2026-05-05 23:45] session | Blueprint tabular Melissa + restore pacientes
|
||||
Touched: none (sem mudança de wiki — handoff em HANDOFF.md)
|
||||
Detalhes: criou `blueprints/melissa-table-page-blueprint.md` (~530L, 18 seções);
|
||||
@@ -601,3 +737,126 @@ ComponentCadastroRapido + PatientCadastroDialog pra uso in-flow.
|
||||
|
||||
Database backup gerado: backups/2026-05-11/ (138 tabelas, 141 FKs).
|
||||
Dashboard regenerado.
|
||||
|
||||
## [2026-05-11 17:00] session | AgendaEventDialog redesign completo + 2º dialog WIP
|
||||
Touched: HANDOFF.md (reescrito do zero)
|
||||
Detalhes: sessao longa de refator visual + UX do AgendaEventDialog.
|
||||
Headers dos 4 cards (Paciente, Data/Horario, Sessao/Honorarios, Frequencia)
|
||||
com altura fixa 40px, label so mobile, acoes a direita. Card Paciente
|
||||
ganhou toggle Presencial/Online com pi-pencil substituindo SelectButton;
|
||||
mini-links Editar/Limpar no lugar dos botoes redondos. Card Data e
|
||||
Horario com body em 2 linhas (Data · Duracao / Inicio → Termino). Card
|
||||
Sessao/Honorarios (renomeado de Pagamento) com Select dropdown default
|
||||
particular + 3 estados (gratuito/empty/configurado-resumo). Card Extras
|
||||
renomeado, com botao ? abrindo popover educativo. Layout 50/50 via
|
||||
.aed-row-50 (Paciente|Data e Sessao|Frequencia).
|
||||
|
||||
DIALOGS NOVOS:
|
||||
- serviceDialogOpen: cada servico vira card individual com preco unit,
|
||||
total, botoes colapsaveis (Aplicar desconto, Alterar quantidade);
|
||||
desconto mostra calculo em vermelho; footer fixo com Valor desta
|
||||
sessao em pill tracejada primary; hint educativo Unidades vs
|
||||
Recorrencia
|
||||
- freqDialogOpen: empty/resumo, 4 sub-cards (.aed-freq-section: Tipo,
|
||||
Dias, Quantidade, Proximas), chips renovados (.freq-tab borda solida
|
||||
+ variant 2-line com 1 mes/4 sessoes), proximas ocorrencias com
|
||||
separador por mes + referencia relativa (em 2 semanas/em 1 mes).
|
||||
"Como interpretar o valor" REMOVIDO.
|
||||
|
||||
CONCEITO PACOTE (recorrencia >= 2):
|
||||
- isPacote computed: criando >=2 OU editando hasSerie
|
||||
- pacoteTotal = totalFromItems × totalOcorrencias
|
||||
- Header dialog adapta: "Pacote · 4 Sessoes" / "Sessao do Pacote · Sessao"
|
||||
/ "Editar Sessao" / "Nova Sessao"
|
||||
- Resumo: modalidade vira "Presencial · Pacote"; wallet mostra total
|
||||
pacote; linha extra "4× R$ 40 = R$ 160"
|
||||
- Status da Sessao escondido em pacote
|
||||
- pluralCommitment PT-BR (Sessao→Sessoes, Analise→Analises, ão→ões)
|
||||
|
||||
MODO EDIÇAO:
|
||||
- Cadastro Rapido NAO aparece
|
||||
- Cadastro Completo + toggle Modalidade + Ajustar Horario: disabled
|
||||
com tooltip explicativo
|
||||
- time-hero ganha --readonly (sem cursor pointer)
|
||||
|
||||
OUTROS: animacao de Dialog + backdrop blur REMOVIDOS (so nativo
|
||||
PrimeVue); DataTable picker paciente coluna Acao agora frozen
|
||||
alignFrozen=right; lista Recorrencias Aplicadas com numeracao 1/2/3
|
||||
em badge primary; badge "atual" → "selecionado".
|
||||
|
||||
2º DIALOG EMPILHADO (WIP — BLOQUEIO PRA AMANHA):
|
||||
- useMelissaAgenda.js: refs novos occDialogOpen/EventRow/StartISO/EndISO
|
||||
- onEditSeriesOccurrence agora abre 2º dialog (em vez de mutar
|
||||
dialogEventRow in-place silenciosamente)
|
||||
- _buildHandlers recebe occDialog* via deps (sem isso dava
|
||||
ReferenceError em runtime)
|
||||
- MelissaLayout.vue: 2º AgendaEventDialog mountado paralelo, refs
|
||||
destruturados como agendaOccDialog* (refs aninhados nao auto-
|
||||
unwrappam no template — pattern conhecido do projeto)
|
||||
- Status: ABRE, mas user reportou "nao é essa janela que tem de
|
||||
abrir" — investigar amanha. Provavelmente precisa de prop pra
|
||||
esconder Frequencia + Recorrencias Aplicadas no 2º dialog e
|
||||
ajustar titulo pra "Editar Ocorrencia"
|
||||
- Pendente replicar em Rail (AgendaTerapeutaPage L1630 + L3080) e
|
||||
Clinica (AgendaClinicaPage L1119 + L2398) DEPOIS de estabilizar
|
||||
no Melissa
|
||||
|
||||
Mudancas NAO commitadas: 5 arquivos (AgendaEventDialog.vue + dois
|
||||
QuickCreateDialog + MelissaLayout + useMelissaAgenda). HANDOFF.md
|
||||
reescrito do zero documentando tudo.
|
||||
|
||||
## [2026-05-12 17:55] session | occurrenceMode no 2º dialog da agenda
|
||||
Touched: recorrencia-agenda
|
||||
|
||||
## [2026-05-13 14:00] session | pesquisa fluxo agenda Cliniko SimplePractice TherapyNotes
|
||||
Touched: none
|
||||
nTouched: agenda-billing-pesquisa-mercado, index
|
||||
|
||||
## [2026-05-13 21:00] session | Pesquisa mercado agenda billing
|
||||
Touched: agenda-billing-pesquisa-mercado, index
|
||||
|
||||
## [2026-05-14 sessao continua] session | AgendaEventDialog testes manuais + correcoes
|
||||
Touched: none (apenas logs detalhados; sem nova pagina wiki)
|
||||
Detalhes: User testou fluxo de criacao avulsa (Henrique Lima Souza) e
|
||||
recorrente (Donald Winnicott, 4×R$40) passo-a-passo. Achados/correcoes:
|
||||
(1) Bug badge financeiro "Despesa" — campo `type` faltava em BASE_SELECT
|
||||
de useFinancialRecords.js (caia em else → "Despesa"). Fix: adicionar type
|
||||
no SELECT. (2) E5 toggle Presencial/Online: removido :disabled="isEdit"
|
||||
(habilitado em ediçao tambem). (3) E6 Ajustar Horario: trocado por
|
||||
v-if="!isEdit || !hasSerie" — visivel em criacao E em avulsa em edicao;
|
||||
escondido em série recorrente (politica "esconder em vez de disabled"
|
||||
salva na memoria, vale apenas pra agenda). (4) Botao cog + popover sobre
|
||||
horarios online no time picker — padrao espelhado do Card Extras, linka
|
||||
pra /melissa/agenda-config (ou /configuracoes/agenda fora do Melissa).
|
||||
(5) Bug visual: pill --current + --online-cfg perdia destaque selected
|
||||
porque online-cfg !important ganhava da cascade. Fix: regra combo com
|
||||
mais especificidade. (6) Time picker vazava dia/hora/duracao pro card
|
||||
principal quando fechado sem confirmar — snapshot ao abrir + revert no
|
||||
@hide se _tpCommitted=false (added Cancelar button no footer). (7)
|
||||
Opção C1 implementada — checkbox bool gerarCobrancaAoSalvar substituido
|
||||
por SelectButton chargeMode com opcoes dinamicas:
|
||||
- Avulsa: Não / Gerar cobrança
|
||||
- Recorrente: Não / Pacote único / 1 por sessão
|
||||
Handler em useMelissaAgenda agora suporta 3 modos: 'session' (1
|
||||
financial_record, igual Fase 1 original), 'package' (1 billing_contract
|
||||
inline em vez de confirm.require pós-save), 'per_session' (materializa N
|
||||
agenda_eventos + cria N financial_records via RPC, respeitando
|
||||
recurrence_exceptions). _offerBillingContract removido (codigo morto).
|
||||
useAgendaEventActions.gerarCobrancaAoSalvar → chargeMode. ESLint: 0
|
||||
erros novos. Vitest useAgendaEventComposer.spec: 76/76 passed.
|
||||
|
||||
## [2026-05-13 22:00] session | Fase 1 — drop agenda_excecoes + render bloqueios cinza
|
||||
Touched: agenda-compromisso-fluxo
|
||||
Detalhes: Fase 1 da auditoria fase-a-fase concluida. Auditoria revelou
|
||||
agenda_excecoes orfa (0 refs em src/, embora policies+trigger+enums
|
||||
existissem) e bloqueios nunca renderizados no FullCalendar (so impediam
|
||||
criacao). Aplicado: (1) migration 20260513000001_drop_agenda_excecoes.sql
|
||||
dropa tabela+enums+trigger; (2) agendaMappers.buildBloqueioBackgroundEvents
|
||||
renderiza dia-cheio/com-hora/recorrente como background event #6b728033;
|
||||
(3) composable useAgendaBloqueios reusavel (load aceita owner unico OU
|
||||
array); (4) wire nos 3 layouts (Melissa via useMelissaAgenda+MelissaAgenda,
|
||||
Rail via AgendaTerapeutaPage, Clinica via AgendaClinicaPage com multi-owner);
|
||||
(5) docs/schema_map.md e db.config.json limpos. ESLint 0 novos errors;
|
||||
agendaMappers.spec 40/40 passed. Pendente: rodar migration no banco local
|
||||
+ validacao visual nos 3 layouts. Plano de 8 fases salvo em
|
||||
[[agenda-compromisso-fluxo]]; pesquisa de mercado em [[agenda-billing-pesquisa-mercado]].
|
||||
|
||||
Reference in New Issue
Block a user