Files
agenciapsilmno/HANDOFF.md
T
Leonardo 86311ef305 Melissa: hub Configuracoes + Embed + 9 Pages novas + dialog blueprint dark
Sprints 04-29 + 04-30 acumuladas.

- MelissaConfiguracoes: hub 2-col com 6 grupos (Layout/Conta/Agenda/
  Financeiro/WhatsApp/Sistema), tudo embedado via MelissaEmbed.
- MelissaEmbed: wrapper generico que injeta layout-variant=melissa
  e remove cromos pra reaproveitar Pages tradicionais.
- 9 Melissa Pages novas: CadastrosRecebidos, Compromissos, Configuracoes,
  Conversas, Embed, Grupos, Medicos, Recorrencias, Tags.
- Dialog blueprint atualizado: bg-gray-100 (hardcoded light) ->
  bg-[var(--surface-ground)] (tema-aware). 22 dialogs migrados em
  9 arquivos. Anti-pattern documentado.
- PatientsCadastroPage: bug fix dropdown Grupo (optionLabel nome->name),
  toggle vertical/abas com persist localStorage, sticky margin-top.
- Surface picker no popover do MelissaLayout (8 swatches).
- useTopbarPlanMenu, useMelissaWhatsapp, useMelissaPacientesAside novos.
- Migration: status agenda remarcado/confirmado.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 11:41:19 -03:00

30 KiB
Raw Blame History

HANDOFF — 2026-04-30 (quinta, sprint MelissaConfiguracoes + MelissaEmbed + dialog blueprint dark)

Documento de continuidade. Quando voltar, comece lendo esta página. Sessão grande — criação do hub de configs Melissa (com tudo embedado), wrapper genérico pra pages tradicionais, polimento do cadastro de paciente, migração de 22 ocorrências de bg-gray-100 em dialogs pra tema-aware. Working tree NÃO commitado ainda.

A sessão anterior (2026-04-29) deixou 7 Melissa Pages novas também não commitadas — estão acumuladas com esta. Decidir junto: 1 commit grande ou chunks lógicos.


🚦 STATUS — Working tree

Modificados (acumulado das 2 sprints):

M HANDOFF.md
M blueprints/dialog-blueprint.md
M src/assets/layout/_menu.scss
M src/components/CadastroRapidoConvenio.vue
M src/components/CadastroRapidoMedico.vue
M src/components/agenda/AgendaQuickAddDialog.vue
M src/components/ui/PatientCadastroDialog.vue
M src/features/patients/cadastro/PatientsCadastroPage.vue
M src/features/patients/medicos/MedicosPage.vue
M src/layout/AppMenu.vue
M src/layout/AppRail.vue
M src/layout/AppRailPanel.vue
M src/layout/AppRailSidebar.vue
M src/layout/composables/layout.js
M src/layout/configuracoes/ConfiguracoesAgendaPage.vue
M src/layout/configuracoes/ConfiguracoesRecursosExtrasPage.vue
M src/layout/configuracoes/ConfiguracoesWhatsappPage.vue
M src/layout/melissa/MelissaAgenda.vue
M src/layout/melissa/MelissaLayout.vue
M src/layout/melissa/MelissaMenu.vue
M src/layout/melissa/MelissaPacientes.vue
M src/layout/melissa/composables/useMelissaAgenda.js
M src/router/routes.clinic.js
M src/router/routes.therapist.js
M src/views/pages/account/ProfilePage.vue
M src/views/pages/saas/SaasAddonsPage.vue
M src/views/pages/saas/SaasNotificationTemplatesPage.vue

Novos (acumulado):

?? blueprints/melissa-page-blueprint.md
?? src/layout/melissa/MelissaCadastrosRecebidos.vue
?? src/layout/melissa/MelissaCompromissos.vue
?? src/layout/melissa/MelissaConfiguracoes.vue
?? src/layout/melissa/MelissaConversas.vue
?? src/layout/melissa/MelissaEmbed.vue
?? src/layout/melissa/MelissaGrupos.vue
?? src/layout/melissa/MelissaMedicos.vue
?? src/layout/melissa/MelissaRecorrencias.vue
?? src/layout/melissa/MelissaTags.vue
?? src/layout/melissa/composables/useMelissaPacientesAside.js

FEITO HOJE (2026-04-30)

