Update index.js
This commit is contained in:
166
backend/index.js
166
backend/index.js
@@ -57,6 +57,47 @@ app.post('/api/auth/register', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- SETTINGS ENDPOINTS ---
|
||||||
|
|
||||||
|
app.get('/api/settings', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const rows = await query('SELECT * FROM settings WHERE id = 1');
|
||||||
|
if (rows.length === 0) return res.status(404).json({ error: 'Settings not found' });
|
||||||
|
|
||||||
|
const s = rows[0];
|
||||||
|
const settings = {
|
||||||
|
branding: typeof s.branding === 'string' ? JSON.parse(s.branding) : s.branding,
|
||||||
|
smtp: typeof s.smtp === 'string' ? JSON.parse(s.smtp) : s.smtp,
|
||||||
|
emailTemplates: typeof s.email_templates === 'string' ? JSON.parse(s.email_templates) : s.email_templates,
|
||||||
|
features: typeof s.features === 'string' ? JSON.parse(s.features) : s.features,
|
||||||
|
aiConfig: typeof s.ai_config === 'string' ? JSON.parse(s.ai_config) : s.ai_config
|
||||||
|
};
|
||||||
|
res.json(settings);
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.put('/api/settings', async (req, res) => {
|
||||||
|
const { branding, smtp, emailTemplates, features, aiConfig } = req.body;
|
||||||
|
try {
|
||||||
|
await query(
|
||||||
|
'UPDATE settings SET branding=?, smtp=?, email_templates=?, features=?, ai_config=? WHERE id=1',
|
||||||
|
[
|
||||||
|
JSON.stringify(branding),
|
||||||
|
JSON.stringify(smtp),
|
||||||
|
JSON.stringify(emailTemplates),
|
||||||
|
JSON.stringify(features),
|
||||||
|
JSON.stringify(aiConfig)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error saving settings:", e);
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// --- DATA FETCHING ENDPOINTS ---
|
// --- DATA FETCHING ENDPOINTS ---
|
||||||
|
|
||||||
app.get('/api/initial-data', async (req, res) => {
|
app.get('/api/initial-data', async (req, res) => {
|
||||||
@@ -82,12 +123,27 @@ app.get('/api/initial-data', async (req, res) => {
|
|||||||
// Fetch Surveys
|
// Fetch Surveys
|
||||||
const surveys = await query('SELECT * FROM survey_results ORDER BY timestamp DESC');
|
const surveys = await query('SELECT * FROM survey_results ORDER BY timestamp DESC');
|
||||||
|
|
||||||
|
// Fetch Settings
|
||||||
|
let settings = null;
|
||||||
|
const settingsRows = await query('SELECT * FROM settings WHERE id = 1');
|
||||||
|
if (settingsRows.length > 0) {
|
||||||
|
const s = settingsRows[0];
|
||||||
|
settings = {
|
||||||
|
branding: typeof s.branding === 'string' ? JSON.parse(s.branding) : s.branding,
|
||||||
|
smtp: typeof s.smtp === 'string' ? JSON.parse(s.smtp) : s.smtp,
|
||||||
|
emailTemplates: typeof s.email_templates === 'string' ? JSON.parse(s.email_templates) : s.email_templates,
|
||||||
|
features: typeof s.features === 'string' ? JSON.parse(s.features) : s.features,
|
||||||
|
aiConfig: typeof s.ai_config === 'string' ? JSON.parse(s.ai_config) : s.ai_config
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
agents: parsedAgents,
|
agents: parsedAgents,
|
||||||
clientUsers,
|
clientUsers,
|
||||||
queues,
|
queues,
|
||||||
articles,
|
articles,
|
||||||
surveys
|
surveys,
|
||||||
|
settings
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
@@ -99,8 +155,6 @@ app.get('/api/initial-data', async (req, res) => {
|
|||||||
|
|
||||||
app.get('/api/tickets', async (req, res) => {
|
app.get('/api/tickets', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
// Complex query to get tickets + messages + attachments
|
|
||||||
// Note: We use a subquery or JSON_ARRAYAGG to bundle messages
|
|
||||||
const sql = `
|
const sql = `
|
||||||
SELECT
|
SELECT
|
||||||
t.*,
|
t.*,
|
||||||
@@ -140,7 +194,7 @@ app.get('/api/tickets', async (req, res) => {
|
|||||||
|
|
||||||
app.post('/api/tickets', async (req, res) => {
|
app.post('/api/tickets', async (req, res) => {
|
||||||
const { subject, description, priority, queue, customerName, attachments } = req.body;
|
const { subject, description, priority, queue, customerName, attachments } = req.body;
|
||||||
const id = `T-${Date.now()}`; // Generate a simple ID or UUID
|
const id = `T-${Date.now()}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await query(
|
await query(
|
||||||
@@ -148,7 +202,6 @@ app.post('/api/tickets', async (req, res) => {
|
|||||||
[id, subject, description, 'APERTO', priority, customerName, queue, JSON.stringify(attachments || [])]
|
[id, subject, description, 'APERTO', priority, customerName, queue, JSON.stringify(attachments || [])]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Fetch the created ticket to return it
|
|
||||||
const newTicket = {
|
const newTicket = {
|
||||||
id,
|
id,
|
||||||
subject,
|
subject,
|
||||||
@@ -181,7 +234,7 @@ app.patch('/api/tickets/:id', async (req, res) => {
|
|||||||
if (updates.assignedAgentId !== undefined) { fields.push('assigned_agent_id = ?'); values.push(updates.assignedAgentId || null); }
|
if (updates.assignedAgentId !== undefined) { fields.push('assigned_agent_id = ?'); values.push(updates.assignedAgentId || null); }
|
||||||
if (updates.queue) { fields.push('queue = ?'); values.push(updates.queue); }
|
if (updates.queue) { fields.push('queue = ?'); values.push(updates.queue); }
|
||||||
|
|
||||||
if (fields.length === 0) return res.json({ success: true }); // Nothing to update
|
if (fields.length === 0) return res.json({ success: true });
|
||||||
|
|
||||||
values.push(id);
|
values.push(id);
|
||||||
|
|
||||||
@@ -193,10 +246,8 @@ app.patch('/api/tickets/:id', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- MESSAGING ENDPOINTS ---
|
|
||||||
|
|
||||||
app.post('/api/tickets/:id/messages', async (req, res) => {
|
app.post('/api/tickets/:id/messages', async (req, res) => {
|
||||||
const { id } = req.params; // Ticket ID
|
const { id } = req.params;
|
||||||
const { role, content } = req.body;
|
const { role, content } = req.body;
|
||||||
const messageId = `m-${Date.now()}`;
|
const messageId = `m-${Date.now()}`;
|
||||||
|
|
||||||
@@ -206,7 +257,6 @@ app.post('/api/tickets/:id/messages', async (req, res) => {
|
|||||||
[messageId, id, role, content]
|
[messageId, id, role, content]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Se il messaggio è dell'utente e il ticket era risolto, riapriamolo
|
|
||||||
if (role === 'user') {
|
if (role === 'user') {
|
||||||
await query("UPDATE tickets SET status = 'APERTO' WHERE id = ? AND status = 'RISOLTO'", [id]);
|
await query("UPDATE tickets SET status = 'APERTO' WHERE id = ? AND status = 'RISOLTO'", [id]);
|
||||||
}
|
}
|
||||||
@@ -222,7 +272,98 @@ app.post('/api/tickets/:id/messages', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- SURVEY ENDPOINTS ---
|
// --- MANAGEMENT ENDPOINTS (Agents, Users, Queues) ---
|
||||||
|
|
||||||
|
app.post('/api/agents', async (req, res) => {
|
||||||
|
const agent = req.body;
|
||||||
|
try {
|
||||||
|
await query(
|
||||||
|
'INSERT INTO agents (id, name, email, password, role, avatar, avatar_config, skills, queues) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||||
|
[
|
||||||
|
agent.id, agent.name, agent.email, agent.password, agent.role, agent.avatar,
|
||||||
|
JSON.stringify(agent.avatarConfig || {}),
|
||||||
|
JSON.stringify(agent.skills || []),
|
||||||
|
JSON.stringify(agent.queues || [])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.put('/api/agents/:id', async (req, res) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
const agent = req.body;
|
||||||
|
try {
|
||||||
|
await query(
|
||||||
|
'UPDATE agents SET name=?, email=?, password=?, role=?, avatar=?, avatar_config=?, skills=?, queues=? WHERE id=?',
|
||||||
|
[
|
||||||
|
agent.name, agent.email, agent.password, agent.role, agent.avatar,
|
||||||
|
JSON.stringify(agent.avatarConfig),
|
||||||
|
JSON.stringify(agent.skills),
|
||||||
|
JSON.stringify(agent.queues),
|
||||||
|
id
|
||||||
|
]
|
||||||
|
);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete('/api/agents/:id', async (req, res) => {
|
||||||
|
try {
|
||||||
|
await query('DELETE FROM agents WHERE id = ?', [req.params.id]);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.put('/api/client_users/:id', async (req, res) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
const { name, email, company, status } = req.body;
|
||||||
|
try {
|
||||||
|
await query(
|
||||||
|
'UPDATE client_users SET name=?, email=?, company=?, status=? WHERE id=?',
|
||||||
|
[name, email, company, status, id]
|
||||||
|
);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete('/api/client_users/:id', async (req, res) => {
|
||||||
|
try {
|
||||||
|
await query('DELETE FROM client_users WHERE id = ?', [req.params.id]);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/api/queues', async (req, res) => {
|
||||||
|
const { id, name, description } = req.body;
|
||||||
|
try {
|
||||||
|
await query('INSERT INTO queues (id, name, description) VALUES (?, ?, ?)', [id, name, description]);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete('/api/queues/:id', async (req, res) => {
|
||||||
|
try {
|
||||||
|
await query('DELETE FROM queues WHERE id = ?', [req.params.id]);
|
||||||
|
res.json({ success: true });
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).json({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- SURVEY & KB ENDPOINTS ---
|
||||||
app.post('/api/surveys', async (req, res) => {
|
app.post('/api/surveys', async (req, res) => {
|
||||||
const { rating, comment, source, referenceId } = req.body;
|
const { rating, comment, source, referenceId } = req.body;
|
||||||
const id = randomUUID();
|
const id = randomUUID();
|
||||||
@@ -237,7 +378,6 @@ app.post('/api/surveys', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- KB ENDPOINTS ---
|
|
||||||
app.post('/api/articles', async (req, res) => {
|
app.post('/api/articles', async (req, res) => {
|
||||||
const { title, content, category, type, url, source } = req.body;
|
const { title, content, category, type, url, source } = req.body;
|
||||||
const id = `kb-${Date.now()}`;
|
const id = `kb-${Date.now()}`;
|
||||||
@@ -266,10 +406,8 @@ app.patch('/api/articles/:id', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Avvio del server
|
|
||||||
const startServer = async () => {
|
const startServer = async () => {
|
||||||
await initDb();
|
await initDb();
|
||||||
|
|
||||||
app.listen(PORT, () => {
|
app.listen(PORT, () => {
|
||||||
console.log(`🚀 Backend Server running on port ${PORT}`);
|
console.log(`🚀 Backend Server running on port ${PORT}`);
|
||||||
checkConnection();
|
checkConnection();
|
||||||
|
|||||||
Reference in New Issue
Block a user