const express = require('express'); const router = express.Router(); const { Pool } = require('pg'); // In a real app, you would have an admin middleware protecting this // const { verifyAdminToken } = require('../middleware/adminAuth'); const pgPool = new Pool({ host: process.env.PGHOST || 'postgres', port: process.env.PGPORT || 5432, user: process.env.PGUSER || 'postgres', password: process.env.PGPASSWORD || 'postgres', database: process.env.PGDATABASE || 'ckqr', }); // List all users router.get('/users', async (req, res) => { try { const result = await pgPool.query('SELECT id, email, role, created_at FROM users ORDER BY created_at DESC'); res.json(result.rows); } catch (err) { console.error(err); res.status(500).json({ error: 'Server Error' }); } }); // Get user details (QR codes, scans) router.get('/users/:id/details', async (req, res) => { const { id } = req.params; try { // Fetch user info const userRes = await pgPool.query('SELECT id, email, role, created_at FROM users WHERE id = $1', [id]); if (userRes.rows.length === 0) { return res.status(404).json({ error: 'User not found' }); } // Fetch QR codes and scan counts const qrRes = await pgPool.query(` SELECT q.id, q.type, q.data_type, q.destination_url, q.short_url_id, q.created_at, q.name, (SELECT COUNT(*) FROM qr_scans s WHERE s.qr_code_id = q.id) as scan_count FROM qr_codes q WHERE q.user_id = $1 ORDER BY q.created_at DESC `, [id]); res.json({ user: userRes.rows[0], qrCodes: qrRes.rows }); } catch (err) { console.error(err); res.status(500).json({ error: 'Server Error fetching user details' }); } }); // Update a user's tier router.put('/users/:id/tier', async (req, res) => { const { id } = req.params; const { role } = req.body; // 'free', 'pro', 'enterprise', 'admin' if (!['free', 'pro', 'enterprise', 'admin'].includes(role)) { return res.status(400).json({ error: 'Invalid role specified' }); } try { if (role === 'pro' || role === 'enterprise') { const userCheck = await pgPool.query('SELECT is_email_verified FROM users WHERE id = $1', [id]); if (userCheck.rows.length === 0) return res.status(404).json({ error: 'User not found' }); if (!userCheck.rows[0].is_email_verified) { return res.status(400).json({ error: 'Cannot upgrade tier: User email is not verified' }); } } const result = await pgPool.query( 'UPDATE users SET role = $1 WHERE id = $2 RETURNING id, email, role', [role, id] ); if (result.rows.length === 0) { return res.status(404).json({ error: 'User not found' }); } res.json({ message: 'User tier updated successfully', user: result.rows[0] }); } catch (err) { console.error(err); res.status(500).json({ error: 'Server Error' }); } }); // Get all API settings router.get('/settings', async (req, res) => { try { const result = await pgPool.query('SELECT * FROM app_settings ORDER BY category, key'); res.json(result.rows); } catch (err) { console.error(err); res.status(500).json({ error: 'Server Error fetching settings' }); } }); // Update multiple API settings router.put('/settings', async (req, res) => { const { settings } = req.body; // Array of { key, value } if (!Array.isArray(settings)) return res.status(400).json({ error: 'Invalid settings format' }); const client = await pgPool.connect(); try { await client.query('BEGIN'); for (const setting of settings) { await client.query( `INSERT INTO app_settings (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = $2, updated_at = CURRENT_TIMESTAMP`, [setting.key, setting.value] ); } await client.query('COMMIT'); res.json({ message: 'Settings updated successfully' }); } catch (err) { await client.query('ROLLBACK'); console.error(err); res.status(500).json({ error: 'Server Error updating settings' }); } finally { client.release(); } }); module.exports = router;