export const inactivityPolicy = { closeAfter: 10 * 60_000, expireAfter: 24 * 60 * 60_000, }; export function roomActivityAt(room) { return Date.parse( room.lastGameActivityAt ?? room.events?.at(-1)?.createdAt ?? room.startedAt ?? room.createdAt, ); } export function roomDeadlines(room) { const activity = roomActivityAt(room); return { inactiveCloseAt: activity + inactivityPolicy.closeAfter, autoCloseAt: activity + inactivityPolicy.expireAfter, }; } export function canCloseInactive(room, seat, now = Date.now()) { if ( room.status !== 'playing' || !room.players[seat] || room.players[seat].withdrawnAt ) return false; const waiting = room.state?.phase === 'scoring' ? room.state.accepted?.[seat] && room.state.accepted.some((accepted, i) => i !== seat && !accepted) : room.state?.turn !== seat; return Boolean(waiting && now >= roomDeadlines(room).inactiveCloseAt); }