Files
GPI/src/server/controllers/systemSettingsController.ts
2026-03-12 19:36:34 +00:00

180 lines
6.1 KiB
TypeScript

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',
clerkUserId: '$clerkUserId',
isBanned: '$isBanned'
}
},
lastActive: { $max: '$updatedAt' }
}
},
{
$lookup: {
from: 'organizations', // Ensure this matches the collection name of Organization model
localField: '_id',
foreignField: 'clerkId',
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(
{ clerkId: 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.' });
}
};