PatientsCadastroPage — polimento

  1. Bug fix dropdown Grupo vaziooptionLabel="nome""name" (PatientsCadastroPage.vue:1542). Repo listGroups retorna {name,color} mas template buscava nome. Tags já estavam OK.
  2. Toggle Vertical/Abas — botão segmented na sidebar (entre avatar e nav). Em "Abas", esconde nav vertical da sidebar + mostra tab list em cima do main + esconde headers do Accordion (via .pcd-horizontal :deep(.p-accordionheader)). Persiste em localStorage (chave pcd.viewMode.v1).
  3. Sticky + margin-top fantasma — adicionado xl:items-start no grid container (era stretch por default). Sticky da esquerda mantido como estava. Margin-top fantasma resolveu.

Dialog blueprint — dark/light aware

  1. blueprints/dialog-blueprint.md atualizado: trocado bg-gray-100 (hardcoded light) por bg-[var(--surface-ground)] (tema-aware: --p-surface-100 light / --p-surface-950 dark). Removido o hack shadow-[0_1px_0_0_rgba(255,255,255,0.06)]. Adicionada seção Anti-pattern explícita.
  2. 22 ocorrências em 9 arquivos migradas pro novo padrão:
    • MedicosPage.vue (1 dialog)
    • SaasNotificationTemplatesPage.vue (1)
    • SaasAddonsPage.vue (3 dialogs)
    • PatientsCadastroPage.vue (2 dialogs internos: criar grupo, criar tag)
    • ConfiguracoesWhatsappPage.vue (1)
    • CadastroRapidoMedico.vue (1)
    • CadastroRapidoConvenio.vue (1)
    • ConfiguracoesRecursosExtrasPage.vue (1)
    • AgendaQuickAddDialog.vue (1)

Surface picker no popover do canto superior direito

  1. MelissaLayout.vue — importado surfaces de theme.options, criado setSurface() análogo a setPrimary(), computed activeSurface com fallback (zinc no dark, slate no light). Popover do canto sup. dir. agora mostra Surface (8 swatches) abaixo de Cor primária.

MelissaConfiguracoes — hub de configurações

  1. Novo arquivo: src/layout/melissa/MelissaConfiguracoes.vue

    • Layout 2-col (estilo MelissaAgenda): aside ~320px com Accordion de grupos + main com conteúdo da seção ativa
    • 6 grupos (espelham /configuracoes/ + extensões):
      • Layout Melissa: Aparência, Plano de fundo, Relógio, Cronômetro (4 inlines com controles definidos no próprio arquivo)
      • Conta (NOVO): Meu Perfil, Meu Plano, Meu Negócio, Segurança
      • Agenda: 3 sub-itens
      • Financeiro: 5 sub-itens
      • WhatsApp & Conversas: 9 sub-itens
      • Comunicação: 2 sub-itens
      • Empresa & Plataforma: 3 sub-itens
    • Total: 30 sub-itens — 4 inlines + 26 embedados via defineAsyncComponent + <Suspense>
    • COMPONENT_MAP mapeia keys pra defineAsyncComponent(() => import(...))
    • mcfg-embed-hero sticky no topo (z-index: 11) com ícone+label+desc+slot #cfg-page-actions pros Teleports das pages tradicionais
    • mcfg-embed-wrap dá padding equivalente ao px-3 md:px-4 pb-5 da ConfiguracoesPage
    • Aceita prop secaoRota que mapeia rota → secaoAtiva (ROUTE_TO_SECAO): permite deep-link tipo /melissa/perfil abrir direto na seção certa
  2. MelissaLayout.vue — adicionou ao SECOES:

    • aparencia (default do MelissaConfiguracoes)
    • perfil, plano, negocio, seguranca (atalhos de Conta — montam MelissaConfiguracoes pré-selecionado)
    • provide('melissaSettings', {...}) após testarToque (ordem importa pra ter todas as refs definidas) — expõe pro MelissaConfiguracoes

MelissaEmbed — wrapper genérico (Onda 1)

  1. Novo arquivo: src/layout/melissa/MelissaEmbed.vue

    • 1-coluna (sem aside) — mais leve que MelissaConfiguracoes
    • Hero glass sticky (z-index 11) + <Suspense> + <component :is> lazy
    • 9 pages embedadas (EMBED_MAP):
      • Financeiro Visão geral + Lançamentos
      • Documents List + Templates
      • Agendamentos Recebidos
      • Online Scheduling
      • Relatórios
      • Notifications History
      • Patients External Link
    • Reusa Teleport target #cfg-page-actions (compartilhado com ConfiguracoesPage tradicional)
  2. MelissaLayout.vueMELISSA_EMBED_KEYS array + render condicional + filtro do placeholder atualizado

