From 0e27dbf1ffbb170be659184c7e625fb099868fec Mon Sep 17 00:00:00 2001 From: guisilvagomes Date: Tue, 28 Oct 2025 10:41:28 -0300 Subject: [PATCH] =?UTF-8?q?chore:=20limpar=20arquivos=20de=20teste=20e=20d?= =?UTF-8?q?ocumenta=C3=A7=C3=A3o=20tempor=C3=A1ria?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MEDICONNECT 2/API-CONFIG.md | 315 ------------------ MEDICONNECT 2/add-fernando-patient.cjs | 76 ----- MEDICONNECT 2/create-aurora-appointment.cjs | 121 ------- .../create-fernando-availability.cjs | 91 ----- MEDICONNECT 2/create-fernando.cjs | 87 ----- .../create-patient-with-password.cjs | 78 ----- MEDICONNECT 2/fix-aurora-user-id.cjs | 72 ---- MEDICONNECT 2/get-aurora-info.cjs | 59 ---- MEDICONNECT 2/get-fernando-complete.cjs | 76 ----- MEDICONNECT 2/get-fernando-doctor-id.cjs | 78 ----- MEDICONNECT 2/get-fernando-user-id.cjs | 38 --- MEDICONNECT 2/search-fernando.cjs | 86 ----- MEDICONNECT 2/test-recovery-with-redirect.cjs | 54 --- README.md | 188 ++++++----- 14 files changed, 103 insertions(+), 1316 deletions(-) delete mode 100644 MEDICONNECT 2/API-CONFIG.md delete mode 100644 MEDICONNECT 2/add-fernando-patient.cjs delete mode 100644 MEDICONNECT 2/create-aurora-appointment.cjs delete mode 100644 MEDICONNECT 2/create-fernando-availability.cjs delete mode 100644 MEDICONNECT 2/create-fernando.cjs delete mode 100644 MEDICONNECT 2/create-patient-with-password.cjs delete mode 100644 MEDICONNECT 2/fix-aurora-user-id.cjs delete mode 100644 MEDICONNECT 2/get-aurora-info.cjs delete mode 100644 MEDICONNECT 2/get-fernando-complete.cjs delete mode 100644 MEDICONNECT 2/get-fernando-doctor-id.cjs delete mode 100644 MEDICONNECT 2/get-fernando-user-id.cjs delete mode 100644 MEDICONNECT 2/search-fernando.cjs delete mode 100644 MEDICONNECT 2/test-recovery-with-redirect.cjs diff --git a/MEDICONNECT 2/API-CONFIG.md b/MEDICONNECT 2/API-CONFIG.md deleted file mode 100644 index 50ca5d56c..000000000 --- a/MEDICONNECT 2/API-CONFIG.md +++ /dev/null @@ -1,315 +0,0 @@ -# Configuração das APIs - MediConnect - -## ✅ APIs Testadas e Funcionando - -### 1. Autenticação (Auth API) - -**Base URL:** `https://yuanqfswhberkoevtmfr.supabase.co/auth/v1` - -#### Endpoints Funcionais: - -- **Login** ✅ - - `POST /token?grant_type=password` - - Body: `{ email, password }` - - Retorna: `{ access_token, refresh_token, user }` - -- **Recuperação de Senha** ✅ - - `POST /recover` - - Body: `{ email, options: { redirectTo: url } }` - - Envia email com link de recuperação - -- **Atualizar Senha** ✅ - - `PUT /user` - - Headers: `Authorization: Bearer ` - - Body: `{ password: "nova_senha" }` - - **IMPORTANTE:** Nova senha deve ser diferente da anterior (erro 422 se for igual) - -### 2. REST API - -**Base URL:** `https://yuanqfswhberkoevtmfr.supabase.co/rest/v1` - -#### Tabelas e Campos Corretos: - -##### **appointments** ✅ -```typescript -{ - id: string (UUID) - order_number: string (auto-gerado: APT-YYYY-NNNN) - patient_id: string (UUID) - doctor_id: string (UUID) - scheduled_at: string (ISO 8601 DateTime) - duration_minutes: number - appointment_type: "presencial" | "telemedicina" - status: "requested" | "confirmed" | "checked_in" | "in_progress" | "completed" | "cancelled" | "no_show" - chief_complaint: string | null - patient_notes: string | null - notes: string | null - insurance_provider: string | null - checked_in_at: string | null - completed_at: string | null - cancelled_at: string | null - cancellation_reason: string | null - created_at: string - updated_at: string - created_by: string (UUID) - updated_by: string | null -} -``` - -**Criar Consulta:** -```bash -POST /rest/v1/appointments -Headers: - - apikey: - - Authorization: Bearer - - Content-Type: application/json - - Prefer: return=representation - -Body: -{ - "patient_id": "uuid", - "doctor_id": "uuid", - "scheduled_at": "2025-11-03T10:00:00.000Z", - "duration_minutes": 30, - "appointment_type": "presencial", - "chief_complaint": "Motivo da consulta" -} -``` - -##### **doctor_availability** ✅ -```typescript -{ - id: string (UUID) - doctor_id: string (UUID) - weekday: "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" - start_time: string (HH:MM:SS, ex: "07:00:00") - end_time: string (HH:MM:SS, ex: "19:00:00") - slot_duration_minutes: number (ex: 30) - appointment_type: "presencial" | "telemedicina" - is_active: boolean - created_at: string - updated_at: string - created_by: string (UUID) - updated_by: string | null -} -``` - -**Criar Disponibilidade:** -```bash -POST /rest/v1/doctor_availability -Headers: - - apikey: - - Authorization: Bearer - - Content-Type: application/json - - Prefer: return=representation - -Body: -{ - "doctor_id": "uuid", - "weekday": "monday", // ⚠️ Texto, não número! - "start_time": "07:00:00", - "end_time": "19:00:00", - "slot_duration_minutes": 30, - "appointment_type": "presencial", - "is_active": true, - "created_by": "admin_user_id" -} -``` - -##### **patients** ✅ -```typescript -{ - id: string (UUID) - user_id: string (UUID) // ⚠️ Deve estar vinculado ao auth.users - full_name: string - email: string - cpf: string - phone_mobile: string - // ... outros campos -} -``` - -**Atualizar Patient:** -```bash -PATCH /rest/v1/patients?id=eq. -Headers: - - apikey: - - Authorization: Bearer - - Content-Type: application/json - -Body: -{ - "user_id": "auth_user_id" -} -``` - -##### **doctors** ✅ -```typescript -{ - id: string (UUID) - user_id: string (UUID) - full_name: string - email: string - crm: string - crm_uf: string - specialty: string - // ... outros campos -} -``` - -### 3. Edge Functions - -**Base URL:** `https://yuanqfswhberkoevtmfr.supabase.co/functions/v1` - -#### Funcionais: - -- **create-user-with-password** ✅ - - `POST /functions/v1/create-user-with-password` - - Cria usuário com senha e perfil completo - - Body: - ```json - { - "email": "email@example.com", - "password": "senha123", - "full_name": "Nome Completo", - "phone_mobile": "(11) 99999-9999", - "cpf": "12345678900", - "create_patient_record": true, - "role": "paciente" - } - ``` - -#### Com Problemas: - -- **request-password-reset** ❌ - - CORS blocking - não usar - - Usar diretamente `/auth/v1/recover` em vez disso - -## 🔑 Chaves de API - -```typescript -SUPABASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co" -SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ" -``` - -## 👥 Usuários de Teste - -### Admin -- Email: `riseup@popcode.com.br` -- Senha: `riseup` - -### Dr. Fernando Pirichowski -- Email: `fernando.pirichowski@souunit.com.br` -- Senha: `fernando123` -- User ID: `38aca60d-7418-4c35-95b6-cb206bb18a0a` -- Doctor ID: `6dad001d-229b-40b5-80f3-310243c4599c` -- CRM: `24245` -- Disponibilidade: Segunda a Domingo, 07:00-19:00 - -### Aurora Sabrina Clara Nascimento (Paciente) -- Email: `aurora-nascimento94@gmx.com` -- Senha: `auroranasc94` -- User ID: `6dc15cc5-7dae-4b30-924a-a4b4fa142f24` -- Patient ID: `b85486f7-9135-4b67-9aa7-b884d9603d12` -- CPF: `66864784231` -- Telefone: `(21) 99856-3014` - -## ⚠️ Pontos de Atenção - -### 1. Weekday no doctor_availability -- ❌ **NÃO** usar números (0-6) -- ✅ **USAR** strings em inglês: `"sunday"`, `"monday"`, `"tuesday"`, `"wednesday"`, `"thursday"`, `"friday"`, `"saturday"` - -### 2. scheduled_at em appointments -- ❌ **NÃO** usar campos separados `appointment_date` e `appointment_time` -- ✅ **USAR** campo único `scheduled_at` com ISO 8601 DateTime -- Exemplo: `"2025-11-03T10:00:00.000Z"` - -### 3. user_id nas tabelas patients e doctors -- ⚠️ Sempre vincular ao `auth.users.id` -- Sem esse vínculo, queries por `user_id` não funcionam - -### 4. Senha na recuperação -- ⚠️ Nova senha DEVE ser diferente da anterior -- Erro 422 com `error_code: "same_password"` se tentar usar a mesma - -### 5. redirectTo no password recovery -- ⚠️ Supabase pode ignorar o parâmetro `redirectTo` -- ✅ Implementar detecção de token no lado do cliente -- Verificar tanto query string `?token=` quanto hash `#access_token=` - -## 📦 Estrutura de Serviços no Frontend - -```typescript -// Tudo configurado em: -src/services/api/config.ts // URLs e chaves -src/services/api/client.ts // Cliente axios -src/services/appointments/ // Serviço de consultas -src/services/availability/ // Disponibilidade médicos -src/services/auth/ // Autenticação -src/services/doctors/ // Médicos -src/services/patients/ // Pacientes -src/services/index.ts // Exportações centralizadas -``` - -## ✅ Status Atual - -- [x] Autenticação funcionando -- [x] Recuperação de senha funcionando -- [x] Criação de usuários funcionando -- [x] Criação de pacientes funcionando -- [x] Criação de disponibilidade médica funcionando -- [x] Criação de consultas funcionando -- [x] Vinculação user_id ↔ patient_id corrigida -- [x] Todos os serviços usando campos corretos - -## 🚀 Próximos Passos - -1. Testar agendamento completo no frontend -2. Verificar listagem de consultas -3. Testar cancelamento e atualização de consultas -4. Verificar notificações SMS -5. Testar fluxo completo de check-in e prontuário - -## 📝 Exemplos de Uso - -### Criar Consulta -```typescript -import { appointmentService } from '@/services'; - -const appointment = await appointmentService.create({ - patient_id: 'patient-uuid', - doctor_id: 'doctor-uuid', - scheduled_at: '2025-11-03T10:00:00.000Z', - duration_minutes: 30, - appointment_type: 'presencial', - chief_complaint: 'Consulta de rotina' -}); -``` - -### Criar Disponibilidade -```typescript -import { availabilityService } from '@/services'; - -const availability = await availabilityService.create({ - doctor_id: 'doctor-uuid', - weekday: 'monday', - start_time: '07:00:00', - end_time: '19:00:00', - slot_duration_minutes: 30, - appointment_type: 'presencial' -}); -``` - -### Login -```typescript -import { authService } from '@/services'; - -const response = await authService.login({ - email: 'user@example.com', - password: 'senha123' -}); - -// response.access_token - JWT token -// response.user - dados do usuário -``` diff --git a/MEDICONNECT 2/add-fernando-patient.cjs b/MEDICONNECT 2/add-fernando-patient.cjs deleted file mode 100644 index 8dfe8cf2f..000000000 --- a/MEDICONNECT 2/add-fernando-patient.cjs +++ /dev/null @@ -1,76 +0,0 @@ -const axios = require("axios"); - -const ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; -const BASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; - -(async () => { - try { - console.log("🔐 Fazendo login como admin..."); - const loginRes = await axios.post( - `${BASE_URL}/auth/v1/token?grant_type=password`, - { - email: "riseup@popcode.com.br", - password: "riseup", - }, - { - headers: { - "Content-Type": "application/json", - apikey: ANON_KEY, - }, - } - ); - - console.log("✅ Login admin bem-sucedido!\n"); - const token = loginRes.data.access_token; - - // Buscar o ID do Fernando no profiles - console.log("🔍 Buscando ID do Fernando..."); - const profileRes = await axios.get( - `${BASE_URL}/rest/v1/profiles?email=eq.fernando.pirichowski@souunit.com.br&select=*`, - { - headers: { - apikey: ANON_KEY, - Authorization: `Bearer ${token}`, - }, - } - ); - - if (profileRes.data.length === 0) { - console.log("❌ Fernando não encontrado no profiles"); - return; - } - - const fernandoId = profileRes.data[0].id; - console.log("✅ Fernando encontrado! ID:", fernandoId); - - // Criar entrada na tabela patients - console.log("\n📋 Criando entrada na tabela patients..."); - const patientRes = await axios.post( - `${BASE_URL}/rest/v1/patients`, - { - id: fernandoId, - email: "fernando.pirichowski@souunit.com.br", - full_name: "Fernando Pirichowski", - phone_mobile: "51999999999", - cpf: "12345678909", // CPF válido fictício - }, - { - headers: { - "Content-Type": "application/json", - apikey: ANON_KEY, - Authorization: `Bearer ${token}`, - Prefer: "return=representation", - }, - } - ); - - console.log("✅ Entrada na tabela patients criada!"); - console.log("\n🎉 Usuário Fernando Pirichowski completo!"); - console.log("📧 Email: fernando.pirichowski@souunit.com.br"); - console.log("🔑 Senha: fernando123"); - console.log("\n✨ Agora você pode testar a recuperação de senha!"); - } catch (err) { - console.error("❌ Erro:", err.response?.data || err.message); - } -})(); diff --git a/MEDICONNECT 2/create-aurora-appointment.cjs b/MEDICONNECT 2/create-aurora-appointment.cjs deleted file mode 100644 index f0d93a4e7..000000000 --- a/MEDICONNECT 2/create-aurora-appointment.cjs +++ /dev/null @@ -1,121 +0,0 @@ -const axios = require('axios'); - -const SUPABASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; -const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; - -async function createAppointment() { - try { - console.log('🔐 Fazendo login como Aurora...'); - - // Login como Aurora - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: 'aurora-nascimento94@gmx.com', - password: 'auroranasc94' - }, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Content-Type': 'application/json' - } - } - ); - - const auroraToken = loginResponse.data.access_token; - console.log('✅ Login realizado como Aurora'); - - // Buscar o patient_id da Aurora - console.log('\n👤 Buscando dados da paciente...'); - const patientResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?user_id=eq.${loginResponse.data.user.id}`, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${auroraToken}` - } - } - ); - - if (!patientResponse.data || patientResponse.data.length === 0) { - throw new Error('Paciente não encontrada'); - } - - const patientId = patientResponse.data[0].id; - console.log(`✅ Patient ID: ${patientId}`); - - // Buscar disponibilidade do Dr. Fernando para segunda-feira - console.log('\n📅 Buscando disponibilidade do Dr. Fernando...'); - const availabilityResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/doctor_availability?doctor_id=eq.6dad001d-229b-40b5-80f3-310243c4599c&weekday=eq.monday`, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${auroraToken}` - } - } - ); - - if (!availabilityResponse.data || availabilityResponse.data.length === 0) { - throw new Error('Disponibilidade não encontrada'); - } - - const availability = availabilityResponse.data[0]; - console.log(`✅ Disponibilidade encontrada: ${availability.start_time} - ${availability.end_time}`); - - // Criar consulta para próxima segunda-feira às 10:00 - const today = new Date(); - const daysUntilMonday = (1 - today.getDay() + 7) % 7 || 7; // Próxima segunda - const appointmentDate = new Date(today); - appointmentDate.setDate(today.getDate() + daysUntilMonday); - appointmentDate.setHours(10, 0, 0, 0); - - const scheduledAt = appointmentDate.toISOString(); - - console.log(`\n📝 Criando consulta para ${scheduledAt}...`); - - const appointmentData = { - patient_id: patientId, - doctor_id: '6dad001d-229b-40b5-80f3-310243c4599c', - scheduled_at: scheduledAt, - duration_minutes: 30, - appointment_type: 'presencial', - chief_complaint: 'Consulta de rotina' - }; - - const appointmentResponse = await axios.post( - `${SUPABASE_URL}/rest/v1/appointments`, - appointmentData, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${auroraToken}`, - 'Content-Type': 'application/json', - 'Prefer': 'return=representation' - } - } - ); - - console.log('\n✅ Consulta criada com sucesso!'); - console.log('\n📋 Detalhes da consulta:'); - console.log(` - Paciente: Aurora Sabrina Clara Nascimento`); - console.log(` - Médico: Dr. Fernando Pirichowski`); - console.log(` - Data/Hora: ${scheduledAt}`); - console.log(` - Duração: 30 minutos`); - console.log(` - Tipo: presencial`); - - if (appointmentResponse.data && appointmentResponse.data.length > 0) { - console.log(` - ID da consulta: ${appointmentResponse.data[0].id}`); - console.log(` - Order Number: ${appointmentResponse.data[0].order_number}`); - console.log(` - Status: ${appointmentResponse.data[0].status}`); - } - - } catch (error) { - console.error('❌ Erro ao criar consulta:', error.response?.data || error.message); - if (error.response?.data) { - console.error('Detalhes:', JSON.stringify(error.response.data, null, 2)); - } - } -} - -createAppointment(); diff --git a/MEDICONNECT 2/create-fernando-availability.cjs b/MEDICONNECT 2/create-fernando-availability.cjs deleted file mode 100644 index e47e5ef72..000000000 --- a/MEDICONNECT 2/create-fernando-availability.cjs +++ /dev/null @@ -1,91 +0,0 @@ -const axios = require('axios'); - -const SUPABASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; -const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; - -// IDs -const DOCTOR_ID = '6dad001d-229b-40b5-80f3-310243c4599c'; // Fernando (CRM 24245) -const ADMIN_ID = 'c7fcd702-9a6e-4b7c-abd3-956b25af407d'; // Admin (riseup) - -async function main() { - try { - console.log('🔐 Fazendo login como admin...'); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: 'riseup@popcode.com.br', - password: 'riseup' - }, - { - headers: { - 'Content-Type': 'application/json', - 'apikey': SUPABASE_ANON_KEY - } - } - ); - - const adminToken = loginResponse.data.access_token; - console.log('✅ Login realizado\n'); - - console.log('📅 Criando disponibilidade para Dr. Fernando...'); - console.log('⏰ Horário: 07:00 às 19:00'); - console.log('📆 Dias: Segunda a Domingo\n'); - - const weekdays = [ - { num: 'sunday', name: 'Domingo' }, - { num: 'monday', name: 'Segunda-feira' }, - { num: 'tuesday', name: 'Terça-feira' }, - { num: 'wednesday', name: 'Quarta-feira' }, - { num: 'thursday', name: 'Quinta-feira' }, - { num: 'friday', name: 'Sexta-feira' }, - { num: 'saturday', name: 'Sábado' } - ]; - - for (const day of weekdays) { - try { - const availabilityData = { - doctor_id: DOCTOR_ID, - weekday: day.num, - start_time: '07:00:00', - end_time: '19:00:00', - slot_minutes: 30, - appointment_type: 'presencial', - active: true, - created_by: ADMIN_ID - }; - - const response = await axios.post( - `${SUPABASE_URL}/rest/v1/doctor_availability`, - availabilityData, - { - headers: { - 'Content-Type': 'application/json', - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${adminToken}`, - 'Prefer': 'return=representation' - } - } - ); - - console.log(`✅ ${day.name}: Disponibilidade criada`); - - } catch (error) { - console.error(`❌ ${day.name}: Erro -`, error.response?.data?.message || error.message); - } - } - - console.log('\n🎉 Disponibilidade criada com sucesso!'); - console.log('\n📋 Resumo:'); - console.log('- Médico: Dr. Fernando Pirichowski'); - console.log('- Dias: Todos os dias da semana (Domingo a Sábado)'); - console.log('- Horário: 07:00 às 19:00'); - console.log('- Duração consulta: 30 minutos'); - console.log('- Tipo: Presencial'); - - } catch (error) { - console.error('❌ Erro geral:', error.response?.data || error.message); - } -} - -main(); diff --git a/MEDICONNECT 2/create-fernando.cjs b/MEDICONNECT 2/create-fernando.cjs deleted file mode 100644 index 83c5cfbef..000000000 --- a/MEDICONNECT 2/create-fernando.cjs +++ /dev/null @@ -1,87 +0,0 @@ -const axios = require("axios"); - -const ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; -const BASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; - -(async () => { - try { - console.log("🔐 Fazendo login como admin..."); - const loginRes = await axios.post( - `${BASE_URL}/auth/v1/token?grant_type=password`, - { - email: "riseup@popcode.com.br", - password: "riseup", - }, - { - headers: { - "Content-Type": "application/json", - apikey: ANON_KEY, - }, - } - ); - - console.log("✅ Login admin bem-sucedido!\n"); - const token = loginRes.data.access_token; - - console.log("👤 Criando usuário Fernando Pirichowski..."); - - // Criar usuário via signup - const signupRes = await axios.post( - `${BASE_URL}/auth/v1/signup`, - { - email: "fernando.pirichowski@souunit.com.br", - password: "fernando123", // Senha temporária - options: { - data: { - full_name: "Fernando Pirichowski", - phone: "51999999999", - }, - }, - }, - { - headers: { - "Content-Type": "application/json", - apikey: ANON_KEY, - }, - } - ); - - console.log("✅ Usuário criado com sucesso!"); - console.log("📧 Email:", signupRes.data.user.email); - console.log("🆔 ID:", signupRes.data.user.id); - console.log("🔑 Senha temporária: fernando123\n"); - - // Criar entrada na tabela patients - console.log("📋 Criando entrada na tabela patients..."); - const patientRes = await axios.post( - `${BASE_URL}/rest/v1/patients`, - { - id: signupRes.data.user.id, - email: "fernando.pirichowski@souunit.com.br", - full_name: "Fernando Pirichowski", - phone_mobile: "51999999999", - cpf: "12345678909", // CPF válido fictício - }, - { - headers: { - "Content-Type": "application/json", - apikey: ANON_KEY, - Authorization: `Bearer ${token}`, - Prefer: "return=representation", - }, - } - ); - - console.log("✅ Entrada na tabela patients criada!"); - console.log("\n🎉 Usuário Fernando Pirichowski criado com sucesso!"); - console.log("📧 Email: fernando.pirichowski@souunit.com.br"); - console.log("🔑 Senha: fernando123"); - console.log("\n💡 Agora você pode testar a recuperação de senha!"); - } catch (err) { - console.error("❌ Erro:", err.response?.data || err.message); - if (err.response?.data?.msg) { - console.error("Mensagem:", err.response.data.msg); - } - } -})(); diff --git a/MEDICONNECT 2/create-patient-with-password.cjs b/MEDICONNECT 2/create-patient-with-password.cjs deleted file mode 100644 index 68b003924..000000000 --- a/MEDICONNECT 2/create-patient-with-password.cjs +++ /dev/null @@ -1,78 +0,0 @@ -const axios = require('axios'); - -// Configuração -const SUPABASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; -const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; - -// Credenciais do admin -const ADMIN_EMAIL = 'riseup@popcode.com.br'; -const ADMIN_PASSWORD = 'riseup'; - -// Dados do paciente (Aurora Sabrina Clara Nascimento) -const PATIENT_DATA = { - email: 'aurora-nascimento94@gmx.com', - password: 'auroranasc94', - full_name: 'Aurora Sabrina Clara Nascimento', - phone_mobile: '(21) 99856-3014', - cpf: '66864784231', // CPF sem pontuação - create_patient_record: true, - role: 'paciente' -}; - -async function main() { - try { - console.log('🔐 1. Fazendo login como admin...'); - - // 1. Login do admin - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: ADMIN_EMAIL, - password: ADMIN_PASSWORD - }, - { - headers: { - 'Content-Type': 'application/json', - 'apikey': SUPABASE_ANON_KEY - } - } - ); - - const adminToken = loginResponse.data.access_token; - console.log('✅ Login realizado com sucesso!'); - console.log('🔑 Token:', adminToken.substring(0, 30) + '...'); - - console.log('\n👤 2. Criando paciente...'); - console.log('Dados:', JSON.stringify(PATIENT_DATA, null, 2)); - - // 2. Criar paciente - const createResponse = await axios.post( - `${SUPABASE_URL}/functions/v1/create-user-with-password`, - PATIENT_DATA, - { - headers: { - 'Content-Type': 'application/json', - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${adminToken}` - } - } - ); - - console.log('\n✅ Paciente criado com sucesso!'); - console.log('Resposta:', JSON.stringify(createResponse.data, null, 2)); - - if (createResponse.data.patient_id) { - console.log('\n📋 ID do paciente:', createResponse.data.patient_id); - console.log('✉️ Email de confirmação enviado para:', PATIENT_DATA.email); - console.log('🔐 Senha temporária:', PATIENT_DATA.password); - console.log('\n⚠️ O usuário precisa confirmar o email antes de fazer login!'); - } - - } catch (error) { - console.error('❌ Erro:', error.response?.data || error.message); - console.error('Status:', error.response?.status); - console.error('URL:', error.config?.url); - } -} - -main(); diff --git a/MEDICONNECT 2/fix-aurora-user-id.cjs b/MEDICONNECT 2/fix-aurora-user-id.cjs deleted file mode 100644 index b27e40ae8..000000000 --- a/MEDICONNECT 2/fix-aurora-user-id.cjs +++ /dev/null @@ -1,72 +0,0 @@ -const axios = require('axios'); - -const SUPABASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; -const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; - -async function fixAuroraUserId() { - try { - console.log('🔐 Fazendo login como admin...'); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: 'riseup@popcode.com.br', - password: 'riseup' - }, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Content-Type': 'application/json' - } - } - ); - - const adminToken = loginResponse.data.access_token; - console.log('✅ Login realizado'); - - // Fazer login como Aurora para pegar o user_id - console.log('\n👤 Fazendo login como Aurora...'); - const auroraLoginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: 'aurora-nascimento94@gmx.com', - password: 'auroranasc94' - }, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Content-Type': 'application/json' - } - } - ); - - const auroraUserId = auroraLoginResponse.data.user.id; - console.log(`✅ User ID da Aurora: ${auroraUserId}`); - - // Atualizar patient com user_id - console.log('\n📝 Atualizando registro da paciente...'); - const updateResponse = await axios.patch( - `${SUPABASE_URL}/rest/v1/patients?id=eq.b85486f7-9135-4b67-9aa7-b884d9603d12`, - { - user_id: auroraUserId - }, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${adminToken}`, - 'Content-Type': 'application/json', - 'Prefer': 'return=representation' - } - } - ); - - console.log('✅ Registro atualizado com sucesso!'); - console.log(` - Patient ID: b85486f7-9135-4b67-9aa7-b884d9603d12`); - console.log(` - User ID: ${auroraUserId}`); - - } catch (error) { - console.error('❌ Erro:', error.response?.data || error.message); - } -} - -fixAuroraUserId(); diff --git a/MEDICONNECT 2/get-aurora-info.cjs b/MEDICONNECT 2/get-aurora-info.cjs deleted file mode 100644 index 026052609..000000000 --- a/MEDICONNECT 2/get-aurora-info.cjs +++ /dev/null @@ -1,59 +0,0 @@ -const axios = require('axios'); - -const SUPABASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; -const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; - -async function main() { - try { - console.log('🔐 Fazendo login como admin...'); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: 'riseup@popcode.com.br', - password: 'riseup' - }, - { - headers: { - 'Content-Type': 'application/json', - 'apikey': SUPABASE_ANON_KEY - } - } - ); - - const adminToken = loginResponse.data.access_token; - console.log('✅ Login realizado\n'); - - console.log('👤 Buscando dados de Aurora na tabela patients...'); - - const patientsResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/patients?email=eq.aurora-nascimento94@gmx.com`, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${adminToken}` - } - } - ); - - if (patientsResponse.data.length > 0) { - const patient = patientsResponse.data[0]; - console.log('✅ Paciente encontrada!\n'); - console.log('📋 DADOS DA AURORA:\n'); - console.log('User ID (auth):', patient.id); - console.log('Patient ID:', patient.id); // Em patients, o id é o mesmo do auth - console.log('Nome:', patient.full_name); - console.log('Email:', patient.email); - console.log('CPF:', patient.cpf); - console.log('Telefone:', patient.phone_mobile); - console.log('\n📄 Dados completos:', JSON.stringify(patient, null, 2)); - } else { - console.log('❌ Paciente não encontrada na tabela patients'); - } - - } catch (error) { - console.error('❌ Erro:', error.response?.data || error.message); - } -} - -main(); diff --git a/MEDICONNECT 2/get-fernando-complete.cjs b/MEDICONNECT 2/get-fernando-complete.cjs deleted file mode 100644 index e4fd5b393..000000000 --- a/MEDICONNECT 2/get-fernando-complete.cjs +++ /dev/null @@ -1,76 +0,0 @@ -const axios = require('axios'); - -const SUPABASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; -const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; - -async function main() { - try { - console.log('🔐 Fazendo login como admin...'); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: 'riseup@popcode.com.br', - password: 'riseup' - }, - { - headers: { - 'Content-Type': 'application/json', - 'apikey': SUPABASE_ANON_KEY - } - } - ); - - const adminToken = loginResponse.data.access_token; - console.log('✅ Login realizado\n'); - - console.log('🔍 Buscando Fernando em profiles...'); - - const profilesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/profiles?email=eq.fernando.pirichowski@souunit.com.br`, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${adminToken}` - } - } - ); - - if (profilesResponse.data.length > 0) { - console.log(`✅ ${profilesResponse.data.length} perfil(is) encontrado(s)!\n`); - - profilesResponse.data.forEach((profile, index) => { - console.log(`📋 PERFIL ${index + 1}:\n`); - console.log('User ID:', profile.id); - console.log('Email:', profile.email); - console.log('Nome:', profile.full_name); - console.log('Telefone:', profile.phone || 'Não informado'); - console.log('\n' + '='.repeat(60) + '\n'); - }); - - // Pegar roles do primeiro perfil - const userId = profilesResponse.data[0].id; - console.log('🔍 Buscando roles...'); - - const rolesResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/user_roles?user_id=eq.${userId}`, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${adminToken}` - } - } - ); - - console.log('📌 Roles:', rolesResponse.data.map(r => r.role).join(', ')); - - } else { - console.log('❌ Nenhum perfil encontrado'); - } - - } catch (error) { - console.error('❌ Erro:', error.response?.data || error.message); - } -} - -main(); diff --git a/MEDICONNECT 2/get-fernando-doctor-id.cjs b/MEDICONNECT 2/get-fernando-doctor-id.cjs deleted file mode 100644 index c6544e4c0..000000000 --- a/MEDICONNECT 2/get-fernando-doctor-id.cjs +++ /dev/null @@ -1,78 +0,0 @@ -const axios = require('axios'); - -const SUPABASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; -const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; - -async function main() { - try { - console.log('🔐 Fazendo login como admin...'); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: 'riseup@popcode.com.br', - password: 'riseup' - }, - { - headers: { - 'Content-Type': 'application/json', - 'apikey': SUPABASE_ANON_KEY - } - } - ); - - const adminToken = loginResponse.data.access_token; - console.log('✅ Login realizado\n'); - - console.log('👨‍⚕️ Buscando dados de Fernando na tabela doctors...'); - - const doctorsResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/doctors?email=eq.fernando.pirichowski@souunit.com.br`, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${adminToken}`, - 'Prefer': 'return=representation' - } - } - ); - - if (doctorsResponse.data.length > 0) { - console.log(`✅ ${doctorsResponse.data.length} médico(s) encontrado(s)!\n`); - - doctorsResponse.data.forEach((doctor, index) => { - console.log(`📋 MÉDICO ${index + 1}:\n`); - console.log('Doctor ID:', doctor.id); - console.log('Nome:', doctor.full_name); - console.log('Email:', doctor.email); - console.log('CRM:', doctor.crm); - console.log('Especialidade:', doctor.specialty || 'Não informada'); - console.log('Telefone:', doctor.phone || 'Não informado'); - console.log('\n' + '='.repeat(60) + '\n'); - }); - } else { - console.log('❌ Nenhum médico chamado Fernando encontrado'); - console.log('\n🔍 Buscando todos os médicos...'); - - const allDoctorsResponse = await axios.get( - `${SUPABASE_URL}/rest/v1/doctors`, - { - headers: { - 'apikey': SUPABASE_ANON_KEY, - 'Authorization': `Bearer ${adminToken}` - } - } - ); - - console.log(`\n📊 Total de médicos cadastrados: ${allDoctorsResponse.data.length}`); - allDoctorsResponse.data.forEach((doctor, index) => { - console.log(`${index + 1}. ${doctor.full_name} - ${doctor.email}`); - }); - } - - } catch (error) { - console.error('❌ Erro:', error.response?.data || error.message); - } -} - -main(); diff --git a/MEDICONNECT 2/get-fernando-user-id.cjs b/MEDICONNECT 2/get-fernando-user-id.cjs deleted file mode 100644 index 6d181c64d..000000000 --- a/MEDICONNECT 2/get-fernando-user-id.cjs +++ /dev/null @@ -1,38 +0,0 @@ -const axios = require('axios'); - -const SUPABASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; -const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; - -async function main() { - try { - console.log('🔐 Fazendo login como Fernando...'); - - const loginResponse = await axios.post( - `${SUPABASE_URL}/auth/v1/token?grant_type=password`, - { - email: 'fernando.pirichowski@souunit.com.br', - password: 'fernando123' - }, - { - headers: { - 'Content-Type': 'application/json', - 'apikey': SUPABASE_ANON_KEY - } - } - ); - - const userData = loginResponse.data; - console.log('✅ Login realizado\n'); - - console.log('📋 DADOS DO FERNANDO (AUTH):\n'); - console.log('User ID:', userData.user.id); - console.log('Email:', userData.user.email); - console.log('Role:', userData.user.role); - console.log('\n' + '='.repeat(60)); - - } catch (error) { - console.error('❌ Erro:', error.response?.data || error.message); - } -} - -main(); diff --git a/MEDICONNECT 2/search-fernando.cjs b/MEDICONNECT 2/search-fernando.cjs deleted file mode 100644 index 11067f49b..000000000 --- a/MEDICONNECT 2/search-fernando.cjs +++ /dev/null @@ -1,86 +0,0 @@ -const axios = require('axios'); - -const ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ'; -const BASE_URL = 'https://yuanqfswhberkoevtmfr.supabase.co'; - -(async () => { - try { - console.log('🔐 Fazendo login como admin...'); - const loginRes = await axios.post(`${BASE_URL}/auth/v1/token?grant_type=password`, { - email: 'riseup@popcode.com.br', - password: 'riseup' - }, { - headers: { - 'Content-Type': 'application/json', - 'apikey': ANON_KEY - } - }); - - console.log('✅ Login admin bem-sucedido!\n'); - const token = loginRes.data.access_token; - - console.log('🔍 Buscando usuário fernando na tabela profiles...'); - const profilesRes = await axios.get(`${BASE_URL}/rest/v1/profiles?select=*`, { - headers: { - 'apikey': ANON_KEY, - 'Authorization': `Bearer ${token}` - } - }); - - console.log(`📊 Total de profiles: ${profilesRes.data.length}\n`); - - const fernandoProfile = profilesRes.data.find(u => - u.email && ( - u.email.toLowerCase().includes('fernando') || - u.full_name?.toLowerCase().includes('fernando') - ) - ); - - if (fernandoProfile) { - console.log('✅ Fernando encontrado na tabela profiles:'); - console.log(JSON.stringify(fernandoProfile, null, 2)); - } else { - console.log('❌ Fernando NÃO encontrado na tabela profiles\n'); - } - - // Buscar nos pacientes também - console.log('\n🔍 Buscando fernando na tabela patients...'); - const patientsRes = await axios.get(`${BASE_URL}/rest/v1/patients?select=*`, { - headers: { - 'apikey': ANON_KEY, - 'Authorization': `Bearer ${token}` - } - }); - - console.log(`📊 Total de patients: ${patientsRes.data.length}\n`); - - const fernandoPatient = patientsRes.data.find(p => - p.email && ( - p.email.toLowerCase().includes('fernando') || - p.full_name?.toLowerCase().includes('fernando') - ) - ); - - if (fernandoPatient) { - console.log('✅ Fernando encontrado na tabela patients:'); - console.log(JSON.stringify(fernandoPatient, null, 2)); - } else { - console.log('❌ Fernando NÃO encontrado na tabela patients\n'); - } - - // Listar alguns emails para referência - if (!fernandoProfile && !fernandoPatient) { - console.log('\n📧 Alguns emails cadastrados nos profiles:'); - profilesRes.data.slice(0, 10).forEach((u, i) => { - if (u.email) console.log(` ${i+1}. ${u.email} - ${u.full_name || 'sem nome'}`); - }); - } - - } catch (err) { - console.error('❌ Erro:', err.response?.data || err.message); - if (err.response) { - console.error('Status:', err.response.status); - console.error('Headers:', err.response.headers); - } - } -})(); diff --git a/MEDICONNECT 2/test-recovery-with-redirect.cjs b/MEDICONNECT 2/test-recovery-with-redirect.cjs deleted file mode 100644 index 92db618ed..000000000 --- a/MEDICONNECT 2/test-recovery-with-redirect.cjs +++ /dev/null @@ -1,54 +0,0 @@ -const axios = require("axios"); - -const ANON_KEY = - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ"; -const BASE_URL = "https://yuanqfswhberkoevtmfr.supabase.co"; - -(async () => { - try { - console.log("\n=== TESTE DE RECUPERAÇÃO COM REDIRECT_TO CORRETO ===\n"); - - const email = "fernando.pirichowski@souunit.com.br"; - const redirectTo = "https://mediconnectbrasil.app/reset-password"; - - console.log(`📧 Enviando email de recuperação para: ${email}`); - console.log(`🔗 Redirect URL: ${redirectTo}\n`); - - const response = await axios.post( - `${BASE_URL}/auth/v1/recover`, - { - email: email, - options: { - redirectTo: redirectTo, - }, - }, - { - headers: { - "Content-Type": "application/json", - apikey: ANON_KEY, - }, - } - ); - - console.log("✅ Email de recuperação enviado com sucesso!"); - console.log("Status:", response.status); - console.log("Response:", JSON.stringify(response.data, null, 2)); - - console.log("\n📬 Verifique o email:", email); - console.log("🔗 O link DEVE redirecionar para:", redirectTo); - console.log("\n💡 IMPORTANTE: Se ainda vier o link errado, você precisa:"); - console.log(" 1. Acessar o painel do Supabase"); - console.log(" 2. Ir em Authentication > URL Configuration"); - console.log( - ' 3. Atualizar o "Site URL" para: https://mediconnectbrasil.app' - ); - console.log( - ' 4. Adicionar https://mediconnectbrasil.app/* nos "Redirect URLs"' - ); - - console.log("\n=== TESTE CONCLUÍDO ===\n"); - } catch (error) { - console.error("❌ Erro ao enviar email de recuperação:"); - console.error(error.response?.data || error.message); - } -})(); diff --git a/README.md b/README.md index 85960df20..5da65b346 100644 --- a/README.md +++ b/README.md @@ -61,12 +61,14 @@ O MediConnect é uma plataforma web que conecta **pacientes**, **médicos** e ** ### 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 @@ -81,6 +83,7 @@ O MediConnect é uma plataforma web que conecta **pacientes**, **médicos** e ** ## 🛠️ Tecnologias ### Frontend + - **React** 18.3.1 - Biblioteca UI - **TypeScript** 5.9.3 - Tipagem estática - **Vite** 7.1.10 - Build tool @@ -91,11 +94,13 @@ O MediConnect é uma plataforma web que conecta **pacientes**, **médicos** e ** - **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 @@ -187,106 +192,112 @@ export const API_CONFIG = { STORAGE_KEYS: { ACCESS_TOKEN: "mediconnect_access_token", REFRESH_TOKEN: "mediconnect_refresh_token", - USER: "mediconnect_user" - } -} + USER: "mediconnect_user", + }, +}; ``` ### Serviços Disponíveis #### 1. **authService** - Autenticação + ```typescript // Login -await authService.login({ email, password }) +await authService.login({ email, password }); // Registro -await authService.signup({ email, password, full_name }) +await authService.signup({ email, password, full_name }); // Logout -await authService.logout() +await authService.logout(); // Recuperação de senha -await authService.requestPasswordReset(email) -await authService.updatePassword(accessToken, newPassword) +await authService.requestPasswordReset(email); +await authService.updatePassword(accessToken, newPassword); // Refresh token -await authService.refreshToken(refreshToken) +await authService.refreshToken(refreshToken); ``` #### 2. **userService** - Usuários + ```typescript // Buscar informações do usuário autenticado -const userInfo = await userService.getUserInfo() +const userInfo = await userService.getUserInfo(); // Criar usuário com role -await userService.createUser({ email, full_name, role }) +await userService.createUser({ email, full_name, role }); // Deletar usuário -await userService.deleteUser(userId) +await userService.deleteUser(userId); ``` #### 3. **patientService** - Pacientes + ```typescript // Listar pacientes -const patients = await patientService.list() +const patients = await patientService.list(); // Buscar por ID -const patient = await patientService.getById(id) +const patient = await patientService.getById(id); // Criar paciente -await patientService.create({ email, full_name, cpf, phone }) +await patientService.create({ email, full_name, cpf, phone }); // Atualizar -await patientService.update(id, data) +await patientService.update(id, data); // Registrar paciente (público) -await patientService.register({ email, full_name, cpf }) +await patientService.register({ email, full_name, cpf }); ``` #### 4. **doctorService** - Médicos + ```typescript // Listar médicos -const doctors = await doctorService.list() +const doctors = await doctorService.list(); // Buscar por ID -const doctor = await doctorService.getById(id) +const doctor = await doctorService.getById(id); // Buscar disponibilidade -const slots = await doctorService.getAvailableSlots(doctorId, date) +const slots = await doctorService.getAvailableSlots(doctorId, date); ``` #### 5. **appointmentService** - Consultas + ```typescript // Listar consultas -const appointments = await appointmentService.list() +const appointments = await appointmentService.list(); // Criar consulta await appointmentService.create({ patient_id, doctor_id, scheduled_at, - reason -}) + reason, +}); // Atualizar status -await appointmentService.updateStatus(id, status) +await appointmentService.updateStatus(id, status); // Cancelar -await appointmentService.cancel(id, reason) +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 -}) + end_time, +}); // Listar disponibilidade -const slots = await availabilityService.listByDoctor(doctorId) +const slots = await availabilityService.listByDoctor(doctorId); ``` --- @@ -296,61 +307,65 @@ const slots = await availabilityService.listByDoctor(doctorId) ### Fluxo de Autenticação 1. **Login** + ```typescript // 1. Usuário envia credenciais -const response = await authService.login({ email, password }) +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) +localStorage.setItem("access_token", response.access_token); +localStorage.setItem("refresh_token", response.refresh_token); // 3. Busca informações completas -const userInfo = await userService.getUserInfo() +const userInfo = await userService.getUserInfo(); // 4. Valida roles -if (userInfo.roles.includes('medico')) { - navigate('/painel-medico') +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') +axios.interceptors.request.use((config) => { + const token = localStorage.getItem("access_token"); if (token) { - config.headers.Authorization = `Bearer ${token}` + config.headers.Authorization = `Bearer ${token}`; } - return config -}) + return config; +}); ``` 3. **Refresh Token Automático** + ```typescript axios.interceptors.response.use( - response => response, - async error => { + (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) + 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 | +| 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 ``` @@ -397,26 +412,26 @@ sequenceDiagram // LoginMedico.tsx const handleLogin = async () => { // 1. Login - const loginResponse = await authService.login({ email, password }) - + const loginResponse = await authService.login({ email, password }); + // 2. Buscar roles - const userInfo = await userService.getUserInfo() - const roles = userInfo.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') - + 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 + toast.error("Você não tem permissão para acessar esta área"); + await authService.logout(); + return; } - + // 4. Redirecionar - navigate('/painel-medico') -} + navigate("/painel-medico"); +}; ``` --- @@ -462,7 +477,7 @@ npx wrangler pages deploy dist --project-name=mediconnect --commit-dirty=true ### Pré-requisitos -- Node.js 18+ +- Node.js 18+ - pnpm 8+ - Git @@ -522,6 +537,7 @@ VITE_APP_URL=http://localhost:5173 ### Tabelas Principais #### `profiles` + ```sql - id (uuid, PK) - email (text, unique) @@ -532,6 +548,7 @@ VITE_APP_URL=http://localhost:5173 ``` #### `patients` + ```sql - id (uuid, PK, FK -> profiles) - email (text, unique) @@ -544,6 +561,7 @@ VITE_APP_URL=http://localhost:5173 ``` #### `doctors` + ```sql - id (uuid, PK, FK -> profiles) - email (text, unique) @@ -555,6 +573,7 @@ VITE_APP_URL=http://localhost:5173 ``` #### `appointments` + ```sql - id (uuid, PK) - patient_id (uuid, FK -> patients) @@ -567,6 +586,7 @@ VITE_APP_URL=http://localhost:5173 ``` #### `user_roles` + ```sql - user_id (uuid, FK -> profiles) - role (text: admin, gestor, medico, secretaria, paciente) @@ -621,9 +641,9 @@ node search-fernando.cjs ```typescript // Imports -import React, { useState, useEffect } from "react" -import { useNavigate } from "react-router-dom" -import { serviceImport } from "../services" +import React, { useState, useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { serviceImport } from "../services"; // Types interface Props { @@ -633,28 +653,24 @@ interface Props { // Component const ComponentName: React.FC = ({ ...props }) => { // Hooks - const navigate = useNavigate() - const [state, setState] = useState() - + const navigate = useNavigate(); + const [state, setState] = useState(); + // Effects useEffect(() => { // ... - }, []) - + }, []); + // Handlers const handleAction = async () => { // ... - } - - // Render - return ( -
- {/* JSX */} -
- ) -} + }; -export default ComponentName + // Render + return
{/* JSX */}
; +}; + +export default ComponentName; ``` --- @@ -670,6 +686,7 @@ export default ComponentName ## 📝 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 @@ -679,6 +696,7 @@ export default ComponentName - ✅ Interface responsiva e dark mode ### v1.0.0 (Setembro 2024) + - ✅ Lançamento inicial - ✅ Login de pacientes, médicos e secretárias - ✅ Agendamento de consultas