/*********************************************************************************************************************************************************************** * File Name : expire_advertisements.cron.js * Type : Cron Job * Description : Auto-archives (soft-deletes) advertisements once their * end_date has passed, so expired ads don't sit indefinitely * in the active Advertisements list — they fall through to * the Archived Advertisements table, same path as a manual * archive action. * * Only touches rows with end_date IS NOT NULL so ads with no * end date (run indefinitely) are never auto-archived. * * Schedule : Every minute ("* * * * *"). Registered by cron/client.cron.js. * * Author: Kenneth Obsequio (@lash0000) * Date Created: Jul. 11, 2026 ***********************************************************************************************************************************************************************/ 'use strict'; const { Op } = require('sequelize'); const mdl_Advertisements = require('../../models/advertisements/advertisements.mdl'); async function run() { let expired; try { expired = await mdl_Advertisements.findAll({ where: { deletedAt: null, end_date: { [Op.ne]: null, [Op.lt]: new Date() }, }, attributes: ['advertisement_id'], }); } catch (err) { console.error('[CRON][EXPIRE ADVERTISEMENTS] Failed to query advertisements:', err); return; } if (!expired.length) return; const ids = expired.map((a) => a.advertisement_id); try { await mdl_Advertisements.update({ status: 'expired' }, { where: { advertisement_id: { [Op.in]: ids } } }); await mdl_Advertisements.destroy({ where: { advertisement_id: { [Op.in]: ids } } }); } catch (err) { console.error('[CRON][EXPIRE ADVERTISEMENTS] Archive failed:', err); return; } console.log(`[CRON][EXPIRE ADVERTISEMENTS] Auto-archived ${ids.length} expired advertisement(s).`); } module.exports = { name: 'expireAdvertisements', schedule: '* * * * *', run, };