MelissaMenu — handlers internos + Onda 1

  1. MelissaMenu.vue — várias mudanças:
    • Footer: goPerfil/goPlano/goSeguranca trocados de navAndClose(rota_externa) pra emit('select', '...') interno. Adicionado goNegocio + botão "Meu Negócio".
    • Backdrop blur no .mm-layer: background: rgba(0,0,0,0.25) + backdrop-filter: blur(2px) (equivalente ao backdrop-blur-xs do PrimeVue Dialog)
    • Categoria Configurações > Layout Melissa > "Aparência e cronômetro"
    • Onda 1 entries:
      • Agenda e Pacientes > Principais: + Agendamentos recebidos
      • Agenda e Pacientes > Outros: + Agendador online, Link externo de cadastro
      • Prontuários: novo grupo "Documentos" (Documentos, Templates)
      • Financeiro: convertido fin-overview/fin-lancamentos (route externo) → financeiro/financeiro-lancamentos (internos), + grupo "Análise" com Relatórios
      • WhatsApp > Atendimento: + Notificações enviadas

📊 Estado da migração Melissa

Promovidas (10 nativas): Agenda, Pacientes, Compromissos, Recorrências, Conversas, Tags, Grupos, CadastrosRecebidos, Médicos, Configurações Embedadas via MelissaConfiguracoes (26): 22 configs + 4 conta Embedadas via MelissaEmbed (9): Financeiro+Lançamentos, Documents+Templates, Agendamentos Recebidos, Online Scheduling, Relatórios, Notificações, Link Externo

Faltam (🟢 baixa prioridade): Dashboards (Therapist/Clinic — paradigma diferente, resumo já cobre), Setup Wizard, Upgrade pages, Clinic admin (Features/Professionals)

🚫 Fora de escopo: routes.saas.js (admin SaaS), Auth pages


🧪 ROTEIRO DE TESTE — passo a passo (7 fases, ~35 min)

Setup (1 min)

Remove-Item -Recurse -Force node_modules\.vite -ErrorAction SilentlyContinue
npm run dev
  • Abre http://localhost:5173 → faz login
  • /account/profile → terceiro card "Layout" → confirma Melissa selecionado
  • DevTools console aberto durante TODOS os testes (F12)

Se ver Cannot read properties of null → mata vite, limpa cache (Remove-Item -Recurse -Force node_modules\.vite), reinicia.


Fase 1 — Smoke (3 min)

# Passo Esperado
1.1 Acessa /melissa Resumo carrega: relógio gigante + saudação + cards. Console limpo.
1.2 Click no ψ (canto inf. esq.) Menu Win11 abre. Fundo escurece com blur sutil (mudança nova)
1.3 Click fora do menu Menu fecha

Fase 2 — Cadastro de paciente (5 min)

  1. /melissa/pacientes → click "+ Novo paciente"
  2. Toggle Vertical/Abas (topo da sidebar do dialog):
    • Click "Abas" → tabs aparecem em cima do form (6 com cores) + nav vertical da sidebar some
    • Painel ativo continua sendo mostrado
    • Click "Vertical" → volta ao Accordion
  3. Painel "Clínico & origem" (seção 2):
    • Dropdown Grupo mostra nomes (era vazio antes)
    • Multiselect Tags funciona
    • Botão + ao lado de Grupo → abre dialog "Novo grupo"
    • Botão + ao lado de Tag → abre dialog "Nova tag"
  4. Sticky / margin-top fantasma:
    • Expande painel grande, scroll pra baixo
    • Coluna esquerda acompanha sticky
    • Sem espaço fantasma entre topo e sidebar
  5. Refresh hard (Ctrl+Shift+R) → reabre dialog → toggle Vertical/Abas persiste

Fase 3 — Dialogs dark/light (3 min)

  1. /account/profile → tema claro
  2. /melissa/pacientes → abre dialog (criar tag pelo + na sidebar)
    • Header e footer com cor levemente cinza (var --surface-ground)
  3. Troca pra escuro → reabre dialog
    • Header e footer com cor levemente preta (mais escuro que body)
  4. Repete em outros dialogs:
    • Cadastro paciente
    • Médicos (/melissa/medicos → editar)
    • Convênio (cadastro rápido)
    • Agenda quick add (/melissa/agenda → click numa célula vazia)

