Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
- **`README.md` reescrito como vitrine.** Era um índice de pastas. Agora abre pelo problema (a rotina real do fisioterapeuta domiciliar e a responsabilidade LGPD que um SaaS tradicional transfere ao profissional), explica o BYODB como resposta, e traz badges de CI/versão/testes/licença, diagrama Mermaid da arquitetura (o app fala direto com Drive e Sheets; o Firebase Hosting só serve estático), tabela de stack, instruções de execução, testes e CI/CD. A pendência do `google-services.json` do `com.rodrigo.alta` foi preservada. Seção de screenshots criada com os arquivos ainda pendentes.
- **Ruído removido:** `package-lock.json` (lockfile npm órfão, sem `package.json`, que ainda carregava `"name": "app-fisio2"`) apagado, e `.playwright-mcp/` removido do índice e adicionado ao `.gitignore` — artefato de sessão de ferramenta, não pertence ao repositório.

### Alterado
- **CPF deixou de ser obrigatório e de ser validado no cadastro de paciente.** Pedido explícito do cliente: nem todo paciente chega ao primeiro atendimento com o CPF em mãos, e o app não deve travar o cadastro por isso. `TelaCadastroPaciente` não checa mais o campo em `_listarCamposFaltando()` (campo vazio passa) nem chama `ValidadorCpf.validar()` (dígitos verificadores não são mais exigidos — qualquer sequência de até 11 dígitos é aceita, válida ou não). O rótulo do campo perdeu o `*` de obrigatório.
- **Duplicidade continua bloqueada**, mas só quando o campo não está vazio — a comparação de CPF (`p.cpf` vs. o texto digitado, sem máscara) é puramente textual, então dois pacientes sem CPF não colidem entre si, mas dois pacientes com o **mesmo** CPF "inválido" (ex.: `11111111111` repetido) continuam sendo barrados igual a qualquer duplicata real.
- `Validadores.validarCPF`/`ValidadorCpf.validar` (o algoritmo em si) não foram tocados — continuam disponíveis e testados como utilitário; só pararam de ser chamados nesta tela.
- `test/widgets/telas/tela_cadastro_paciente_test.dart`: CT-F1/CT-F2/CT-F4 ajustados (CPF não conta mais como pendência), CT-F3 reescrito para testar exatamente isso, e 3 novos testes cobrindo CPF com sequência sem checksum válido, CPF em branco não gerando falso positivo de duplicata, e CPF duplicado sendo barrado mesmo quando "inválido".
- Total de testes: **365 → 368** (`tela_cadastro_paciente_test.dart` 23 → 26).

