Commit Graph

12 Commits

Author SHA1 Message Date
Leonardo 1feb7112ff agenda: C7 OK + Fase 6 lock-edit ativada em Melissa + cross-week payment propagation
Cenário 7 (Pacote UPFRONT — Ana Souza Ferreira 4×R$ 200 = R$ 800)
- Testado e passou. User criou Ana, pagou os R$ 800 em dinheiro pelo
  Financeiro. Borda verde + popover "Pago R$ 800" funcionando.

Fase 6 (lock-edit cobrada) ativada em Melissa
- Removido guard `if (!props.occurrenceMode) return;` em
  loadOccFinancialRecord (useAgendaEventLifecycle.js:217+). Agora ele
  carrega em ambos modos (Rail/Clínica E Melissa)
- loadOccFinancialRecord SINTETIZA record paid/pending pra siblings de
  contrato upfront ativo — assim TODAS as ocorrências da série mostram
  "Cobrança paga R$ 800 do pacote" no AgendaEventDialog
- AgendaEventDialog card Sessão/Honorários (flow Melissa) ganhou lock
  template: Tag em vez de Select billingType quando occFinancialRecord
  existe; Message com cadeado "Cobrança de R$ X já emitida"
- AgendaEventoFinanceiroPanel só renderiza dentro do lock quando record
  é REAL (não sintetizado) — evita "Gerar cobrança" indevido em sibling
- paymentSummary do Resumo lateral unificado pra usar occFinancialRecord
  (em vez do sessionPaymentRecord paralelo de antes)

Cross-week propagation de pacote upfront
- BUG: ao navegar pra semana só com virtuais (sem reais), bulk-load
  caía no else `_rulePaymentMap.value = {}` — virtuais perdiam estado
  paid herdado
- FIX em useMelissaAgenda._reloadRange:
  * Maps (payment/amount/rule) inicializados SEMPRE no início
  * Propagação roda independente de realIds.length (depende só de
    ruleIdsInView.size>0, considera reais E virtuais com recurrence_id)
  * Query cross-week: pra cada rule em view, busca QUALQUER evento
    sibling em qualquer semana + seus records pra determinar estado do
    contrato. Encontra o record do pacote mesmo em outra semana
- Saldo NÃO propaga (filter: charging_style='upfront' || NULL); cada
  sessão de saldo gera cobrança individual ao realizar
- Memória durável: memory/project_cross_week_propagation.md

Visualização de virtuais cobertas
- MelissaEventoPanel.showPaymentRow: virtuais só escondem quando state
  ='none'. Com paid/pending herdado, exibem linha colorida
- MelissaAgenda fcEvents: isPaidSession e badge $ pendente removeram
  exigência de !is_occurrence. Virtuais herdadas via propagação mostram
  borda verde / badge amber

Atalho "Gerar fatura" no popover
- Pill amber pequeno ao lado de "A cobrar R$ X" quando paymentVariant
  ='none' && !is_occurrence. Click → gerarCobrancaManual direto, fecha
  popover pra impedir double-click. Tooltip: "Gerar fatura agora"
- Wire em MelissaLayout via novo emit gerar-cobranca + handler
  onGerarCobrancaQuick

Info de pacote no popover
- Header agora mostra "Sessão · Pacote · N sessões" (computed
  seriesLabel lê de _raw do rule)

Botão "Excluir série inteira"
- Novo emit delete-series em MelissaEventoPanel + botão ao lado de
  "Excluir sessão" quando evento tem recurrence_id
- Handler onDeleteSeries em MelissaLayout: hard delete em 3 etapas
  (financial_records pendentes → agenda_eventos materializados →
  recurrence_rules CASCADE leva exceptions). Bloqueia se algum record
  paid (estorno via Financeiro primeiro)

cancel_session some da agenda
- useRecurrence.expandRules agora pula occurrence com exception.type=
  'cancel_session' (era visível com status cancelado; doc dizia que
  some). patient_missed/therapist_canceled/holiday_block permanecem
  como histórico

recurrence_exceptions cancel idempotente
- MelissaLayout onDeleteEvento usa upsert com onConflict pra exception
  cancel — não quebra mais com unique violation em re-cancel

billing_contract_id na 1ª materializada
- _createPackageContract agora .select() o contrato após insert e seta
  billing_contract_id no insert da 1ª agenda_eventos materializada