Fase 4 — MelissaConfiguracoes (10 min) — mais densa

Acessa /melissa/aparencia

Sidebar — confirma 6 grupos no Accordion:

  • Layout Melissa (aberto por default)
  • Conta, Agenda, Financeiro, WhatsApp & Conversas, Comunicação, Empresa & Plataforma

Grupo "Layout Melissa" — 4 inlines:

Sub-item O que confere
Aparência Segmented Tema, swatches Primary, swatches Surface, botão "Padrão"
Plano de fundo Preview, upload de imagem, sliders
Relógio Segmented 24h/12h
Cronômetro Select de toque + botão "Testar"

Grupo "Conta" — 4 embedados:

  • Meu Perfil → ProfilePage com hero "Meu Perfil" no topo
  • Meu Plano → TherapistMeuPlanoPage
  • Meu Negócio → NegocioPage
  • Segurança → SecurityPage

Grupo "Agenda" — 3 embedados: Agenda, Bloqueios, Agendador Online

Grupo "Financeiro" — 5 embedados: Pagamento, Precificação, Descontos, Exceções, Convênios

Grupo "WhatsApp" — 9 embedados: testa pelo menos 2-3 (ex: Templates, Créditos, Histórico)

Grupo "Plataforma" — 3 embedados: Empresa, Recursos Extras, Auditoria

Em TODAS as embedadas, conferir:

  • Hero contextual sticky no topo do main, z-index acima de qq sticky interno
  • Ícone + título + descrição corretos por seção
  • Padding adequado — conteúdo não cola na borda

Fase 5 — Atalhos MelissaMenu (5 min)

Click no ψ pra abrir menu:

Footer (5 botões):

Botão Esperado
Meu Perfil Fecha menu, abre /melissa/perfil (embedado, não navega externo)
Meus Planos /melissa/plano
Meu Negócio /melissa/negocio (botão NOVO desta sprint)
Segurança /melissa/seguranca
Modo escuro Toggle dark/light

Categoria Configurações:

  • Configurações → grupo "Layout Melissa" → "Aparência e cronômetro" → vai pra /melissa/aparencia

Backdrop:

  • Ao abrir menu, fundo escurece (rgba 0.25) + blur 2px

Fase 6 — Onda 1 embedadas (8 min)

Pra cada URL: hero contextual + conteúdo renderiza + botão X fecha + console limpo

URL Como chegar pelo menu
/melissa/financeiro ψ → Financeiro → Visão geral
/melissa/financeiro-lancamentos ψ → Financeiro → Lançamentos
/melissa/documentos ψ → Prontuários → Documentos
/melissa/documentos-templates ψ → Prontuários → Templates de documentos
/melissa/agendamentos-recebidos ψ → Agenda e Pacientes → Agendamentos recebidos
/melissa/online-scheduling ψ → Agenda e Pacientes → Agendador online
/melissa/relatorios ψ → Financeiro → Relatórios
/melissa/notificacoes ψ → WhatsApp → Notificações enviadas
/melissa/link-externo ψ → Agenda e Pacientes → Link externo de cadastro

Fase 7 — Surface picker (1 min)

  1. /melissa → click engrenagem (canto sup. dir.)
  2. Aparece Cor primária + Surface abaixo (8 swatches)
  3. Click em diferentes surfaces → fundo de cards/dialogs muda

Como reportar bugs (pra cada problema)

  • Fase + step (ex: "Fase 4, Conta > Meu Plano")
  • O que aconteceu (frase curta)
  • Console error (stack se tiver)
  • Screenshot se for visual

Prioridade pra arrumar:

  1. 🔴 Crashes (página em branco, erro vermelho)
  2. 🟠 Funcionalidade quebrada
  3. 🟡 Polish visual

⏭️ PRÓXIMOS PASSOS (após testes)

1. Bugs encontrados → arrumar pontual

2. Bug aberto pendente — A#37

  • "Erros ao salvar paciente + dialog não fecha"
  • Botão maximizar já corrigido (sessão anterior)
  • Falta erro específico do Leonardo (console + toast + Network)
  • Hipóteses: RLS, NOT NULL constraint, validação silenciosa