### Correções
- **Login no web não completava no iPhone, e no resto sempre pedia duas tentativas.** O fluxo antigo abria dois popups do Google: identidade pelo botão do GIS sobreposto ao desenho, e autorização dos escopos Drive/Sheets num segundo popup disparado automaticamente pelo stream `authenticationEvents` — sem clique nenhum nesta página, já que o clique original tinha sido consumido pela interação inteira com o primeiro popup. O Chrome tolerava isso na maioria das vezes (daí precisar tentar duas vezes); o WebKit do iOS — usado por todo navegador no iOS, Chrome incluso, por exigência da Apple — bloqueava sempre, impedindo o login por completo. Um cliente relatou não conseguir entrar de jeito nenhum pelo iPhone.
- **Login interativo no web virou um popup só.** `AutorizadorGoogleWeb.entrarInterativo` (`lib/servicos/autorizador_google_web.dart`) pede conta e consentimento dos escopos juntos, chamado sem nenhum `await` real entre o toque do usuário e `requestAccessToken()` — preserva a ativação do usuário que o navegador exige para não bloquear o popup. Identidade (nome/e-mail) passa a vir do próprio access token via `userinfo` do Google.
Expand Down
16 changes: 8 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ fisio-home-care/
│ │ ├── gerador_id_test.dart (8 testes — 100% cobertura)
│ │ └── mensagens_erro_google_test.dart (8 testes — diagnóstico de login)
│ │
│ └── widgets/ # 191 testes — UI + componentes
│ └── widgets/ # 194 testes — UI + componentes
│ ├── componentes/
│ │ ├── modal_detalhes_evolucao_test.dart (6 testes)
│ ├── modal_detalhes_paciente_test.dart (12 testes)
Expand All @@ -143,7 +143,7 @@ fisio-home-care/
│ ├── tela_splash_test.dart (7 testes — abertura animada + handoff para o login)
│ ├── tela_login_test.dart (13 testes — navegação única + login não-programático)
│ ├── tela_dashboard_test.dart (19 testes)
│ ├── tela_cadastro_paciente_test.dart (23 testes)
│ ├── tela_cadastro_paciente_test.dart (26 testes)
│ ├── tela_editar_paciente_test.dart (6 testes — campos travados + atualização)
│ ├── tela_editar_sessao_test.dart (7 testes — editar/reagendar sessão)
│ ├── tela_financeiro_test.dart (8 testes — resumo financeiro mensal)
Expand All @@ -166,9 +166,9 @@ fisio-home-care/
│ ├── chaves.md # (no .gitignore) — credenciais
│ └── testes/
│ ├── README.md # Índice de testes
│ ├── VISAO_GERAL.md # Overview 365 testes
│ ├── VISAO_GERAL.md # Overview 368 testes
│ ├── UNITARIOS.md # Detalhe dos 174 unitários
│ └── WIDGETS.md # Detalhe dos 191 widgets
│ └── WIDGETS.md # Detalhe dos 194 widgets
│
├── QA/
│ └── qa.md # Script QA manual (NOT E2E automatizado)
Expand Down Expand Up @@ -309,7 +309,7 @@ Paciente.calcularIdade() // ✓ delega para UtilitariosData

---

## Testes (365 testes automatizados)
## Testes (368 testes automatizados)

### Estrutura

Expand All @@ -321,7 +321,7 @@ test/
│ ├── servicos/ — 50 testes (preferencias, Drive, Sheets, repositório)
│ └── utilitarios/ — 94 testes (validadores, data, CPF, gerador_id, erros do Google)
│
└── widgets/ (191 testes)
└── widgets/ (194 testes)
├── telas/ — 13 telas principais (UI, interação)
├── componentes/ — modal de detalhes do paciente + rodapé versão
└── utilitarios/ — ações de agendamento
Expand Down Expand Up @@ -354,7 +354,7 @@ flutter test --coverage
✅ **Validação de entrada** — 55 testes (CPF, telefone, nome, data)
✅ **Modelos** — 25 testes (serialização, cópia, status)
✅ **Utilitários** — 31 testes (idade, formatação, geração de ID)
✅ **UI + Interação** — 191 testes (13 telas principais + componentes/utilitários)
✅ **UI + Interação** — 194 testes (13 telas principais + componentes/utilitários)

❌ **Não coberto:**
- Google Sheets API real (usaria quota, seria lento)
Expand Down Expand Up @@ -574,7 +574,7 @@ make release-prod # mescla develop → main → dispara deploy de produção (p
| `documentacao/ESPECIFICACOES_TELAS.md` | Requisitos funcionais das telas | ✅ |
| `documentacao/SEGURANCA_E_DADOS.md` | LGPD, OAuth, modelo BYODB | ✅ |
| `documentacao/IMPLEMENTAR.md` | Roadmap priorizado | ✅ |
| `documentacao/testes/` | 365 testes automatizados | ✅ |
| `documentacao/testes/` | 368 testes automatizados | ✅ |
| `documentacao/CI_CD.md` | Pipeline GitHub Actions: fluxo, secrets, uso e troubleshooting | ✅ |
| `QA/qa.md` | Script QA manual (não é E2E) | ✅ |

