2151 lines
65 KiB
Markdown
2151 lines
65 KiB
Markdown
# MediConnect Roadmap
|
||
|
||
|
||
---
|
||
## Page 1
|
||
|
||
MediConnect Roadmap Final (Versão para PDF)
|
||
Data: 2025-11-21 Versão: 1.0 Responsável: Equipe MediConnect
|
||
Legenda de Status:
|
||
EXISTE: funcionalidade ou base já implementada (mesmo que simples)
|
||
PARCIAL: há elementos, mas precisa evolução significativa
|
||
PENDENTE: ainda não implementado
|
||
1. Visão Geral
|
||
Sistema de agendamento médico multi-perfil (médico, paciente, secretaria, admin) com gerenciamento de consultas,
|
||
disponibilidades e relatórios. Este roadmap destaca melhorias para aumentar valor, diferenciação e qualidade antes
|
||
da entrega final.
|
||
2. Design & UI/UX
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
KPIs no topo dos
|
||
painéis
|
||
PENDENTE
|
||
Cards com métricas chave
|
||
(Consultas Hoje, Ocupação
|
||
%, No-show %, Tempo
|
||
médio)
|
||
Consulta agregada via serviço
|
||
analytics; atualização automática a
|
||
cada 60s ou ação do usuário
|
||
Calendário
|
||
Semana/Dia
|
||
PENDENTE
|
||
Modos adicionais além do
|
||
mês
|
||
Alternar tabs (Mês/Semana/Dia);
|
||
Semana mostra colunas por dia, Dia
|
||
mostra timeline vertical com blocos de
|
||
consultas
|
||
Drag & Drop
|
||
consultas
|
||
PENDENTE
|
||
Reagendar arrastando
|
||
bloco
|
||
Biblioteca (react-beautiful-dnd ou
|
||
dnd-kit); atualiza scheduled_at e valida
|
||
conflitos
|
||
Heatmap de
|
||
ocupação
|
||
PENDENTE
|
||
Matriz dias × horas com
|
||
cores densidade
|
||
Pré-calcular slots ocupados vs total e
|
||
renderizar grade com escala de cor
|
||
Modo escuro
|
||
consistente
|
||
PARCIAL
|
||
Existe base Tailwind dark;
|
||
refinamento contraste
|
||
Ajustar tokens semânticos; auditoria
|
||
AA/AAA em principais componentes
|
||
Skeleton loaders
|
||
PENDENTE
|
||
Placeholder cinza animado
|
||
durante fetch
|
||
Wrapper <Skeleton> para listas,
|
||
calendário e relatórios
|
||
Empty states com
|
||
CTA
|
||
PARCIAL
|
||
Algumas mensagens
|
||
simples
|
||
Componente padrão mostrando ícone,
|
||
texto, botão ação principal
|
||
Sidebar colapsável
|
||
PENDENTE
|
||
Reduz largura exibindo
|
||
apenas ícones
|
||
Estado persistido em localStorage;
|
||
botão toggle
|
||
Tokens
|
||
tipografia/spacing
|
||
PENDENTE
|
||
Escala consistente (ex: 12–
|
||
14–16–20–24)
|
||
Arquivo design-tokens.ts e utilitários
|
||
Tailwind personalizados
|
||
|
||
---
|
||
## Page 2
|
||
|
||
Cores semânticas
|
||
status
|
||
PARCIAL
|
||
Mapeamento manual atual
|
||
Centralizar em objeto STATUS_COLORS;
|
||
fácil manutenção e tema
|
||
Perfil médico com
|
||
progress bar
|
||
PENDENTE
|
||
Indicar % completude do
|
||
perfil
|
||
Função calcula campos preenchidos /
|
||
total e exibe barra
|
||
3. Acessibilidade
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Focus rings custom
|
||
PENDENTE
|
||
Outline visível
|
||
padronizado
|
||
Classe utilitária Tailwind aplicada em
|
||
componentes interativos
|
||
Preferências
|
||
ampliadas
|
||
PARCIAL
|
||
Menu existe; adicionar
|
||
alto contraste, fonte
|
||
maior
|
||
Salvar preferências em contexto; aplicar
|
||
classes globais
|
||
Aria-live para toasts
|
||
críticos
|
||
PENDENTE
|
||
Leitura por leitores de tela
|
||
Container <div aria-live="assertive">
|
||
integrando com react-hot-toast
|
||
Labels em ícones
|
||
isolados
|
||
PARCIAL
|
||
Alguns ícones têm texto
|
||
Verificar ícones solo; adicionar aria-
|
||
label ou texto oculto
|
||
Atalhos teclado
|
||
(Command Palette)
|
||
PENDENTE
|
||
Abrir busca global
|
||
(Ctrl+K)
|
||
Modal com busca em pacientes,
|
||
consultas, relatórios; mapear atalhos via
|
||
hook
|
||
Navegação teclado
|
||
calendário
|
||
PENDENTE
|
||
Setas movem seleção;
|
||
Enter abre modal
|
||
Gerenciar estado de dia focado;
|
||
listeners keydown
|
||
Fonte acessível
|
||
(modo dislexia)
|
||
PENDENTE
|
||
Alternar fonte custom
|
||
Importar OpenDyslexic; toggle aplica
|
||
classe root
|
||
4. Performance
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Code-splitting
|
||
PainelMedico
|
||
PENDENTE
|
||
Arquivo muito grande
|
||
fragmentado
|
||
Rotas internas + lazy import via
|
||
React.lazy/Suspense
|
||
Cache com React
|
||
Query
|
||
PENDENTE
|
||
Evita múltiplos fetch
|
||
redundantes
|
||
Reescrever chamadas service.list() em
|
||
hooks useQuery
|
||
Memo mapa
|
||
pacientes
|
||
PARCIAL
|
||
Hoje recalcula
|
||
Hook usePatientNames + cache por tempo
|
||
Debounce em
|
||
buscas
|
||
PENDENTE
|
||
Reduz requisições
|
||
Hook useDebouncedValue aplicado em
|
||
campos de filtro
|
||
Prefetch próxima
|
||
semana
|
||
PENDENTE
|
||
Navegação calendário
|
||
suave
|
||
Ao mudar mês/semana dispara fetch dos
|
||
próximos dias
|
||
|
||
---
|
||
## Page 3
|
||
|
||
PWA offline agenda
|
||
PENDENTE
|
||
Uso básico offline
|
||
Service Worker + cache de assets +
|
||
agenda do dia em IndexedDB
|
||
Lazy-load avatar
|
||
PARCIAL
|
||
Carrega direto
|
||
loading="lazy" + placeholder fallback
|
||
Virtualização listas
|
||
PENDENTE
|
||
Melhor para grandes
|
||
volumes
|
||
react-window ou react-virtualized em
|
||
tabelas extensas
|
||
5. Segurança & Conformidade
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Auditoria ações
|
||
PENDENTE
|
||
Log quem
|
||
criou/editou/cancelou
|
||
Middleware registra ação em tabela
|
||
audit_log
|
||
Renovação de sessão
|
||
PARCIAL
|
||
Autenticação básica
|
||
Refresh token automático antes
|
||
expiração; interceptador fetch
|
||
Anonimização
|
||
exportações
|
||
PENDENTE
|
||
Remover dados sensíveis
|
||
Flag "modo externo" oculta CPF,
|
||
email
|
||
Validações robustas
|
||
(CPF/CRM)
|
||
PARCIAL
|
||
Algumas máscaras
|
||
Zod schemas + feedback inline
|
||
Rate limiting login
|
||
PENDENTE
|
||
Mitigar brute force
|
||
Backend contador tentativas +
|
||
bloqueio temporário
|
||
LGPD gestão
|
||
consentimento
|
||
PENDENTE
|
||
Paciente solicita
|
||
remoção/export
|
||
Página solicita ação; backend fila
|
||
processamento
|
||
Assinatura digital
|
||
consentimento
|
||
PENDENTE
|
||
Registro legal
|
||
Checkbox + timestamp + hash
|
||
assinatura no registro consulta
|
||
Hash integridade
|
||
relatórios
|
||
PENDENTE
|
||
Evita adulteração
|
||
Calcular hash SHA256 conteúdo +
|
||
armazenar junto ao registro
|
||
6. Fluxos Médicos / Consultas
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Check-in paciente
|
||
PENDENTE
|
||
Secretaria marca chegada
|
||
Botão altera status para checked_in;
|
||
notifica médico
|
||
Sala de espera
|
||
virtual
|
||
PENDENTE
|
||
Lista pacientes aguardando
|
||
Painel ordenado por horário; atraso
|
||
calculado em tempo real
|
||
Automação atraso
|
||
médico
|
||
PENDENTE
|
||
Sugere reorganizar agenda
|
||
Se atraso médio > limiar, algoritmo
|
||
propõe empurrar slots
|
||
Tags e tipos consulta
|
||
PARCIAL
|
||
Campo tipo simples
|
||
Lista padronizada (Retorno, Primeira,
|
||
Teleconsulta); filtros
|
||
|
||
---
|
||
## Page 4
|
||
|
||
Reagendamento
|
||
inteligente
|
||
PENDENTE
|
||
Sugere melhor slot
|
||
Busca slot livre mais próximo
|
||
preservando espaçamentos
|
||
Duração adaptativa
|
||
PENDENTE
|
||
Varia tempo conforme tipo
|
||
Campo estimated_duration; impacto na
|
||
geração de slots
|
||
Pré-consulta
|
||
formulário
|
||
PENDENTE
|
||
Dados antes da consulta
|
||
Link enviado; dados salvos e exibidos
|
||
como resumo
|
||
Teleconsulta
|
||
PENDENTE
|
||
Consulta remota
|
||
Botão "Iniciar Teleconsulta" abre sala
|
||
vídeo (WebRTC / serviço externo)
|
||
Encadeamento
|
||
retorno
|
||
PENDENTE
|
||
Cria próxima consulta
|
||
automaticamente
|
||
Regra: tipos específicos geram retorno
|
||
em X dias
|
||
Gestão exceções
|
||
(bloqueios)
|
||
PARCIAL
|
||
Existe ExceptionsManager
|
||
Interface aprimorada para
|
||
férias/manutenção com calendário
|
||
visual
|
||
7. Funcionalidades Paciente
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Portal histórico
|
||
PENDENTE
|
||
Ver consultas, relatórios
|
||
Página protegida com lista e filtros
|
||
Notificações
|
||
multicanal
|
||
PENDENTE
|
||
Email/SMS/push
|
||
lembretes
|
||
Serviço fila agendamento; integra API SMS
|
||
Confirmação 1-
|
||
clique
|
||
PENDENTE
|
||
Reduz no-show
|
||
Link em email muda status para confirmed
|
||
Lista de espera
|
||
PENDENTE
|
||
Preenche
|
||
cancelamentos
|
||
Pacientes optam; ao cancelar consulta
|
||
procura candidato
|
||
Preferências
|
||
paciente
|
||
PENDENTE
|
||
Horários/médicos
|
||
favoritos
|
||
Armazenar em perfil e usar nas sugestões
|
||
de slot
|
||
Avaliação pós-
|
||
consulta
|
||
PENDENTE
|
||
NPS + comentário
|
||
Prompt após status completed; agrega em
|
||
analytics
|
||
8. Funcionalidades Secretaria
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Painel conflitos
|
||
PENDENTE
|
||
Identifica choques de
|
||
agenda
|
||
Varre consultas por sobreposição de
|
||
tempo/sala
|
||
Operações em lote
|
||
PENDENTE
|
||
Alterar/cancelar várias
|
||
Checkboxes + ações em massa com
|
||
confirmação
|
||
Mapa semanal multi-
|
||
médico
|
||
PENDENTE
|
||
Visual global
|
||
Grade com médicos colunas × horas
|
||
linhas
|
||
|
||
---
|
||
## Page 5
|
||
|
||
Filtro avançado
|
||
PARCIAL
|
||
Filtros básicos
|
||
Combinação status, médico, tipo, atraso
|
||
com query builder
|
||
Exportar agenda
|
||
CSV/PDF
|
||
PENDENTE
|
||
Compartilhamento
|
||
externo
|
||
Botão export gera arquivo com seleção
|
||
de colunas
|
||
9. Relatórios & Analytics
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Dashboard KPIs
|
||
PENDENTE
|
||
Métricas principais
|
||
Endpoint /analytics/summary; render cards +
|
||
gráficos
|
||
Curva demanda
|
||
PENDENTE
|
||
Tendência
|
||
solicitações
|
||
Gráfico linha pedidos vs capacidade (últimos
|
||
90 dias)
|
||
Ranking motivos
|
||
PENDENTE
|
||
Motivos mais
|
||
recorrentes
|
||
Agrupamento por tag/motivo; gráfico barras
|
||
No-show evolução
|
||
PENDENTE
|
||
Histórico mensal
|
||
Série temporal + comparação mês anterior
|
||
Análise sazonal
|
||
PENDENTE
|
||
Picos por época
|
||
Agrupar por mês/semana do ano, heatmap
|
||
Builder relatórios
|
||
custom
|
||
PENDENTE
|
||
Personalizar campos
|
||
UI drag & drop colunas; exportar JSON/PDF
|
||
Previsão demanda
|
||
PENDENTE
|
||
Estimativa futura
|
||
simples
|
||
Média móvel + regressão linear leve para
|
||
próximos 14 dias
|
||
Heatmap
|
||
especialidades
|
||
PENDENTE
|
||
Popularidade
|
||
Matriz especialidade × volume consultas
|
||
10. Arquitetura & Código
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Modularizar
|
||
PainelMedico
|
||
PENDENTE
|
||
Separar áreas
|
||
Criar subcomponentes: DashboardSection,
|
||
ConsultasSection, etc.
|
||
Hooks
|
||
especializados
|
||
PENDENTE
|
||
Reuso + cache
|
||
useAppointments, useAvailability com React
|
||
Query
|
||
Tipos centralizados
|
||
+ Zod
|
||
PARCIAL
|
||
Schemas existem
|
||
parcialmente
|
||
Unificar em types/ + validação entrada
|
||
serviços
|
||
Erros padronizados
|
||
PENDENTE
|
||
Classe AppError
|
||
Lançar com código e mapear para
|
||
mensagem amigável
|
||
Logs estruturados
|
||
PARCIAL
|
||
Console logs informais
|
||
Wrapper logEvent(level, context); JSON
|
||
em produção
|
||
Constantes datas
|
||
PARCIAL
|
||
Arrays no componente
|
||
Extrair para lib/date.ts
|
||
|
||
---
|
||
## Page 6
|
||
|
||
Feature flags
|
||
PENDENTE
|
||
Ativar features
|
||
gradualmente
|
||
Objeto config vindo do backend ou .env
|
||
11. Automação & Inteligência
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Sugestão retorno
|
||
PENDENTE
|
||
Agenda retorno
|
||
automático
|
||
Regras por tipo; cria consulta futuro
|
||
pendente confirmação
|
||
Alertas condição
|
||
paciente
|
||
PENDENTE
|
||
Avisa riscos
|
||
Checa dados pré-consulta e mostra banner
|
||
Autocomplete CID
|
||
PENDENTE
|
||
Código diagnóstico
|
||
Campo search com índice local de códigos
|
||
CID
|
||
Alertas laudos
|
||
atrasados
|
||
PENDENTE
|
||
Notifica drafts velhos
|
||
Cron job verifica drafts > X dias
|
||
Triagem inteligente
|
||
PENDENTE
|
||
Priorizar urgência
|
||
Classificação simples por palavras-chave
|
||
(ex: "dor aguda")
|
||
12. Engajamento & Diferenciais
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Gamificação médicos
|
||
PENDENTE
|
||
Badges desempenho
|
||
Regras (pontualidade, zero no-show);
|
||
cálculo semanal
|
||
Selo paciente assíduo
|
||
PENDENTE
|
||
Reconhecimento
|
||
Após N confirmações seguidas sem
|
||
faltas
|
||
Integração calendário
|
||
externo
|
||
PENDENTE
|
||
Sincronizar
|
||
Google/Outlook
|
||
OAuth + push confirmadas para
|
||
calendário do usuário
|
||
Modo treinamento
|
||
PENDENTE
|
||
Sandbox para
|
||
onboarding
|
||
Flag ambiente usa dados fictícios
|
||
segregados
|
||
13. Documentação & Conteúdo
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Central ajuda
|
||
avançada
|
||
PARCIAL
|
||
Páginas
|
||
básicas
|
||
Indexação full-text + categorias + favoritos
|
||
Tour guiado inicial
|
||
PENDENTE
|
||
Onboarding
|
||
Biblioteca (react-joyride) passo a passo pós login
|
||
primeiro
|
||
Glossário paciente
|
||
PENDENTE
|
||
Explica termos
|
||
Página com lista e busca local
|
||
|
||
---
|
||
## Page 7
|
||
|
||
14. Monetização
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Plano lembretes
|
||
avançados
|
||
PENDENTE
|
||
Add-on premium
|
||
Verificação de plano antes de enviar SMS
|
||
Teleconsulta (add-on)
|
||
PENDENTE
|
||
Serviço pago
|
||
Ativado por flag de assinatura; registra
|
||
tempo chamada
|
||
Pagamento antecipado
|
||
PENDENTE
|
||
Cobrar antes
|
||
Integração gateway; status pendente até
|
||
pagamento
|
||
Taxa no-show
|
||
PENDENTE
|
||
Penalização
|
||
opcional
|
||
Ao marcar no_show gera cobrança pré-
|
||
configurada
|
||
15. Privacidade & Transparência
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Histórico de acessos
|
||
PENDENTE
|
||
Quem visualizou
|
||
dados
|
||
Tabela auditoria filtrada por paciente; UI
|
||
dedicada
|
||
Radar de permissões
|
||
admin
|
||
PENDENTE
|
||
Visão roles
|
||
Mapa matrix usuários × permissões
|
||
16. Qualidade Operacional
|
||
Item
|
||
Status
|
||
Descrição
|
||
Como Vai Funcionar
|
||
Monitor SLA
|
||
atendimento
|
||
PENDENTE
|
||
Tempo check-in -> início
|
||
Medir intervalo e exibir média por dia
|
||
Indicador relatórios
|
||
pendentes
|
||
PARCIAL
|
||
Laudos existem
|
||
Card com contagem drafts + link
|
||
direto
|
||
Detector sobrecarga
|
||
agenda
|
||
PENDENTE
|
||
Sinaliza longas
|
||
sequências sem pausa
|
||
Algoritmo varre sequência > N sem
|
||
intervalo >= M minutos
|
||
17. DIVISÃO DE EQUIPES E RESPONSABILIDADES
|
||
Squad Composition (9 membros)
|
||
Equipe 1 - UX/Design System (Trio)
|
||
Alvaro (Lead)
|
||
Gustavo
|
||
Guilherme
|
||
Equipe 2 - Performance & Arquitetura (Dupla)
|
||
João Lopes (Lead)
|
||
|
||
---
|
||
## Page 8
|
||
|
||
Bressan
|
||
Equipe 3 - Features Médicas & Agendamento (Trio)
|
||
Fernando (Lead)
|
||
Peu Gabriel
|
||
Cristiano
|
||
Equipe 4 - Analytics & Relatórios (Dupla Reserve/Support)
|
||
Membros rotativos das outras equipes conforme disponibilidade
|
||
18. DETALHAMENTO POR EQUIPE
|
||
EQUIPE 1: UX/Design System (Alvaro, Gustavo, Guilherme)
|
||
Responsabilidades
|
||
Design tokens e sistema de cores
|
||
Skeleton loaders e estados vazios
|
||
Acessibilidade (atalhos, aria, focus)
|
||
Componentes UI reutilizáveis
|
||
Modo escuro consistente
|
||
Tarefas Prioritárias
|
||
Tarefa 1.1: Design Tokens & Cores Semânticas
|
||
Status: PENDENTE Estimativa: 4h Descrição: Centralizar cores, tipografia e espaçamentos em sistema tokens
|
||
reutilizável.
|
||
Prompt para IA:
|
||
Crie um sistema de design tokens para o MediConnect seguindo essas especificações:
|
||
1. Arquivo: src/styles/design-tokens.ts
|
||
2. Estrutura:
|
||
- Cores semânticas para status de consulta (requested, confirmed, completed, cancelled,
|
||
no_show, checked_in, in_progress)
|
||
- Escala de tipografia modular (12, 14, 16, 20, 24, 32, 48)
|
||
- Escala de espaçamento (xs: 4px, sm: 8px, md: 16px, lg: 24px, xl: 32px, 2xl: 48px)
|
||
- Cores de tema (primary, secondary, success, warning, error, info)
|
||
- Breakpoints responsivos
|
||
3. Exportar como constantes TypeScript tipadas
|
||
4. Criar utility classes Tailwind customizadas em tailwind.config.js
|
||
5. Documentar uso em comentários JSDoc
|
||
Contexto: Sistema de agendamento médico com múltiplos perfis (médico, paciente, secretaria).
|
||
Stack: React + TypeScript + Tailwind CSS
|
||
Tarefa 1.2: Skeleton Loaders
|
||
Status: PENDENTE Estimativa: 6h Descrição: Componentes de placeholder animados para melhorar percepção de
|
||
carregamento.
|
||
Prompt para IA:
|
||
|
||
---
|
||
## Page 9
|
||
|
||
Implemente sistema de skeleton loaders para o MediConnect:
|
||
1. Componente Base: src/components/ui/Skeleton.tsx
|
||
- Variantes: text, avatar, card, table, calendar
|
||
- Props: width, height, rounded, animated (pulse ou shimmer)
|
||
- Usar Tailwind para animação
|
||
2. Componentes Específicos:
|
||
- SkeletonAppointmentCard: Para lista de consultas
|
||
- SkeletonCalendar: Grade de calendário do médico
|
||
- SkeletonPatientList: Lista de pacientes (secretaria)
|
||
- SkeletonReportCard: Cards de relatórios
|
||
3. Integração:
|
||
- Substituir "Carregando..." em DoctorCalendar, PainelMedico, SecretaryAppointmentList
|
||
- Mostrar skeleton enquanto loading=true
|
||
4. Acessibilidade:
|
||
- aria-busy="true" e aria-label="Carregando conteúdo"
|
||
- role="status"
|
||
Contexto: Listas e calendários carregam dados de Supabase; loading pode demorar 1-3s.
|
||
Stack: React + TypeScript + Tailwind
|
||
Tarefa 1.3: Empty States com CTA
|
||
Status: PARCIAL Estimativa: 4h Descrição: Estados vazios consistentes com ícone, mensagem e ação principal.
|
||
Prompt para IA:
|
||
Crie componente EmptyState padronizado e aplique nas principais páginas:
|
||
1. Componente: src/components/ui/EmptyState.tsx
|
||
Props:
|
||
- icon: LucideIcon
|
||
- title: string
|
||
- description: string
|
||
- actionLabel?: string
|
||
- onAction?: () => void
|
||
- variant: 'default' | 'info' | 'warning'
|
||
2. Casos de uso:
|
||
- Calendário sem consultas do dia
|
||
- Paciente sem histórico
|
||
- Nenhum relatório cadastrado
|
||
- Disponibilidade não configurada
|
||
- Sala de espera vazia
|
||
3. Aplicar em:
|
||
- DoctorCalendar (quando appointments.length === 0)
|
||
- PainelMedico seção relatórios
|
||
- SecretaryPatientList (filtros sem resultado)
|
||
- AvailableSlotsPicker (sem horários disponíveis)
|
||
|
||
---
|
||
## Page 10
|
||
|
||
4. Design:
|
||
- Ícone centralizado (lucide-react)
|
||
- Título em text-lg font-semibold
|
||
- Descrição em text-sm text-gray-600
|
||
- Botão CTA primary
|
||
Stack: React + TypeScript + Tailwind + Lucide icons
|
||
Tarefa 1.4: Atalhos de Teclado & Command Palette
|
||
Status: PENDENTE Estimativa: 8h Descrição: Navegação rápida via Ctrl+K e atalhos contextuais.
|
||
Prompt para IA:
|
||
Implemente Command Palette (estilo VSCode/Linear) para o MediConnect:
|
||
1. Hook: src/hooks/useCommandPalette.ts
|
||
- Detectar Ctrl+K / Cmd+K
|
||
- Gerenciar estado aberto/fechado
|
||
- Prevenir comportamento padrão do navegador
|
||
2. Componente: src/components/CommandPalette.tsx
|
||
- Modal com busca fuzzy
|
||
- Categorias: Pacientes, Consultas, Médicos, Relatórios, Navegação
|
||
- Navegar com setas ↑↓, Enter para confirmar, Esc para fechar
|
||
- Mostrar atalho de teclado ao lado de cada ação
|
||
3. Ações Disponíveis:
|
||
- "Nova Consulta" (N) - abre modal agendamento
|
||
- "Buscar Paciente" - autocomplete
|
||
- "Ir para Agenda" (G → A)
|
||
- "Ir para Perfil" (G → P)
|
||
- "Logout" (Shift+L)
|
||
4. Integração:
|
||
- Provider em App.tsx
|
||
- Listener global de teclado
|
||
- Busca indexada em pacientes e consultas (fuse.js ou similar)
|
||
5. Acessibilidade:
|
||
- role="dialog" aria-modal="true"
|
||
- Trap focus dentro do modal
|
||
- Anunciar resultados para screen readers
|
||
Stack: React + TypeScript + Tailwind + Fuse.js (busca fuzzy)
|
||
Referência: cmdk library ou implementação custom
|
||
Tarefa 1.5: Modo Escuro Consistente
|
||
Status: PARCIAL Estimativa: 6h Descrição: Auditoria e refinamento de contraste AA/AAA em todos os componentes.
|
||
Prompt para IA:
|
||
|
||
---
|
||
## Page 11
|
||
|
||
Audite e melhore o modo escuro do MediConnect:
|
||
1. Auditoria de Contraste:
|
||
- Usar ferramenta (ex: axe DevTools) para verificar AA/AAA
|
||
- Listar componentes com problemas de contraste
|
||
- Focar em: botões, badges de status, textos secundários, borders
|
||
2. Ajustes:
|
||
- Atualizar tokens de cores no design-tokens.ts
|
||
- Garantir contraste mínimo 4.5:1 para texto normal
|
||
- Garantir contraste mínimo 3:1 para texto grande e ícones
|
||
- Usar dark:bg-gray-800 dark:text-gray-100 consistentemente
|
||
3. Estados de Foco:
|
||
- Outline visível em dark mode (ex: ring-2 ring-offset-2 ring-blue-500)
|
||
- Aplicar em todos inputs, buttons, links
|
||
4. Componentes Prioritários:
|
||
- Header (todos os painéis)
|
||
- Formulários (AgendamentoConsulta, modais)
|
||
- Calendário (DoctorCalendar)
|
||
- Tabelas (listas de pacientes/consultas)
|
||
- Cards de métricas (quando implementar)
|
||
5. Testes:
|
||
- Verificar em Chrome DevTools (Rendering > Emulate CSS media)
|
||
- Testar com leitor de telas (NVDA/JAWS)
|
||
Contexto: Projeto já usa Tailwind dark: variant, mas falta consistência.
|
||
Stack: React + TypeScript + Tailwind CSS
|
||
EQUIPE 2: Performance & Arquitetura (João Lopes, Bressan)
|
||
Responsabilidades
|
||
Code-splitting e lazy loading
|
||
Cache com React Query
|
||
Otimização de bundles
|
||
Refatoração arquitetural
|
||
PWA e Service Workers
|
||
Tarefas Prioritárias
|
||
Tarefa 2.1: Introduzir React Query (TanStack Query)
|
||
Status: PENDENTE Estimativa: 12h Descrição: Substituir chamadas diretas de service por hooks com cache
|
||
inteligente.
|
||
Prompt para IA:
|
||
Migre o sistema de fetching de dados para React Query no MediConnect:
|
||
1. Setup:
|
||
- Instalar @tanstack/react-query
|
||
|
||
---
|
||
## Page 12
|
||
|
||
- Criar QueryClientProvider em src/main.tsx
|
||
- Configurar devtools (ReactQueryDevtools)
|
||
- staleTime: 5 minutos, cacheTime: 10 minutos
|
||
2. Hooks Personalizados (src/hooks/):
|
||
**useAppointments.ts**
|
||
```typescript
|
||
- useAppointments(filters?: { doctor_id?, patient_id?, status? })
|
||
- useAppointment(id: string)
|
||
- useCreateAppointment()
|
||
- useUpdateAppointment()
|
||
- useCancelAppointment()
|
||
Invalidar queries relacionadas após mutations
|
||
Optimistic updates para melhor UX
|
||
usePatients.ts
|
||
- usePatients()
|
||
- usePatient(id: string)
|
||
- usePatientNames() // retorna Map<id, nome> para lookups rápidos
|
||
useAvailability.ts
|
||
- useAvailability(doctorId: string)
|
||
- useCreateAvailability()
|
||
- useUpdateAvailability()
|
||
useReports.ts
|
||
- useReports(filters)
|
||
- useReport(id)
|
||
- useCreateReport()
|
||
3. Migrar Componentes:
|
||
DoctorCalendar: usar useAppointments + usePatientNames
|
||
PainelMedico: substituir loadConsultas por useAppointments
|
||
SecretaryAppointmentList: idem
|
||
AvailableSlotsPicker: usar useAvailability + useAppointments
|
||
4. Prefetching:
|
||
Ao navegar calendário, prefetch próxima semana
|
||
Ao abrir lista, prefetch primeiros 20 registros
|
||
5. Error Handling:
|
||
Retry automático (3x com backoff exponencial)
|
||
Fallback UI para erros
|
||
Toast de erro integrado
|
||
|
||
---
|
||
## Page 13
|
||
|
||
Contexto: Atualmente cada componente chama appointmentService.list() sem cache. Stack: React 18 + TypeScript +
|
||
Supabase Referência: https://tanstack.com/query/latest/docs/react/overview
|
||
##### Tarefa 2.2: Code-Splitting PainelMedico
|
||
**Status:** PENDENTE
|
||
**Estimativa:** 8h
|
||
**Descrição:** Dividir arquivo gigante (2297 linhas) em módulos lazy-loaded.
|
||
**Prompt para IA:**
|
||
Refatore PainelMedico usando code-splitting e rotas internas:
|
||
1. Estrutura Nova: src/pages/painel-medico/ ├── index.tsx (Shell com tabs e Suspense) ├──
|
||
DashboardTab.tsx ├── ConsultasTab.tsx ├── DisponibilidadeTab.tsx ├── RelatoriosTab.tsx ├──
|
||
MensagensTab.tsx ├── PerfilTab.tsx └── components/ ├── ConsultasList.tsx ├── MetricsCards.tsx └──
|
||
ProfileForm.tsx
|
||
2. Rotas Internas:
|
||
/painel-medico/dashboard
|
||
/painel-medico/consultas
|
||
/painel-medico/disponibilidade
|
||
/painel-medico/relatorios
|
||
/painel-medico/mensagens
|
||
/painel-medico/perfil
|
||
3. Lazy Loading:
|
||
const DashboardTab = lazy(() => import('./DashboardTab'));
|
||
const ConsultasTab = lazy(() => import('./ConsultasTab'));
|
||
// etc.
|
||
4. Shell Component:
|
||
Header fixo com nome médico e logout
|
||
Tabs navigation
|
||
<Suspense fallback={}>
|
||
Outlet para nested routes
|
||
5. State Management:
|
||
Contexto PainelMedicoContext para compartilhar doctorId, user
|
||
React Query para dados assíncronos
|
||
Remover estados duplicados
|
||
6. Migração:
|
||
Preservar funcionalidades existentes
|
||
Manter compatibilidade com AuthContext
|
||
Atualizar imports em App.tsx
|
||
Contexto: Arquivo atual PainelMedico.tsx tem 2297 linhas e carrega tudo de uma vez. Stack: React Router v6 + React
|
||
18 Suspense + TypeScript
|
||
|
||
---
|
||
## Page 14
|
||
|
||
##### Tarefa 2.3: PWA Básico com Offline
|
||
**Status:** PENDENTE
|
||
**Estimativa:** 10h
|
||
**Descrição:** Service Worker para cache de assets e agenda do dia offline.
|
||
**Prompt para IA:**
|
||
Transforme MediConnect em PWA com suporte offline básico:
|
||
1. Manifest (public/manifest.json):
|
||
name: "MediConnect - Agendamento Médico"
|
||
short_name: "MediConnect"
|
||
icons: 192x192, 512x512
|
||
start_url: "/"
|
||
display: "standalone"
|
||
theme_color: cores do design system
|
||
background_color: branco/escuro conforme tema
|
||
2. Service Worker (public/sw.js):
|
||
Cache Strategy:
|
||
Assets estáticos (CSS, JS, fonts): Cache First
|
||
API calls: Network First com fallback para cache
|
||
Imagens: Cache First com expiração 7 dias
|
||
Offline Data:
|
||
Armazenar agenda do dia atual em IndexedDB
|
||
Sincronizar quando voltar online
|
||
Mostrar banner "Você está offline" quando sem rede
|
||
3. Workbox Setup:
|
||
Instalar vite-plugin-pwa
|
||
Configurar em vite.config.ts
|
||
Gerar service worker automaticamente
|
||
Precache assets críticos
|
||
4. IndexedDB para Dados Offline:
|
||
Biblioteca: idb (wrapper promises para IndexedDB)
|
||
Stores: appointments, patients, availability
|
||
Sync queue para mutations offline
|
||
5. UI Feedback:
|
||
Indicador de status de rede (online/offline) no header
|
||
Toast "Conteúdo salvo para acesso offline"
|
||
Badge "Offline" em dados em cache
|
||
6. Update Prompt:
|
||
Detectar nova versão do SW
|
||
Mostrar toast "Nova versão disponível - Clique para atualizar"
|
||
|
||
---
|
||
## Page 15
|
||
|
||
skipWaiting() e clients.claim()
|
||
Contexto: Médicos podem precisar ver agenda em locais com sinal fraco. Stack: Vite + vite-plugin-pwa + Workbox +
|
||
idb Referência: https://vite-pwa-org.netlify.app/
|
||
##### Tarefa 2.4: Otimização de Bundle
|
||
**Status:** PENDENTE
|
||
**Estimativa:** 6h
|
||
**Descrição:** Análise e redução do tamanho final do bundle.
|
||
**Prompt para IA:**
|
||
Otimize o bundle size do MediConnect:
|
||
1. Análise:
|
||
Instalar rollup-plugin-visualizer
|
||
Gerar relatório de bundle (npm run build -- --mode analyze)
|
||
Identificar maiores dependências
|
||
2. Tree-shaking:
|
||
Verificar imports nomeados vs default
|
||
Substituir import * as por imports específicos
|
||
Exemplo: import { format } from 'date-fns' ao invés de importar tudo
|
||
3. Dynamic Imports:
|
||
Biblioteca pesada de gráficos (se adicionar): lazy load
|
||
Modal components: carregar on-demand
|
||
Componentes de relatórios PDF: lazy load
|
||
4. Substituições:
|
||
Avaliar substituir date-fns por date-fns-tz apenas onde necessário
|
||
Usar versão light de bibliotecas quando disponível
|
||
Avaliar alternativas menores (ex: dayjs se date-fns muito grande)
|
||
5. Configuração Vite:
|
||
build: {
|
||
rollupOptions: {
|
||
output: {
|
||
manualChunks: {
|
||
'vendor-react': ['react', 'react-dom'],
|
||
'vendor-ui': ['lucide-react', 'react-hot-toast'],
|
||
'vendor-data': ['@supabase/supabase-js', '@tanstack/react-query']
|
||
}
|
||
}
|
||
},
|
||
chunkSizeWarningLimit: 600
|
||
}
|
||
6. Compressão:
|
||
|
||
---
|
||
## Page 16
|
||
|
||
Habilitar gzip/brotli no Netlify
|
||
Verificar headers de cache
|
||
Meta: Bundle inicial < 200KB gzipped Stack: Vite + Rollup
|
||
---
|
||
### EQUIPE 3: Features Médicas & Agendamento (Fernando, Peu Gabriel, Cristiano)
|
||
#### Responsabilidades
|
||
- Check-in e sala de espera
|
||
- Lista de espera inteligente
|
||
- Reagendamento
|
||
- Notificações e confirmações
|
||
- Melhorias no fluxo de consulta
|
||
#### Tarefas Prioritárias
|
||
##### Tarefa 3.1: Check-in e Sala de Espera Virtual
|
||
**Status:** PENDENTE
|
||
**Estimativa:** 12h
|
||
**Descrição:** Secretaria marca chegada; médico vê fila em tempo real.
|
||
**Prompt para IA:**
|
||
Implemente sistema de Check-in e Sala de Espera para o MediConnect:
|
||
1. Backend (Supabase):
|
||
Adicionar campo checked_in_at (timestamp nullable) na tabela appointments
|
||
Criar função RPC check_in_patient(appointment_id) que:
|
||
Atualiza status para 'checked_in'
|
||
Registra checked_in_at com NOW()
|
||
Retorna sucesso
|
||
2. Service Layer (src/services/appointments/):
|
||
async checkIn(appointmentId: string): Promise<void>
|
||
async getWaitingRoom(doctorId: string): Promise<WaitingRoomItem[]>
|
||
Interface WaitingRoomItem:
|
||
appointmentId, patientName, scheduledTime
|
||
checkedInAt, waitingMinutes (calculado)
|
||
status, type
|
||
3. Componente Secretaria (src/components/secretaria/CheckInButton.tsx):
|
||
Botão "Check-in" aparece em consultas com status 'confirmed' do dia atual
|
||
Ao clicar: chamar checkIn() e atualizar lista
|
||
Toast de sucesso
|
||
Invalidar query do React Query
|
||
4. Painel Sala de Espera (src/components/consultas/WaitingRoom.tsx):
|
||
|
||
---
|
||
## Page 17
|
||
|
||
Lista ordenada por horário agendado
|
||
Card por paciente:
|
||
Nome, horário agendado
|
||
Badge com tempo de espera (ex: "Aguardando há 15 min")
|
||
Indicador de atraso se ultrapassar horário + 10 min
|
||
Auto-refresh a cada 30s (via React Query refetchInterval)
|
||
Botão "Iniciar Atendimento" muda status para 'in_progress'
|
||
5. Integração PainelMedico:
|
||
Nova tab "Sala de Espera" ou sidebar widget
|
||
Contador badge com número de pacientes aguardando
|
||
Som/notificação quando paciente faz check-in (opcional)
|
||
6. Real-time (Opcional para v2):
|
||
Supabase Realtime subscription na tabela appointments
|
||
Atualizar lista automaticamente sem polling
|
||
Contexto: Evita que paciente espere sem médico saber que chegou. Stack: React + TypeScript + Supabase + React
|
||
Query
|
||
##### Tarefa 3.2: Lista de Espera Inteligente
|
||
**Status:** PENDENTE
|
||
**Estimativa:** 16h
|
||
**Descrição:** Pacientes optam por preencher cancelamentos; algoritmo preenche
|
||
automaticamente.
|
||
**Prompt para IA:**
|
||
Implemente sistema de Lista de Espera com preenchimento automático:
|
||
1. Backend (Supabase): Nova tabela waitlist :
|
||
id (uuid PK)
|
||
patient_id (uuid FK)
|
||
doctor_id (uuid FK nullable - pode querer qualquer médico)
|
||
preferred_dates (jsonb) - array de datas preferidas
|
||
preferred_times (jsonb) - "morning" | "afternoon" | "evening"
|
||
max_wait_days (int) - quantos dias no futuro aceita
|
||
created_at, expires_at
|
||
status: 'active' | 'fulfilled' | 'expired'
|
||
Função RPC fill_cancelled_slot(appointment_id) :
|
||
Busca waitlist candidates compatíveis
|
||
Ordena por: data de inscrição (FIFO)
|
||
Cria nova consulta com status 'pending_confirmation'
|
||
Envia notificação ao paciente
|
||
Marca waitlist como 'fulfilled'
|
||
2. Service Layer (src/services/waitlist/):
|
||
|
||
---
|
||
## Page 18
|
||
|
||
async addToWaitlist(data: WaitlistInput): Promise<void>
|
||
async getWaitlistCandidates(appointmentId: string): Promise<Candidate[]>
|
||
async assignSlot(waitlistId: string, appointmentId: string): Promise<void>
|
||
async removeFromWaitlist(waitlistId: string): Promise<void>
|
||
3. UI Paciente (src/components/waitlist/JoinWaitlistModal.tsx):
|
||
Formulário:
|
||
Selecionar médico (ou "Qualquer médico")
|
||
Datas preferidas (multi-select calendar)
|
||
Horário preferencial (manhã/tarde/noite)
|
||
Prazo máximo (ex: "até 7 dias")
|
||
Mostrar estimativa de probabilidade (baseado em histórico de cancelamentos)
|
||
Confirmar e adicionar à fila
|
||
4. UI Secretaria (src/components/secretaria/WaitlistManager.tsx):
|
||
Ao cancelar consulta: mostrar modal
|
||
"Há N pacientes na lista de espera para este horário"
|
||
Lista com compatibilidade (score visual)
|
||
Botão "Atribuir Horário" ao lado de cada candidato
|
||
Modo manual: secretaria escolhe quem
|
||
Modo automático: sistema escolhe o primeiro compatível
|
||
5. Algoritmo de Matching:
|
||
Critérios de compatibilidade:
|
||
Doctor match (se especificado)
|
||
Data está em preferred_dates
|
||
Horário está em preferred_times
|
||
Não ultrapassou max_wait_days
|
||
Score: 100 (match perfeito) a 0
|
||
6. Notificações:
|
||
Email/SMS: "Uma vaga abriu! Confirme em 2 horas ou será oferecida ao próximo"
|
||
Timeout: se não confirmar, oferecer ao próximo da fila
|
||
Contexto: Reduzir slots vazios e dar oportunidade para pacientes urgentes. Stack: React + TypeScript + Supabase +
|
||
React Query
|
||
##### Tarefa 3.3: Reagendamento Inteligente
|
||
**Status:** PENDENTE
|
||
**Estimativa:** 10h
|
||
**Descrição:** Sugerir melhor slot ao reagendar, evitando conflitos.
|
||
**Prompt para IA:**
|
||
Implemente sistema de Reagendamento Inteligente:
|
||
1. Service (src/services/appointments/reschedule.ts):
|
||
|
||
---
|
||
## Page 19
|
||
|
||
async getSuggestedSlots(input: {
|
||
appointmentId: string,
|
||
doctorId: string,
|
||
preferredDates?: string[], // YYYY-MM-DD
|
||
preferredTimes?: ('morning' | 'afternoon')[],
|
||
minDaysFromNow?: number
|
||
}): Promise<SuggestedSlot[]>
|
||
Interface SuggestedSlot:
|
||
date: string
|
||
time: string
|
||
score: number (0-100)
|
||
reasons: string[] (ex: ["Sem conflitos", "Horário preferencial"])
|
||
conflicts?: Conflict[]
|
||
2. Algoritmo de Sugestão:
|
||
Buscar disponibilidade do médico (próximos 30 dias)
|
||
Gerar todos os slots disponíveis
|
||
Filtrar:
|
||
Já ocupados
|
||
Fora de preferred_dates/times (se especificado)
|
||
Muito próximos (< minDaysFromNow)
|
||
Calcular score:
|
||
+30: está em preferred_dates
|
||
+20: está em preferred_times
|
||
+15: não tem consultas adjacentes (médico tem respiro)
|
||
+10: mesmo dia da semana que original
|
||
+5: mesma hora que original
|
||
Ordenar por score DESC
|
||
Retornar top 10
|
||
3. Componente Modal (src/components/consultas/RescheduleModal.tsx):
|
||
Props: appointment (dados atuais)
|
||
Mostrar:
|
||
Data/hora atual
|
||
Campo busca de nova data (calendar picker)
|
||
Lista de slots sugeridos (cards)
|
||
Badge com score visual (cores: verde alto, amarelo médio)
|
||
Botão "Selecionar"
|
||
Ao confirmar:
|
||
Atualizar appointment.scheduled_at
|
||
Notificar paciente da mudança
|
||
Toast de sucesso
|
||
4. Validações:
|
||
Não permitir reagendar para horário passado
|
||
Verificar conflitos em tempo real antes de salvar
|
||
|
||
---
|
||
## Page 20
|
||
|
||
Confirmar via dialog se slot tem score < 50
|
||
5. Integrações:
|
||
Botão "Reagendar" em:
|
||
Lista de consultas (PainelMedico)
|
||
Detalhes da consulta (modal)
|
||
Painel secretaria
|
||
Log de auditoria: registrar quem reagendou e quando
|
||
Contexto: Facilitar reorganização de agenda sem conflitos. Stack: React + TypeScript + Supabase + date-fns
|
||
##### Tarefa 3.4: Confirmação de Consulta 1-Clique
|
||
**Status:** PENDENTE
|
||
**Estimativa:** 8h
|
||
**Descrição:** Link em email/SMS para paciente confirmar presença.
|
||
**Prompt para IA:**
|
||
Implemente sistema de Confirmação 1-Clique via email/SMS:
|
||
1. Backend (Supabase Functions ou Netlify): Endpoint: POST /api/appointments/:id/confirm
|
||
Validar token de confirmação (JWT ou hash)
|
||
Atualizar status para 'confirmed'
|
||
Registrar confirmed_at timestamp
|
||
Retornar página de sucesso
|
||
2. Geração de Token: Service (src/services/appointments/confirmation.ts):
|
||
async generateConfirmationToken(appointmentId: string): Promise<string>
|
||
async sendConfirmationRequest(appointmentId: string): Promise<void>
|
||
Token: JWT com payload { appointmentId, exp: 7 dias }
|
||
OU hash seguro: SHA256(appointmentId + secret + expiry)
|
||
3. Template de Email/SMS: Email:
|
||
Olá {paciente},
|
||
Sua consulta com Dr(a). {medico} está agendada para:
|
||
📅 {data} às {hora}
|
||
📍 {local}
|
||
Por favor confirme sua presença clicando no link abaixo:
|
||
[CONFIRMAR PRESENÇA] (botão verde grande)
|
||
Link: https://mediconnectbrasil.app/confirmar/{token}
|
||
Caso não possa comparecer, por favor reagende ou cancele com antecedência.
|
||
SMS:
|
||
|
||
---
|
||
## Page 21
|
||
|
||
MediConnect: Consulta {data} {hora} com Dr. {medico}. Confirme: {link_curto}
|
||
4. Landing Page (src/pages/ConfirmarConsulta.tsx):
|
||
Route: /confirmar/:token
|
||
Ao carregar:
|
||
Validar token
|
||
Buscar dados da consulta
|
||
Mostrar resumo (médico, data, hora)
|
||
Botão "Confirmar Presença"
|
||
Após confirmar:
|
||
Animação de sucesso ✅
|
||
Opção de adicionar ao calendário (Google/Apple)
|
||
Botão "Ver Meus Agendamentos"
|
||
5. Automação de Envio:
|
||
Cron job ou agendamento:
|
||
7 dias antes: lembrete inicial
|
||
24 horas antes: lembrete urgente + link confirmação
|
||
Integração com serviço SMS (Twilio, Zenvia, etc.)
|
||
Fallback: se SMS falhar, enviar apenas email
|
||
6. Métricas:
|
||
Rastrear taxa de confirmação
|
||
Dashboard admin: % confirmados vs não confirmados
|
||
Enviar lembrete adicional se não confirmar em 48h
|
||
Contexto: Reduzir no-show de ~30% para <10%. Stack: React + TypeScript + Supabase Functions + Twilio/Zenvia
|
||
---
|
||
### EQUIPE 4 (ROTATIVA): Analytics & Relatórios
|
||
#### Responsabilidades
|
||
- Dashboard de métricas
|
||
- Gráficos de ocupação
|
||
- Relatórios customizáveis
|
||
- Exportações CSV/PDF
|
||
#### Tarefas Prioritárias
|
||
##### Tarefa 4.1: Dashboard KPIs
|
||
**Status:** PENDENTE
|
||
**Estimativa:** 12h
|
||
**Descrição:** Cards de métricas principais com gráficos simples.
|
||
**Prompt para IA:**
|
||
Crie Dashboard de KPIs para o PainelMedico:
|
||
1. Endpoint Analytics (Backend): Supabase Function ou View: get_doctor_metrics Retorna:
|
||
|
||
---
|
||
## Page 22
|
||
|
||
{
|
||
today: {
|
||
total_appointments: number,
|
||
confirmed: number,
|
||
completed: number,
|
||
no_show: number,
|
||
waiting: number
|
||
},
|
||
week: {
|
||
total: number,
|
||
occupancy_rate: number, // % slots preenchidos
|
||
avg_duration_minutes: number,
|
||
no_show_rate: number
|
||
},
|
||
month: {
|
||
total: number,
|
||
trend: 'up' | 'down' | 'stable', // vs mês anterior
|
||
trend_percentage: number
|
||
},
|
||
top_reasons: Array<{ reason: string, count: number }>
|
||
}
|
||
2. Service (src/services/analytics/):
|
||
async getDoctorMetrics(doctorId: string): Promise<DoctorMetrics>
|
||
3. Componentes UI (src/components/dashboard/):
|
||
MetricCard.tsx:
|
||
Props: title, value, change (±%), icon, trend ('up'|'down'|'neutral')
|
||
Design: Card branco, ícone colorido, valor grande, delta pequeno
|
||
Exemplo: "Consultas Hoje: 12 | +3 vs ontem"
|
||
OccupancyChart.tsx:
|
||
Gráfico de barras simples (últimos 7 dias)
|
||
Eixo Y: % ocupação (0-100%)
|
||
Eixo X: dias da semana
|
||
Usar biblioteca leve: recharts ou chart.js
|
||
NoShowTrend.tsx:
|
||
Linha temporal de no-show % (últimos 3 meses)
|
||
Destacar pico e vale
|
||
4. Layout DashboardTab.tsx:
|
||
+----------------+----------------+----------------+
|
||
| Consultas Hoje | Taxa Ocupação | No-Show Taxa |
|
||
| 12 | 78% | 8% |
|
||
+----------------+----------------+----------------+
|
||
| Tempo Médio | Retornos | Novos |
|
||
|
||
---
|
||
## Page 23
|
||
|
||
| 45 min | 8 | 4 |
|
||
+----------------+----------------+----------------+
|
||
| Gráfico Ocupação Semanal |
|
||
+--------------------------------------------------+
|
||
| Top 5 Motivos de Consulta |
|
||
+--------------------------------------------------+
|
||
5. Atualização:
|
||
Refetch automático a cada 5 minutos (React Query)
|
||
Botão manual "Atualizar"
|
||
Skeleton durante loading
|
||
6. Responsivo:
|
||
Mobile: cards empilhados verticalmente
|
||
Desktop: grid 3 colunas
|
||
Stack: React + TypeScript + React Query + Recharts Referência design: Linear, Notion Analytics
|
||
##### Tarefa 4.2: Heatmap de Ocupação
|
||
**Status:** PENDENTE
|
||
**Estimativa:** 10h
|
||
**Descrição:** Matriz visual de densidade de consultas (dias × horas).
|
||
**Prompt para IA:**
|
||
Implemente Heatmap de Ocupação para visualizar padrões de agenda:
|
||
1. Cálculo de Densidade: Service (src/services/analytics/heatmap.ts):
|
||
async getOccupancyHeatmap(doctorId: string, startDate: string, endDate: string):
|
||
Promise<HeatmapData>
|
||
HeatmapData:
|
||
{
|
||
days: string[], // ['2025-11-21', '2025-11-22', ...]
|
||
hours: number[], // [8, 9, 10, ..., 18]
|
||
matrix: number[][] // [dia][hora] = densidade 0-100
|
||
}
|
||
Algoritmo:
|
||
Para cada dia no range:
|
||
Para cada hora (8h-18h):
|
||
Contar slots totais (baseado availability)
|
||
Contar slots ocupados (appointments)
|
||
Densidade = (ocupados / totais) * 100
|
||
2. Componente (src/components/analytics/OccupancyHeatmap.tsx):
|
||
|
||
---
|
||
## Page 24
|
||
|
||
Renderização:
|
||
Grid CSS ou SVG
|
||
Linhas = dias (últimos 30 dias ou semana selecionada)
|
||
Colunas = horas (8h-18h)
|
||
Células coloridas por densidade:
|
||
0-25%: verde claro
|
||
26-50%: amarelo
|
||
51-75%: laranja
|
||
76-100%: vermelho
|
||
Interatividade:
|
||
Hover: tooltip mostra "70% ocupação | 7/10 slots"
|
||
Click: filtrar consultas daquele dia/hora
|
||
3. Filtros:
|
||
Período: última semana, último mês, customizado
|
||
Tipo de consulta: todas, presencial, teleconsulta
|
||
Status: incluir/excluir canceladas
|
||
4. Insights Automáticos:
|
||
Badge: "Pico às quartas-feiras 14h-16h"
|
||
Sugestão: "Considere adicionar horários às segundas de manhã (baixa ocupação)"
|
||
5. Exportar:
|
||
Botão "Exportar PNG" (html2canvas)
|
||
CSV dos dados brutos
|
||
Stack: React + TypeScript + D3.js (ou CSS Grid simples) + Tailwind
|
||
---
|
||
## 19. Quick Wins Priorizados (Primeira Sprint)
|
||
1. **Skeleton loaders** (Equipe 1 - 6h)
|
||
2. **Design Tokens** (Equipe 1 - 4h)
|
||
3. **Empty states com CTA** (Equipe 1 - 4h)
|
||
4. **React Query setup** (Equipe 2 - 8h - fundação para demais)
|
||
5. **Check-in básico** (Equipe 3 - 6h - versão simples sem real-time)
|
||
**Total Sprint 1:** ~28h de trabalho distribuído
|
||
---
|
||
## 20. Roadmap por Fase Detalhado
|
||
### Fase 1: Quick Wins (Sprint 1 - 1 semana)
|
||
**Objetivo:** Melhorias visuais e fundação técnica
|
||
| Tarefa | Equipe | Esforço | Impacto |
|
||
|--------|--------|---------|---------|
|
||
| Design Tokens | Equipe 1 | 4h | Alto - base para todo sistema |
|
||
| Skeleton Loaders | Equipe 1 | 6h | Alto - UX imediata |
|
||
|
||
---
|
||
## Page 25
|
||
|
||
| Empty States | Equipe 1 | 4h | Médio - polish |
|
||
| React Query Setup | Equipe 2 | 8h | Crítico - fundação |
|
||
| Check-in Básico | Equipe 3 | 6h | Alto - operação diária |
|
||
**Entregas:**
|
||
- Sistema de design consistente
|
||
- Loading states profissionais
|
||
- Cache inteligente funcionando
|
||
- Secretaria pode fazer check-in
|
||
---
|
||
### Fase 2: Features Core (Sprints 2-3 - 2 semanas)
|
||
**Objetivo:** Funcionalidades que reduzem no-show e melhoram operação
|
||
| Tarefa | Equipe | Esforço | Impacto |
|
||
|--------|--------|---------|---------|
|
||
| Sala de Espera Virtual | Equipe 3 | 12h | Alto |
|
||
| Lista de Espera | Equipe 3 | 16h | Muito Alto |
|
||
| Confirmação 1-Clique | Equipe 3 | 8h | Muito Alto |
|
||
| Command Palette | Equipe 1 | 8h | Médio |
|
||
| Code-Splitting PainelMedico | Equipe 2 | 8h | Médio |
|
||
| Dashboard KPIs | Equipe 4 | 12h | Alto |
|
||
**Entregas:**
|
||
- Fluxo check-in completo
|
||
- Sistema de lista de espera funcional
|
||
- Confirmações automáticas reduzindo no-show
|
||
- Navegação rápida por teclado
|
||
- Performance melhorada
|
||
---
|
||
### Fase 3: Analytics & Otimização (Sprint 4 - 1 semana)
|
||
**Objetivo:** Inteligência de dados e otimização
|
||
| Tarefa | Equipe | Esforço | Impacto |
|
||
|--------|--------|---------|---------|
|
||
| Heatmap Ocupação | Equipe 4 | 10h | Médio |
|
||
| Reagendamento Inteligente | Equipe 3 | 10h | Alto |
|
||
| PWA Básico | Equipe 2 | 10h | Médio |
|
||
| Modo Escuro Auditoria | Equipe 1 | 6h | Médio |
|
||
**Entregas:**
|
||
- Visualizações analíticas
|
||
- Sugestões inteligentes de horários
|
||
- App instalável e offline
|
||
- Acessibilidade AAA
|
||
---
|
||
### Fase 4: Diferenciais (Futuro/Opcional)
|
||
- Teleconsulta integrada
|
||
- Previsão de demanda com ML
|
||
- Auditoria completa LGPD
|
||
|
||
---
|
||
## Page 26
|
||
|
||
- Integração calendários externos
|
||
- Sistema de pagamentos
|
||
---
|
||
## 21. Prompts Adicionais por Categoria
|
||
### PROMPTS DE INTEGRAÇÃO
|
||
#### Integração Twilio para SMS
|
||
Configure integração Twilio para envio de SMS no MediConnect:
|
||
1. Setup:
|
||
Criar conta Twilio (trial ou production)
|
||
Obter Account SID e Auth Token
|
||
Adicionar variáveis ambiente (.env): TWILIO_ACCOUNT_SID=xxx TWILIO_AUTH_TOKEN=xxx
|
||
TWILIO_PHONE_NUMBER=+5511xxxxx
|
||
2. Service (src/services/sms/twilioService.ts):
|
||
import twilio from 'twilio';
|
||
const client = twilio(
|
||
process.env.TWILIO_ACCOUNT_SID,
|
||
process.env.TWILIO_AUTH_TOKEN
|
||
);
|
||
export async function sendSMS(to: string, message: string): Promise<void> {
|
||
await client.messages.create({
|
||
body: message,
|
||
from: process.env.TWILIO_PHONE_NUMBER,
|
||
to: formatPhoneNumber(to) // +55 11 99999-9999 -> +5511999999999
|
||
});
|
||
}
|
||
export async function sendAppointmentReminder(appointment: Appointment) {
|
||
const message = `MediConnect: Lembrete consulta
|
||
${formatDate(appointment.scheduled_at)} com Dr. ${appointment.doctor_name}. Confirme:
|
||
${getConfirmationLink(appointment.id)}`;
|
||
await sendSMS(appointment.patient_phone, message);
|
||
}
|
||
3. Netlify Function (netlify/functions/send-sms.ts):
|
||
Endpoint seguro para envio
|
||
Validar API key interna
|
||
Rate limiting
|
||
4. Agendamento:
|
||
Usar Netlify Scheduled Functions ou cron job
|
||
Função roda diariamente às 8h
|
||
|
||
---
|
||
## Page 27
|
||
|
||
Busca consultas das próximas 24h
|
||
Envia SMS para cada paciente
|
||
Stack: Twilio SDK + Netlify Functions + Supabase
|
||
#### Real-time com Supabase
|
||
Implemente atualizações em tempo real para sala de espera:
|
||
1. Setup Subscription (src/hooks/useRealtimeAppointments.ts):
|
||
import { useEffect } from 'react';
|
||
import { supabase } from '../lib/supabase';
|
||
import { useQueryClient } from '@tanstack/react-query';
|
||
export function useRealtimeAppointments(doctorId: string) {
|
||
const queryClient = useQueryClient();
|
||
useEffect(() => {
|
||
const channel = supabase
|
||
.channel('appointments-changes')
|
||
.on(
|
||
'postgres_changes',
|
||
{
|
||
event: '*', // INSERT, UPDATE, DELETE
|
||
schema: 'public',
|
||
table: 'appointments',
|
||
filter: `doctor_id=eq.${doctorId}`
|
||
},
|
||
(payload) => {
|
||
console.log('Real-time update:', payload);
|
||
// Invalidar queries relevantes
|
||
queryClient.invalidateQueries(['appointments', doctorId]);
|
||
queryClient.invalidateQueries(['waitingRoom', doctorId]);
|
||
}
|
||
)
|
||
.subscribe();
|
||
return () => {
|
||
supabase.removeChannel(channel);
|
||
};
|
||
}, [doctorId, queryClient]);
|
||
}
|
||
2. Usar no componente:
|
||
function WaitingRoom({ doctorId }) {
|
||
const { data: patients } = useWaitingRoom(doctorId);
|
||
useRealtimeAppointments(doctorId); // auto-update
|
||
|
||
---
|
||
## Page 28
|
||
|
||
return (...);
|
||
}
|
||
3. Policies Supabase:
|
||
Habilitar realtime na tabela appointments
|
||
Row Level Security para filtrar apenas consultas autorizadas
|
||
Stack: Supabase Realtime + React Query
|
||
---
|
||
### PROMPTS DE TESTES
|
||
#### Testes Unitários com Vitest
|
||
Configure ambiente de testes e crie testes para componentes críticos:
|
||
1. Setup:
|
||
Instalar: vitest, @testing-library/react, @testing-library/user-event, jsdom
|
||
Configurar vitest.config.ts:
|
||
import { defineConfig } from 'vitest/config';
|
||
import react from '@vitejs/plugin-react';
|
||
export default defineConfig({
|
||
plugins: [react()],
|
||
test: {
|
||
environment: 'jsdom',
|
||
globals: true,
|
||
setupFiles: './src/test/setup.ts'
|
||
}
|
||
});
|
||
2. Helpers (src/test/setup.ts):
|
||
import '@testing-library/jest-dom';
|
||
import { cleanup } from '@testing-library/react';
|
||
import { afterEach } from 'vitest';
|
||
afterEach(() => {
|
||
cleanup();
|
||
});
|
||
3. Testes Prioritários:
|
||
AvailableSlotsPicker.test.tsx:
|
||
import { render, screen, waitFor } from '@testing-library/react';
|
||
import { AvailableSlotsPicker } from './AvailableSlotsPicker';
|
||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||
|
||
---
|
||
## Page 29
|
||
|
||
const queryClient = new QueryClient();
|
||
test('mostra skeleton durante loading', () => {
|
||
render(
|
||
<QueryClientProvider client={queryClient}>
|
||
<AvailableSlotsPicker doctorId="123" date="2025-11-21" onSelect={vi.fn()} />
|
||
</QueryClientProvider>
|
||
);
|
||
expect(screen.getByText(/carregando/i)).toBeInTheDocument();
|
||
});
|
||
test('mostra slots disponíveis após carregar', async () => {
|
||
// Mock do service
|
||
vi.mock('../../services', () => ({
|
||
availabilityService: {
|
||
list: vi.fn().mockResolvedValue([
|
||
{ weekday: 4, start_time: '09:00', end_time: '12:00', slot_minutes: 30 }
|
||
])
|
||
},
|
||
appointmentService: {
|
||
list: vi.fn().mockResolvedValue([])
|
||
}
|
||
}));
|
||
render(...);
|
||
await waitFor(() => {
|
||
expect(screen.getByText('09:00')).toBeInTheDocument();
|
||
expect(screen.getByText('09:30')).toBeInTheDocument();
|
||
});
|
||
});
|
||
useAppointments.test.ts:
|
||
Testar hook isoladamente
|
||
Mock Supabase client
|
||
Verificar cache e invalidation
|
||
4. Coverage:
|
||
Meta: > 70% nos componentes críticos
|
||
Command: vitest --coverage
|
||
Stack: Vitest + Testing Library + MSW (mock API)
|
||
---
|
||
### PROMPTS DE SEGURANÇA
|
||
#### Auditoria de Ações
|
||
Implemente sistema de auditoria (audit trail) para ações sensíveis:
|
||
|
||
---
|
||
## Page 30
|
||
|
||
1. Tabela (Supabase):
|
||
CREATE TABLE audit_logs (
|
||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||
user_id UUID REFERENCES auth.users(id),
|
||
action VARCHAR(100) NOT NULL, -- 'create_appointment', 'cancel_appointment', etc.
|
||
resource_type VARCHAR(50), -- 'appointment', 'patient', 'report'
|
||
resource_id UUID,
|
||
details JSONB, -- dados antes/depois
|
||
ip_address INET,
|
||
user_agent TEXT,
|
||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||
);
|
||
CREATE INDEX idx_audit_user ON audit_logs(user_id);
|
||
CREATE INDEX idx_audit_resource ON audit_logs(resource_type, resource_id);
|
||
CREATE INDEX idx_audit_created ON audit_logs(created_at DESC);
|
||
2. Service (src/services/audit/auditService.ts):
|
||
interface AuditLogInput {
|
||
action: string;
|
||
resourceType: string;
|
||
resourceId: string;
|
||
details?: Record<string, any>;
|
||
}
|
||
export async function logAction(input: AuditLogInput): Promise<void> {
|
||
const { data: { user } } = await supabase.auth.getUser();
|
||
|
||
await supabase.from('audit_logs').insert({
|
||
user_id: user?.id,
|
||
action: input.action,
|
||
resource_type: input.resourceType,
|
||
resource_id: input.resourceId,
|
||
details: input.details,
|
||
ip_address: await getClientIP(), // helper function
|
||
user_agent: navigator.userAgent
|
||
});
|
||
}
|
||
// Wrapper para ações críticas
|
||
export async function auditedAction<T>(
|
||
action: string,
|
||
resourceType: string,
|
||
resourceId: string,
|
||
fn: () => Promise<T>
|
||
): Promise<T> {
|
||
const before = await getResourceState(resourceType, resourceId);
|
||
const result = await fn();
|
||
const after = await getResourceState(resourceType, resourceId);
|
||
|
||
---
|
||
## Page 31
|
||
|
||
await logAction({
|
||
action,
|
||
resourceType,
|
||
resourceId,
|
||
details: { before, after }
|
||
});
|
||
return result;
|
||
}
|
||
3. Integração:
|
||
// Antes:
|
||
await appointmentService.cancel(id);
|
||
// Depois:
|
||
await auditedAction(
|
||
'cancel_appointment',
|
||
'appointment',
|
||
id,
|
||
() => appointmentService.cancel(id)
|
||
);
|
||
4. Visualização Admin (src/pages/AuditLogs.tsx):
|
||
Tabela filtrada por usuário, ação, data
|
||
Diff visual de before/after
|
||
Exportar CSV
|
||
5. Ações Auditadas:
|
||
create/update/delete appointment
|
||
cancel_appointment
|
||
check_in_patient
|
||
create/update/delete report
|
||
access_patient_data (LGPD)
|
||
Stack: Supabase + PostgreSQL JSONB
|
||
---
|
||
## 22. Checklist de Qualidade Pré-Entrega
|
||
### Equipe 1 (UX/Design)
|
||
- [ ] Todos os estados de loading têm skeleton
|
||
- [ ] Todos os estados vazios têm mensagem + CTA
|
||
- [ ] Contraste AAA em textos principais
|
||
- [ ] Focus visible em todos os elementos interativos
|
||
- [ ] Modo escuro consistente em todas as páginas
|
||
- [ ] Responsivo testado em mobile/tablet/desktop
|
||
- [ ] Atalhos de teclado documentados
|
||
|
||
---
|
||
## Page 32
|
||
|
||
### Equipe 2 (Performance)
|
||
- [ ] Bundle size < 200KB gzipped
|
||
- [ ] Lighthouse Performance > 90
|
||
- [ ] Lighthouse Accessibility > 95
|
||
- [ ] Nenhum console.error em produção
|
||
- [ ] React Query configurado em todos os fetches
|
||
- [ ] Code-splitting em rotas principais
|
||
- [ ] Service Worker registrado e funcional
|
||
### Equipe 3 (Features)
|
||
- [ ] Check-in funcionando sem bugs
|
||
- [ ] Lista de espera preenchendo cancelamentos
|
||
- [ ] Confirmação por email funcionando
|
||
- [ ] Reagendamento sugerindo horários válidos
|
||
- [ ] Notificações sendo enviadas 24h antes
|
||
- [ ] Validações em todos os formulários
|
||
- [ ] Mensagens de erro amigáveis
|
||
### Equipe 4 (Analytics)
|
||
- [ ] Dashboard carregando métricas reais
|
||
- [ ] Gráficos renderizando corretamente
|
||
- [ ] Heatmap mostrando densidade real
|
||
- [ ] Exportações CSV funcionando
|
||
- [ ] Dados atualizando em tempo real
|
||
- [ ] Filtros aplicando corretamente
|
||
### Geral
|
||
- [ ] Nenhum erro TypeScript
|
||
- [ ] Nenhum warning ESLint crítico
|
||
- [ ] README.md atualizado com setup
|
||
- [ ] Variáveis ambiente documentadas (.env.example)
|
||
- [ ] Deploy em staging funcionando
|
||
- [ ] Testes críticos passando
|
||
- [ ] Supabase RLS policies revisadas
|
||
---
|
||
## 23. Distribuição de Horas por Equipe
|
||
| Equipe | Fase 1 | Fase 2 | Fase 3 | Total |
|
||
|--------|--------|--------|--------|-------|
|
||
| Equipe 1 (UX) | 14h | 14h | 6h | 34h |
|
||
| Equipe 2 (Perf) | 8h | 8h | 20h | 36h |
|
||
| Equipe 3 (Features) | 6h | 36h | 10h | 52h |
|
||
| Equipe 4 (Analytics) | - | 12h | 10h | 22h |
|
||
**Total Projeto:** 144h (aprox. 3-4 semanas com squad de 9 pessoas)
|
||
---
|
||
## 24. Comunicação e Sincronização
|
||
### Daily Standups (15 min)
|
||
- Cada equipe reporta: ontem, hoje, bloqueios
|
||
|
||
---
|
||
## Page 33
|
||
|
||
- Identificar dependências entre equipes
|
||
- Resolver impedimentos rapidamente
|
||
### Revisões de Código
|
||
- Pull requests obrigatórios
|
||
- Mínimo 1 aprovação de outro membro
|
||
- Checklist de qualidade antes de merge
|
||
- Convenção de commits: `feat:`, `fix:`, `refactor:`, `test:`
|
||
### Integração Contínua
|
||
- Branch: `main` (produção), `develop` (staging)
|
||
- Feature branches: `feature/nome-tarefa`
|
||
- Deploys automáticos em staging para PRs
|
||
- Deploy manual para produção após QA
|
||
### Documentação
|
||
- Cada feature documentada em `docs/features/`
|
||
- Prompts usados salvos para referência
|
||
- Decisões técnicas em `docs/adr/` (Architecture Decision Records)
|
||
---
|
||
## 25. Dependências Técnicas Detalhadas
|
||
| Biblioteca | Versão | Uso | Comando Instalação |
|
||
|------------|--------|-----|-------------------|
|
||
| @tanstack/react-query | ^5.0.0 | Cache e sincronização dados | `npm install @tanstack/react-
|
||
query` |
|
||
| @tanstack/react-query-devtools | ^5.0.0 | Debug React Query | `npm install -D
|
||
@tanstack/react-query-devtools` |
|
||
| @dnd-kit/core | ^6.0.0 | Drag & drop consultas | `npm install @dnd-kit/core @dnd-
|
||
kit/sortable` |
|
||
| react-window | ^1.8.10 | Virtualização listas | `npm install react-window` |
|
||
| @types/react-window | ^1.8.8 | Types React Window | `npm install -D @types/react-window` |
|
||
| react-joyride | ^2.7.0 | Tour guiado | `npm install react-joyride` |
|
||
| fuse.js | ^7.0.0 | Busca fuzzy (Command Palette) | `npm install fuse.js` |
|
||
| vite-plugin-pwa | ^0.20.0 | PWA e Service Worker | `npm install -D vite-plugin-pwa` |
|
||
| workbox-window | ^7.0.0 | Workbox runtime | `npm install workbox-window` |
|
||
| idb | ^8.0.0 | IndexedDB wrapper | `npm install idb` |
|
||
| recharts | ^2.12.0 | Gráficos simples | `npm install recharts` |
|
||
| twilio | ^5.0.0 | SMS (backend) | `npm install twilio` |
|
||
| rollup-plugin-visualizer | ^5.12.0 | Análise bundle | `npm install -D rollup-plugin-
|
||
visualizer` |
|
||
| vitest | ^2.0.0 | Testes unitários | `npm install -D vitest` |
|
||
| @testing-library/react | ^16.0.0 | Testes componentes | `npm install -D @testing-
|
||
library/react` |
|
||
| @testing-library/user-event | ^14.5.0 | Simulação interações | `npm install -D @testing-
|
||
library/user-event` |
|
||
| jsdom | ^25.0.0 | DOM para testes | `npm install -D jsdom` |
|
||
---
|
||
## 26. Estrutura de Pastas Proposta Pós-Refatoração
|
||
|
||
---
|
||
## Page 34
|
||
|
||
src/ ├── components/ │ ├── ui/ # Componentes base reutilizáveis │ │ ├── Skeleton.tsx │ │ ├── EmptyState.tsx │
|
||
│ ├── Button.tsx │ │ ├── Input.tsx │ │ ├── Modal.tsx │ │ └── Badge.tsx │ ├── dashboard/ # Componentes de
|
||
dashboard │ │ ├── MetricCard.tsx │ │ ├── OccupancyChart.tsx │ │ └── NoShowTrend.tsx │ ├── consultas/ #
|
||
Features de consultas │ │ ├── ConsultaModal.tsx │ │ ├── WaitingRoom.tsx │ │ ├── RescheduleModal.tsx │ │
|
||
└── CheckInButton.tsx │ ├── waitlist/ # Lista de espera │ │ ├── JoinWaitlistModal.tsx │ │ └──
|
||
WaitlistManager.tsx │ ├── analytics/ # Analytics e relatórios │ │ ├── OccupancyHeatmap.tsx │ │ └──
|
||
CustomReportBuilder.tsx │ └── CommandPalette.tsx # Busca global ├── hooks/ │ ├── useAppointments.ts # React
|
||
Query hooks │ ├── usePatients.ts │ ├── useAvailability.ts │ ├── useReports.ts │ ├── useWaitingRoom.ts │ ├──
|
||
useRealtimeAppointments.ts │ ├── useCommandPalette.ts │ └── useDebounce.ts ├── services/ │ ├──
|
||
appointments/ │ │ ├── types.ts │ │ ├── appointmentService.ts │ │ ├── reschedule.ts │ │ └── confirmation.ts │
|
||
├── waitlist/ │ │ └── waitlistService.ts │ ├── analytics/ │ │ ├── metricsService.ts │ │ └── heatmapService.ts │
|
||
├── audit/ │ │ └── auditService.ts │ └── sms/ │ └── twilioService.ts ├── pages/ │ ├── painel-medico/ #
|
||
Modularizado │ │ ├── index.tsx │ │ ├── DashboardTab.tsx │ │ ├── ConsultasTab.tsx │ │ ├──
|
||
DisponibilidadeTab.tsx │ │ ├── RelatoriosTab.tsx │ │ └── PerfilTab.tsx │ ├── ConfirmarConsulta.tsx # Landing page
|
||
confirmação │ └── AuditLogs.tsx # Admin audit trail ├── styles/ │ ├── design-tokens.ts # Sistema de design │
|
||
└── design-system.css ├── lib/ │ ├── supabase.ts │ ├── queryClient.ts # Config React Query │ └── date.ts #
|
||
Helpers de data └── test/ ├── setup.ts ├── mocks/ └── fixtures/
|
||
---
|
||
## 27. Exemplo de Prompt Completo (Template)
|
||
### Template Genérico para Novas Features
|
||
CONTEXTO: Sistema de agendamento médico multi-perfil (médico, paciente, secretaria, admin). Stack: React 18 +
|
||
TypeScript + Tailwind CSS + Supabase + React Query Arquitetura: Services layer + React Query hooks +
|
||
Componentes funcionais
|
||
OBJETIVO: [Descrever feature claramente em 1-2 frases]
|
||
REQUISITOS FUNCIONAIS:
|
||
1. [Requisito 1]
|
||
2. [Requisito 2]
|
||
3. [Requisito 3]
|
||
REQUISITOS NÃO-FUNCIONAIS:
|
||
Performance: [ex: carregar em < 2s]
|
||
Acessibilidade: [ex: WCAG AA]
|
||
Responsivo: mobile-first
|
||
TypeScript: tipagem estrita, sem 'any'
|
||
ESPECIFICAÇÃO TÉCNICA:
|
||
1. BACKEND (se aplicável): Tabela/Função Supabase:
|
||
[SQL schema ou RPC function]
|
||
2. SERVICE LAYER: Arquivo: src/services/[categoria]/[nome].ts
|
||
[Interfaces e funções principais]
|
||
|
||
---
|
||
## Page 35
|
||
|
||
3. REACT QUERY HOOK: Arquivo: src/hooks/use[Nome].ts
|
||
[Hook signature e config]
|
||
4. COMPONENTE UI: Arquivo: src/components/[categoria]/[Nome].tsx Props:
|
||
[prop1]: [tipo] - [descrição]
|
||
[prop2]: [tipo] - [descrição]
|
||
Comportamento:
|
||
[Behavior 1]
|
||
[Behavior 2]
|
||
5. INTEGRAÇÃO:
|
||
Onde usar: [páginas/componentes]
|
||
Dependências: [outros componentes/hooks]
|
||
Side effects: [invalidações, notificações]
|
||
6. TESTES:
|
||
Casos de teste prioritários:
|
||
[Test case 1]
|
||
[Test case 2]
|
||
7. ACESSIBILIDADE:
|
||
[Requisitos aria-*]
|
||
[Navegação por teclado]
|
||
[Anúncios para screen readers]
|
||
DESIGN:
|
||
Referência visual: [link Figma ou descrição]
|
||
Cores: usar tokens de design-tokens.ts
|
||
Ícones: lucide-react
|
||
VALIDAÇÕES:
|
||
[Validação 1]
|
||
[Validação 2]
|
||
MENSAGENS DE ERRO:
|
||
[Cenário erro 1]: "[Mensagem amigável]"
|
||
[Cenário erro 2]: "[Mensagem amigável]"
|
||
CRITÉRIOS DE ACEITAÇÃO:
|
||
[Critério 1]
|
||
[Critério 2]
|
||
[Critério 3]
|
||
TypeScript compila sem erros
|
||
Acessível via teclado
|
||
Responsivo mobile/desktop
|
||
|
||
---
|
||
## Page 36
|
||
|
||
Loading states implementados
|
||
---
|
||
## 28. Riscos e Mitigações Detalhados
|
||
| Risco | Probabilidade | Impacto | Mitigação | Responsável |
|
||
|-------|---------------|---------|-----------|-------------|
|
||
| Complexidade Teleconsulta muito alta | Alta | Alto | Usar serviço terceiro (Whereby,
|
||
Daily.co) primeiro | Equipe 3 + Tech Lead |
|
||
| Performance degradar com muitos dados | Média | Alto | Virtualização + paginação + índices
|
||
DB | Equipe 2 |
|
||
| Atraso em integrações SMS | Média | Médio | Começar cedo; ter fallback email-only | Equipe 3
|
||
|
|
||
| Baixa adoção lista de espera | Alta | Médio | UX clara + comunicação ativa + incentivos |
|
||
Equipe 3 + Product |
|
||
| Conflitos merge entre equipes | Média | Médio | PRs pequenos + comunicação diária + code
|
||
reviews | Todos |
|
||
| Supabase rate limits | Baixa | Alto | Monitorar uso + cache agressivo + plano adequado |
|
||
Equipe 2 + DevOps |
|
||
| Falta de tempo para testes | Alta | Alto | Priorizar testes críticos + automated CI | Todos
|
||
|
|
||
| Scope creep (adicionar features demais) | Alta | Alto | Focar em quick wins Fase 1; resto é
|
||
bonus | Product Owner |
|
||
---
|
||
## 29. Métricas de Sucesso Detalhadas
|
||
### Métricas Técnicas
|
||
| Métrica | Baseline Atual | Meta Fase 1 | Meta Fase 3 |
|
||
|---------|----------------|-------------|-------------|
|
||
| Lighthouse Performance | ~70 | > 85 | > 90 |
|
||
| Lighthouse Accessibility | ~80 | > 90 | > 95 |
|
||
| Bundle Size (gzipped) | ~300KB | < 250KB | < 200KB |
|
||
| Time to Interactive (TTI) | ~4s | < 3s | < 2s |
|
||
| First Contentful Paint (FCP) | ~2s | < 1.5s | < 1s |
|
||
| Cumulative Layout Shift (CLS) | N/A | < 0.1 | < 0.05 |
|
||
### Métricas de Produto
|
||
| Métrica | Baseline | Meta 1 Mês | Meta 3 Meses |
|
||
|---------|----------|------------|--------------|
|
||
| Taxa No-show | ~30% | < 20% | < 10% |
|
||
| Taxa Confirmação (1-clique) | 0% | > 60% | > 80% |
|
||
| Tempo médio agendamento | ~5 min | < 3 min | < 2 min |
|
||
| Slots vazios por cancelamento | ~80% | < 50% | < 20% |
|
||
| Satisfação médico (NPS) | N/A | > 7 | > 8 |
|
||
| Satisfação paciente (NPS) | N/A | > 7 | > 8 |
|
||
| Uso Command Palette | 0% | > 20% usuários | > 40% |
|
||
| Uso App Offline (PWA) | 0% | > 10% | > 25% |
|
||
---
|
||
|
||
---
|
||
## Page 37
|
||
|
||
## 30. Próximos Passos Imediatos (Semana 1)
|
||
### Segunda-feira
|
||
- [ ] Kickoff squad completo (1h)
|
||
- [ ] Alinhar visão e prioridades
|
||
- [ ] Distribuir equipes e tarefas
|
||
- [ ] Setup ambientes de desenvolvimento
|
||
- [ ] Equipe 1: Começar Design Tokens
|
||
- [ ] Equipe 2: Setup React Query
|
||
### Terça-feira
|
||
- [ ] Equipe 1: Implementar Skeleton loaders
|
||
- [ ] Equipe 2: Migrar primeiro hook (useAppointments)
|
||
- [ ] Equipe 3: Design da tela Check-in
|
||
- [ ] Daily standup
|
||
### Quarta-feira
|
||
- [ ] Equipe 1: Empty States
|
||
- [ ] Equipe 2: Code-splitting inicial
|
||
- [ ] Equipe 3: Backend Check-in (Supabase)
|
||
- [ ] Primeira revisão de código
|
||
- [ ] Daily standup
|
||
### Quinta-feira
|
||
- [ ] Equipe 1: Iniciar Command Palette
|
||
- [ ] Equipe 2: Testes de performance
|
||
- [ ] Equipe 3: UI Check-in
|
||
- [ ] Integração contínua
|
||
- [ ] Daily standup
|
||
### Sexta-feira
|
||
- [ ] Finalizar Quick Wins Sprint 1
|
||
- [ ] Code freeze 14h
|
||
- [ ] QA e testes integrados
|
||
- [ ] Deploy staging
|
||
- [ ] Retrospectiva (1h)
|
||
- [ ] Planejamento Sprint 2
|
||
---
|
||
## 31. Glossário Técnico
|
||
| Termo | Definição |
|
||
|-------|-----------|
|
||
| **Code-splitting** | Técnica de dividir bundle JavaScript em chunks menores carregados sob
|
||
demanda |
|
||
| **Skeleton Loader** | Placeholder animado que simula estrutura do conteúdo durante
|
||
carregamento |
|
||
| **Empty State** | Interface exibida quando não há dados para mostrar |
|
||
| **Design Tokens** | Valores centralizados (cores, espaçamentos, fontes) usados
|
||
consistentemente |
|
||
| **React Query** | Biblioteca para cache, sincronização e gerenciamento de estado server |
|
||
| **PWA** | Progressive Web App - app web com capacidades offline e instalável |
|
||
|
||
---
|
||
## Page 38
|
||
|
||
| **Service Worker** | Script que roda em background para cache e funcionalidades offline |
|
||
| **Heatmap** | Visualização de densidade de dados usando escala de cores |
|
||
| **Fuzzy Search** | Busca que tolera erros de digitação e aproxima resultados |
|
||
| **Optimistic Update** | Atualizar UI antes da confirmação do servidor para melhor UX |
|
||
| **Prefetch** | Carregar dados antecipadamente antes do usuário solicitar |
|
||
| **Tree-shaking** | Remover código não usado do bundle final |
|
||
| **Bundle Size** | Tamanho total do JavaScript/CSS enviado ao navegador |
|
||
| **Lazy Loading** | Carregar recursos apenas quando necessários |
|
||
| **Debounce** | Atrasar execução de função até usuário parar de digitar |
|
||
| **WCAG** | Web Content Accessibility Guidelines - padrão de acessibilidade |
|
||
| **ARIA** | Accessible Rich Internet Applications - atributos para acessibilidade |
|
||
| **RLS** | Row Level Security - segurança a nível de linha no Supabase |
|
||
| **Audit Trail** | Registro completo de ações para conformidade e segurança |
|
||
---
|
||
## 32. FAQs para o Squad
|
||
**Q: Por que React Query ao invés de Redux?**
|
||
A: React Query é especializado em estado server (dados de API), elimina boilerplate, cache
|
||
automático e sincronização. Redux é mais adequado para estado cliente complexo, que não é
|
||
nosso caso principal.
|
||
**Q: Preciso saber todos os prompts de cor?**
|
||
A: Não. Use como referência e adapte conforme necessário. Copie, cole na IA e ajuste detalhes
|
||
específicos.
|
||
**Q: E se minha equipe terminar antes?**
|
||
A: Ajude outras equipes, faça code review, ou comece tarefas da próxima fase. Comunicar no
|
||
daily.
|
||
**Q: Posso usar biblioteca diferente da sugerida?**
|
||
A: Sim, desde que justifique tecnicamente e não quebre integrações. Discutir com squad
|
||
primeiro.
|
||
**Q: Como testar integrações Supabase localmente?**
|
||
A: Use Supabase local dev (`supabase start`) ou aponte para projeto de staging. Nunca testar
|
||
direto em produção.
|
||
**Q: Onde colocar variáveis sensíveis (API keys)?**
|
||
A: Arquivo `.env.local` (nunca commitar). Para produção, usar Netlify Environment Variables.
|
||
**Q: Como resolver conflitos de merge?**
|
||
A: Comunicação proativa, PRs pequenos e frequentes, rebase regular da branch develop. Pedir
|
||
ajuda se necessário.
|
||
**Q: Testes são obrigatórios?**
|
||
A: Testes unitários para lógica crítica (hooks, services) são altamente recomendados. E2E
|
||
opcional mas valorizado.
|
||
---
|
||
## 33. Recursos de Referência
|
||
|
||
---
|
||
## Page 39
|
||
|
||
### Documentação Oficial
|
||
- [React Query Docs](https://tanstack.com/query/latest/docs/react/overview)
|
||
- [Supabase Docs](https://supabase.com/docs)
|
||
- [Tailwind CSS](https://tailwindcss.com/docs)
|
||
- [Vite Guide](https://vitejs.dev/guide/)
|
||
- [WCAG 2.1](https://www.w3.org/WAI/WCAG21/quickref/)
|
||
### Inspiração de Design
|
||
- [Linear](https://linear.app) - Dashboard limpo e rápido
|
||
- [Notion](https://notion.so) - UX intuitiva
|
||
- [Cal.com](https://cal.com) - Agendamento moderno
|
||
- [Vercel Dashboard](https://vercel.com/dashboard) - Métricas claras
|
||
### Ferramentas Úteis
|
||
- [Lighthouse](https://developer.chrome.com/docs/lighthouse) - Auditoria performance
|
||
- [axe DevTools](https://www.deque.com/axe/devtools/) - Auditoria acessibilidade
|
||
- [Bundle Analyzer](https://www.npmjs.com/package/rollup-plugin-visualizer) - Análise bundle
|
||
- [React DevTools](https://react.dev/learn/react-developer-tools) - Debug React
|
||
- [Supabase Studio](https://supabase.com/docs/guides/platform/studio) - Admin DB
|
||
---
|
||
## 34. Observações Finais
|
||
### Para o Product Owner
|
||
Este roadmap é ambicioso mas realista. Priorize Fase 1 e 2 para entrega com máximo impacto.
|
||
Fase 3 e 4 são diferenciais que podem ser negociados conforme tempo.
|
||
### Para Tech Lead
|
||
Monitore integrações entre equipes. Equipe 2 (Performance) desbloqueia outras com React Query.
|
||
Code reviews são críticos para manter qualidade.
|
||
### Para o Squad
|
||
Trabalhem com autonomia mas comuniquem cedo e frequentemente. Use os prompts como ponto de
|
||
partida, não receita definitiva. Adaptem conforme aprendem.
|
||
### Sobre Prompts de IA
|
||
Os prompts fornecidos são detalhados para reduzir ambiguidade. Ao usar com IA (ChatGPT,
|
||
Claude, Copilot):
|
||
1. Copie prompt completo
|
||
2. Adicione contexto específico do arquivo que está editando
|
||
3. Revise código gerado antes de aceitar
|
||
4. Ajuste para seguir padrões do projeto
|
||
5. Teste localmente antes de commitar
|
||
---
|
||
## 35. Celebração e Reconhecimento
|
||
### Marcos para Comemorar
|
||
- ✅ Primeira feature em produção
|
||
- ✅ Lighthouse score > 90
|
||
- ✅ Primeiro paciente usando lista de espera com sucesso
|
||
- ✅ Zero no-shows em um dia
|
||
|
||
---
|
||
## Page 40
|
||
|
||
- ✅ Deploy sem bugs críticos
|
||
- ✅ Feedback positivo de usuários reais
|
||
### Como o Squad Será Avaliado (Plus)
|
||
1. **Qualidade Técnica** (30%)
|
||
- Código limpo, tipado, testado
|
||
- Performance e acessibilidade
|
||
- Arquitetura escalável
|
||
2. **Impacto no Produto** (40%)
|
||
- Features que reduzem no-show
|
||
- Melhorias em UX validadas por usuários
|
||
- Redução de fricção operacional
|
||
3. **Inovação** (20%)
|
||
- Soluções criativas para problemas
|
||
- Uso inteligente de tecnologia
|
||
- Diferenciais competitivos
|
||
4. **Colaboração** (10%)
|
||
- Trabalho em equipe
|
||
- Code reviews construtivos
|
||
- Documentação e compartilhamento
|
||
---
|
||
## 36. Contato e Suporte
|
||
**Dúvidas Técnicas:**
|
||
- Criar issue no repositório com label `question`
|
||
- Mencionar tech lead nas discussões
|
||
**Bloqueios:**
|
||
- Reportar imediatamente no daily
|
||
- Não esperar mais de 4h tentando resolver sozinho
|
||
**Ideias e Melhorias:**
|
||
- Adicionar em `docs/ideas.md`
|
||
- Discutir na retrospectiva
|
||
---
|
||
## 37. Anexo: Status Consolidado
|
||
### IMPLEMENTADO (EXISTE/PARCIAL)
|
||
✅ Agenda básica (visualização mês)
|
||
✅ Disponibilidades do médico
|
||
✅ Exceções de agenda
|
||
✅ Relatórios básicos (CRUD)
|
||
✅ Laudos em draft/completed
|
||
✅ Autenticação multi-role
|
||
✅ Mensagens médico-paciente
|
||
✅ Componentes acessibilidade básicos
|
||
✅ Chatbot base
|
||
|
||
---
|
||
## Page 41
|
||
|
||
✅ Modo escuro (parcial)
|
||
### PRIORIDADE ALTA (Fase 1-2)
|
||
🔴 Design Tokens
|
||
🔴 Skeleton Loaders
|
||
🔴 Empty States
|
||
🔴 React Query
|
||
🔴 Check-in
|
||
🔴 Sala de Espera
|
||
🔴 Lista de Espera
|
||
🔴 Confirmação 1-clique
|
||
🔴 Dashboard KPIs
|
||
🔴 Command Palette
|
||
### PRIORIDADE MÉDIA (Fase 3)
|
||
🟡 Heatmap Ocupação
|
||
🟡 Reagendamento Inteligente
|
||
🟡 PWA Offline
|
||
🟡 Code-splitting Completo
|
||
🟡 Modo Escuro AAA
|
||
🟡 Notificações SMS
|
||
### OPCIONAL (Fase 4/Futuro)
|
||
⚪ Teleconsulta
|
||
⚪ Previsão Demanda ML
|
||
⚪ Auditoria LGPD Completa
|
||
⚪ Integração Calendários Externos
|
||
⚪ Sistema Pagamentos
|
||
⚪ Gamificação
|
||
---
|
||
## 38. Instruções para Regenerar PDF
|
||
### Método 1: NPM Script (Recomendado)
|
||
```bash
|
||
npm run pdf:roadmap
|
||
Método 2: Pandoc (Se instalado)
|
||
pandoc docs/mediConnect-roadmap.md -o docs/mediConnect-roadmap.pdf --pdf-engine=xelatex -V
|
||
geometry:margin=1in
|
||
Método 3: VS Code Extension
|
||
1. Instalar extensão "Markdown PDF"
|
||
2. Abrir mediConnect-roadmap.md
|
||
3. Ctrl+Shift+P → "Markdown PDF: Export (pdf)"
|
||
Documento preparado para: Squad 18 - MediConnect Última atualização: 2025-11-21 Versão: 2.0 (Detalhada com
|
||
equipes e prompts)
|
||
|
||
---
|
||
## Page 42
|
||
|
||
Bom trabalho, time! 🚀 Vamos fazer o melhor sistema de agendamento médico! 💪
|