3. Commits

  • Decidir: 1 mega-commit ou chunks lógicos. Acumulado = 27 modificados + 11 novos.
  • Sugestão de chunks (em ordem):
    1. Sprint anterior (HANDOFF 2026-04-29) — 7 Melissa Pages + bugfixes Teleport
    2. PatientsCadastroPage polish (toggle + bug Grupo + sticky)
    3. Dialog blueprint dark/light (blueprint + 9 arquivos migrados)
    4. Surface picker + provide melissaSettings
    5. MelissaConfiguracoes (hub completo)
    6. MelissaEmbed (Onda 1)
    7. MelissaMenu (handlers internos + Onda 1 entries + blur)

4. Onda 2/3 — decisão pendente

  • Onda 2: MelissaDocumentos nativa (~700 linhas glass card 2-col)
  • Onda 3: MelissaFinanceiro nativa (~1000 linhas, dashboard cards Win11)
  • Critério: se usar muito → vale nativa. Se ocasional → embedado tá bom.
  • Decidir DEPOIS de testar a Onda 1 atual.

5. Itens 🟢 baixa prioridade (talvez nunca)

  • Dashboards tradicionais (resumo já cobre)
  • Setup Wizard (fluxo pontual)
  • Upgrade pages
  • Clinic admin specific (Features/Professionals — admin só)

📚 Tracking persistente

  • A#32 — Fase 5 router wire-up (ainda pendente, sessão dedicada)
  • A#33-A#36 — bugs resolvidos sessões anteriores (memória project_layout_melissa.md)
  • A#37 — Cadastro paciente erro ao salvar: ⚠️ INVESTIGAR (preciso erro específico)
  • Memória atualizada: project_layout_melissa.md (sprint 2026-04-29 completa)
  • Blueprints: dialog-blueprint.md (atualizado dark/light), melissa-page-blueprint.md (referência)

📦 Setup pra retomar

# Terminal 1 — Functions
supabase functions serve --no-verify-jwt --env-file supabase/functions/.env

# Terminal 2 — Vite
rm -rf node_modules/.vite  # se cache estiver bagunçado
npm run dev

# Browser
http://localhost:5173/melissa

HANDOFF — 2026-05-03 (sábado, sprint Melissa polishing + topbar parity + notif redesign)

Sessão longa. Working tree continua não-commitado (acumula com as duas anteriores de 04-29 e 04-30). Dados de demo no DB (9 eventos hoje com price/billed) — limpar antes de qualquer push pra outro ambiente.

FEITO HOJE

Melissa: timeline do resumo com paridade FullCalendar

  • Range derivado de agenda_regras_semanais (regra do dia atual) com fallback pra agenda_configuracoes (agenda_custom_start/end) → 0818h hardcoded. Substitui as constantes HORA_INICIO=8 / HORA_FIM=20.
  • Range expande pra fora do expediente — sessões agendadas fora da jornada (ex: 22h num dia 0818) ainda aparecem; a timeline cresce pra acomodar.
  • Badge "Folga" / "Feriado: " no header — isFolga checa ausência de rule pro dia_semana; todayFeriado busca em agendaFeriados (já exposto via useMelissaAgenda). Não bloqueia, só sinaliza.
  • Scroll horizontal com min-width por slot via CSS var --m-tl-slot-w (default 80px); --m-tl-cols setada inline. Wrapper .tl-h-scroll com scrollbar fina theme-aware.
  • Auto-scroll inicial pra "agora" registrado dentro de onMounted (TDZ-safe); watch [HORA_INICIO, HORA_FIM] com _tlAutoScrolled flag pra disparar uma vez só. ResizeObserver mantém viewW/innerW frescos.
  • Eco lateral — minimap pulsante de cores nas bordas. Faixa 8px com tracinhos coloridos (cor do status) posicionados por tempo dentro da janela invisível. Click anima scroll até o evento. Pulse 2.4s só quando há off-screen. Hover expande tracinho scaleX(2.2) pra fora da faixa.

Cards do resumo Melissa (todos funcionais)

  • Próximo paciente — computed de eventosHojeReais, filtra sessao pendente, ordem por startH, primeiro. "Em curso" pulsa avatar quando hNow ∈ [start, end].
  • Recebíveis hojeprice + billed do agenda_eventos. 3 estados: com valores (barra de progresso), sem preço, sem sessões. billed=true é proxy pra "pago" (fonte real seria financial_records.status='paid' — refinamento futuro).
  • WhatsApp — novo composable useMelissaWhatsapp lendo conversation_threads filtrando channel=whatsapp + unread_count>0. Limit 50, agregação local. Fallback pra contact_number quando patient_name vazio.
  • Copilot — virou implementado: false no catálogo; cai no placeholder "Em breve" honesto (sem mock). Backend de IA não existe.