onVerLancamentos cobre virtual de upfront
- Antes virtual sempre toast "Sem lançamentos". Agora busca records via
  siblings da série pra encontrar o do pacote. Saldo/sem pacote continua
  com toast

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 20:54:23 -03:00
Leonardo e95ed9b585 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>
2026-05-19 08:31:18 -03:00
Leonardo 279b4f78e8 melissa/agenda: view lista 2 anos + selector SelectButton + sticky header + visual inativo
View lista: 'listWeek' -> custom 'listAll' (duration { years: 2 },
centrada em hoje via gotoDate(hoje - 1 ano) no setView). Antes a lista
mostrava so 7 dias e ocultava 3 das 4 ocorrencias semanais — agora cobre
passado + presente + futuro numa varredura. Cap MAX_RANGE_DAYS=730 do
loadAndExpand bate exato com 2 anos.

Banner showRecurrenceHint: aparece quando ha virtuais visiveis em
day/week/month (nao mostra em listAll). Texto curto + botao "Ver na
lista" que chama setView('lista').

Sticky day header (.fc-list-day): adicionado position:relative + z-index 3
+ bg opaco. Sem isso, .fc-event passava POR CIMA do header conforme
scroll (stacking context da row de evento ganhava do cushion sem z-index).

View selector: botoes manuais (.ma-cal__view-btn) -> PrimeVue SelectButton.
Visual herdado do tema, menos CSS custom.

Visual evento inativo: classNames=['ma-evt--inactive-patient'] em fcEvents
quando paciente_status === 'Arquivado'|'Inativo'. CSS aplica borda
tracejada + opacidade 0.58 (italico em list view). Mantem a cor do
commitment pra preservar contexto.

FC touch defaults: adiciona spread de FC_TOUCH_DEFAULTS (utility commitada
antes) — paridade touch <-> mouse, tap dispara select na hora em vez de
exigir long-press de 1000ms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 10:46:31 -03:00
Leonardo 71ee51d38f MelissaPaciente Fase 8: wire-up final (Dialog -> route /melissa/paciente?id=X)
PLANO DE 8 FASES COMPLETO. Os 2 callsites Melissa do PatientProntuario.vue
legacy (3593L Dialog) trocam por navegacao pra MelissaPaciente nativo via
router.push. PatientProntuario continua intocado pros 2 callsites legacy
fora do Melissa (TherapistDashboard, PatientsListPage).

MELISSAPACIENTE.VUE — wire-up interno
- Imports: useRouter + useConversationDrawerStore
- close(): emit + router.push('/melissa/pacientes')
- editPatient(): emit + router.push('/melissa/pacientes', query: {edit: id})
  pra MelissaPacientes auto-abrir o cadastroFullDialog
- openWhatsapp(): emit + conversationDrawerStore.openForPatient({id, name,
  phone, avatar_url}) — drawer global desce sobre Melissa
- addFinancial(): emit + toast "Em breve" (Fase 9 — dialog inline)

MELISSAPACIENTES.VUE
- Removeu import PatientProntuario + refs prontuarioOpen/prontuarioPatient
- Removeu <PatientProntuario> template (substituido por comentario)
- abrirProntuario(p): router.push('/melissa/paciente', query: {id})
- onMounted detecta route.query.edit -> abre cadastroFullDialog +
  router.replace pra limpar query (handshake com MelissaPaciente)
- Comentario header atualizado

MELISSAAGENDA.VUE
- Removeu import PatientProntuario + refs prontuarioOpen/prontuarioPatient
- Removeu <PatientProntuario> template
- abrirProntuarioPorId(id): router.push pra rota Melissa nativa
- abrirProntuarioPaciente / openProntuario / kebab "Prontuario" delegam
  pra abrirProntuarioPorId

MELISSALAYOUT.VUE
- Render <MelissaPaciente> simplificado: so @close="fecharSecao".
  Acoes edit/open-whatsapp/add-financial ficam internas.

ESLint: 0 errors da minha mudanca (9 pre-existentes nos arquivos tocados
sao baseline; confirmados via git stash — mesmos errors em ambos lados).

