diff --git a/db.ts b/db.ts index ceed120f1e25b6a1d1065e9e391192688ce2904d..7fdb9e4b70e9a6223eee70fcb681716f3e952417 100644 --- a/db.ts +++ b/db.ts @@ -301,3 +301,22 @@ export function getItemsWithVotes(roomCode: string) { GROUP BY i.id `).all(roomCode) as Array<{id: string, text: string, votes: string | null}>; } + +export function deleteInactiveRooms(daysInactive: number = 30): number { + const cutoffTimestamp = Math.floor(Date.now() / 1000) - (daysInactive * 24 * 60 * 60); + + // Find rooms where the most recent activity (item or vote) is older than the cutoff + const result = db.prepare(` + DELETE FROM rooms + WHERE code IN ( + SELECT r.code + FROM rooms r + LEFT JOIN items i ON r.code = i.room_code + LEFT JOIN votes v ON i.id = v.item_id + GROUP BY r.code + HAVING COALESCE(MAX(i.created_at), MAX(v.created_at), r.created_at) < ? + ) + `).run(cutoffTimestamp); + + return result.changes || 0; +} diff --git a/server.ts b/server.ts index a369463022be4d25ed9ebadd400b663294861334..5a09ed0324f88204cfcec6d819b3ade8cd9d3647 100644 --- a/server.ts +++ b/server.ts @@ -367,6 +367,18 @@ function handleWebSocket(ws: WebSocket, roomCode: string, userId: string) { }; } +// Room cleanup scheduler +function cleanupInactiveRooms() { + const deleted = db.deleteInactiveRooms(30); + if (deleted > 0) { + console.log(`🧹 Cleaned up ${deleted} inactive room(s)`); + } +} + +// Run cleanup on startup and schedule daily +cleanupInactiveRooms(); +setInterval(cleanupInactiveRooms, 24 * 60 * 60 * 1000); // Every 24 hours + serve(async (req) => { const url = new URL(req.url);