Dock pinned (Agenda + WhatsApp)

  • Adicionados ao .melissa-dock (que estava vazio, esperando uso). Ícones rounded-square 44px (vs ψ full-circle 56px) — hierarquia auto-resolve.
  • Active state primary-tinted quando seção correspondente aberta. Badge vermelho no WhatsApp com whatsappPendente.count (99+ se passar).
  • Hover: lift -3px + sombra crescendo (Win11 dock peek).

Topbar Melissa (paridade com Rail)

  • 3 botões trazidos do AppTopbar pro Melissa (canto sup. dir., flex row): plan switcher DEV (DEV-only), notificações (com badge), ajuda. Cog continua o rightmost.
  • Composable extraído: src/composables/useTopbarPlanMenu.js encapsula ~250 linhas de plan-menu logic (resolveActiveSubscriptionContext, listPlans, changePlanTo, etc). Reusável. AppTopbar inline NÃO foi refatorado (evita risco de regressão — refactor opcional).
  • <NotificationDrawer /> montado em MelissaLayout (idem <Toast />).
  • <AjudaDrawer /> já é global em App.vue, só importei o toggle.

Toast funcionando no Melissa

  • Bug: rota /melissa/:secao? está em routes.misc.js fora do AppLayout (que monta <Toast />). Resultado: toast.add() era silenciado em qualquer page embedada.
  • Fix: <Toast /> adicionado no fim do template do MelissaLayout (PrimeVue auto-import via PrimeVueResolver).

Refresh da timeline ao salvar jornada

  • Bug: useMelissaAgenda.loadSettings() rodava só no mount. Salvar jornada em /melissa/configuracoes/agenda atualizava DB mas Melissa ficava com workRules antigas até reload.
  • Fix: ConfiguracoesAgendaPage.saveJornada() dispara window.dispatchEvent(new CustomEvent('agenda:settings-saved')) após sucesso. useMelissaAgenda registra listener em window, chama loadSettings() quando ouve. Cleanup em onBeforeUnmount. Pattern espelha app:session-refreshed já em uso (main.js:134).

Profile: redirect ao trocar Melissa→Rail/Classic

  • Bug: saveAll() em ProfilePage persistia layout_variant mas não navegava. Usuário ficava preso em /melissa mesmo com flag mudado.
  • Fix: depois do save bem-sucedido, se estamos em /melissa E variant ≠ melissa → toast "Aplicando layout" + setTimeout(700ms, window.location.assign('/')). Hard reload pra remontar a árvore com AppLayout. Caminho inverso (qualquer→melissa) já era tratado em selectMelissa.

Tratamento visual por status nas pílulas (Melissa)

  • Helpers no MelissaLayout: statusKey(ev), statusIcon(ev), isEvEmCurso(ev), pillStatusClass(ev). Aplicados na pílula horizontal e no .vt-event vertical.
  • Tratamentos:
    • realizado ✓ → glow verde sutil
    • faltou ✗ → opacidade 0.78 + label tachado
    • cancelado ⊘ → opacidade 0.6 + diagonal hatching 135° + label tachado
    • remarcar 🔄 → ring âmbar 2px + glow âmbar
    • em-curso → pulse 2.2s usando --ev-color (color-mix) — herda hue do bg
  • eventStyle() agora também injeta --ev-color inline pra o pulse usar.

Status updates: refetch fix

  • Bug: status mudava no DB mas timeline visual não atualizava. M.refetch() só refresh a Agenda (composable separado).
  • Fix: capturei refetch do useMelissaEventosHoje no destructure e chamo junto com M.refetch() em updateEventoStatus.

Dialog do evento (MelissaEventoPanel) — botões

  • Blur XS.evento-layer baixou blur(20px) pra blur(4px) + saturate 110%. Overlay opacidade 0.5→0.32 (dark) / 0.18 (light). Resumo atrás continua legível, só com leve "tilt-shift".
  • Editar funciona — antes precisava de _raw que useMelissaEventosHoje não inclui (select limitado). Agora busca select('*') do row antes de chamar M.onEditEvento(data). Toast de erro com detalhe se falhar.
  • Prontuário e Histórico funcionam mesmo sem Agenda montada — novo helper _callOnAgenda(action): se melissaAgendaRef.value existe executa imediato, senão enfileira em _pendingAgendaAction ref e abre seção Agenda. Watch em melissaAgendaRef drena a queue quando o ref aparece.

