97 lines
2.9 KiB
Plaintext
97 lines
2.9 KiB
Plaintext
import { executeQuery, getPoolStats, closePool } from "./database"
|
|
|
|
// Clean up old admin actions (keep only last 30 days)
|
|
export async function cleanupOldActions() {
|
|
try {
|
|
const result = await executeQuery("DELETE FROM admin_actions WHERE timestamp < DATE_SUB(NOW(), INTERVAL 30 DAY)")
|
|
console.log(`Cleaned up old admin actions: ${(result as any).affectedRows} rows deleted`)
|
|
return (result as any).affectedRows
|
|
} catch (error) {
|
|
console.error("Error cleaning up old actions:", error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
// Reset inactive user sessions (users who haven't updated status in 24 hours)
|
|
export async function resetInactiveSessions() {
|
|
try {
|
|
const result = await executeQuery(
|
|
"UPDATE users SET in_shelter = NULL WHERE last_updated < DATE_SUB(NOW(), INTERVAL 24 HOUR) AND in_shelter IS NOT NULL",
|
|
)
|
|
console.log(`Reset inactive sessions: ${(result as any).affectedRows} users reset`)
|
|
return (result as any).affectedRows
|
|
} catch (error) {
|
|
console.error("Error resetting inactive sessions:", error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
// Get database statistics
|
|
export async function getDatabaseStats() {
|
|
try {
|
|
const [userStats] = (await executeQuery(`
|
|
SELECT
|
|
COUNT(*) as total_users,
|
|
COUNT(CASE WHEN in_shelter IS NOT NULL THEN 1 END) as active_users,
|
|
COUNT(CASE WHEN is_admin = TRUE THEN 1 END) as admin_users,
|
|
COUNT(CASE WHEN last_updated > DATE_SUB(NOW(), INTERVAL 1 HOUR) THEN 1 END) as recent_activity
|
|
FROM users
|
|
`)) as any[]
|
|
|
|
const [actionStats] = (await executeQuery(`
|
|
SELECT
|
|
COUNT(*) as total_actions,
|
|
COUNT(CASE WHEN timestamp > DATE_SUB(NOW(), INTERVAL 24 HOUR) THEN 1 END) as actions_24h,
|
|
COUNT(CASE WHEN action_type = 'reset_all' THEN 1 END) as reset_actions
|
|
FROM admin_actions
|
|
`)) as any[]
|
|
|
|
const poolStats = getPoolStats()
|
|
|
|
return {
|
|
users: userStats,
|
|
actions: actionStats,
|
|
pool: poolStats,
|
|
timestamp: new Date().toISOString(),
|
|
}
|
|
} catch (error) {
|
|
console.error("Error getting database stats:", error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
// Graceful shutdown with connection cleanup
|
|
export async function gracefulShutdown() {
|
|
console.log("Starting graceful database shutdown...")
|
|
|
|
try {
|
|
// Clean up old data
|
|
await cleanupOldActions()
|
|
|
|
// Close all connections
|
|
await closePool()
|
|
|
|
console.log("Database shutdown completed successfully")
|
|
} catch (error) {
|
|
console.error("Error during database shutdown:", error)
|
|
}
|
|
}
|
|
|
|
// Schedule periodic cleanup (run every hour)
|
|
if (process.env.NODE_ENV === "production") {
|
|
setInterval(
|
|
async () => {
|
|
try {
|
|
console.log("Running scheduled database cleanup...")
|
|
await cleanupOldActions()
|
|
|
|
const stats = await getDatabaseStats()
|
|
console.log("Database stats:", stats)
|
|
} catch (error) {
|
|
console.error("Scheduled cleanup failed:", error)
|
|
}
|
|
},
|
|
60 * 60 * 1000,
|
|
) // Every hour
|
|
}
|