Expand Down
21 changes: 12 additions & 9 deletions QA/qa.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Você é um Analista de Qualidade Sênior. Sua tarefa é criar scripts de teste
- **Agenda do dia:** Exibe somente sessões com `Situacao = "Agendado"` na data atual; sessões antigas sem desfecho aparecem em **Pendências**.
- **Desfechos de sessão:** `Realizado`, `Cancelado`, `Cancelado pelo paciente`, `Cancelado pelo profissional`, `Faltou com aviso`, `Faltou sem aviso`.
- **Nova sessão:** Não permite agendar horários retroativos (anteriores ao momento atual).
- **Pacientes:** Cadastro com validação de campos obrigatórios (nome, CPF, telefone, endereço, dados clínicos iniciais); filtros `Todos` e `Ativos`.
- **Pacientes:** Cadastro com validação de campos obrigatórios (nome, telefone, endereço, dados clínicos iniciais); CPF é opcional e aceito sem validação de dígitos verificadores; filtros `Todos` e `Ativos`.
- **Evolução clínica:** Registro estruturado obrigatório após atendimento realizado.
- **Rotas:** Integração com Google Maps e Waze a partir do endereço do paciente.
- **LGPD:** O profissional atua como Controlador dos dados; o app exige consentimento na entrada e oferece ferramentas de privacidade em Configurações.
Expand Down Expand Up @@ -143,10 +143,10 @@ Use este helper para interagir com qualquer elemento na tela, seja do app ou do

### 7. Validação de Campos Obrigatórios via AlertDialog

A validação de campos obrigatórios (Nome, CPF, Telefone, Data de Nascimento, Endereço) no cadastro de paciente usa `AlertDialog` em vez de validadores inline do `TextFormField`, pois os erros inline do Flutter **não são expostos na árvore de acessibilidade do Android**.
A validação de campos obrigatórios (Nome, Telefone, Data de Nascimento, Endereço) no cadastro de paciente usa `AlertDialog` em vez de validadores inline do `TextFormField`, pois os erros inline do Flutter **não são expostos na árvore de acessibilidade do Android**. CPF **não** é obrigatório e não passa por nenhuma validação de dígitos verificadores — aceita qualquer sequência de até 11 dígitos, inclusive vazia (pedido explícito do cliente: nem todo paciente tem CPF em mãos no primeiro atendimento). Duplicidade de CPF continua bloqueada, mas só quando o campo não está vazio — dois pacientes sem CPF não colidem entre si.

