# 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 }) => { // Hooks const navigate = useNavigate(); const [state, setState] = useState(); // Effects useEffect(() => { // ... }, []); // Handlers const handleAction = async () => { // ... }; // Render return
{/* JSX */}
; }; export default ComponentName; ``` --- ## � 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**