/** * Serviço de Usuários */ import axios from "axios"; import { apiClient } from "../api/client"; import { API_CONFIG } from "../api/config"; import type { UserRoleRecord, UserInfo, User, CreateUserInput, CreateUserResponse, CreateDoctorInput, CreateDoctorResponse, CreatePatientInput, CreatePatientResponse, } from "./types"; class UserService { /** * Lista roles de usuários */ async listRoles(): Promise { const response = await apiClient.get("/user_roles"); return response.data; } /** * Obtém informações completas do usuário autenticado * Inclui perfil, roles e permissões calculadas */ async getUserInfo(): Promise { const token = localStorage.getItem(API_CONFIG.STORAGE_KEYS.ACCESS_TOKEN); if (!token) { throw new Error("Token não encontrado"); } const response = await axios.post( `${API_CONFIG.FUNCTIONS_URL}/user-info`, {}, { headers: { "Content-Type": "application/json", apikey: API_CONFIG.SUPABASE_ANON_KEY, Authorization: `Bearer ${token}`, }, } ); return response.data; } /** * Obtém dados básicos do usuário autenticado */ async getCurrentUser(): Promise { const token = localStorage.getItem(API_CONFIG.STORAGE_KEYS.ACCESS_TOKEN); if (!token) { throw new Error("Token não encontrado"); } const response = await axios.get(`${API_CONFIG.AUTH_URL}/user`, { headers: { "Content-Type": "application/json", apikey: API_CONFIG.SUPABASE_ANON_KEY, Authorization: `Bearer ${token}`, }, }); return response.data; } /** * Cria novo usuário no sistema * Pode ser chamado COM ou SEM autenticação: * - SEM autenticação: usa signup nativo (/auth/v1/signup) - PÚBLICO * - COM autenticação: usa Edge Function (/functions/v1/create-user) - ADMIN */ async createUser( data: CreateUserInput, isPublicRegistration: boolean = true ): Promise { // Registro público: usar endpoint nativo do Supabase if (isPublicRegistration) { const response = await axios.post<{ user: User; session: { access_token: string; refresh_token: string }; }>( `${API_CONFIG.AUTH_URL}/signup`, { email: data.email, password: data.password, options: { data: { full_name: data.full_name, phone: data.phone, }, }, }, { headers: { "Content-Type": "application/json", apikey: API_CONFIG.SUPABASE_ANON_KEY, }, } ); return { success: true, user: { id: response.data.user.id, email: response.data.user.email, full_name: data.full_name, phone: data.phone || null, roles: [data.role], }, message: "Usuário criado com sucesso", }; } // Criação por admin: usar Edge Function const token = localStorage.getItem(API_CONFIG.STORAGE_KEYS.ACCESS_TOKEN); const response = await axios.post( `${API_CONFIG.FUNCTIONS_URL}/create-user`, data, { headers: { "Content-Type": "application/json", apikey: API_CONFIG.SUPABASE_ANON_KEY, Authorization: `Bearer ${token}`, }, } ); return response.data; } /** * Adiciona uma role a um usuário * Requer permissão de admin */ async addUserRole(userId: string, role: string): Promise { const response = await apiClient.post("/user_roles", { user_id: userId, role: role, }); return response.data; } /** * Remove uma role de um usuário * Requer permissão de admin */ async removeUserRole(userId: string, role: string): Promise { await apiClient.delete(`/user_roles?user_id=eq.${userId}&role=eq.${role}`); } /** * Cria novo médico no sistema (endpoint especializado) * Cria: Auth user + Profile + Role medico + Entrada completa em doctors * Obrigatório: crm, crm_uf, cpf, full_name, email * Validações: CRM válido, CPF válido, UF válido * Use quando tiver TODOS os dados do médico */ async createDoctor(data: CreateDoctorInput): Promise { const token = localStorage.getItem(API_CONFIG.STORAGE_KEYS.ACCESS_TOKEN); const url = `${API_CONFIG.FUNCTIONS_URL}/create-doctor`; console.log("[userService.createDoctor] URL:", url); console.log("[userService.createDoctor] Data:", data); const response = await axios.post( url, data, { headers: { "Content-Type": "application/json", apikey: API_CONFIG.SUPABASE_ANON_KEY, Authorization: `Bearer ${token}`, }, } ); return response.data; } /** * Cria novo paciente no sistema (endpoint especializado) * Cria: Auth user + Profile + Role paciente + Entrada completa em patients * Obrigatório: cpf, full_name, email, phone_mobile * Validações: CPF válido, telefone válido * Use quando tiver TODOS os dados do paciente */ async createPatient( data: CreatePatientInput ): Promise { const token = localStorage.getItem(API_CONFIG.STORAGE_KEYS.ACCESS_TOKEN); const url = `${API_CONFIG.FUNCTIONS_URL}/create-patient`; console.log("[userService.createPatient] URL:", url); console.log("[userService.createPatient] Data:", data); const response = await axios.post( url, data, { headers: { "Content-Type": "application/json", apikey: API_CONFIG.SUPABASE_ANON_KEY, Authorization: `Bearer ${token}`, }, } ); return response.data; } /** * Cria usuário com email e senha (alternativa ao Magic Link) * POST /functions/v1/create-user-with-password * Requer permissão de admin, gestor ou secretaria * O usuário precisa confirmar o email antes de fazer login */ async createUserWithPassword(data: { email: string; password: string; full_name: string; phone?: string; role: string; create_patient_record?: boolean; cpf?: string; phone_mobile?: string; }): Promise<{ success: boolean; user: { id: string; email: string; full_name: string; roles: string[]; email_confirmed_at: string | null; patient_id?: string; }; message: string; }> { const token = localStorage.getItem(API_CONFIG.STORAGE_KEYS.ACCESS_TOKEN); const response = await axios.post( `${API_CONFIG.FUNCTIONS_URL}/create-user-with-password`, data, { headers: { "Content-Type": "application/json", apikey: API_CONFIG.SUPABASE_ANON_KEY, Authorization: `Bearer ${token}`, }, } ); return response.data; } /** * Deleta usuário permanentemente (Hard Delete) * POST /delete-user * ⚠️ OPERAÇÃO IRREVERSÍVEL! Use apenas em desenvolvimento/QA * Requer permissão de admin ou gestor * Deleta em cascata: profiles, user_roles, doctors, patients, etc. */ async deleteUser(userId: string): Promise<{ success: boolean; message: string; userId: string; }> { const token = localStorage.getItem(API_CONFIG.STORAGE_KEYS.ACCESS_TOKEN); const response = await axios.post<{ success: boolean; message: string; userId: string; }>( `${API_CONFIG.FUNCTIONS_URL}/delete-user`, { userId }, { headers: { "Content-Type": "application/json", apikey: API_CONFIG.SUPABASE_ANON_KEY, Authorization: `Bearer ${token}`, }, } ); return response.data; } /** * Obtém informações de usuário por ID * POST /functions/v1/user-info-by-id * Requer permissão de admin ou gestor */ async getUserInfoById(userId: string): Promise { const token = localStorage.getItem(API_CONFIG.STORAGE_KEYS.ACCESS_TOKEN); if (!token) { throw new Error("Token não encontrado"); } const response = await axios.post( `${API_CONFIG.FUNCTIONS_URL}/user-info-by-id`, { user_id: userId }, { headers: { "Content-Type": "application/json", apikey: API_CONFIG.SUPABASE_ANON_KEY, Authorization: `Bearer ${token}`, }, } ); return response.data; } } export const userService = new UserService();