import { Request, Response } from 'express'; import SystemSettings from '../models/SystemSettings.js'; import User from '../models/User.js'; import OrganizationMember from '../models/OrganizationMember.js'; import Organization from '../models/Organization.js'; import path from 'path'; import fs from 'fs'; import os from 'os'; export const getSettings = async (req: Request, res: Response) => { try { let settings = await SystemSettings.findOne({ settingsId: 'global' }); if (!settings) { // Create default if not exists settings = await SystemSettings.create({ settingsId: 'global', appName: 'GPI', appSubtitle: 'Gestão de Pintura Industrial' }); } res.json(settings); } catch (error) { console.error('Error fetching system settings:', error); res.status(500).json({ error: 'Erro ao buscar configurações do sistema' }); } }; export const updateSettings = async (req: Request, res: Response) => { try { const { appName, appSubtitle, appLogoUrl } = req.body; const settings = await SystemSettings.findOneAndUpdate( { settingsId: 'global' }, { appName, appSubtitle, appLogoUrl, updatedBy: req.appUser?.email }, { new: true, upsert: true } // Create if not exists ); console.log(`⚙️ System Settings updated by ${req.appUser?.email}`); res.json(settings); } catch (error) { console.error('Error updating system settings:', error); res.status(500).json({ error: 'Erro ao atualizar configurações do sistema' }); } }; export const serveLogo = async (req: Request, res: Response) => { try { const { filename } = req.params as { filename: string }; // Check tmp dir first (Serverless/Netlify uploads) const tmpPath = path.join(os.tmpdir(), 'uploads', filename); // Check local dir (Development) const localPath = path.join(process.cwd(), 'uploads', filename); if (fs.existsSync(tmpPath)) { res.sendFile(tmpPath); } else if (fs.existsSync(localPath)) { res.sendFile(localPath); } else { console.error(`Logo file not found in tmp or local: ${filename}`); res.status(404).json({ error: 'Imagem não encontrada' }); } } catch (error) { console.error('Error serving logo:', error); res.status(500).json({ error: 'Erro ao processar imagem' }); } }; export const uploadLogo = async (req: Request, res: Response) => { try { if (!req.file) { return res.status(400).json({ error: 'Nenhum arquivo enviado.' }); } // Return the API URL instead of static path // This ensures requests go through /api proxy and we control serving const fileUrl = `/api/system-settings/logo-image/${req.file.filename}`; res.json({ url: fileUrl }); } catch (error) { console.error('Error uploading logo:', error); res.status(500).json({ error: 'Erro ao fazer upload do logo.' }); } }; // Global Admin Functions export const getGlobalUsers = async (req: Request, res: Response) => { try { const users = await User.find({}).sort({ createdAt: -1 }); res.json(users); } catch (error) { console.error('Error getting global users:', error); res.status(500).json({ error: 'Erro ao buscar usuários globais.' }); } }; export const getGlobalOrganizations = async (req: Request, res: Response) => { try { // Aggregate members to group by org and get full member lists const organizations = await OrganizationMember.aggregate([ { $group: { _id: '$organizationId', members: { $push: { name: '$name', email: '$email', role: '$role', userId: '$userId', isBanned: '$isBanned' } }, lastActive: { $max: '$updatedAt' } } }, { $lookup: { from: 'organizations', // Ensure this matches the collection name of Organization model localField: '_id', foreignField: 'externalId', as: 'orgDetails' } }, { $unwind: { path: '$orgDetails', preserveNullAndEmptyArrays: true } }, { $project: { _id: 1, lastActive: 1, members: 1, memberCount: { $size: '$members' }, isBanned: { $ifNull: ['$orgDetails.isBanned', false] }, name: { $ifNull: ['$orgDetails.name', ''] } } }, { $sort: { memberCount: -1 } } ]); res.json(organizations); } catch (error) { console.error('Error getting global organizations:', error); res.status(500).json({ error: 'Erro ao buscar organizações globais.' }); } }; export const toggleOrganizationBan = async (req: Request, res: Response) => { try { const { organizationId, isBanned } = req.body; if (!organizationId) { return res.status(400).json({ error: 'ID da organização é obrigatório.' }); } // Upsert the Organization record const org = await Organization.findOneAndUpdate( { externalId: organizationId }, { isBanned: isBanned }, { new: true, upsert: true } ); console.log(`Organization ${organizationId} ban status set to ${isBanned} by ${req.appUser?.email}`); res.json(org); } catch (error) { console.error('Error toggling organization ban:', error); res.status(500).json({ error: 'Erro ao atualizar status da organização.' }); } };