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:
@@ -0,0 +1,228 @@
|
||||
---
|
||||
title: Pesquisa de mercado — fluxo de compromisso e cobrança
|
||||
date: 2026-05-13
|
||||
status: levantamento
|
||||
players: Cliniko, SimplePractice, TherapyNotes
|
||||
---
|
||||
|
||||
## Contexto do produto
|
||||
|
||||
SaaS BR pra clínicas de psicologia, multi-tenant. Agenda + paciente + recorrência já funcionando. Invariante "cobrança emitida é imutável pelo dialog da agenda" já implementada (padrão SimplePractice). Auditando fase-a-fase o fluxo antes de fechar gaps. Restrições fiscais BR: PIX, NFS-e, LGPD.
|
||||
|
||||
Cross-links: [[recorrencia-agenda]], [[index]]
|
||||
|
||||
---
|
||||
|
||||
## 1. Criação de compromisso SEM paciente
|
||||
|
||||
### Cliniko
|
||||
- **Default:** existe entidade dedicada chamada **Unavailable block**. Não é appointment — não interfere em relatórios clínicos. Funciona como bloqueio puro de calendário (almoço, reunião, férias, manutenção).
|
||||
- **Admin pode:** criar **Unavailable block types** customizados (nome, duração default, cor). Aceita arquivamento individual ("Archive" remove o bloco).
|
||||
- **Fonte:** [Scheduling time off](https://help.cliniko.com/en/articles/1023892-scheduling-time-off), [Changing Your Calendar to Time Blocks](https://help.cliniko.com/en/articles/1024048-changing-your-calendar-to-time-blocks).
|
||||
|
||||
### SimplePractice
|
||||
- **Default:** duas entidades distintas — **Calendar event** (cinza escuro, para reunião, supervisão, tempo pessoal) e **Out of office (OOO) block** (cinza claro, para indisponibilidade que deve bloquear request de agendamento). Calendar events também podem ser recorrentes.
|
||||
- **Admin pode:** marcar evento como recorrente; OOO bloqueia automaticamente o widget de pedidos de horário online.
|
||||
- **Fonte:** [Creating a calendar event](https://support.simplepractice.com/hc/en-us/articles/41930878513933-Creating-a-calendar-event), [Managing out of office blocks](https://support.simplepractice.com/hc/en-us/articles/41931023345165-Managing-out-of-office-blocks).
|
||||
|
||||
### TherapyNotes
|
||||
- **Default:** dois tipos — **Scheduled Event** (atividade não-clínica: reunião, supervisão, treinamento; aparece no calendário do clínico) e **Unavailable** (vetar agendamento de pacientes em horários específicos: férias, almoço, compromisso pessoal). Ambos suportam descrição, duração e recorrência sem vincular paciente.
|
||||
- **Admin pode:** decidir clínico-alvo, frequência (one-time ou recurring), texto livre.
|
||||
- **Fonte:** [Schedule Non-Clinical Events](https://support.therapynotes.com/hc/en-us/articles/30661451456667-Schedule-Non-Clinical-Events), [Quick Start: Scheduling](https://support.therapynotes.com/hc/en-us/articles/30661279632539-Quick-Start-Scheduling).
|
||||
|
||||
**Convergência:** os 3 têm entidade não-clínica separada de "appointment" — nunca usam appointment-sem-paciente como hack.
|
||||
|
||||
---
|
||||
|
||||
## 2. Criação de compromisso COM paciente
|
||||
|
||||
### Cliniko
|
||||
- **Default:** appointment exige paciente + appointment type + data/hora + practitioner. Paciente pode ser criado on-the-fly direto do dialog do appointment com apenas nome (descrição/categoria são opcionais).
|
||||
- **Admin pode:** definir custom patient fields opcionais; appointment type carrega billable items default associados.
|
||||
- **Fonte:** [Booking an appointment](https://help.cliniko.com/en/articles/1024061-booking-an-appointment), [Set up appointment types](https://help.cliniko.com/en/articles/1023911-set-up-appointment-types).
|
||||
|
||||
### SimplePractice
|
||||
- **Default:** appointment exige cliente. Existe entidade intermediária chamada **Prospective client / Inquiry** — perfil parcial usado pra leads vindos de contact form ou pedido online. Pode-se enviar intake antes mesmo de aceitar o appointment (perfil definitivo só nasce ao aceitar).
|
||||
- **Admin pode:** mandar link de agendamento; criar task de follow-up; enviar intake; rodar prescreener; converter inquiry em client.
|
||||
- **Fonte:** [Managing prospective clients on the Inquiries page](https://support.simplepractice.com/hc/en-us/articles/33726366744589-Managing-prospective-clients-on-the-Inquiries-page), [Adding a new client](https://support.simplepractice.com/hc/en-us/articles/12416306860429-Adding-a-new-client-and-navigating-your-Clients-and-contacts-list).
|
||||
|
||||
### TherapyNotes
|
||||
- **Default:** appointment clínico exige client + clinician + appointment type + date. Cliente novo precisa pelo menos de **last name**; demais campos (DOB, endereço, e-mail, sexo administrativo, HIPAA acknowledgment) só viram obrigatórios quando se vai submeter claim de plano ou ativar portal.
|
||||
- **Admin pode:** liberar last-name-only para um "stub client" que recebe billable items mas não é submetível a plano até completar cadastro.
|
||||
- **Fonte:** [Add a New Client](https://support.therapynotes.com/hc/en-us/articles/30661347776539-Add-a-New-Client), [Schedule a Clinical Appointment](https://support.therapynotes.com/hc/en-us/articles/30661407698203-Schedule-a-Clinical-Appointment).
|
||||
|
||||
**Convergência:** todos aceitam appointment com cadastro de paciente mínimo. SimplePractice é o único com camada formal de "lead" pré-prontuário.
|
||||
|
||||
---
|
||||
|
||||
## 3. Cobrança / fatura — quando é gerada?
|
||||
|
||||
### Cliniko
|
||||
- **Default:** invoice é **explicitamente criada** pelo usuário a partir do appointment (botão "Create invoice" no card do compromisso). Não há geração automática no agendamento.
|
||||
- **Admin pode:** vincular billable items / produtos a um appointment type, então o "Create invoice" já vem populado. Em fluxo de pagamento online, a invoice é gerada e marcada como paga automaticamente no momento do pagamento confirmando o appointment.
|
||||
- **Fonte:** [Create an invoice](https://help.cliniko.com/en/articles/1023907-create-an-invoice), [Relate billable items and products to an appointment type](https://help.cliniko.com/en/articles/1023847-relate-billable-items-and-products-to-an-appointment-type).
|
||||
|
||||
### SimplePractice
|
||||
- **Default:** geração **automática**, configurável globalmente entre Daily (overnight, à meia-noite do timezone da prática), Monthly ou Manual. Status do appointment determina se vira invoice: apenas appointments com status **Show**, **Late canceled** ou **No show** geram invoice automaticamente.
|
||||
- **Admin pode:** escolher daily/monthly/manual em Settings → Client billing → Client billing documents. Recomendação oficial: Daily quando cobra na hora da sessão; Monthly quando fecha o mês.
|
||||
- **Fonte:** [Setting up your billing and automations](https://support.simplepractice.com/hc/en-us/articles/207925643-Setting-up-your-billing-and-automations), [Managing appointment statuses and billing](https://support.simplepractice.com/hc/en-us/articles/360018410872-Managing-appointment-statuses-and-billing), [Best practices for time-of-session billing](https://support.simplepractice.com/hc/en-us/articles/115000837406-Best-practices-for-time-of-session-billing).
|
||||
|
||||
### TherapyNotes
|
||||
- **Default:** billing line item é gerado **quando a nota da sessão é completada e assinada** pelo clínico. Cada appointment tem aba Billing acessível direto do dialog, mas o disparo de claim/invoice depende de note signed.
|
||||
- **Admin pode:** configurar default billing method por payer; o To-Do list cria o lembrete pra submeter claim ou gerar CMS-1500 assim que a nota é assinada.
|
||||
- **Fonte:** [Billing Overview](https://support.therapynotes.com/hc/en-us/articles/30661437130139-Billing-Overview), [Submit Electronic Claims](https://support.therapynotes.com/hc/en-us/articles/30661415430811-Submit-Electronic-Claims), [Quick Start: Billing](https://support.therapynotes.com/hc/en-us/articles/30661397280155-Quick-Start-Billing).
|
||||
|
||||
**Convergência:** ninguém cobra no momento de criar o appointment (futuro). Cliniko = manual sob demanda. SimplePractice = automático pós-sessão (status driven). TherapyNotes = automático pós-assinatura de nota (clinical-doc driven).
|
||||
|
||||
---
|
||||
|
||||
## 4. Recorrência (séries) — billing
|
||||
|
||||
### Cliniko
|
||||
- **Default:** repeating appointment (daily/weekly/fortnightly/monthly). Cada ocorrência é **appointment independente**; invoice continua sendo manual por ocorrência. Pra pacotes, recomenda usar **patient cases + account credit**: cobra o pacote inteiro upfront, o crédito fica no perfil do paciente e é consumido por cada invoice subsequente.
|
||||
- **Admin pode:** decidir entre invoice-por-sessão (manual ou via pagamento online) ou pacote upfront via account credit.
|
||||
- **Fonte:** [Book repeating appointments](https://help.cliniko.com/en/articles/1777286-book-repeating-appointments), [Tracking packages with patient cases and account credit](https://help.cliniko.com/en/articles/6477363-tracking-packages-with-patient-cases-and-account-credit).
|
||||
|
||||
### SimplePractice
|
||||
- **Default:** série de até 100 ocorrências, recorrência semanal/mensal/anual. Cada ocorrência é independente para billing — invoice é criada na ocorrência conforme regra global daily/monthly. Editar uma ocorrência pergunta "just this one" ou "all in series". Ao deletar série inteira incluindo passado, **passa por cima** de ocorrências sem nota ou invoice anexada; ocorrências com invoice/nota são preservadas.
|
||||
- **Admin pode:** ajustar fee de ocorrência já faturada via **fee adjustment invoice** (novo doc que ajusta o saldo, não toca a invoice original — esse é exatamente o padrão "cobrança emitida imutável" já adotado no projeto).
|
||||
- **Fonte:** [Managing recurring appointments](https://support.simplepractice.com/hc/en-us/articles/41930568779021-Managing-recurring-appointments), [Creating invoices](https://support.simplepractice.com/hc/en-us/articles/207925663-Creating-invoices).
|
||||
|
||||
### TherapyNotes
|
||||
- **Default:** recurring appointments indefinidos ou com data-fim. Cada ocorrência tem nota e billing independentes — billing line item nasce com a assinatura de cada nota individualmente.
|
||||
- **Admin pode:** cancelar "só esta" ou "todas futuras" da série; alertas podem ser anexados à série inteira.
|
||||
- **Fonte:** [Quick Start: Scheduling](https://support.therapynotes.com/hc/en-us/articles/30661279632539-Quick-Start-Scheduling).
|
||||
|
||||
**Convergência:** os 3 tratam ocorrência como unidade de billing. Pacote upfront é exceção (Cliniko via account credit). Nenhum gera "fatura única da série".
|
||||
|
||||
---
|
||||
|
||||
## 5. No-show / cancelamento tardio
|
||||
|
||||
### Cliniko
|
||||
- **Default:** plataforma não impõe fee; fornece ferramenta — terms of use no online booking + janela mínima de cancelamento (lock). Se paciente pagou full upfront online, ele **não consegue** cancelar pelo link; deposit parcial libera cancelamento.
|
||||
- **Admin pode:** configurar minimum notice (várias opções entre "sem restrição" e "vários dias"); redigir política nos terms of use; aplicar fee manualmente via invoice.
|
||||
- **Fonte:** [Restrict when a patient can cancel an appointment](https://help.cliniko.com/en/articles/1150562-restrict-when-a-patient-can-cancel-an-appointment), [Let patients cancel their appointments](https://help.cliniko.com/en/articles/1023945-let-patients-cancel-their-appointments).
|
||||
|
||||
### SimplePractice
|
||||
- **Default:** statuses formais — **No show** e **Late canceled** (ambos billable, ambos geram invoice como qualquer Show quando auto-billing está ativo). Cancelamento dentro da janela permitida vira status não-billable.
|
||||
- **Admin pode:** definir janela (24h ou 48h são presets) em Settings; statuses vão pra Client billing summary; appointments late-canceled aparecem em vermelho no calendário.
|
||||
- **Fonte:** [Setting up your practice's cancellation policy](https://support.simplepractice.com/hc/en-us/articles/360046771271-Setting-up-your-practice-s-cancellation-policy), [Managing appointment statuses and billing](https://support.simplepractice.com/hc/en-us/articles/360018410872-Managing-appointment-statuses-and-billing).
|
||||
|
||||
### TherapyNotes
|
||||
- **Default:** **Missed Appointment Note** dedicada — registra ausência e tem checkbox que automaticamente cria billing line item para fee de cancelamento. TherapyPortal mostra warning ao paciente quando ele tenta cancelar fora da janela.
|
||||
- **Admin pode:** habilitar/desabilitar criação automática de fee; configurar valor; texto da política aparece no portal.
|
||||
- **Fonte:** [Complete a Missed Appointment Note](https://support.therapynotes.com/hc/en-us/articles/30661183276315-Complete-a-Missed-Appointment-Note), [TherapyNotes 4.15 release notes](https://blog.therapynotes.com/version-4-15).
|
||||
|
||||
**Convergência:** todos têm conceito de "cobrar pelo no-show". SimplePractice é o mais automatizado (status billable triggera invoice junto com os outros). TherapyNotes é o mais explícito (note dedicada + checkbox). Cliniko é o mais manual.
|
||||
|
||||
---
|
||||
|
||||
## 6. Reembolso / cancelamento de cobrança emitida
|
||||
|
||||
### Cliniko
|
||||
- **Default:** invoice criada por engano pode ser **arquivada** (Archive button). **Número fiscal não retorna** — invoice 000001 arquivada não pode ser reemitida com o mesmo número. Reembolso real usa botão **Reverse** que cria credit note com itens negativos; usuário escolhe **Create credit & refund** (devolve dinheiro) ou **Create credit** (vira account credit). Para desfazer um refund, arquiva-se a credit note.
|
||||
- **Fonte:** [Archive an invoice](https://help.cliniko.com/en/articles/1359931-archive-an-invoice), [Recording refunds: an overview](https://help.cliniko.com/en/articles/4372587-recording-refunds-an-overview), [Undo a refund](https://help.cliniko.com/en/articles/4521200-undo-a-refund).
|
||||
|
||||
### SimplePractice
|
||||
- **Default:** invoice paga **não deve ser deletada** (deletar quebra alocação de pagamento). Refund full ou parcial é fluxo separado. Pagamentos cash/check/external podem ser deletados se foram erro; pagamento online com cartão não pode ser deletado, só refunded. Para mudar fee de invoice já emitida, usa **fee adjustment invoice** (novo doc com diff).
|
||||
- **Fonte:** [Navigating client payments](https://support.simplepractice.com/hc/en-us/articles/8497757602957-Navigating-client-payments), [Managing unallocated client payments](https://support.simplepractice.com/hc/en-us/articles/42078634883469-Managing-unallocated-client-payments).
|
||||
|
||||
### TherapyNotes
|
||||
- **Default:** **deletar pagamento ≠ refund** — deletar só remove o registro, não devolve dinheiro. Refund usa botão **Enter Refund** no Patient Accounting do tab Billing. Refund de payer (plano) tem opção dedicada que marca valor negativo automaticamente.
|
||||
- **Fonte:** [Edit, Delete and Refund Client Payments](https://support.therapynotes.com/hc/en-us/articles/30661497068443-Edit-Delete-and-Refund-Client-Payments).
|
||||
|
||||
**Convergência:** os 3 distinguem "anular registro" de "estornar dinheiro". Os 3 preservam histórico fiscal (Cliniko via número não-reaproveitável + credit note; SimplePractice via fee adjustment; TherapyNotes via refund line item). Padrão "cobrança imutável" do projeto está alinhado com o estado da arte.
|
||||
|
||||
---
|
||||
|
||||
## Tabela comparativa 3 × 6
|
||||
|
||||
| Etapa | Cliniko | SimplePractice | TherapyNotes |
|
||||
|---|---|---|---|
|
||||
| 1. Compromisso sem paciente | Unavailable block (tipos customizáveis) | Calendar event + OOO block (2 entidades) | Scheduled Event + Unavailable (2 tipos) |
|
||||
| 2. Compromisso com paciente | Quick-create paciente (nome basta) | Lead (Inquiry) → cliente formal | Last name basta; demais campos só pra claim |
|
||||
| 3. Quando gera cobrança | Manual via botão no appointment | Automático overnight (Daily/Monthly/Manual) condicionado a status billable | Quando nota da sessão é assinada |
|
||||
| 4. Recorrência billing | Ocorrência individual ou pacote upfront (account credit) | Série até 100; ocorrência individual; fee adjustment para edit pós-fatura | Ocorrência individual; billing nasce na assinatura de cada nota |
|
||||
| 5. No-show / late cancel | Política em terms of use; lock manual | Statuses billable (No show / Late canceled); janela 24h/48h | Missed Appointment Note com checkbox auto-fee |
|
||||
| 6. Refund / cancel cobrança | Archive + Reverse → credit note | Não deletar invoice paga; fee adjustment + refund | Enter Refund (delete ≠ refund) |
|
||||
|
||||
---
|
||||
|
||||
## Consenso de mercado
|
||||
|
||||
1. **Bloqueio de tempo é entidade própria**, separada de appointment. Nunca um appointment "sem paciente".
|
||||
2. **Cadastro mínimo de paciente** (1 campo) é aceito; campos pesados só ficam obrigatórios na hora de cobrar plano ou ativar portal.
|
||||
3. **Recorrência cria ocorrências independentes** para billing; nenhum gera "fatura única da série".
|
||||
4. **Edit de uma ocorrência pergunta "esta / todas / futuras"** — padrão consagrado.
|
||||
5. **Cobrança nunca é gerada na criação do appointment futuro** — sempre depois (sessão, status, nota, ou trigger manual).
|
||||
6. **Cobrança emitida é imutável**; ajustes vêm via documento novo (credit note, fee adjustment invoice, refund line item). Validação direta do invariante do projeto.
|
||||
7. **Deletar pagamento ≠ reembolsar dinheiro** — distinção explícita nos 3.
|
||||
8. **Janela de cancelamento configurável + política em texto livre** é o mínimo.
|
||||
|
||||
## Divergência
|
||||
|
||||
- **Quem aciona a cobrança:** Cliniko = humano clica. SimplePractice = job overnight via status. TherapyNotes = assinatura de nota clínica. Três paradigmas distintos.
|
||||
- **Lead / prospect:** SimplePractice tem entidade formal (Inquiry). Cliniko e TherapyNotes esperam o paciente já ter perfil mínimo.
|
||||
- **No-show fee:** SimplePractice = mais automatizado (status billable). TherapyNotes = mais auditável (note dedicada). Cliniko = mais manual.
|
||||
- **Pacote upfront:** Cliniko documenta explicitamente via account credit. SimplePractice/TherapyNotes não têm pacote nativo — cobram ocorrência a ocorrência.
|
||||
- **Reaproveitamento de número de invoice arquivada:** Cliniko proíbe (alinhado com fiscal BR via NFS-e). Outros não documentam regra equivalente.
|
||||
|
||||
---
|
||||
|
||||
## Perguntas-chave pro produto decidir
|
||||
|
||||
1. **O que dispara a cobrança no fluxo padrão?**
|
||||
a) Manual (humano clica) — máxima auditabilidade, exige disciplina (Cliniko).
|
||||
b) Job automático com base em status do appointment (SimplePractice) — pouco atrito, dependente de status estar correto.
|
||||
c) Assinatura de nota da sessão (TherapyNotes) — vincula clínica e financeira, atrasa cobrança se nota demora.
|
||||
**Trade-off:** quanto mais automático, menos atrito mas mais risco de cobrança errada; quanto mais manual, mais fricção mas auditoria perfeita.
|
||||
|
||||
2. **Devemos ter conceito formal de "lead/contato" antes de prontuário?**
|
||||
a) Sim — entidade Inquiry separada com pipeline (modelo SimplePractice).
|
||||
b) Não — paciente nasce na quick-create do agendamento com nome só (modelo Cliniko/TherapyNotes).
|
||||
**Trade-off:** Inquiry casa com funil comercial mas duplica entidade; quick-create é simples mas dificulta funil de pré-vendas.
|
||||
|
||||
3. **Recorrência cobra cada ocorrência ou suporta pacote upfront?**
|
||||
a) Só ocorrência individual (SimplePractice/TherapyNotes).
|
||||
b) Suporta também pacote upfront com saldo (Cliniko via patient case + account credit).
|
||||
**Trade-off:** pacote upfront atende prática que vende "10 sessões antecipado"; ocorrência-a-ocorrência casa direto com NFS-e brasileira (1 nota por serviço).
|
||||
|
||||
4. **No-show vira invoice automática ou exige ação manual?**
|
||||
a) Automático — status "No show" / "Late canceled" entram no auto-billing como Show (SimplePractice).
|
||||
b) Semi — note dedicada com checkbox que controla geração (TherapyNotes).
|
||||
c) Manual — admin cria invoice de no-show à mão (Cliniko).
|
||||
**Trade-off:** automático reduz perda mas pode constranger paciente sem revisão; manual exige rotina disciplinada.
|
||||
|
||||
5. **Edição de uma ocorrência de série recorrente: o que faz com cobrança já emitida?**
|
||||
a) Bloqueia edição (invariante atual — alinhado com SimplePractice "fee adjustment invoice" preservando original).
|
||||
b) Permite edição com nova cobrança suplementar (delta).
|
||||
c) Permite edição e refaz a cobrança (cancela + recria).
|
||||
**Trade-off:** opção a é a mais defensável fiscalmente (NFS-e já transmitida não pode ser silenciosamente mutada); b atende UX; c é perigoso mas familiar.
|
||||
|
||||
6. **Janela de cancelamento: presets ou livre?**
|
||||
a) Presets (24h / 48h) com texto da política livre (SimplePractice).
|
||||
b) Configuração granular por appointment type (Cliniko).
|
||||
c) Cliente final só vê warning, sem lock (TherapyNotes).
|
||||
**Trade-off:** presets cobrem 90% dos casos; granular casa com clínica que tem terapia de grupo + casal + individual com janelas diferentes.
|
||||
|
||||
7. **Reembolso preserva o documento fiscal original?**
|
||||
a) Sim, sempre — credit note nova, número fiscal original nunca volta (Cliniko + alinhado com NFS-e brasileira: cancelamento ≠ deletar).
|
||||
b) Sim, mas via fee adjustment que não toca a invoice (SimplePractice).
|
||||
c) Sim, refund é line item separado (TherapyNotes).
|
||||
**Trade-off:** modelo brasileiro de NFS-e exige (a) ou (c); SimplePractice (b) só funciona em mercados sem NF transmitida por API.
|
||||
|
||||
8. **Pagamento via PIX (e cartão online) confirma e marca invoice paga automaticamente?**
|
||||
a) Sim — pagamento confirmado dispara appointment confirmado + invoice paga (Cliniko online payment).
|
||||
b) Pagamento é entidade separada que pode ser alocada/desalocada (SimplePractice).
|
||||
**Trade-off:** auto-confirm é UX premium mas exige tolerância a falhas de webhook do PSP; pagamento desalocado é seguro mas exige conciliação.
|
||||
|
||||
---
|
||||
|
||||
## Implicações imediatas pro projeto
|
||||
|
||||
- O invariante "cobrança emitida é imutável" já implementado é consenso de mercado — manter.
|
||||
- "Compromisso sem paciente" precisa virar entidade própria (block/event), não um appointment com paciente null. Ver [[recorrencia-agenda]] para integração com expansão de série.
|
||||
- Recorrência por ocorrência individual é o caminho seguro (cabe em NFS-e). Pacote upfront fica para fase 2.
|
||||
- Disparo de cobrança: avaliar híbrido SimplePractice (status-driven) + TherapyNotes (note-signed), com fallback manual estilo Cliniko.
|
||||
- Perguntas 1, 4, 5, 7, 8 são pré-requisito pra fechar o gap atual de billing antes de F1 de fiscal.
|
||||
@@ -0,0 +1,216 @@
|
||||
---
|
||||
title: Plano de auditoria fase-a-fase — fluxo de compromisso da agenda
|
||||
date: 2026-05-13
|
||||
status: em-andamento
|
||||
related: [[agenda-billing-pesquisa-mercado]], [[recorrencia-agenda]]
|
||||
---
|
||||
|
||||
## Contexto
|
||||
|
||||
Auditoria do ciclo completo de compromisso da agenda, fase-a-fase, validando cada etapa contra a [[agenda-billing-pesquisa-mercado|pesquisa de mercado]] (Cliniko / SimplePractice / TherapyNotes). Cada fase tem 3 entregas: **auditar o que existe**, **decidir o gap**, **codar**.
|
||||
|
||||
## Decisões já tomadas (5 das 8 perguntas)
|
||||
|
||||
| # | Decisão |
|
||||
|---|---|
|
||||
| 1 | Disparo de cobrança: **híbrido configurável** (manual / status-driven / note-signed) |
|
||||
| 4 | No-show: **semi-automático via dialog de confirmação** ao mudar status |
|
||||
| 5 | Edit de cobrada: **bloqueia** (já implementado) |
|
||||
| 7 | Refund: **credit note nova** (alinhado NFS-e) |
|
||||
| 8 | Pagamento: **entidade separada** de financial_records |
|
||||
|
||||
Pendentes: #2 (lead/Inquiry), #3 (pacote upfront), #6 (janela de cancelamento — provavelmente já resolvido por `min_hours_notice` em `financial_exceptions`).
|
||||
|
||||
---
|
||||
|
||||
## Plano de 8 fases
|
||||
|
||||
Ordem por dependência ("o que destrava o quê") e por estado atual.
|
||||
|
||||
### ✅ Fase 1 — Compromisso SEM paciente (bloqueio/feriado/exceção) — **CONCLUÍDA 2026-05-13**
|
||||
|
||||
**Auditoria fez:**
|
||||
- ✅ `agenda_excecoes` é tabela órfã (0 referências em src/) — apesar de schema, policies, trigger e enums existentes
|
||||
- ✅ `agenda_bloqueios` é a entidade canônica usada pelos 3 layouts
|
||||
- ✅ `BloqueioDialog` (4 modos: horário/período/dia/feriados) é compartilhado por Melissa Agenda (via `MelissaLayout.vue:2186`), Rail e Clínica
|
||||
- ✅ `MelissaBloqueios.vue` tem form inline próprio pra **admin/edit** (caso de uso legítimo distinto do dialog de 4 modos)
|
||||
- ✅ Bloqueios não eram renderizados no FullCalendar — apenas impediam criação. UX inconsistente vs pausas/feriados que aparecem como background events
|
||||
- ⚠️ Tipos customizáveis de bloqueio: descartado no MVP (sem cliente real)
|
||||
- ⚠️ Robustez de `marcarSessoesParaRemarcar`: adiado pra Fase 5 (status change)
|
||||
|
||||
**Aplicado:**
|
||||
1. Migration `20260513000001_drop_agenda_excecoes.sql` — dropa tabela + 2 enums + trigger; policies caem com CASCADE
|
||||
2. `agendaMappers.js`: nova função `buildBloqueioBackgroundEvents(bloqueios, rangeStart, rangeEnd)` — renderiza bloqueios como background events cinza (`#6b728033`), suporta dia-inteiro, com hora, e recorrente semanal
|
||||
3. Novo composable `useAgendaBloqueios.js` — load por owner único OU array (multi-owner pra Clínica), `buildEventsForRange` reutilizável
|
||||
4. Wire em `useMelissaAgenda` + `MelissaAgenda.vue` — bloqueios concatenados ao `fcEvents`
|
||||
5. Wire em `AgendaTerapeutaPage` — bloqueios concatenados ao `calendarEvents`
|
||||
6. Wire em `AgendaClinicaPage` — bloqueios consolidados de todos os ownerIds
|
||||
7. Refs stale removidas de `database-novo/docs/schema_map.md` e `database-novo/db.config.json`
|
||||
|
||||
**Verificação:**
|
||||
- ESLint nos arquivos modificados: 0 errors novos (11 pré-existentes em código não-tocado)
|
||||
- Vitest `agendaMappers.spec.js`: 40/40 tests passed
|
||||
- ⚠️ **Falta rodar a migration no banco local** (pendente de execução manual; arquivo SQL pronto)
|
||||
- ⚠️ **Falta validar visualmente** nos 3 layouts (Melissa/Rail/Clínica) — verificar que bloqueios aparecem em cinza após criar pelo BloqueioDialog
|
||||
|
||||
---
|
||||
|
||||
### 🟢 Fase 2 — Compromisso COM paciente
|
||||
**Estado:** dialog refatorado em 11/05 (cards 40px, picker DataTable, 50/50 layout, 3 estados Sessão/Honorários, conceito Pacote, resumo flutuante). Working tree.
|
||||
|
||||
**Auditar:**
|
||||
- Fluxo de cadastro mínimo de paciente in-line (já existe via `PatientCadastroDialog` quick mode?)
|
||||
- Decidir #2 (Inquiry/lead separado ou só quick-create)
|
||||
- Modalidade presencial/online consistente
|
||||
|
||||
**Gap potencial:**
|
||||
- Quick-create exige só nome ou mais campos? (Cliniko: só nome; TherapyNotes: só last name)
|
||||
- Decisão #2 (Inquiry/lead) — adiar pra v2 provável
|
||||
|
||||
**Codar:** ajustes pequenos, principalmente UX. Provavelmente quase nada novo.
|
||||
|
||||
---
|
||||
|
||||
### 🟢 Fase 3 — Recorrência
|
||||
**Estado:** modelo "1 real + N-1 virtual" + `occurrenceMode` no 2º dialog estabilizado em 12/05. Ver [[recorrencia-agenda]].
|
||||
|
||||
**Auditar:**
|
||||
- `occurrenceMode` já replicado em Melissa; falta Rail (`AgendaTerapeutaPage` L1630 + L3080) e Clínica (`AgendaClinicaPage` L1119 + L2398)
|
||||
- Decisão #3 (pacote upfront via account credit) — adiar provável
|
||||
|
||||
**Codar:** replicar `occurrenceMode` em Rail/Clínica. Talvez add de pacote upfront (Cliniko model) numa fase futura.
|
||||
|
||||
---
|
||||
|
||||
### 🟠 Fase 4 — Cobrança: modo de disparo configurável (DECISÃO #1)
|
||||
**Estado:** Fase 1 atual ("Gerar cobrança ao salvar") existe como checkbox em criação avulsa+particular. Não tem setting de modo.
|
||||
|
||||
**Auditar:**
|
||||
- Onde vive a config? Card novo em `/configuracoes/excecoes-financeiras` ou página irmã `/configuracoes/cobranca-defaults`?
|
||||
- Granularidade: por tenant (clínica), por owner (terapeuta), ou ambos com herança?
|
||||
|
||||
**Gap:**
|
||||
- Tabela/coluna nova pra `charge_trigger_mode` enum (`manual` / `status_driven` / `note_signed`)
|
||||
- UI de config
|
||||
- Job overnight pra modo `status_driven` (Supabase edge function + cron)
|
||||
- Trigger no signature de nota pra `note_signed` (depende de modulo de notas; nao temos)
|
||||
- Checkbox atual da agenda passa a fazer sentido **só em modo manual** (ou vira override universal?)
|
||||
|
||||
**Codar:**
|
||||
1. Migration: setting de modo (tenant_billing_settings ou colunas em agenda_configuracoes)
|
||||
2. UI de config
|
||||
3. Job pra modo status_driven (avaliar se entra na v1 ou v2)
|
||||
4. Refator do checkbox atual pra respeitar o modo
|
||||
|
||||
---
|
||||
|
||||
### 🟠 Fase 5 — Status change → cobrança com confirm dialog (DECISÃO #4)
|
||||
**Estado:** lógica automática roda em `useAgendaFinanceiro.handleStatusChange`. Consulta regra em `financial_exceptions`, cria/ajusta/cancela `financial_record` SEM perguntar.
|
||||
|
||||
**Auditar:**
|
||||
- Quais status disparam: hoje só `faltou` e `cancelado` (mapping `STATUS_TO_EXCEPTION`)
|
||||
- `professional_cancellation` na tabela mas não no mapping
|
||||
- Onde `handleStatusChange` é chamado (quais entradas de status change disparam)
|
||||
|
||||
**Gap:**
|
||||
- Confirm dialog ao mudar status pra `faltou` / `cancelado`: *"Aplicar cobrança de R$X conforme regra? [Sim / Não / Editar valor]"*
|
||||
- Adicionar `professional_cancellation` ao mapping (status atual da agenda inclui? checar)
|
||||
- Decidir: dialog aparece **sempre** ou só quando `charge_mode !== 'none'`
|
||||
|
||||
**Codar:**
|
||||
1. Dialog componente novo (`AgendaStatusChargeConfirmDialog.vue`)
|
||||
2. Interceptar `handleStatusChange` antes da aplicação automática
|
||||
3. Adicionar `professional_cancellation` no mapping
|
||||
4. Toast diferenciado pra "aplicado/recusado/editado"
|
||||
|
||||
---
|
||||
|
||||
### 🟢 Fase 6 — Edit de cobrada (DECISÃO #5 — JÁ IMPLEMENTADO)
|
||||
**Estado:** `propagateToSerie` filtra por `financial_records` em status imutável. UI lock em `AgendaEventDialog` via `occFinancialRecord`. Working tree.
|
||||
|
||||
**Auditar:** validar contra cenários reais (testar série com 4 sessões, 2 cobradas, 2 abertas; editar template; verificar que cobranças não mudam).
|
||||
|
||||
**Codar:** zero (talvez add de aviso UX se faltar clareza).
|
||||
|
||||
---
|
||||
|
||||
### 🔴 Fase 7 — Pagamento como entidade separada (DECISÃO #8)
|
||||
**Estado:** hoje `financial_records.paid_at` marca pagamento (acoplado). Não tem entidade `payments` independente.
|
||||
|
||||
**Auditar:**
|
||||
- Como financial_records.paid_at é usado hoje (queries de receita, dashboards, conciliação)
|
||||
- Webhook PSP existente? (provável que PIX e cartão sejam manuais hoje)
|
||||
|
||||
**Gap:**
|
||||
- Migration: tabela `payments` (id, amount, method, paid_at, source, allocated_to_record_id NULL-able)
|
||||
- Alocação manual de pagamento "solto" a um financial_record
|
||||
- Pagamento parcial (1 payment cobre N records ou 1 record recebe N payments?)
|
||||
- Repo + composable + UI
|
||||
|
||||
**Codar:** fase pesada — provavelmente sub-dividir.
|
||||
|
||||
---
|
||||
|
||||
### 🔴 Fase 8 — Reembolso / credit note (DECISÃO #7)
|
||||
**Estado:** hoje só tem `financial_records.status='cancelled'`. Não preserva original como doc fiscal.
|
||||
|
||||
**Auditar:** processo fiscal atual (já emite NFS-e? quando? como cancela?)
|
||||
|
||||
**Gap:**
|
||||
- Migration: tabela `credit_notes` (id, original_record_id, amount, reason, issued_at)
|
||||
- Constraint: credit note tem valor ≤ |original|
|
||||
- UI no Financeiro pra "Reembolsar"
|
||||
- Integração com NFS-e (pode ser separada)
|
||||
|
||||
**Codar:** fase pesada — provavelmente sub-dividir.
|
||||
|
||||
---
|
||||
|
||||
### 🟣 Fase 9 — Plano Inicial (entrevista + N sessões regulares)
|
||||
**Estado:** apenas conceito; nada codado.
|
||||
|
||||
**Pedido do user (2026-05-14):** clínica cobra **1 entrevista inicial** (valor X) + **4 sessões regulares** (valor Y cada). É o "plano de entrada" pra novos pacientes. User faz isso manualmente hoje na clínica dele.
|
||||
|
||||
**Conceito:**
|
||||
- Config nas settings da agenda do tenant:
|
||||
- Toggle "Habilitar plano inicial"
|
||||
- Valor entrevista (R$)
|
||||
- Qtd de sessões regulares (default 4)
|
||||
- Valor por sessão regular (R$)
|
||||
- (Opcional) Texto/descrição que aparece no fluxo
|
||||
- Quando user cria 1ª sessão de **paciente novo** (sem histórico):
|
||||
- Sistema oferece: "Aplicar plano inicial? Entrevista R$ X + 4× R$ Y = total R$ Z"
|
||||
- Ao aceitar, materializa 5 sessões com `price` diferenciado: 1ª = X, demais = Y
|
||||
- Pode ser tratado como 1 série recorrente "especial" com 1ª ocorrência destacada
|
||||
- OU como 2 entidades distintas (1 avulsa entrevista + 1 série de 4)
|
||||
|
||||
**Decisões pendentes:**
|
||||
- Estrutura: série única com 1ª diferenciada OU avulsa + série separada?
|
||||
- Onde fica a config: `agenda_configuracoes` (jsonb adicional?) ou tabela nova `intake_plans`?
|
||||
- "Paciente novo" = sem sessões anteriores? Ou marcador manual no cadastro?
|
||||
- Plano único do tenant ou múltiplos planos (avaliação clínica, avaliação neuropsi, etc)?
|
||||
|
||||
**Cabe na Fase 4 (cobrança)?** Não — Fase 4 é só modo de disparo; aqui é estrutura de pacote pré-configurado. Fica como Fase 9 separada.
|
||||
|
||||
---
|
||||
|
||||
## Ordem sugerida de execução
|
||||
|
||||
| Ordem | Fase | Razão |
|
||||
|---|---|---|
|
||||
| 1ª | **Fase 1** | Curta, validação, define se tem cleanup de tabelas necessário |
|
||||
| 2ª | **Fase 5** | Destrava UX urgente (confirm dialog evita cobrar errado) |
|
||||
| 3ª | **Fase 4** | Híbrido configurável — destrava racional do checkbox atual |
|
||||
| 4ª | **Fase 2** | Quase 100% pronta, validar e finalizar |
|
||||
| 5ª | **Fase 3** | Replicar `occurrenceMode` em Rail/Clínica |
|
||||
| 6ª | **Fase 6** | Já feito; só testar |
|
||||
| 7ª | **Fase 7** | Refator estrutural pesado — entra depois das fases UX |
|
||||
| 8ª | **Fase 8** | Depende fiscal NFS-e — pode ir pra v2 |
|
||||
| 9ª | **Fase 9** | Plano Inicial (entrevista + 4 sessões) — pedido do user, conceito pronto, codar pós-7 |
|
||||
|
||||
## Como cada fase termina
|
||||
|
||||
1. Página da fase na wiki é atualizada com o resultado
|
||||
2. Commit dedicado com prefixo `agenda(fase-N): ...`
|
||||
3. Update no [[index]] da wiki
|
||||
4. Entrada no `log.md`
|
||||
@@ -24,6 +24,9 @@ _(summaries of specific sources you've ingested)_
|
||||
|
||||
_(synthesized answers to questions you've asked, filed back as pages)_
|
||||
|
||||
- [[agenda-billing-pesquisa-mercado]] — comparativo Cliniko / SimplePractice / TherapyNotes do ciclo compromisso→cobrança (6 etapas), consenso/divergência e 8 perguntas-chave pro produto
|
||||
- [[agenda-compromisso-fluxo]] — plano de auditoria fase-a-fase (8 fases) do ciclo de compromisso da agenda; ordem de execução + decisões já tomadas
|
||||
|
||||
---
|
||||
|
||||
*This index is maintained by Claude via `/wiki-brain`. Do not edit by hand unless you know what you're doing.*
|
||||
|
||||
@@ -81,11 +81,66 @@ WHERE patient_id IS NULL
|
||||
|
||||
Causa raiz já corrigida em 2026-05-11 (guard contra `rid` null em `onUpdateSeriesEvent`), mas o pattern de query é útil pra catch futuros.
|
||||
|
||||
## Invariante de cobrança em séries — "cobrança emitida é imutável"
|
||||
|
||||
**Padrão adotado (SimplePractice / TherapyNotes / Cliniko):** `financial_records` em status `pending`/`paid`/`overdue` são **imutáveis pelo dialog da agenda**. Ajustes só via fluxo do Financeiro (cancelar + refaturar). Garante:
|
||||
- Trilha fiscal estável.
|
||||
- Paciente não vê valor "mágico" mudando.
|
||||
- Dashboards de MRR e projeção consistentes.
|
||||
|
||||
### Como o sistema honra a invariante
|
||||
|
||||
**1. Lock no `occurrenceMode`** (`AgendaEventDialog.vue`):
|
||||
- Card "Sessão / Honorários" detecta `occFinancialRecord` via query `financial_records` filtrada por `agenda_evento_id` + status `in ('pending','paid','overdue')`.
|
||||
- Se record existe → renderiza apenas `AgendaEventoFinanceiroPanel` + mensagem de lock + Tag de status. Select de billingType e botão "Editar itens" desaparecem.
|
||||
- Se record não existe (virtual ou materializado sem cobrança) → edição livre, marca `services_customized=true` ao salvar.
|
||||
- Card "Aplicar alterações em" também é ocultado quando há cobrança (mudanças estruturais não se aplicam — usuário só pode mexer em status/horário).
|
||||
|
||||
**2. Filtro em `propagateToSerie`** (`useCommitmentServices.js`):
|
||||
- Após filtrar eventos elegíveis (recurrence_id + opcionalmente fromDate + opcionalmente services_customized=false), faz 1 query batch em `financial_records` pra coletar `agenda_evento_id` lockados.
|
||||
- Remove esses IDs da lista de elegíveis antes de fazer `delete + insert` de `commitment_services`.
|
||||
- Resultado: editar template da regra **nunca toca** ocorrências cobradas, mesmo em escopo `todos`.
|
||||
|
||||
**3. Aviso fixo no dialog pai** (em `isEdit && hasSerie`):
|
||||
- Mensagem inline abaixo do `AgendaEventoFinanceiroPanel`: "Alterações de tipo ou serviços afetam apenas sessões futuras ainda não cobradas. Cobranças já emitidas permanecem inalteradas — para ajustá-las, acesse o Financeiro."
|
||||
|
||||
### Opção `todos_sem_excecao` removida da UI
|
||||
|
||||
- O nome confundia (sugeria "ignorar cobranças") quando na verdade era "ignorar customização operacional" (`services_customized=true`).
|
||||
- Backend mantém o caso pra compat, mas `editScopeOptions` agora só retorna 3 valores: `somente_este`, `este_e_seguintes`, `todos`.
|
||||
- Mercado consolidado (SimplePractice etc) não expõe override de customizações — admin que precisa reseta sessão-a-sessão.
|
||||
|
||||
### Onde está cada peça
|
||||
- `src/features/agenda/composables/useAgendaEventLifecycle.js` — `loadOccFinancialRecord` + `occFinancialRecord` ref
|
||||
- `src/features/agenda/components/AgendaEventDialog.vue` — card lock/unlock + aviso pai
|
||||
- `src/features/agenda/composables/useCommitmentServices.js:162` — `propagateToSerie` com filtro financial_records
|
||||
- `src/features/agenda/composables/useAgendaEventComposer.js:91` — `editScopeOptions` com 3 valores
|
||||
- `src/components/agenda/AgendaEventoFinanceiroPanel.vue` — UI do fluxo Financeiro embarcado
|
||||
|
||||
## 2º dialog empilhado — edição de ocorrência (occurrenceMode)
|
||||
|
||||
Quando o user clica "Editar" em uma pill da lista "Recorrências Aplicadas", abre um **segundo `AgendaEventDialog` empilhado** por cima do principal. Ele compartilha o mesmo componente, mas com a prop `occurrenceMode=true` que muda comportamento:
|
||||
|
||||
- **Título:** `Pacote · X de Y Sessões` (computa `occurrenceIndex` via `currentRecurrenceDate` + `serieEvents`) em vez do padrão `Sessão do Pacote · {nome}`.
|
||||
- **Layout enxuto:** renderiza apenas 4 cards na ordem: (1) Dados da Recorrência (read-only summary), (2) Status, (3) Horário, (4) Aplicar alterações em. Tudo o resto (paciente-hero, fields-grid, serie-panel, sessão/honorários, frequência, extras, resumo mobile) fica oculto via `v-if="!occurrenceMode"`.
|
||||
- **Escopo `Aplicar alterações em`:** migrou do `composer-right` do dialog pai pra dentro do dialog de ocorrência. O pai não mostra mais esse card — pra mudar escopo, o user obrigatoriamente vai pela pill.
|
||||
- **Horário editável:** botão "Ajustar horário" não fica `:disabled="isEdit"` no occurrenceMode (no pai sim — data/horário do pacote inteiro é imutável após criação).
|
||||
|
||||
Stack relevante:
|
||||
- `MelissaLayout.vue:2160` monta o 2º dialog passando `:occurrenceMode="true"` + `eventRow={ ...row, recurrence_date, _is_virtual }` via refs `agendaOccDialog*` (destructurados de `useMelissaAgenda` no setup — refs aninhados não auto-unwrap no template).
|
||||
- `useMelissaAgenda.onEditSeriesOccurrence` popula `occDialogEventRow` + abre `occDialogOpen=true`. Substituiu o pattern antigo de mutar `dialogEventRow` in-place (que trocava silenciosamente os dados do dialog atual).
|
||||
- `useAgendaEventLifecycle.onPillEditClick` emite `editSeriesOccurrence({ id, recurrence_date, inicio_em, fim_em, is_virtual })`.
|
||||
|
||||
**Pendente replicar:** Rail (`AgendaTerapeutaPage`) e Clínica (`AgendaClinicaPage`) ainda têm só o dialog principal — o 2º só existe no Melissa por enquanto.
|
||||
|
||||
## Referências de código
|
||||
|
||||
- `src/features/agenda/composables/useRecurrence.js` — `loadAndExpand`, `expandRules`, `mergeWithStoredSessions`, `buildOccurrence`
|
||||
- `src/layout/melissa/composables/useMelissaAgenda.js:809` — `onUpdateSeriesEvent`
|
||||
- `src/layout/melissa/composables/useMelissaAgenda.js:817` — `onEditSeriesOccurrence`
|
||||
- `src/layout/melissa/composables/useMelissaAgenda.js:837` — `onUpdateSeriesEvent`
|
||||
- `src/features/agenda/composables/useAgendaEventActions.js:65` — watcher do form.status
|
||||
- `src/features/patients/composables/usePatientSessions.js:189` — `updateStatus` com materialização
|
||||
- `src/features/agenda/components/AgendaEventDialog.vue` — props `occurrenceMode`, computeds `occurrenceIndex` / `occurrenceTotalSessions` / `headerMainLabel`
|
||||
- `src/layout/melissa/MelissaLayout.vue:655` — `updateEventoStatus` do `MelissaEventoPanel`
|
||||
- `src/layout/melissa/MelissaLayout.vue:2160` — 2º AgendaEventDialog empilhado
|
||||
- `src/layout/melissa/MelissaAgenda.vue:244` — `VIEW_MAP.lista = 'listAll'`
|
||||
|
||||
Reference in New Issue
Block a user