PLANO COMPLETO. Total de 8 commits no branch (Fases 1-8). MelissaPaciente.vue
~2400L + 5 composables (~407L) + utils ~280L. PatientProntuario.vue
intocado pra fallback legacy (TherapistDashboard, PatientsListPage).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 10:21:35 -03:00
Leonardo 9966b5f175 Melissa: paginas nativas cfg-* + temas + textos com fundo + drawer WA
CHROME COMPARTILHADO + 18 PAGINAS NATIVAS
- MelissaConfigPage: chrome unico (header, drawer mobile, sidebar com Configuracoes
  + FAQ slot, main com Suspense). Replica fake-dialog right rule e fica flush
  com o config-aside global.
- 18 wrappers finos (~25 linhas cada): cfg-precificacao, cfg-descontos,
  cfg-excecoes, cfg-convenios, cfg-wa, cfg-wa-pessoal, cfg-wa-oficial,
  cfg-wa-templates, cfg-conversas-tags/autoreply/optouts/sla/bots,
  cfg-lembretes, cfg-creditos-wa, cfg-sms, cfg-email-templates,
  cfg-recursos-extras, cfg-recursos-extras-extrato, cfg-auditoria.
- Cada wrapper usa defineAsyncComponent + Suspense pra evitar race com
  tenantStore no boot (loading travado em alguns chooser-style pages).
- MelissaLayout: imports + SECOES + MELISSA_NON_CONFIG_SLUGS + render
  conditions atualizados pra cobrir os 18 slugs.

PAGINAS LEGADAS DETECTAM CONTEXTO MELISSA
- ConfiguracoesWhatsappChooserPage, WhatsappPage, TwilioWhatsappPage,
  SmsPage, RecursosExtrasPage, EmailTemplatesPage, AddonsExtratoPage,
  AgendadorPage, ConversasAutoreplyPage: route.startsWith('/melissa')
  decide se router.push vai pro slug Melissa ou /configuracoes legado.
- Anchors <a href="/configuracoes/..."> (que recarregavam pagina e
  vazavam o usuario do Melissa) trocados por RouterLink context-aware.
- MelissaAgenda.goSettings agora vai pra /melissa/agenda-config.

PERSONALIZAR > TEMAS
- melissaThemes.js: catalogo Freud/Klein/Jung (wallpaper + cor primaria
  + preset Lara/Nora + surface).
- Toggle de tema aplica tudo de uma vez; persistido em melissa_prefs.themeName.
- Boot resolve themeName -> imagem via fetch + data URL (sem guardar
  data URL gigante no DB).
- onCustomFileChange/onClearBg invalidam themeName quando user mexe no bg.

PERSONALIZAR > FUNDO NOS TEXTOS
- Pref textBgEnabled em melissa_prefs.
- MelissaHeroClock: prop textBg envolve relogio/data/saudacao/resumo
  em <span class="hero-text"> que ganha bg branco/preto 60% + borda
  + padding + radius quando o toggle esta on.
- Vars --m-hero-text-bg / --m-hero-text-border flipam com light/dark.

TOP + DOCK COM GRADIENT HORIZONTAL
- Var --m-band: preto 80% (dark) / branco 80% (light).
- .melissa-topbar-band: gradiente cor->transparente (right->left) atras
  dos botoes do topo.
- .melissa-dock: gradiente cor->transparente (left->right) atras dos pins.

MELISSANEGOCIO ABSORVE MINHA EMPRESA
- Adiciona logo upload + preview "cartao de visita" (computeds
  enderecoLinhas/redesValidas/temDados/logoDisplay + redeIcon helper).
- Normaliza dados legados do cfg-empresa: redes_sociais.{rede} virou {name}.
- Preview teleporta entre 3 destinos baseado no viewport:
  mobile -> drawer; mid-desktop -> sidebar; wide-desktop (>=1340px) ->
  painel flutuante FORA do fake dialog (ancora no right edge + 14px gap,
  altura segue conteudo, header alinhado com header do dialog).
- Remove cfg-empresa de melissaConfigGrupos.js + COMPONENT_MAP do
  MelissaConfiguracoes; grupo "Empresa & Plataforma" -> "Plataforma".

CRONOMETRO -> SESSAO AGENDADA
- MelissaCronometro emite session-end ao parar com paciente selecionado
  (threshold 5s pra ignorar start/stop acidental).
- MelissaLayout.onCronometroSessionEnd busca agenda_eventos do paciente
  no dia (tipo='sessao'), pega o mais recente e grava em
  extra_fields.cronometro_duracao_seg + cronometro_parado_em.
