diff --git a/HANDOFF.md b/HANDOFF.md index ce81bc3..6ee9627 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,644 +1,436 @@ -# HANDOFF — 2026-04-30 (quinta, sprint MelissaConfiguracoes + MelissaEmbed + dialog blueprint dark) +# HANDOFF — 2026-05-05 (sprint blueprint tabular Melissa + arquivamento de pacientes) 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. +> **🟡 PENDENTE — Sub-sessão 2 do A66 (V2 dialog)**: skeleton entregue +> em 2026-05-05 mas user **não gostou do design** ao olhar o preview. +> Aguarda feedback específico (3 zonas tá errado? hierarquia? hero +> grande demais? mobile? referência visual?). Iteração só depois disso. +> Detalhes na seção "Sessões dedicadas pendentes" no fim deste doc. + +> **🟢 ENTREGUE HOJE — Blueprint de página tabular Melissa**: documentado +> em `blueprints/melissa-table-page-blueprint.md` (~530 linhas, 18 seções) +> e aplicado em **MelissaCadastrosRecebidos** (refator) + +> **MelissaAgendamentosRecebidos** (NOVO, native page) + +> **MelissaPacientes** (refator parcial). Inclui DataTable com `:loading` +> + `paginator` + frozen action column, view toggle list/grade, +> sidebar com filtros coloridos por status, subheader explicativo, +> Tailwind 600 status colors, e mobile pencil + popover menu. + +Sessão de polimento e estruturação — não houve commit. Working tree +acumulada de 4 sprints (28 modificados + 22 novos). --- ## 🚦 STATUS — Working tree -**Modificados (acumulado das 2 sprints):** +**Modificados:** ``` 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 database-novo/agenciapsi-db-dashboard.html +M database-novo/db.config.json +M database-novo/generate-dashboard.cjs +M src/components/notifications/NotificationDrawer.vue +M src/components/notifications/NotificationItem.vue +M src/composables/useFeriados.js +M src/features/agenda/components/AgendaClinicMosaic.vue +M src/features/agenda/components/AgendaEventDialog.vue ← A66 sub-sessão 1 done +M src/features/agenda/composables/useAgendaSettings.js +M src/features/agenda/pages/AgendaTerapeutaPage.vue +M src/features/documents/DocumentsListPage.vue +M src/features/patients/cadastro/PatientsCadastroPage.vue ← statusOpts +Arquivado HOJE +M src/features/patients/prontuario/PatientConversationsTab.vue +M src/features/patients/prontuario/PatientProntuario.vue +M src/features/patients/services/patientsRepository.js ← +restorePatient HOJE 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/MelissaCadastrosRecebidos.vue ← refator blueprint HOJE +M src/layout/melissa/MelissaEmbed.vue ← agendamentos-recebidos removido HOJE +M src/layout/melissa/MelissaEventoPanel.vue +M src/layout/melissa/MelissaLayout.vue ← MAR wire-up HOJE +M src/layout/melissa/MelissaPacientes.vue ← refator grande HOJE 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 +M src/layout/melissa/composables/useMelissaEventos.js +M src/layout/melissa/composables/useMelissaPacientes.js +M src/layout/melissa/composables/useMelissaPacientesAside.js +M src/router/routes.misc.js +D database-novo/backups/2026-03-27/ (3 arquivos antigos) +D database-novo/backups/2026-03-29/ (3 arquivos antigos) ``` -**Novos (acumulado):** +**Novos:** ``` -?? 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 +?? blueprints/melissa-table-page-blueprint.md ← NOVO HOJE +?? database-novo/migrations/20260504000001_fix_cancel_notifications_excluido.sql +?? src/features/agenda/components/AgendaEventDialog.vue.bak ← rollback A66 +?? src/features/agenda/components/AgendaEventDialogV2.vue ← A66 sub-sessão 2 (NÃO TESTADO) +?? src/features/agenda/components/InsurancePlanQuickCreateDialog.vue +?? src/features/agenda/components/ServiceQuickCreateDialog.vue +?? src/features/agenda/composables/agendaEventHelpers.js ← A66 1A +?? src/features/agenda/composables/useAgendaEventActions.js ← A66 1C-i +?? src/features/agenda/composables/useAgendaEventComposer.js ← A66 1B +?? src/features/agenda/composables/useAgendaEventLifecycle.js ← A66 1C-ii-b +?? src/features/agenda/composables/useAgendaEventPickerBilling.js ← A66 1C-ii-a +?? src/features/agenda/composables/__tests__/ (5 specs) +?? src/features/patients/prontuario/PatientProntuario.vue.bak +?? src/layout/melissa/MelissaAgendaHistoricoCard.vue +?? src/layout/melissa/MelissaAgendamentosRecebidos.vue ← NOVO HOJE +?? src/layout/melissa/composables/useMelissaAgendaHistorico.js +?? src/layout/melissa/composables/useMelissaDockPins.js +?? src/stores/melissaCacheStore.js +?? src/views/pages/preview/ (V2 preview) ``` --- -## ✅ FEITO HOJE (2026-04-30) +## ✅ FEITO HOJE (2026-05-05) -### PatientsCadastroPage — polimento +### 1. Blueprint de página tabular — `melissa-table-page-blueprint.md` -1. **Bug fix dropdown Grupo vazio** — `optionLabel="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. +Novo arquivo em `blueprints/`. ~530 linhas, **18 seções**: -### Dialog blueprint — dark/light aware +1. Princípio (sidebar de filtros + main com toolbar + tabela) +2. Estrutura do template (com **subheader explicativo**) +3. Estado JS (script setup) — busca, statusFilter, paginação, viewMode +4. DataTable view Lista — props canônicas explicadas +5. View Grade — cards em CSS grid, `
` +6. Tokens de surface (light/dark) — `--p-content-background` canônico +7. Cores de status — Tailwind 600 (azul/verde/vermelho), aplicadas em 4 lugares +8. Filtro de status + Limpar filtro com Transition fade +9. **Subheader explicativo** — diferencia páginas de layout idêntico +10. Toolbar — busca + view toggle +11. DataTable estilos completos (header transparent, frozen column, paginator) +12. Botão pencil — coluna fixa +13. Empty / loading +14. Mobile (<1024px) — scroll horizontal, NÃO esconde colunas +15. Acessibilidade +16. Checklist de adoção (16 itens) +17. Anti-patterns (11 erros documentados) +18. Referência canônica → `MelissaCadastrosRecebidos.vue` -4. **`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. -5. **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) +### 2. MelissaCadastrosRecebidos — refator pra blueprint -### Surface picker no popover do canto superior direito +Antes era lista de cards verticais; agora é DataTable PrimeVue com: +- **Sidebar** `--m-bg-soft` + border-right + sombra `0 2px 8px` nos cards +- **Stats card** (Total / Novos / Convertidos / Rejeitados) — Novos azul / Conv verde / Rej vermelho +- **Status filter card** com 3 níveis de cor (default 5%, hover 10%, active 16% + ring) + botão + "Limpar filtro" com Transition fade quando ativo +- **Toolbar main** com search + view toggle (lista/grade) +- **DataTable** `:loading + paginator + scrollable scrollHeight="flex" + + tableStyle="min-width:640px"` — colunas: Paciente / Contato / Recebido / Ação (frozen 60px right) +- **Coluna frozen** com bg `--p-content-background` (canônico, opaco em ambos modos), + sombra à esquerda, hover/selected herdam da row +- **Botão pencil** (`mcr-row__action`) primary tinted +- **View Grade** alternativa — cards em CSS grid `auto-fill, minmax(220px, 1fr)` + com Paginator standalone abaixo +- **Subheader explicativo** com `pi pi-info-circle` em primary -6. **`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**. +### 3. MelissaAgendamentosRecebidos — NOVO native page -### MelissaConfiguracoes — hub de configurações +Substitui o embed via `MelissaEmbed`. Espelha 1:1 o blueprint, prefixo `mar`. -7. **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` + `` - - **`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 +- Tabela DB: `agendador_solicitacoes` (não `patient_intake_requests`) +- **4 status com cores próprias**: + - 🔵 Pendente (`rgb(37, 99, 235)`) + - 🟢 Autorizado (`rgb(22, 163, 74)`) + - 🟦 Convertido (`rgb(13, 148, 136)` — teal, distinto) + - 🔴 Recusado (`rgb(220, 38, 38)`) +- **DataTable**: 6 colunas (Paciente / Solicitado / Tipo / Contato / Recebido / Ação frozen) +- **3 ações condicionais** no dialog de detalhes: + - **Pendente** → Recusar (com motivo) | Autorizar | Converter em sessão + - **Autorizado** → Converter em sessão (cria paciente se necessário + abre `AgendaEventDialog`) + - **Convertido/Recusado** → só fechar +- **AgendaEventDialog wired** com props canônicas (event-row, owner-id, tenant-id, + agenda-settings, commitment-options, preset-commitment-id, + restrict-patients-to-owner) +- Subheader explicativo próprio -8. **`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 +**Wire-up no `MelissaLayout.vue`:** +- Import de MelissaAgendamentosRecebidos +- `MELISSA_EMBED_KEYS` perdeu `agendamentos-recebidos` +- `MELISSA_NON_CONFIG_SLUGS` ganhou direto +- Render block conditional entre Cadastros e Médicos +- `MelissaEmbed.EMBED_MAP` perdeu a entry agendamentos-recebidos (com comentário) -### MelissaEmbed — wrapper genérico (Onda 1) +**Importante**: o `MelissaEmbed.vue` foi modificado pra fazer `hideChrome` flag ++ close flutuante numa tentativa anterior — **revertido** ao original +porque ficou ruim. Layout Rail (`/therapist/agendamentos-recebidos`, +`/admin/agendamentos-recebidos`) continua usando `AgendamentosRecebidosPage.vue` +inalterada. -9. **Novo arquivo: `src/layout/melissa/MelissaEmbed.vue`** - - 1-coluna (sem aside) — mais leve que MelissaConfiguracoes - - Hero glass sticky (z-index 11) + `` + `` 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) +### 4. MelissaPacientes — refator parcial pra blueprint -10. **`MelissaLayout.vue`** — `MELISSA_EMBED_KEYS` array + render condicional + filtro do placeholder atualizado +A página é 3-pane (filters / list / detail) — não converti pra +DataTable (perderia o detail panel). Aplicado o que faz sentido: -### MelissaMenu — handlers internos + Onda 1 +**Sidebar:** +- Sombra `0 2px 8px` nos cards `.mp-w` (sidebar + quick view direita) +- Status pills com cores próprias por status: + - Todos = neutral (sem cor) + - 🟢 Ativos verde + - 🟡 Inativos amber `rgb(217, 119, 6)` (warn, pausa temporária) + - 🔴 Arquivados vermelho +- Botão "+" do header de Grupos/Tags **substituído** por: + - Botão `pi pi-cog` no header (sem borda, hover primary) — emite + `goto-grupos`/`goto-tags` que navegam pras Melissa Pages nativas + - Botão tracejado "+ Grupo / + Tag" (texto sem "+", só com ícone + `pi pi-plus`) abaixo de cada lista — abre popover de criação +- Botão `[×]` (clear filter) agora vermelho `rgb(220, 38, 38)` -11. **`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 +**Card de paciente (list view):** +- **Email em coluna própria** (220px, truncate) — separada do main +- **Telefone em coluna própria** (140px) — paralela ao email +- Em mobile (<768px) email/phone escondem (info no detail panel) +- Subheader explicativo + +**Mobile:** +- Coluna ação fixa (`position: sticky; right: 0; bg --m-bg-medium`) +- 5 botões inline → 1 botão `pi pi-pencil` único que abre `` +- **Popover de ações** global no fim da `
` com 5 items: + Prontuário / Sessões / WhatsApp / Editar / Arquivar (com divider) +- Bug fix: **`min-height: 0` na `.mp-list`** — sem isso a `mp-list__body` + não scrollava em mobile (`flex: 1; overflow-y: auto` precisa de + parent constrained) + +**Toolbar:** +- View toggle list/grade (persistido em `mp.viewMode.v1` localStorage) +- Botão "Novo paciente" usa `PatientCreatePopover` (mesmo do agenda) — + já estava wired, só explicitei `$event` no click handler + +**Grid view (NOVO):** +- CSS grid `auto-fill, minmax(240px, 1fr)` +- Cards com avatar+pencil topo, nome+novo, status, email+phone empilhados, + tags, "Última: X" com border-top +- Mantém `selecionarPaciente` (mostra detail panel mesmo no grid) +- `
` com handlers de teclado + +### 5. Subheader explicativo (padrão novo do blueprint § 9) + +Aplicado em 3 páginas, cada uma com texto próprio que diferencia +páginas de layout idêntico: + +- **MelissaCadastrosRecebidos**: "Cadastros completos enviados por + pacientes via formulário externo (link público). Revise os dados, + **converta em paciente ativo** com 1 clique ou **rejeite** com motivo + opcional." +- **MelissaAgendamentosRecebidos**: "Solicitações de horário vindas do + agendador online à espera de ação. **Autorize** pra reservar o slot, + **recuse** com motivo, ou **converta direto em sessão** — a gente cria + o paciente automaticamente se ainda não existir." +- **MelissaPacientes**: "Lista completa dos pacientes cadastrados. + Filtre por **status, grupo ou tag** à esquerda, busque por nome ou + contato, e clique numa linha pra abrir o **prontuário** com histórico, + sessões e documentos." + +CSS padrão: `bg --m-bg-soft` + ícone `pi pi-info-circle` em primary + +texto muted 0.78rem com `` em `--m-text`. Border-bottom matching +o page__head. + +### 6. Arquivamento de pacientes — restore implementado + +**Repository** (`patientsRepository.js`): +- Novo `restorePatient(id, { tenantId })` — espelha `softDeletePatient` + mas seta `status = 'Ativo'` + +**PatientsCadastroPage** (`statusOpts:749`): +- Adicionado `{ label:'Arquivado', value:'Arquivado' }` à lista de + opções do dropdown — fecha o gap de inconsistência ao editar paciente + arquivado + +**MelissaPacientes**: +- Helper `isArquivado(p)` (case-insensitive) +- Função `restaurarPaciente(p)` com confirm dialog → `restorePatient` → + toast "Restaurado" → `refetchTudo` +- **Toggle visual condicional**: + - Paciente **ativo**: 🗑 trash vermelho ("Arquivar") + - Paciente **arquivado**: ↶ undo primary ("Restaurar") +- Aplicado em ambos contextos: + - Desktop (5 botões inline) — `mp-card__action--restore` com hover primary + - Mobile popover menu — `mp-actions-menu__item.is-restore` --- -## 📊 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) +## 🧪 ROTEIRO DE TESTE (rápido — ~15 min) +### Setup ```powershell 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) +### Fase 1 — MelissaCadastrosRecebidos (5 min) +- `/melissa/cadastros-recebidos` → DataTable com header transparent + + bold, paginator centralizado, coluna Ação frozen direita com bg + branco no light +- Toolbar: search + view toggle (lista/grade) +- Sidebar: stats com Novos azul, Convertidos verde, Rejeitados vermelho + (quando >0); Status filter com 3 cores + Limpar filtro fade +- Subheader azul info-circle explicativo +- Mobile: drawer abre, scroll horizontal funciona, pencil único na + Ação frozen, todas colunas visíveis (não escondem) -❌ Se ver `Cannot read properties of null` → mata vite, limpa cache (`Remove-Item -Recurse -Force node_modules\.vite`), reinicia. +### Fase 2 — MelissaAgendamentosRecebidos (5 min) +- `/melissa/agendamentos-recebidos` → mesma estrutura, 4 status com cor + (Pendente azul / Autorizado verde / Convertido teal / Recusado vermelho) +- Click numa pendente → dialog mostra 3 ações (Recusar / Autorizar / + Converter em sessão); converter cria paciente automático + abre + AgendaEventDialog +- Subheader próprio diferenciando da Cadastros Recebidos + +### Fase 3 — MelissaPacientes (5 min) +- `/melissa/pacientes`: + - Sidebar com sombras nos cards (Estatísticas, Status, Grupos, Tags) + - Cards Grupos/Tags: cog `⚙` no header (sem borda, navega pra + `/melissa/grupos` e `/melissa/tags`); botão tracejado "+ Grupo" / + "+ Tag" abaixo da lista; X de limpar filtro vermelho + - Status pills coloridas (Ativos verde / Inativos amber / Arquivados + vermelho) +- Card de paciente: email coluna própria, phone coluna própria +- Toolbar: view toggle lista/grade (persiste); "Novo paciente" abre + PatientCreatePopover com 3 opções (rápido / completo / link) +- **Mobile (<1024px)**: scroll vertical funciona (era bug, corrigido com + `min-height: 0` na `.mp-list`); ações reduzem a 1 pencil sticky-right + com Popover de 5 items +- **Restore de arquivado**: + - Filtra por "Arquivados" (cor vermelha) + - Hover num card → desktop mostra ↶ "Restaurar" (primary) no lugar + do 🗑 trash + - Mobile: pencil → popover mostra "Restaurar" primary + - Click → confirm "Restaurar X?" → status volta a Ativo → some do + filtro Arquivados, aparece em Ativos --- -### Fase 1 — Smoke (3 min) +## ⏭️ PRÓXIMOS PASSOS (sugestão) -| # | 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 | +### 1. Decidir A66 V2 — design + +User testou o esqueleto V2 em `/preview/agenda-dialog-v2` (rota em +`routes.misc.js`) e **não gostou do design**. Aguarda feedback +específico antes de iterar: +- Estrutura: 3 zonas (PACIENTE/QUANDO/O QUÊ) tá errado? Prefere 2 zonas? + 1 coluna scroll? Tabs? +- Hierarquia: hero PACIENTE muito grande/pequeno? +- Densidade: airy demais ou apertado demais? +- Chips de duração/scope/status: muito visuais? +- Mobile: já testou viewport pequeno? +- Referência visual: Win11? Cleaner? Mais como V1? Algum app? + +Quando tiver feedback, iterar em `AgendaEventDialogV2.vue`. Sub-sessão +3 (migração nos 9 consumers) só depois do V2 estabilizar. + +### 2. Aplicar blueprint nas demais páginas tabulares Melissa + +Ainda faltam (todas seguem `melissa-table-page-blueprint.md`): +- `MelissaCompromissos.vue` +- `MelissaMedicos.vue` +- `MelissaConversas.vue` +- `MelissaRecorrencias.vue` +- `MelissaTags.vue` +- `MelissaGrupos.vue` + +Padrão: prefixo próprio (`mco`, `mmd`, etc.), sidebar com filtros +coloridos, DataTable com frozen action column, view toggle, subheader, +mobile pencil+popover. + +### 3. Decidir commits + +Acumulado de 4 sprints sem commitar (28 mod + 22 novos). Sugestão de +chunks lógicos (em ordem temporal): + +1. **Sprint A** — Sprint 04-29/30 (hub Configurações + 7 Melissa Pages + + dialog blueprint dark) +2. **Sprint B** — Sprint 05-03 (timeline FullCalendar parity, cards + resumo, dock pins, topbar, NotificationDrawer redesign, + melissaCacheStore, useMelissaDockPins) +3. **Sprint C** — Sprint 05-04 (MelissaAgendaHistoricoCard, useFeriados + cache opt-in, PatientProntuario aba Visão Geral, migration + `20260504000001_fix_cancel_notifications_excluido.sql`) +4. **Sprint D** — A66 sub-sessão 1 (5 composables + 5 specs + 265 + testes) + sub-sessão 2 esqueleto (V2 + preview) — **MARCAR como WIP** +5. **Sprint E HOJE** — Blueprint tabular Melissa + MelissaCadastrosRecebidos + + MelissaAgendamentosRecebidos + MelissaPacientes refator + restore + de pacientes arquivados + +### 4. Restore em outros layouts + +A `PatientsListPage.vue` (layout Rail) também tem KPI "Arquivados" +mas SEM botão Restaurar. Quando tocar nela, replicar o pattern: +botão condicional ↶ "Restaurar" baseado em `p.status === 'Arquivado'`, +chama `restorePatient` do mesmo repository. --- -### Fase 2 — Cadastro de paciente (5 min) +## 🛠️ Sessões dedicadas pendentes -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** +### A66 — Refactor `AgendaEventDialog` V2 (3 sub-sessões) ---- +**Estado**: +- ✅ Sub-sessão 1 (composables) — 5 composables + 265 testes, 495/495 + suite passando, AgendaEventDialog 3522→2632 linhas (-25%) +- 🟡 Sub-sessão 2 (template V2) — esqueleto entregue 2026-05-05, + **user não gostou do design**, aguarda feedback específico +- ⏳ Sub-sessão 3 (migração nos 9 consumers) — depende do V2 estabilizar -### Fase 3 — Dialogs dark/light (3 min) +**Por que sessão dedicada**: arquivo tinha 3522 linhas, é consumido em +9 páginas críticas (AgendaTerapeutaPage, AgendaClinicaPage, +MelissaLayout, MelissaEventoPanel, useMelissaAgenda, +AgendamentosRecebidosPage, TherapistDashboard, AgendaDevDocs). +Refatoração inteira não cabe em uma única conversa sem alto risco +de regressão. -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) +**Estado dos arquivos**: +- Backup: `src/features/agenda/components/AgendaEventDialog.vue.bak` + (155KB, byte-idêntico ao original) +- 5 composables novos em `src/features/agenda/composables/`: + `agendaEventHelpers.js` (262L) + + `useAgendaEventComposer.js` (485L) + + `useAgendaEventActions.js` (387L) + + `useAgendaEventPickerBilling.js` (378L) + + `useAgendaEventLifecycle.js` (474L) +- 5 specs em `__tests__/` (75+76+28+43+43 = 265 testes) +- `AgendaEventDialogV2.vue` (~1100L, 3 zonas) — não testado visualmente +- Preview em `/preview/agenda-dialog-v2` com 5 cenários ---- - -### 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ó) +**Próxima ação**: user dá feedback design → eu itero V2. --- ## 📚 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) +- **A66** — sub-sessão 2 (V2 design) aguardando feedback do user +- **Blueprint tabular Melissa** — referência canônica: + `MelissaCadastrosRecebidos.vue`. Próximas adoções planejadas: + Compromissos, Médicos, Conversas, Recorrências, Tags, Grupos +- **Restore pacientes** — implementado no Melissa; replicar no Rail + (`PatientsListPage.vue`) quando tocar +- **Migration aplicada local**: `20260504000001_fix_cancel_notifications_excluido.sql` + (cancela 'excluido' do enum trigger). Já aplicada no DB local. --- ## 📦 Setup pra retomar -```bash -# Terminal 1 — Functions -supabase functions serve --no-verify-jwt --env-file supabase/functions/.env +```powershell +# Limpa cache do Vite (recomendado depois de muita mudança em styles) +Remove-Item -Recurse -Force node_modules\.vite -ErrorAction SilentlyContinue -# Terminal 2 — Vite -rm -rf node_modules/.vite # se cache estiver bagunçado +# Sobe dev npm run dev -# Browser -http://localhost:5173/melissa +# Build sanity check (opcional, mas roda em ~25s) +npm run build ``` +**Suite de testes** (495 testes do A66 incluídos): +```powershell +npm run test +``` + +**Login**: user com `layout_variant=melissa` no profile pra testar +direto em `/melissa/...`. Pra testar Rail (regressão), troca em +`/account/profile` → terceiro card "Layout". + --- -# 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`) → 08–18h 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 08–18) 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 hoje** — `price + 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). -- `` montado em MelissaLayout (idem ``). -- `` 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 ``). Resultado: toast.add() era silenciado em qualquer - page embedada. -- Fix: `` 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 07–20h (preserva range visual original do Dashboard, em vez - do 08–18 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 `` 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 `