riseup-squad18/README.md

696 lines
16 KiB
Markdown
Raw Blame History

# MediConnect - Sistema de Agendamento Médico
Sistema completo de gestão de consultas médicas desenvolvido pela **Squad 18** do programa Rise Up.
## 🚀 Acesso ao Sistema
- **URL Principal:** https://mediconnectbrasil.app/
- **URL Cloudflare:** https://mediconnect-5oz.pages.dev/
## 📋 Índice
1. [Visão Geral](#visão-geral)
2. [Arquitetura](#arquitetura)
3. [Tecnologias](#tecnologias)
4. [Estrutura do Projeto](#estrutura-do-projeto)
5. [API e Serviços](#api-e-serviços)
6. [Autenticação](#autenticação)
7. [Fluxos Principais](#fluxos-principais)
8. [Deploy](#deploy)
9. [Desenvolvimento Local](#desenvolvimento-local)
---
## 🎯 Visão Geral
O MediConnect é uma plataforma web que conecta **pacientes**, **médicos** e **secretárias** de forma eficiente e segura, permitindo:
- ✅ Agendamento de consultas online
- ✅ Gestão de disponibilidade dos médicos
- ✅ Acompanhamento de consultas e prontuários
- ✅ Recuperação de senha
- ✅ Sistema de roles e permissões
- ✅ Interface responsiva e acessível
---
## 🏗️ Arquitetura
### Diagrama de Arquitetura
```
┌─────────────────┐
│ Frontend │
│ React + TS │
│ (Cloudflare) │
└────────┬────────┘
│ HTTPS
┌─────────────────┐
│ Supabase API │
│ (Backend) │
├─────────────────┤
│ • Auth │
│ • PostgreSQL │
│ • Functions │
│ • Storage │
└─────────────────┘
```
### Camadas da Aplicação
1. **Apresentação (UI)**
- React 18.3.1 com TypeScript
- React Router para navegação
- Tailwind CSS para estilização
- Lucide React para ícones
2. **Lógica de Negócio (Services)**
- Services organizados por domínio
- Axios para requisições HTTP
- Interceptors para autenticação automática
3. **Persistência (Supabase)**
- PostgreSQL com Row Level Security (RLS)
- Supabase Auth para autenticação
- Supabase Functions para lógica serverless
---
## 🛠️ Tecnologias
### Frontend
- **React** 18.3.1 - Biblioteca UI
- **TypeScript** 5.9.3 - Tipagem estática
- **Vite** 7.1.10 - Build tool
- **React Router** 6.30.1 - Roteamento
- **Tailwind CSS** 3.4.17 - Estilização
- **Axios** 1.12.2 - Cliente HTTP
- **React Hot Toast** 2.4.1 - Notificações
- **date-fns** 4.1.0 - Manipulação de datas
### Backend
- **Supabase** - Backend as a Service
- **PostgreSQL** - Banco de dados relacional
- **Supabase Auth** - Autenticação JWT
### Deploy
- **Cloudflare Pages** - Hospedagem frontend
- **Wrangler** 4.44.0 - CLI Cloudflare
---
## 📁 Estrutura do Projeto
```
MEDICONNECT 2/
├── src/
│ ├── pages/ # Páginas da aplicação
│ │ ├── Home.tsx
│ │ ├── LoginPaciente.tsx
│ │ ├── LoginMedico.tsx
│ │ ├── LoginSecretaria.tsx
│ │ ├── ResetPassword.tsx
│ │ ├── PainelMedico.tsx
│ │ ├── PainelSecretaria.tsx
│ │ ├── AcompanhamentoPaciente.tsx
│ │ └── ...
│ │
│ ├── components/ # Componentes reutilizáveis
│ │ ├── Header.tsx
│ │ ├── HeroBanner.tsx
│ │ ├── Chatbot.tsx
│ │ ├── MetricCard.tsx
│ │ ├── auth/
│ │ ├── agenda/
│ │ ├── consultas/
│ │ └── secretaria/
│ │
│ ├── services/ # Serviços de API
│ │ ├── api/
│ │ │ ├── client.ts # Cliente HTTP
│ │ │ └── config.ts # Configurações
│ │ ├── auth/
│ │ │ ├── authService.ts
│ │ │ └── types.ts
│ │ ├── patients/
│ │ ├── doctors/
│ │ ├── appointments/
│ │ ├── availability/
│ │ └── users/
│ │
│ ├── hooks/ # React Hooks customizados
│ │ ├── useAuth.ts
│ │ └── useAccessibilityPrefs.ts
│ │
│ ├── context/ # Context API
│ │ └── AuthContext.tsx
│ │
│ ├── i18n/ # Internacionalização
│ │ ├── pt-BR.ts
│ │ └── en-US.ts
│ │
│ ├── types/ # Definições de tipos
│ │ └── api.d.ts
│ │
│ └── utils/ # Utilitários
│ └── validators.ts
├── public/ # Arquivos públicos
├── dist/ # Build de produção
├── scripts/ # Scripts utilitários
│ ├── manage-users.js
│ └── cleanup-users.js
├── vite.config.ts # Configuração Vite
├── tailwind.config.js # Configuração Tailwind
└── tsconfig.json # Configuração TypeScript
```
---
## 🔌 API e Serviços
### Configuração da API
```typescript
// src/services/api/config.ts
export const API_CONFIG = {
SUPABASE_URL: "https://yuanqfswhberkoevtmfr.supabase.co",
SUPABASE_ANON_KEY: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
AUTH_URL: `${SUPABASE_URL}/auth/v1`,
REST_URL: `${SUPABASE_URL}/rest/v1`,
FUNCTIONS_URL: `${SUPABASE_URL}/functions/v1`,
APP_URL: "https://mediconnectbrasil.app",
TIMEOUT: 30000,
STORAGE_KEYS: {
ACCESS_TOKEN: "mediconnect_access_token",
REFRESH_TOKEN: "mediconnect_refresh_token",
USER: "mediconnect_user"
}
}
```
### Serviços Disponíveis
#### 1. **authService** - Autenticação
```typescript
// Login
await authService.login({ email, password })
// Registro
await authService.signup({ email, password, full_name })
// Logout
await authService.logout()
// Recuperação de senha
await authService.requestPasswordReset(email)
await authService.updatePassword(accessToken, newPassword)
// Refresh token
await authService.refreshToken(refreshToken)
```
#### 2. **userService** - Usuários
```typescript
// Buscar informações do usuário autenticado
const userInfo = await userService.getUserInfo()
// Criar usuário com role
await userService.createUser({ email, full_name, role })
// Deletar usuário
await userService.deleteUser(userId)
```
#### 3. **patientService** - Pacientes
```typescript
// Listar pacientes
const patients = await patientService.list()
// Buscar por ID
const patient = await patientService.getById(id)
// Criar paciente
await patientService.create({ email, full_name, cpf, phone })
// Atualizar
await patientService.update(id, data)
// Registrar paciente (público)
await patientService.register({ email, full_name, cpf })
```
#### 4. **doctorService** - Médicos
```typescript
// Listar médicos
const doctors = await doctorService.list()
// Buscar por ID
const doctor = await doctorService.getById(id)
// Buscar disponibilidade
const slots = await doctorService.getAvailableSlots(doctorId, date)
```
#### 5. **appointmentService** - Consultas
```typescript
// Listar consultas
const appointments = await appointmentService.list()
// Criar consulta
await appointmentService.create({
patient_id,
doctor_id,
scheduled_at,
reason
})
// Atualizar status
await appointmentService.updateStatus(id, status)
// Cancelar
await appointmentService.cancel(id, reason)
```
#### 6. **availabilityService** - Disponibilidade
```typescript
// Gerenciar disponibilidade do médico
await availabilityService.create({
doctor_id,
day_of_week,
start_time,
end_time
})
// Listar disponibilidade
const slots = await availabilityService.listByDoctor(doctorId)
```
---
## 🔐 Autenticação
### Fluxo de Autenticação
1. **Login**
```typescript
// 1. Usuário envia credenciais
const response = await authService.login({ email, password })
// 2. Recebe tokens JWT
localStorage.setItem('access_token', response.access_token)
localStorage.setItem('refresh_token', response.refresh_token)
// 3. Busca informações completas
const userInfo = await userService.getUserInfo()
// 4. Valida roles
if (userInfo.roles.includes('medico')) {
navigate('/painel-medico')
}
```
2. **Interceptor Automático**
```typescript
// Todo request adiciona o token automaticamente
axios.interceptors.request.use(config => {
const token = localStorage.getItem('access_token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
```
3. **Refresh Token Automático**
```typescript
axios.interceptors.response.use(
response => response,
async error => {
if (error.response?.status === 401) {
// Token expirado, tenta refresh
const refreshToken = localStorage.getItem('refresh_token')
const newTokens = await authService.refreshToken(refreshToken)
// Retry request original
}
}
)
```
### Roles e Permissões
| Role | Acesso |
|------|--------|
| **admin** | Acesso total ao sistema |
| **gestor** | Gestão de médicos, secretárias e relatórios |
| **medico** | Painel médico, consultas, prontuários |
| **secretaria** | Agendamento, gestão de pacientes |
| **paciente** | Agendamento, visualização de consultas |
**Hierarquia de Roles:**
```
admin > gestor > medico/secretaria > paciente
```
---
## 🔄 Fluxos Principais
### 1. Fluxo de Agendamento de Consulta
```mermaid
sequenceDiagram
Paciente->>LoginPaciente: Faz login
LoginPaciente->>Supabase: POST /auth/v1/token
Supabase-->>LoginPaciente: access_token
LoginPaciente->>UserService: getUserInfo()
UserService-->>LoginPaciente: dados + roles
Paciente->>ListaMedicos: Escolhe médico
ListaMedicos->>DoctorService: getAvailableSlots()
DoctorService-->>ListaMedicos: horários disponíveis
Paciente->>AppointmentService: create()
AppointmentService->>Supabase: POST /rest/v1/appointments
Supabase-->>Paciente: Consulta criada ✅
```
### 2. Fluxo de Recuperação de Senha
```mermaid
sequenceDiagram
Usuário->>LoginPage: Clica "Esqueceu a senha?"
LoginPage->>AuthService: requestPasswordReset(email)
AuthService->>Supabase: POST /auth/v1/recover
Supabase->>Email: Envia link de recuperação
Usuário->>Email: Clica no link
Email->>ResetPassword: Redireciona com token
ResetPassword->>AuthService: updatePassword(token, novaSenha)
AuthService->>Supabase: PUT /auth/v1/user
Supabase-->>ResetPassword: Senha atualizada ✅
```
### 3. Fluxo de Validação de Roles
```typescript
// LoginMedico.tsx
const handleLogin = async () => {
// 1. Login
const loginResponse = await authService.login({ email, password })
// 2. Buscar roles
const userInfo = await userService.getUserInfo()
const roles = userInfo.roles || []
// 3. Validar permissão
const isAdmin = roles.includes('admin')
const isGestor = roles.includes('gestor')
const isMedico = roles.includes('medico')
if (!isAdmin && !isGestor && !isMedico) {
toast.error("Você não tem permissão para acessar esta área")
await authService.logout()
return
}
// 4. Redirecionar
navigate('/painel-medico')
}
```
---
## 🚀 Deploy
### Cloudflare Pages
O projeto é hospedado no **Cloudflare Pages** com deploy automático via Wrangler CLI.
#### Comandos de Deploy
```bash
# Build de produção
pnpm build
# Deploy para Cloudflare
npx wrangler pages deploy dist --project-name=mediconnect
# Deploy com branch específica
npx wrangler pages deploy dist --project-name=mediconnect --branch=production
# Deploy ignorando mudanças não commitadas
npx wrangler pages deploy dist --project-name=mediconnect --commit-dirty=true
```
#### Configuração do Cloudflare
1. **Production Branch:** `production`
2. **Build Command:** `pnpm build`
3. **Build Output:** `dist`
4. **Custom Domain:** `mediconnectbrasil.app`
#### URLs de Deploy
- **Production:** https://mediconnectbrasil.app/
- **Preview:** https://mediconnect-5oz.pages.dev/
- **Branch Preview:** https://[branch].mediconnect-5oz.pages.dev/
---
## 💻 Desenvolvimento Local
### Pré-requisitos
- Node.js 18+
- pnpm 8+
- Git
### Instalação
```bash
# 1. Clone o repositório
git clone https://git.popcode.com.br/RiseUP/riseup-squad18.git
cd riseup-squad18/"MEDICONNECT 2"
# 2. Instale as dependências
pnpm install
# 3. Configure as variáveis de ambiente (se necessário)
# Crie um arquivo .env.local com as configurações do Supabase
# 4. Inicie o servidor de desenvolvimento
pnpm dev
# 5. Acesse http://localhost:5173
```
### Scripts Disponíveis
```bash
# Desenvolvimento
pnpm dev # Inicia servidor dev
# Build
pnpm build # Build de produção
pnpm preview # Preview do build
# Testes
pnpm test # Executa testes
pnpm test:ui # UI de testes
# Lint
pnpm lint # Verifica código
# Type check
pnpm type-check # Verifica tipos TypeScript
```
### Variáveis de Ambiente
```env
# .env.local (opcional - já configurado no código)
VITE_SUPABASE_URL=https://yuanqfswhberkoevtmfr.supabase.co
VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
VITE_APP_URL=http://localhost:5173
```
---
## 📊 Estrutura do Banco de Dados
### Tabelas Principais
#### `profiles`
```sql
- id (uuid, PK)
- email (text, unique)
- full_name (text)
- phone (text)
- created_at (timestamp)
- updated_at (timestamp)
```
#### `patients`
```sql
- id (uuid, PK, FK -> profiles)
- email (text, unique)
- full_name (text)
- cpf (text, unique)
- phone_mobile (text)
- birth_date (date)
- address (text)
- created_at (timestamp)
```
#### `doctors`
```sql
- id (uuid, PK, FK -> profiles)
- email (text, unique)
- full_name (text)
- specialty (text)
- crm (text, unique)
- phone (text)
- created_at (timestamp)
```
#### `appointments`
```sql
- id (uuid, PK)
- patient_id (uuid, FK -> patients)
- doctor_id (uuid, FK -> doctors)
- scheduled_at (timestamp)
- status (enum: requested, confirmed, completed, cancelled)
- reason (text)
- notes (text)
- created_at (timestamp)
```
#### `user_roles`
```sql
- user_id (uuid, FK -> profiles)
- role (text: admin, gestor, medico, secretaria, paciente)
- created_at (timestamp)
```
---
## 🔧 Scripts Utilitários
### Gerenciamento de Usuários
```bash
# Listar todos os usuários
node scripts/manage-users.js list
# Criar usuário
node scripts/manage-users.js create email@example.com "Nome Completo"
# Deletar usuário
node scripts/manage-users.js delete user-id
# Limpar usuários de teste
node scripts/cleanup-users.js
```
### Testes de API
```bash
# Testar recuperação de senha
node test-password-recovery.js
# Criar usuário Fernando (exemplo)
node create-fernando.cjs
# Buscar usuário Fernando
node search-fernando.cjs
```
---
## 🎨 Padrões de Código
### Nomenclatura
- **Componentes:** PascalCase (`LoginPaciente.tsx`)
- **Serviços:** camelCase (`authService.ts`)
- **Hooks:** camelCase com prefixo `use` (`useAuth.ts`)
- **Tipos:** PascalCase (`LoginInput`, `AuthUser`)
### Estrutura de Componentes
```typescript
// Imports
import React, { useState, useEffect } from "react"
import { useNavigate } from "react-router-dom"
import { serviceImport } from "../services"
// Types
interface Props {
// ...
}
// Component
const ComponentName: React.FC<Props> = ({ ...props }) => {
// Hooks
const navigate = useNavigate()
const [state, setState] = useState()
// Effects
useEffect(() => {
// ...
}, [])
// Handlers
const handleAction = async () => {
// ...
}
// Render
return (
<div>
{/* JSX */}
</div>
)
}
export default ComponentName
```
---
## <20> Suporte e Contato
- **Equipe:** Squad 18 - Rise Up
- **Repositório:** https://git.popcode.com.br/RiseUP/riseup-squad18.git
- **Trello:** [Squad 18 - Idealização/Planejamento](https://trello.com/b/CCl3Azxk/squad-18-idealizacao-planejamento)
---
## 📝 Changelog
### v2.0.0 (Outubro 2024)
- ✅ Migração completa de Netlify Functions para Supabase
- ✅ Implementação de recuperação de senha
- ✅ Deploy no Cloudflare Pages
- ✅ Novo HeroBanner com imagens rotativas
- ✅ Chatbot integrado
- ✅ Sistema de roles e permissões
- ✅ Interface responsiva e dark mode
### v1.0.0 (Setembro 2024)
- ✅ Lançamento inicial
- ✅ Login de pacientes, médicos e secretárias
- ✅ Agendamento de consultas
- ✅ Gestão de disponibilidade
---
## 📄 Licença
Este projeto é parte do programa Rise Up e está sob licença proprietária da PopCode.
---
**Desenvolvido com ❤️ pela Squad 18**