Notification drawer redesign

  • NotificationItem.vue — repensado como card-item:
    • --type-rgb injetado inline; uma var pinta ícone, spine, chips e actions via color-mix em várias intensidades.
    • Avatar 40px circular (iniciais OU ícone do tipo) com pulse dot 9px no canto sup-direito quando não-lida.
    • Spine vertical 3px à esquerda na cor do tipo (cresce no hover de 80% pra 100%).
    • Card border-radius 10px + margin lateral; hover lifta 1px com shadow tinted.
    • Header com type label uppercase + horário relativo. Title 2-line clamp, detail 2-line clamp.
    • Quick actions: chips type-colored, primária filled (deeplink), outline (Conversa). Actions secundárias revelam no hover deslizando da direita.
  • NotificationDrawer.vue — toolbar limpa + grupos por data:
    • Width 380→420px. Header: título + count-pill ("3 não lidas").
    • Browser-notif vira icon-btn com active state primary-tinted.
    • Body com bg ground sutil. Toolbar sticky. Tabs em segmented control.
    • Mark-all virou ghost button compacto.
    • Grupos por data: Hoje / Ontem / Esta semana / Mais antigas (date-fns isToday/isYesterday/differenceInDays). Cada grupo tem header label-uppercase + linha + count.
    • Empty state: círculo 72px primary-tinted com check-circle, copy refinada, link "Ver tudo" se filtro=unread mas há itens.
    • Footer: pílula com border (em vez de link plain), arrow scoot 2px no hover.

TherapistDashboard (rail layout) — timeline parity

  • Mesmas features do Melissa aplicadas inline no TherapistDashboard.vue (cópia consciente, não extração — risco de regressão).
  • useAgendaSettings + useFeriados importados; loadFeriadosBase(tid) chamado em load() após resolver tid.
  • TL_START/TL_END viraram computeds (eram constantes 7/20). Default fallback 0720h (preserva range visual original do Dashboard, em vez do 0818 do Melissa).
  • Novo timelineEventsRaw evita dep circular: TL_START depende de timelineEventsRaw (que NÃO depende de TL_START). timelineEvents então adiciona positioning baseado em TL_START.
  • Folga/feriado badge inline no header.
  • Wrapper .dash-tl-frame > .dash-tl-scroll > .dash-tl-inner. Eco lateral com .dash-tl-eco. CSS scoped ao componente — duplicação consciente do Melissa até eventual extração pra <DailyTimelineStrip /> compartilhado.

Plan menu popover — ancoragem

  • Bug: ao clicar no botão Plan-DEV no Melissa, popover abria no top-left (sem âncora). Causas:
    1. planBtn.value?.$el é a forma correta pra PrimeVue Button mas Melissa usa <button> HTML cru, onde planBtn.value já É o DOM (sem $el).
    2. event.currentTarget é null DEPOIS do await loadPlanMenuData() — DOM event spec normal: após a microtask, ciclo de propagação acabou.
  • Fix em useTopbarPlanMenu.js: captura âncora ANTES do await, com fallback ampliado: planBtn.value?.$el || planBtn.value || event?.currentTarget || event?.target. Suporta os dois tipos de trigger sem branch.

Migration aplicada: status_evento_agenda + remarcado + confirmado

  • Enum tinha só {agendado, realizado, faltou, cancelado, remarcar} mas o código (AgendaTerapeutaPage.vue:1339 — bloqueio por feriado) e o trigger fn_notify_agenda_status_change (migration 20260423000009) referenciam 'remarcado' e 'confirmado'. Tentativas de save falhavam com invalid input value for enum status_evento_agenda.
  • Migration: database-novo/migrations/20260503000001_status_evento_agenda_remarcado_confirmado.sql. Idempotente (ADD VALUE IF NOT EXISTS). Aplicada local.
  • NOTIFY pgrst, 'reload schema' + restart do container supabase_rest_* pra dropar cache do PostgREST.
  • Distinção semântica preservada: remarcar (verbo, action label) ≠ remarcado (state final, sessão remarcada efetivamente). confirmado = paciente confirmou presença antes da sessão.

🗄️ DEMO DATA NO DB (LOCAL)

