All files / src/routes suggestions-maintenance.js

100% Statements 50/50
100% Branches 4/4
100% Functions 8/8
100% Lines 48/48

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 8469x 69x 69x 69x   69x     69x 22x 15x   69x     14x 9x 10x 9x 9x     69x 5x 5x 4x               4x   1x 1x       69x 2x 2x 1x   1x 1x       69x 2x 2x 1x   1x 1x       69x 3x 3x 1x 2x 1x   1x 1x       69x 3x 3x 2x   1x 1x       69x  
const router = require('express').Router();
const { db } = require('../utils/firebase');
const log = require('../utils/log');
const { now } = require('../utils/helpers');
 
const { requireAdmin } = require('../middleware/auth'); // shared — live claim check
 
// Every route in this file is admin-only — gate by path prefix.
const adminGuard = async (req, res, next) => {
  if (await requireAdmin(req, res)) return;
  next();
};
router.use('/admin/maintenance', adminGuard);
 
async function deleteCollection(name) {
  const snap = await db.collection(name).get();
  const batch = db.batch();
  snap.docs.forEach((d) => batch.delete(db.doc(name + '/' + d.id)));
  await batch.commit();
  return snap.size;
}
 
router.post('/admin/maintenance/clear-suggestions', async (req, res) => {
  try {
    const deleted = await deleteCollection('suggestions');
    await db.collection('adminAuditLog').add({
      adminUid: req.auth.uniqueId,
      actionType: 'maintenance_clear_suggestions',
      targetType: 'maintenance',
      targetId: 'all',
      details: { deleted },
      timestamp: now(),
    });
    res.json({ success: true, deleted });
  } catch (err) {
    log.error('maintenance', 'Clear suggestions failed', { error: err.message });
    res.status(500).json({ error: 'Internal server error' });
  }
});
 
router.post('/admin/maintenance/clear-subscriptions', async (req, res) => {
  try {
    const deleted = await deleteCollection('subscriptions');
    res.json({ success: true, deleted });
  } catch (err) {
    log.error('maintenance', 'Clear subscriptions failed', { error: err.message });
    res.status(500).json({ error: 'Internal server error' });
  }
});
 
router.post('/admin/maintenance/clear-notifications', async (req, res) => {
  try {
    const deleted = await deleteCollection('notifications');
    res.json({ success: true, deleted });
  } catch (err) {
    log.error('maintenance', 'Clear notifications failed', { error: err.message });
    res.status(500).json({ error: 'Internal server error' });
  }
});
 
router.post('/admin/maintenance/clear-identity-graphs', async (req, res) => {
  try {
    if (!req.body.confirmDangerous)
      return res.status(400).json({ error: 'Confirmation required: set confirmDangerous to true' });
    const deleted = await deleteCollection('identityGraphs');
    res.json({ success: true, deleted });
  } catch (err) {
    log.error('maintenance', 'Clear identity graphs failed', { error: err.message });
    res.status(500).json({ error: 'Internal server error' });
  }
});
 
router.post('/admin/maintenance/clear-audit-log', async (req, res) => {
  try {
    const deleted = await deleteCollection('adminAuditLog');
    res.json({ success: true, deleted });
  } catch (err) {
    log.error('maintenance', 'Clear audit log failed', { error: err.message });
    res.status(500).json({ error: 'Internal server error' });
  }
});
 
module.exports = router;