feat: WordPress Monitor API + Site Availability Checker
- Add POST /api/wp-monitor endpoint for WP plugin data - Add GET /api/wp-monitor for listing monitored sites - Add checkSiteAvailability() function for HTTP health checks - Add checkAllSitesAvailability() for batch checking - Add /api/scripts/check-sites.ts for cron execution - Add POST /api/monitor/check-sites for manual trigger DeskCRM Task: #1556 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,105 @@ interface CategorySummary {
|
||||
critical: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a URL is accessible (HTTP HEAD request)
|
||||
*/
|
||||
export async function checkSiteAvailability(url: string, timeout = 10000): Promise<{
|
||||
available: boolean
|
||||
statusCode?: number
|
||||
responseTime?: number
|
||||
error?: string
|
||||
}> {
|
||||
const startTime = Date.now()
|
||||
const controller = new AbortController()
|
||||
const timeoutId = setTimeout(() => controller.abort(), timeout)
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'HEAD',
|
||||
signal: controller.signal,
|
||||
headers: {
|
||||
'User-Agent': 'Descomplicar-Monitor/1.0'
|
||||
}
|
||||
})
|
||||
|
||||
clearTimeout(timeoutId)
|
||||
const responseTime = Date.now() - startTime
|
||||
|
||||
return {
|
||||
available: response.ok || response.status < 500,
|
||||
statusCode: response.status,
|
||||
responseTime
|
||||
}
|
||||
} catch (error) {
|
||||
clearTimeout(timeoutId)
|
||||
return {
|
||||
available: false,
|
||||
error: (error as Error).message,
|
||||
responseTime: Date.now() - startTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all sites and update their availability status
|
||||
*/
|
||||
export async function checkAllSitesAvailability(): Promise<{
|
||||
checked: number
|
||||
up: number
|
||||
down: number
|
||||
results: any[]
|
||||
}> {
|
||||
// Get all sites from monitoring table
|
||||
const [sites] = await db.query<RowDataPacket[]>(`
|
||||
SELECT id, name, details FROM tbl_eal_monitoring
|
||||
WHERE category = 'site'
|
||||
`)
|
||||
|
||||
const results: any[] = []
|
||||
let up = 0
|
||||
let down = 0
|
||||
|
||||
for (const site of sites) {
|
||||
const details = typeof site.details === 'string' ? JSON.parse(site.details) : site.details
|
||||
const siteUrl = details?.site_url || `https://${site.name}`
|
||||
|
||||
const check = await checkSiteAvailability(siteUrl)
|
||||
|
||||
// Update status if site is down
|
||||
if (!check.available) {
|
||||
await db.query(
|
||||
'UPDATE tbl_eal_monitoring SET status = ?, last_check = NOW() WHERE id = ?',
|
||||
['down', site.id]
|
||||
)
|
||||
down++
|
||||
} else {
|
||||
// If was down and now is up, set to 'up' (will be replaced by plugin data later)
|
||||
const currentStatus = details?.health?.status || 'ok'
|
||||
if (currentStatus === 'down') {
|
||||
await db.query(
|
||||
'UPDATE tbl_eal_monitoring SET status = ?, last_check = NOW() WHERE id = ?',
|
||||
['up', site.id]
|
||||
)
|
||||
}
|
||||
up++
|
||||
}
|
||||
|
||||
results.push({
|
||||
name: site.name,
|
||||
url: siteUrl,
|
||||
...check
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
checked: sites.length,
|
||||
up,
|
||||
down,
|
||||
results
|
||||
}
|
||||
}
|
||||
|
||||
export async function getMonitoringData() {
|
||||
// Get all items
|
||||
const [items] = await db.query<RowDataPacket[]>(`
|
||||
|
||||
Reference in New Issue
Block a user