All files / src/cron index.js

78.78% Statements 52/66
100% Branches 2/2
50% Functions 12/24
83.6% Lines 51/61

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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 1111x 1x   1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x     16x         16x 2x 2x       14x 2x 2x 1x         14x 2x 2x 1x   2x     2x           14x 2x       14x 1x 1x 1x       14x 1x 1x           14x 1x 1x       14x 1x 1x       14x               14x               14x 1x         14x     1x  
const cron = require('node-cron');
const log = require('../utils/log');
 
const archiveReports = require('./archiveReports');
const subscriptions = require('./subscriptions');
const staleRooms = require('./staleRooms');
const backpackCleanup = require('./backpackCleanup');
const backups = require('./backups');
const closedRooms = require('./closedRooms');
const orphanedStorage = require('./orphanedStorage');
const rotateLogs = require('./rotateLogs');
const expireBans = require('./expireBans');
const expireTempIds = require('./expireTempIds');
const serverHealth = require('./serverHealth');
const accountDeletion = require('./accountDeletion');
const expireDataExports = require('./expireDataExports');
const alertManager = require('../utils/alertManagerInstance');
 
function startCronJobs() {
  const isProd = process.env.NODE_ENV === 'production';
 
  // All cron jobs are prod-only. Dev testing happens against local emulators
  // which have no quota limits, so cron cleanup is unnecessary. Running cron
  // on dev was burning ~4k Firestore deletes/day for no benefit.
  if (!isProd) {
    log.info('cron', 'Cron jobs disabled (non-production environment)');
    return;
  }
 
  // Archive old reports — Sunday 03:00 UTC
  cron.schedule('0 3 * * 0', () => {
    log.info('cron', 'Running archiveReports');
    archiveReports().catch((err) =>
      log.error('cron', 'archiveReports failed', { error: err.message }),
    );
  });
 
  // Check expired subscriptions + clean expired backpack items + expire temp IDs — daily midnight UTC
  cron.schedule('0 0 * * *', () => {
    log.info('cron', 'Running subscriptions + backpackCleanup + expireTempIds');
    subscriptions().catch((err) =>
      log.error('cron', 'subscriptions failed', { error: err.message }),
    );
    backpackCleanup().catch((err) =>
      log.error('cron', 'backpackCleanup failed', { error: err.message }),
    );
    expireTempIds().catch((err) =>
      log.error('cron', 'expireTempIds failed', { error: err.message }),
    );
  });
 
  // Close stale OWNER_AWAY rooms — every 5 minutes
  cron.schedule('*/5 * * * *', () => {
    staleRooms().catch((err) => log.error('cron', 'staleRooms failed', { error: err.message }));
  });
 
  // Backup user profiles + cleanup old closed rooms — daily 02:00 UTC
  cron.schedule('0 2 * * *', () => {
    log.info('cron', 'Running backups + closedRooms');
    backups().catch((err) => log.error('cron', 'backups failed', { error: err.message }));
    closedRooms().catch((err) => log.error('cron', 'closedRooms failed', { error: err.message }));
  });
 
  // Cleanup orphaned storage — daily 04:00 UTC
  cron.schedule('0 4 * * *', () => {
    log.info('cron', 'Running orphanedStorage');
    orphanedStorage().catch((err) =>
      log.error('cron', 'orphanedStorage failed', { error: err.message }),
    );
  });
 
  // Rotate logs — every hour
  cron.schedule('0 * * * *', () => {
    log.info('cron', 'Running rotateLogs');
    rotateLogs().catch((err) => log.error('cron', 'rotateLogs failed', { error: err.message }));
  });
 
  // Expire bans — every 15 minutes
  cron.schedule('*/15 * * * *', () => {
    log.info('cron', 'Running expireBans');
    expireBans().catch((err) => log.error('cron', 'expireBans failed', { error: err.message }));
  });
 
  // Account deletion — daily 03:00 UTC
  cron.schedule('0 3 * * *', () => {
    log.info('cron', 'Running accountDeletion');
    accountDeletion().catch((err) =>
      log.error('cron', 'accountDeletion failed', { error: err.message }),
    );
  });
 
  // Expire data exports — daily 04:00 UTC
  cron.schedule('0 4 * * *', () => {
    log.info('cron', 'Running expireDataExports');
    expireDataExports().catch((err) =>
      log.error('cron', 'expireDataExports failed', { error: err.message }),
    );
  });
 
  // Server health check — every 5 minutes
  cron.schedule('*/5 * * * *', () => {
    serverHealth(alertManager).catch((err) =>
      log.error('cron', 'serverHealth failed', { error: err.message }),
    );
  });
 
  log.info('cron', 'Cron jobs scheduled');
}
 
module.exports = { startCronJobs };