import sys from pathlib import Path # Adicionar o diretório raiz ao PYTHONPATH root_dir = Path(__file__).parent.parent sys.path.append(str(root_dir)) import streamlit as st import pandas as pd from user_manager import UserManager from supabase_conex import SupabaseConnection from datetime import datetime from assistentes import CriaAssistente, AssistenteConfig def create_admin_user(email: str, password: str, nome: str, is_admin: bool = False): """Cria um novo usuário diretamente""" try: # Usar admin client para ter permissões totais admin_client = SupabaseConnection().get_admin_client() # 1. Criar usuário na auth auth_response = admin_client.auth.admin.create_user({ "email": email, "password": password, "email_confirm": True, "user_metadata": { "nome": nome, "is_admin": is_admin } }) # Debug detalhado print("\n=== Debug Auth Response ===") print(f"Tipo: {type(auth_response)}") print(f"Dir: {dir(auth_response)}") print(f"Raw: {auth_response}") if not auth_response: raise Exception("Falha na criação da autenticação") # Tentar diferentes formas de acessar o ID user_id = None if hasattr(auth_response, 'user'): user_id = auth_response.user.id elif hasattr(auth_response, 'id'): user_id = auth_response.id else: # Último recurso: converter para dict auth_dict = auth_response.model_dump() if hasattr(auth_response, 'model_dump') else vars(auth_response) print(f"Auth Dict: {auth_dict}") user_id = auth_dict.get('id') or auth_dict.get('user', {}).get('id') if not user_id: raise Exception("Não foi possível obter o ID do usuário") # 2. Inserir dados na tabela public.users user_data = { "id": user_id, "email": email, "nome": nome, "is_admin": is_admin, "created_at": datetime.utcnow().isoformat(), "updated_at": datetime.utcnow().isoformat(), "is_active": True } response = admin_client.from_('users')\ .insert(user_data)\ .execute() return response.data[0] except Exception as e: print(f"\n=== Erro Detalhado ===") print(f"Tipo do erro: {type(e)}") print(f"Mensagem: {str(e)}") import traceback print(f"Traceback:\n{traceback.format_exc()}") raise Exception(f"Erro ao criar usuário: {str(e)}") def delete_user(user_id: str): """Deleta um usuário do sistema""" try: admin_client = SupabaseConnection().get_admin_client() # 1. Deletar da tabela users primeiro response = admin_client.from_('users')\ .delete()\ .eq('id', user_id)\ .execute() # 2. Deletar da autenticação auth_response = admin_client.auth.admin.delete_user(user_id) return True except Exception as e: print(f"\n=== Erro ao deletar usuário ===") print(f"Tipo do erro: {type(e)}") print(f"Mensagem: {str(e)}") import traceback print(f"Traceback:\n{traceback.format_exc()}") raise Exception(f"Erro ao deletar usuário: {str(e)}") def create_user(email: str, password: str, nome: str): """Cria um novo usuário e seu assistente""" try: # 1. Criar usuário no Supabase user = create_admin_user( email=email, password=password, nome=nome, is_admin=False ) # 2. Criar assistente no Pinecone safe_name = "".join(c for c in nome if c.isalnum() or c.isspace()).strip() safe_name = safe_name.lower().replace(" ", "-") assistant_name = f"assistant-{safe_name}-{user['id'][:8]}" config = AssistenteConfig( nome=assistant_name, instrucoes="Você é uma assistente amigável que responde perguntas do usuário. Responda sempre em português do Brasil." ) try: criador = CriaAssistente() assistente = criador.criar(config) # 3. Atualizar usuário com referências do assistente admin_client = SupabaseConnection().get_admin_client() response = admin_client.from_('users')\ .update({ "assistant_name": assistant_name # Salvando apenas o nome })\ .eq('id', user['id'])\ .execute() st.success(f"✅ Usuário {nome} criado com sucesso!") st.success(f"✅ Assistente '{assistant_name}' criado com sucesso!") return response.data[0] except Exception as e: st.error(f"❌ Erro ao criar assistente: {str(e)}") delete_user(user['id']) raise except Exception as e: st.error(f"❌ Erro ao criar usuário: {str(e)}") raise def main(): st.set_page_config(page_title="Cadastro de Usuários", page_icon="👤") st.title("👤 Cadastro de Usuários") st.markdown("### Área Administrativa") # Formulário de cadastro with st.form("admin_cadastro_form"): nome = st.text_input("Nome completo", help="Digite o nome completo do usuário") email = st.text_input("Email", help="Digite o email do usuário") password = st.text_input("Senha", type="password", help="Mínimo 6 caracteres") confirm_password = st.text_input("Confirmar senha", type="password") is_admin = st.checkbox("👑 Usuário Administrador") if st.form_submit_button("Criar Usuário"): try: # Validações if not all([nome, email, password, confirm_password]): st.error("❌ Todos os campos são obrigatórios!") st.stop() if password != confirm_password: st.error("❌ As senhas não coincidem!") st.stop() if len(password) < 6: st.error("❌ A senha deve ter no mínimo 6 caracteres!") st.stop() # Criar usuário user = create_user( email=email, password=password, nome=nome ) st.json(user) # Mostra os dados do usuário criado except Exception as e: st.error(f"❌ Erro ao criar usuário: {str(e)}") # Lista de usuários existentes st.markdown("---") st.subheader("📋 Usuários Cadastrados") try: admin_client = SupabaseConnection().get_admin_client() response = admin_client.from_('users').select('*').execute() if response.data: # Criar DataFrame com os dados df = pd.DataFrame(response.data) # Mostrar tabela st.dataframe( df, column_config={ "nome": "Nome", "email": "Email", "is_admin": "Admin", "is_active": "Ativo", "created_at": "Criado em" }, hide_index=True ) # Seleção de usuário para deletar usuarios = [(f"{u['nome']} ({u['email']})", u['id']) for u in response.data] selected_user = st.selectbox( "Selecione um usuário para deletar:", options=usuarios, format_func=lambda x: x[0] ) # Botão de deletar com confirmação if st.button("🗑️ Deletar Usuário"): if st.session_state.get('is_admin'): # Verifica se é admin user_id = selected_user[1] # Confirmação adicional if st.warning(f"⚠️ Tem certeza que deseja deletar este usuário? Esta ação não pode ser desfeita."): try: delete_user(user_id) st.success("✅ Usuário deletado com sucesso!") st.rerun() # Atualiza a página except Exception as e: st.error(f"❌ Erro ao deletar usuário: {str(e)}") else: st.error("❌ Apenas administradores podem deletar usuários!") else: st.info("Nenhum usuário cadastrado.") except Exception as e: st.error(f"❌ Erro ao listar usuários: {str(e)}") if __name__ == "__main__": main()