riseup-squad18/mediConnect-roadmap.md

2151 lines
65 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
14162024)
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! 💪