- Toast: sucesso ("X min salvos") ou warn ("sessao nao encontrada").

CONVERSATIONDRAWER WHATSAPP-LIKE
- Nova imagem whatsapp-bg.jpg (renomeada de hash random) usada como
  tile (380px) no .cd-msgs.
- Light: bege #efeae2 + multiply blend.
- Dark: #0b141a + camada 78% sobre o doodle.
- Bubbles WA-style (verde out / branco-dark in com tails) ja existiam.

EXTRATO RECURSOS EXTRAS
- Filtros 2-por-linha em Melissa (vs 1/4 no /configuracoes).
- Cards de Resumo teleportam pro #cfg-page-side em Melissa
  (1-col empilhado no drawer; 4-col inline no /configuracoes).
- Botoes de exportar com flex-1 distribuidos em uma unica linha em
  desktop, wrap no mobile.
- DataTable scrollable em ambos os layouts.

OUTROS AJUSTES MENORES
- Cfg-conversas-autoreply: dias semana 4-cols em Melissa (vs 7-cols
  no /configuracoes).
- Cfg-creditos-wa: 1/2 por linha (vs 1/2/4) em Melissa.
- Cfg-recursos-extras: pacotes 1/2 (vs 1/2/4); "Em breve" 1-col.
- WhatsAppPage aba Templates: guia de formatacao teleporta pro side
  drawer em Melissa, deixando textareas full-width.
- ConfigPage chrome agora tem #cfg-page-actions target pros Teleport
  de acoes (refresh button etc).
- Imagens renomeadas em src/assets/themes/ (freudwebp/melainewebp/
  jungwebp.webp) e src/assets/whatsapp-bg.jpg.
- JoditTextEditor.vue novo (wrapper Jodit generico, sem features de email).
- MelissaConfigList.vue novo (lista compartilhada de configs pro drawer).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 23:48:18 -03:00
Leonardo ef3e160b36 MelissaAgenda: migra CSS pra Tailwind + extrai SearchPopover/ActionsPopover + fixes de smell
CSS migration (Tailwind v4 com max-[1023px]:/max-[1279px]: arbitrarios pra preservar pixel-perfect):
- Containers/layout: ma-page, ma-page__head/__title/__actions, ma-close, ma-head-btn, ma-body, ma-menu-btn, ma-mobile-drawer*
- Mini-calendar: weekdays/grid/day/dots/dot bases (state modifiers .is-feriado--* ficam em CSS por usarem color-mix por tipo)
- Aside: ma-side, ma-search*, ma-pat* (avatar/info/name/sub/novo/kebab), ma-act-btn*, paginator
- Toolbar: ma-cal*, ma-cal__nav*, ma-cal__btn (versao ghost + bug pre-existente da definicao duplicada preservado), ma-cal__icon, ma-cal__view*
- Stats/Sessions/Filter chip/Loading/Dock actions: bases full-Tailwind, state modifiers ficam em CSS
- Patient banner + All sessions: bases + grid responsivo via max-[640px]:[grid-column:N] arbitrarios

Extracoes:
- MelissaAgendaSearchPopover.vue: Cmd+K busca de toolbar (datas + paciente). Token monotonico + invalidacao em early returns + cleanup no @hide do Popover.
- MelissaAgendaActionsPopover.vue: popover Acoes mobile (<xl) com SelectButtons + 4 botoes de bloqueio. v-model:calendar-view/only-sessions/time-mode + emit bloqueio.

Fixes acionaveis (smells previamente listados):
- #2 null-safety em M.feriados/workRules (fallbacks pra modo standalone)
- #3 race em searchEventosByText (token monotonico contra out-of-order resolution)
- #5 cleanup _patClickTimer em onBeforeUnmount
- onHistoricoOpen valida inicio_em/fim_em antes de construir startH/endH (evita NaN propagation)
- onPacientesPageChange ignora clicks durante loading (evita resolucao fora de ordem)
- ESC no search popover limpa state via @hide handler centralizado
- fcEvents em 1 passada (for loop) em vez de filter().filter().filter().map() — 4x mais rapido em listView mensal
- pacientesIndex Map O(1) substitui 2 .find() sequenciais + cache extra pra fetch on-demand de patient (resolve dock/banner sumindo silenciosamente em clinicas >1k)
- Bloqueio buttons :disabled quando M=null (standalone)
- Teleport to=.melissa-dock guard com v-if M (evita warn em standalone)
- Dedup em flight de getSessionCounts (Set _sessionFetchInflight)