9 atendimentos populados em agenda_eventos pra hoje (2026-05-03), owner aaaaaaaa-...02, tenant bbbbbbbb-...02. Mix de status (realizado/faltou/ cancelado/agendado), price R$ 200-280, billed em 3 (R$ 780 / R$ 1.680 = 46%). Sessão demo "em curso" às 00:12 (John Bowlby) realinhada pra NOW()±window pra preservar pulse.

Ao virar o dia, shift +1d com:

UPDATE agenda_eventos
SET inicio_em = inicio_em + interval '1 day',
    fim_em    = fim_em    + interval '1 day'
WHERE owner_id = 'aaaaaaaa-0002-0002-0002-000000000002'
  AND inicio_em >= (CURRENT_DATE - 1)::timestamp AT TIME ZONE 'America/Sao_Paulo'
  AND inicio_em <  (CURRENT_DATE)::timestamp     AT TIME ZONE 'America/Sao_Paulo';

Limpar tudo (antes de qualquer push):

DELETE FROM agenda_eventos
WHERE owner_id = 'aaaaaaaa-0002-0002-0002-000000000002'
  AND id IN (
    '6b3ed093-fe1c-48de-a0ad-9bb4ea4d4c00',
    '136c2dcc-9da6-4fe8-bf24-3ca72d36a9e7',
    '8a6386b1-53d6-4043-a80d-90b4d146446b',
    '7002e899-f97e-4ca8-b3f2-826fc71c6e84',
    '3c7f5a11-8684-4adf-9fa0-76906dd5cc3c',
    '8f9f9ee1-3227-408c-9a97-91635a62078a',
    '71623e8b-38a9-4b62-8743-1e66eea2ab73',
    'b673d2db-335a-4c38-a939-9db1f9e400c6',
    '5142ad19-0224-456f-9c41-18c19fafd067'
  );

📂 ARQUIVOS MEXIDOS (SESSÃO 05-03)

Modificados:

M HANDOFF.md
M src/layout/melissa/MelissaLayout.vue              ← massivo
M src/layout/melissa/MelissaEventoPanel.vue         (blur XS)
M src/layout/melissa/composables/useMelissaEventos.js  (price/billed/select)
M src/layout/melissa/composables/useMelissaAgenda.js   (listener settings-saved)
M src/components/notifications/NotificationDrawer.vue  (redesign)
M src/components/notifications/NotificationItem.vue    (redesign)
M src/views/pages/therapist/TherapistDashboard.vue     (timeline parity)
M src/layout/configuracoes/ConfiguracoesAgendaPage.vue (dispatch event)
M src/views/pages/account/ProfilePage.vue              (post-save redirect)

Novos:

?? src/layout/melissa/composables/useMelissaWhatsapp.js
?? src/composables/useTopbarPlanMenu.js
?? database-novo/migrations/20260503000001_status_evento_agenda_remarcado_confirmado.sql

⚠️ EM ABERTO

  • Erro de enum persistente — usuário relatou que erro de enum persiste depois da migration + reload do schema. Não recebi o valor literal rejeitado (devtools → network → resposta da API). Suspeitos: tipo_evento_agenda (só tem sessao/bloqueio, mas código fala em supervisao/reuniao), ou outro enum. Próximo passo amanhã: capturar o erro literal e decidir fix (migration nova ou correção de código).
  • WhatsApp realtime no card — MVP só faz fetch on mount. Pluggar useConversations realtime channel (conv_msg_tenant_<tid> em conversation_messages INSERT) pra atualizar count instantâneo.
  • Recebíveis usa proxy billed — ideal seria query em financial_records com status='paid' filtrado por reference_date hoje. Refinamento futuro.
  • <DailyTimelineStrip /> extração — Dashboard duplicou inline em vez de extrair componente compartilhado. Quando aparecer 3º caller (admin dashboard?), vale a refatoração.
  • AppTopbar plan logic ainda inline — composable useTopbarPlanMenu existe mas AppTopbar não foi refatorado (evita risco). Quando tocar nele por outro motivo, dedupe.
  • Cleanup do demo data — 9 eventos populados local. Não comitar nem pushar antes de DELETE.

🎯 PRÓXIMOS PASSOS (sugestão)

  1. Capturar erro literal de enum + corrigir.
  2. Decidir commits acumulados (3 sprints sem commitar).
  3. WhatsApp realtime (rápido — só pluggar o channel).
  4. Avaliar extração <DailyTimelineStrip /> se for tocar Dashboard de novo.