import { Request, Response } from 'express'; import { supabase, findOneGpi, queryGpi } from '../config/supabase.js'; import { User } from '../lib/compat.js'; interface AuthRequest extends Request { appUser?: any; } export const syncUser = async (req: AuthRequest, res: Response) => { try { // Se já estiver autenticado pelo middleware, usa os dados do appUser if (req.appUser) { return res.json(req.appUser); } const { email, name, logto_id } = req.body; if (!email) { return res.status(400).json({ error: 'Email é obrigatório para sincronização.' }); } let user = await User.findOne({ email }); if (!user) { user = await User.create({ email, name: name || email.split('@')[0], logto_id, role: 'guest' }); } else if (logto_id && !user.logto_id) { user = await User.findByIdAndUpdate(user.id, { logto_id }); } res.json(user); } catch (error: any) { console.error('Error syncing user:', error); res.status(500).json({ error: 'Erro ao sincronizar usuário: ' + error.message }); } }; export const getCurrentUser = async (req: AuthRequest, res: Response) => { try { if (!req.appUser) { // Se o middleware não encontrou, tenta autenticar novamente aqui para garantir const user = await User.findOne({ id: (req as any).headers['x-user-id'] }); // Fallback opcional if (!user) { return res.status(404).json({ error: 'Usuário não autenticado ou não encontrado no banco.' }); } return res.json(user); } res.json(req.appUser); } catch (error: any) { console.error('Error getting current user:', error); res.status(500).json({ error: 'Erro ao buscar perfil do usuário.' }); } }; export const getAllUsers = async (req: Request, res: Response) => { try { const organizationId = req.headers['x-organization-id'] as string; if (!organizationId) { return res.status(400).json({ error: 'Organização não selecionada.' }); } const { data, error } = await supabase .from('user_organizations') .select('*, users(*)') .eq('organization_id', organizationId); if (error) throw error; res.json(data || []); } catch (error: any) { console.error('Error getting users:', error); res.status(500).json({ error: 'Erro ao buscar usuários.' }); } }; export const updateUserRole = async (req: AuthRequest, res: Response) => { try { const { id } = req.params; const { role } = req.body; if (!['guest', 'user', 'admin'].includes(role)) { return res.status(400).json({ error: 'Role inválido.' }); } const { data, error } = await supabase .from('user_organizations') .update({ role }) .eq('id', id) .select() .single(); if (error) throw error; res.json(data); } catch (error: any) { console.error('Error updating role:', error); res.status(500).json({ error: 'Erro ao alterar role.' }); } }; export const toggleBanUser = async (req: AuthRequest, res: Response) => { try { const { id } = req.params; const { isBanned } = req.body; const { data, error } = await supabase .from('user_organizations') .update({ is_banned: isBanned }) .eq('id', id) .select() .single(); if (error) throw error; res.json(data); } catch (error: any) { console.error('Error toggling ban:', error); res.status(500).json({ error: 'Erro ao alterar banimento.' }); } }; export const heartbeat = async (req: AuthRequest, res: Response) => { try { if (!req.appUser) { return res.status(401).json({ error: 'Não autenticado.' }); } await supabase .from('users') .update({ last_seen_at: new Date().toISOString() }) .eq('id', req.appUser.id); res.status(200).send(); } catch (error) { console.error('Heartbeat error:', error); res.status(500).send(); } }; export const getActiveUsers = async (req: AuthRequest, res: Response) => { try { const organizationId = req.headers['x-organization-id'] as string; if (!organizationId) { return res.status(400).json([]); } const twoMinutesAgo = new Date(Date.now() - 2 * 60 * 1000).toISOString(); const { data, error } = await supabase .from('users') .select('id, email, name, last_seen_at') .gte('last_seen_at', twoMinutesAgo); if (error) throw error; res.json(data || []); } catch (error: any) { console.error('Error getting active users:', error); res.status(500).json([]); } }; export const deleteUser = async (req: Request, res: Response) => { try { const { id } = req.params; const { error } = await supabase .from('user_organizations') .delete() .eq('id', id); if (error) throw error; res.json({ message: 'Membro removido com sucesso.' }); } catch (error: any) { console.error('Error deleting user:', error); res.status(500).json({ error: 'Erro ao remover membro.' }); } };