MelissaAgenda: 4181 -> 2851 linhas (-1330, -32%)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 10:37:59 -03:00
Leonardo 957e912a7f Melissa polish + Prontuario Visao Geral + agenda historico
Sprints B (05-03) e C (05-04) acumulados:

- NotificationDrawer/Item redesign (visual mais limpo, ações inline)
- Dock pins compose (useMelissaDockPins) + cache store global (melissaCacheStore)
- MelissaAgenda: timeline FullCalendar parity + cards resumo, histórico
  card com useMelissaAgendaHistorico, MelissaEventoPanel ajustado
- useFeriados: cache opt-in pra evitar fetch redundante de feriados
- PatientProntuario: aba Visão Geral nova; PatientConversationsTab polish
- AgendaClinicMosaic / AgendaTerapeutaPage / useAgendaSettings: ajustes
  de paridade com Melissa
- DocumentsListPage: pequenos ajustes
- DB migration 20260504000001: fix do trigger pra status 'excluido' nas
  cancel_notifications

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 09:11:55 -03:00
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
Leonardo 7b67bd083a Melissa Agenda: breakpoint compact + drawer mobile teleportado
Dois pontos de quebra agora:
- <xl (<=1279px) "compact": view-switcher (Dia/Semana/Mes/Lista) sai da
  toolbar e entra no menu "Acoes" com check icon no ativo. Filtros
  tambem migram pra dentro pra nao inflar a barra.
- <lg (<=1023px) "mobile": .ma-side e .ma-widgets viajam pra fora do
  .ma-page via Teleport, num <aside class="ma-mobile-drawer"> sempre
  presente no DOM (v-show controla display) — garante target valido
  desde o mount. Botao "Menu" mobile-only aparece a esquerda do header.
  Backdrop entre drawer e .ma-page com Transition de fade.

Bonus styles.scss: fix borda dupla do FullCalendar.
.fc-scrollgrid em light mode mantinha borda externa que somada com a
borda das celulas da ponta dava 2px na borda do calendario. Zera o
contorno do contairner — celulas (td/th) ja desenham a grade visual.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 17:11:56 -03:00
Leonardo ffcb8b17f9 Melissa Agenda: paridade com AgendaTerapeuta + responsivo mobile
Composable useMelissaAgenda (~1150 linhas, exclusivo Melissa):
- Orquestra useAgendaEvents + useRecurrence + useDeterminedCommitments
  + useFeriados + useCommitmentServices
- 7 cases de save (avulso, recorrente C, somente_este D, este_e_seguintes E,
  todos F, todos_sem_excecao G + tratamento de exclusion constraint)
- 3 cases de delete (somente_este, este_e_seguintes, todos com encerrar série)
- onCreateEvento (botão Agendar), onSelectTime com cap de 120min,
  persistMoveOrResize com confirm dialog descritivo e bold em datas/horas
- Bloqueio: openBloqueioDialog(mode) com 4 modos

MelissaLayout:
- Provide composable via MELISSA_AGENDA_KEY (inject em MelissaAgenda)
- Renderiza AgendaEventDialog + BloqueioDialog + ConfirmDialog
- Slot #message v-html pra renderizar HTML em messages do confirm
- onEditEvento liga panel ao dialog completo (B3 não-stub)

MelissaAgenda:
- Drop useMelissaEventosRange — eventos vêm do composable injetado
- Drag/resize/select-to-create habilitados quando há composable
- Cluster Paciente + Agendar (50/50 primary)
- Toolbar: timeMode (24/12/Meu) + onlySessions + bloquear-menu (desktop)
- Header: Pacientes (mobile-only, abre drawer) + Configurações + Fechar
- Mobile <lg: aside + widgets viram drawer off-canvas (slide esquerda);
  calendar fullwidth; "Ações" menu mobile concentra timeMode/onlySessions/
  bloquear; backdrop com click-outside