**Comportamento:**
- Ao clicar "Salvar Paciente" com campos vazios → `AlertDialog` com título "Campos obrigatórios" e lista dos itens faltando
- Ao clicar "Salvar Paciente" com campos vazios → `AlertDialog` com título "Campos obrigatórios" e lista dos itens faltando (CPF nunca aparece nessa lista)
- Cada item da lista aparece como texto acessível → `getByLabel('Nome Completo')` funciona
- Botão "OK" fecha o dialog → `getByLabel('OK').tap()`
- `barrierDismissible: false` — só fecha clicando no botão OK
Expand All @@ -163,13 +163,16 @@ class MockListaPacientesNotifier extends ListaPacientesNotifier {
}
```

**Testes unitários (6):**
- CT-F1: 5 campos vazios → dialog com 5 itens
- CT-F2: só Nome preenchido → dialog com 4 itens
- CT-F3: só CPF preenchido → dialog com 4 itens
- CT-F4: Nome+CPF+Telefone → dialog com 2 itens (Data, Endereço)
**Testes unitários** (`test/widgets/telas/tela_cadastro_paciente_test.dart`):
- CT-F1: todos os campos obrigatórios vazios → dialog com 4 itens (Nome, Telefone, Data, Endereço)
- CT-F2: só Nome preenchido → dialog com 3 itens
- CT-F3: CPF em branco não aparece nos campos obrigatórios e o cadastro segue normalmente
- CT-F4: Nome+Telefone → dialog com 2 itens (Data, Endereço)
- CT-F5: todos preenchidos → salva sem dialog
- CT-F6: dialog fecha ao clicar OK
- CPF sem dígito verificador válido (ex.: `11111111111`) é aceito, mas duplicado é bloqueado
- CPF com sequência qualquer (sem checksum válido) é salvo como digitado
- CPF em branco não gera falso positivo de duplicidade entre dois pacientes

### 8. `getByLabel` em AlertDialog

Expand All @@ -180,7 +183,7 @@ O Flutter expõe `AlertDialog.title`, `AlertDialog.content` Text widgets e `Text
await expect(screen.getByLabel('Campos obrigatórios')).toBeVisible();
// Verificar itens da lista
await expect(screen.getByLabel('Nome Completo')).toBeVisible();
await expect(screen.getByLabel('CPF')).toBeVisible();
// CPF não é mais obrigatório — não aparece nesta lista.
// Fechar o dialog
await screen.getByLabel('OK').tap();
// Confirmar que fechou
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![Deploy de Produção](https://github.com/lacerdaRodrigo/alta/actions/workflows/deploy-prod.yml/badge.svg)](https://github.com/lacerdaRodrigo/alta/actions/workflows/deploy-prod.yml)
[![Deploy de Testes](https://github.com/lacerdaRodrigo/alta/actions/workflows/deploy-preview.yml/badge.svg)](https://github.com/lacerdaRodrigo/alta/actions/workflows/deploy-preview.yml)
[![Flutter](https://img.shields.io/badge/Flutter-3.44.1-02569B?logo=flutter&logoColor=white)](https://flutter.dev)
[![Testes](https://img.shields.io/badge/testes-365%20passando-success)](documentacao/testes/)
[![Testes](https://img.shields.io/badge/testes-368%20passando-success)](documentacao/testes/)
[![Licença](https://img.shields.io/badge/licen%C3%A7a-propriet%C3%A1ria-lightgrey)](LICENSE)

[**Acessar o aplicativo**](https://app-fisio-care-2.web.app) · [Documentação](documentacao/) · [Modelo de dados](documentacao/MODELO_DADOS.md) · [Segurança e LGPD](documentacao/SEGURANCA_E_DADOS.md)
Expand Down Expand Up @@ -165,7 +165,7 @@ make dev-web # http://localhost:5000

## Testes

**365 testes automatizados** — 174 unitários + 191 de widget, cobrindo as 14
**368 testes automatizados** — 174 unitários + 194 de widget, cobrindo as 14
telas, os 3 modelos, os serviços de Drive/Sheets/repositório e os validadores.

```bash
Expand Down Expand Up @@ -234,7 +234,7 @@ infraestrutura do mantenedor.
| [`documentacao/SEGURANCA_E_DADOS.md`](documentacao/SEGURANCA_E_DADOS.md) | LGPD, OAuth e o modelo BYODB |
| [`documentacao/CI_CD.md`](documentacao/CI_CD.md) | Pipeline, secrets e troubleshooting |
| [`documentacao/IMPLEMENTAR.md`](documentacao/IMPLEMENTAR.md) | Roadmap priorizado |
| [`documentacao/testes/`](documentacao/testes/) | Os 365 testes, um a um |
| [`documentacao/testes/`](documentacao/testes/) | Os 368 testes, um a um |
| [`QA/qa.md`](QA/qa.md) | Roteiro de QA manual |
| [`CHANGELOG.md`](CHANGELOG.md) | Histórico de versões |

Expand Down
2 changes: 1 addition & 1 deletion documentacao/IMPLEMENTAR.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
> registrado no [`CHANGELOG.md`](../CHANGELOG.md); o estado atual da arquitetura
> está no [`CLAUDE.md`](../CLAUDE.md).

**Status:** MVP funcional completo em produção (web) · 365 testes automatizados
**Status:** MVP funcional completo em produção (web) · 368 testes automatizados
**Atualizado em:** 2026-07-29

---
Expand Down
2 changes: 1 addition & 1 deletion documentacao/testes/COBERTURA_ANALISE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# 📊 Análise de Cobertura de Testes

> ⚠️ **ARQUIVADO — snapshot histórico de 2026-06-16.** Todas as 12 telas
> principais já têm testes de widget hoje (365 testes no total). Para os
> principais já têm testes de widget hoje (368 testes no total). Para os
> números atuais, veja [`VISAO_GERAL.md`](./VISAO_GERAL.md). Este documento
> fica só como registro de como a cobertura evoluiu (era 60% de telas
> testadas nessa data) — não reflete o estado atual do projeto.
Expand Down
6 changes: 3 additions & 3 deletions documentacao/testes/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# 📚 Documentação de Testes

Guia completo dos 365 testes automatizados do Alta.
Guia completo dos 368 testes automatizados do Alta.

---

## 📖 Documentos

1. **[VISAO_GERAL.md](./VISAO_GERAL.md)** — Overview, estrutura, como rodar
2. **[UNITARIOS.md](./UNITARIOS.md)** — 174 testes unitários (validadores, modelos, serviços)
3. **[WIDGETS.md](./WIDGETS.md)** — 191 testes de widget (telas, componentes, utilitários)
3. **[WIDGETS.md](./WIDGETS.md)** — 194 testes de widget (telas, componentes, utilitários)

---

Expand Down Expand Up @@ -39,7 +39,7 @@ flutter test test/unitarios/utilitarios/validadores_test.dart
| Unit — Serviços | 50 | 14% |
| Widget — Telas | 164 | 45% |
| Widget — Componentes/Utilitários | 27 | 8% |
| **TOTAL** | **365** | **100%** |
| **TOTAL** | **368** | **100%** |

---

Expand Down
14 changes: 7 additions & 7 deletions documentacao/testes/VISAO_GERAL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 📋 Testes Automatizados — Visão Geral

**Status:** ✅ 365 testes passando
**Status:** ✅ 368 testes passando

---

Expand All @@ -10,12 +10,12 @@ O projeto utiliza **apenas testes unitários e de widget** (sem E2E automatizado

| Categoria | Quantidade | % | Focos |
|---|---|---|---|
| **Unit — Utilitários** | 93 | 26% | Validadores, formatadores, gerador de IDs |
| **Unit — Utilitários** | 94 | 26% | Validadores, formatadores, gerador de IDs |
| **Unit — Modelos** | 30 | 8% | Serialização, transformação, cópia |
| **Unit — Serviços** | 50 | 14% | Preferências, Drive, Sheets e repositório de dados (via `ServidorGoogleFake`) |
| **Widget — Telas** | 164 | 45% | UI, interação, estados visuais |
| **Widget — Telas** | 167 | 45% | UI, interação, estados visuais |
| **Widget — Componentes/Utilitários** | 27 | 8% | Modal de detalhes, rodapé versão, ações de agendamento |
| **TOTAL** | **365** | **100%** | — |
| **TOTAL** | **368** | **100%** | — |

---

Expand All @@ -41,7 +41,7 @@ test/
│ ├── validador_cpf_test.dart (9 testes)
│ ├── validadores_test.dart (46 testes)
│ └── gerador_id_test.dart (8 testes)
└── widgets/ (191 testes — UI + componentes)
└── widgets/ (194 testes — UI + componentes)
├── componentes/
│ ├── modal_detalhes_evolucao_test.dart (6 testes)
│ ├── modal_detalhes_paciente_test.dart (12 testes)
Expand All @@ -52,7 +52,7 @@ test/
├── tela_splash_test.dart (7 testes — abertura animada)
├── tela_login_test.dart (13 testes)
├── tela_dashboard_test.dart (19 testes)
├── tela_cadastro_paciente_test.dart (23 testes)
├── tela_cadastro_paciente_test.dart (26 testes)
├── tela_editar_paciente_test.dart (6 testes — campos travados + atualização)
├── tela_editar_sessao_test.dart (7 testes — editar/reagendar sessão)
├── tela_financeiro_test.dart (8 testes — resumo financeiro mensal)
Expand All @@ -69,7 +69,7 @@ test/
## Como Rodar

```bash
# Todos os 365 testes
# Todos os 368 testes
flutter test

# Apenas unitários
Expand Down
Loading
Loading