Initial commit

This commit is contained in:
2025-06-22 00:01:22 +03:00
parent fd70166cf6
commit 033b80bfad
153 changed files with 26874 additions and 1 deletions

100
lib/database-cleanup.ts Normal file
View File

@@ -0,0 +1,100 @@
import { executeQuery, getPoolStats, closePool } from "./database"
import { startConnectionMonitoring } from "./connection-monitor"
// 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 and start monitoring
if (process.env.NODE_ENV === "production") {
// Start connection monitoring
startConnectionMonitoring()
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
}