MelissaEventoPanel (B3 estático-revisado):
- Substitui panel inline que crashava em campos inexistentes
- Action bar agrupada (status / paciente / geral)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:15:56 -03:00
Leonardo 6a92735366 Melissa Agenda: toolbar polish + stats interativos com filtro
B1 — Toolbar
- Cluster Hoje + chevrons num pill único (mais coeso)
- Título com flex+ellipsis (some min-width:130px que truncava feio em
  view Mês/Lista)
- Botão "Hoje" disabled visual (opacity 0.45) quando hoje cai no range
  visível — antes ficava idêntico, sem affordance
- title="" → v-tooltip.top nos chevrons (memória: tooltips PrimeVue)
- focus-visible com outline accent em todos os botões da toolbar
- Visual refinado: padding/font-weight, view-btn ativo com box-shadow

B2 — Stats interativos
- Click no stat filtra fcEvents + sessoesHoje pelo predicado correspondente
  (Total/Sessões/Realizadas/Faltas — feriados continuam sempre)
- Stat ativo ganha borda accent + bg color-mix
- Stats com value=0 ficam disabled (cursor:not-allowed, opacity 0.4)
- Click no stat ativo limpa o filtro
- Chip flutuante "Filtrando: X" no canto sup direito do FC, click limpa
- Tooltip dinâmico explicando a ação esperada

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 08:29:59 -03:00
Leonardo 1bcb969f72 Layout Melissa (Direção B): preview, /profile, Agenda, dock, cadastro
Sandbox completo do novo layout Win11 lockscreen-style. Não troca o
AppLayout atual — Fase 5 (router wire-up) fica pra sessão dedicada.

Estrutura
- src/layout/melissa/ — MelissaLayout (bg+ψ+overlays), MelissaCronometro,
  MelissaAgenda (fullscreen), MelissaCard, MelissaMenu, MelissaBusca
- composables/useMelissaEventos.js — semana real do FC + range mensal
  pros dots do mini-cal
- composables/useMelissaPacientes.js — agora retorna created_at p/ "novo"
- melissaToques.js — toques Web Audio do término

Rota e persistência
- /preview/melissa (sem auth, sem AppLayout)
- /account/profile ganha 3º card "Melissa" com badge "Em construção"
- bootstrapUserSettings + layout composable aceitam variant='melissa'
- Migration: CHECK constraint user_settings.layout_variant aceita 'melissa'

Light mode
- Gradiente Bloom flipa via CSS vars (--bloom-c1/c2/base-1/base-2)
  Dark: 400/300/950 · Light: 200/100/0
- Cronômetro/Personalização: color: white → var(--m-text)
- Pílula psi-kbd ganha tokens --m-kbd-bg/--m-kbd-text
- Override mapeia text-X-200/300/400 → text-X-600 (17 cores Tailwind)

Agenda fullscreen
- Mini-cal funcional: click pula FC, range visível destacado, dots reais
- Feriados nacional/municipal/personalizado (rose/amber/violet)
- Dias fechados (workRules) cinza apagado, mutex feriado vence
- Card "Hoje" (stats+sessões) mesclado e movido pra sidebar esquerda
- ProximosFeriadosCard reaproveitado entre mini-cal e Hoje
- Avatar paciente: bg --m-accent-strong → --m-accent (saturado em light)
- Cores light: 12 substituições color:white → var(--m-text)

Dock taskbar Win11-style
- .melissa-dock 76px fixed bottom (CSS global, não scoped — Vue static
  hoisting perderia data-v-{hash})
- ψ centralizado vertical na faixa (bottom:10px)
- Chip cronômetro teleportado pro dock + animação minimize macOS
  (dialog encolhe + voa pro canto bottom-left, 340ms cubic-bezier)
- transform-origin: 96px calc(100% - 38px) (posição do chip no dock)

Pacientes na sidebar
- Botão fake "+" no topo abre PatientCreatePopover (rápido/completo/link)
- Reaproveita PatientCadastroDialog + ComponentCadastroRapido
- Pacientes criados nos últimos 7d sobem pro topo + badge "novo"

Dock contextual (ações do paciente selecionado)
- Avatar + nome + count + 5 ações (sessões/whatsapp/prontuário/editar/fechar)
- Teleportado pro .melissa-dock quando há paciente selecionado
- Em mobile, ações vivem em <Menu> kebab por linha
- Pattern <Transition><Teleport v-if> obrigatório (NUNCA o contrário)
  pra evitar comment placeholder + emitsOptions:null no reconciler

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 08:10:53 -03:00