72 lines
2.6 KiB
JavaScript
72 lines
2.6 KiB
JavaScript
import schedule from "node-cron";
|
|
import pool from "../db/pool.js";
|
|
import { getIO, getSocketId } from "../socket.js";
|
|
|
|
// Run every hour
|
|
export const startExpirationJob = () => {
|
|
schedule.schedule("0 * * * *", async () => {
|
|
console.log("Running listing expiration check...");
|
|
const client = await pool.connect();
|
|
try {
|
|
await client.query("BEGIN");
|
|
|
|
// 1. Identify expired listings (active & not updated in last 48h)
|
|
// Using INTERVAL '48 hours'
|
|
const findExpiredQuery = `
|
|
SELECT id, title, seller_id
|
|
FROM listings
|
|
WHERE status = 'active'
|
|
AND updated_at < NOW() - INTERVAL '48 hours'
|
|
AND deleted = FALSE
|
|
FOR UPDATE SKIP LOCKED
|
|
`;
|
|
const { rows: expiredListings } = await client.query(findExpiredQuery);
|
|
|
|
if (expiredListings.length === 0) {
|
|
await client.query("COMMIT");
|
|
return;
|
|
}
|
|
|
|
console.log(`Found ${expiredListings.length} listings to expire.`);
|
|
|
|
// 2. Update status to 'expired'
|
|
const expiredIds = expiredListings.map(l => l.id);
|
|
await client.query(`
|
|
UPDATE listings
|
|
SET status = 'expired'
|
|
WHERE id = ANY($1::uuid[])
|
|
`, [expiredIds]);
|
|
|
|
// 3. Create Notifications & Real-time Alerts
|
|
for (const listing of expiredListings) {
|
|
const message = `Your listing "${listing.title}" has expired after 48 hours of inactivity. Click here to re-list it.`;
|
|
|
|
// Insert Notification
|
|
await client.query(`
|
|
INSERT INTO notifications (user_id, type, message, data)
|
|
VALUES ($1, 'listing_expired', $2, $3)
|
|
`, [listing.seller_id, message, { listing_id: listing.id }]);
|
|
|
|
// Real-time Socket Emit
|
|
const socketId = getSocketId(listing.seller_id);
|
|
if (socketId) {
|
|
getIO().to(socketId).emit("notification", {
|
|
type: "listing_expired",
|
|
message,
|
|
data: { listing_id: listing.id }
|
|
});
|
|
}
|
|
}
|
|
|
|
await client.query("COMMIT");
|
|
console.log("Expiration check completed successfully.");
|
|
|
|
} catch (err) {
|
|
await client.query("ROLLBACK");
|
|
console.error("Error in expiration job:", err);
|
|
} finally {
|
|
client.release();
|
|
}
|
|
});
|
|
};
|