/** * Diagnostic Script: Check AlertStream_monthly for Malformed Time Entries * This table uses alert_time_txt and alert_date columns */ import { rawQuery } from '../src/db.js'; import dotenv from 'dotenv'; dotenv.config(); async function checkAlertStreamTimes() { console.log('šŸ” Checking AlertStream_monthly for malformed time entries...\n'); try { // Check for malformed alert_time_txt entries const malformed = await rawQuery(` SELECT alert_date, alert_time_txt, COUNT(*) as count FROM public.alertstream_monthly WHERE alert_time_txt IS NOT NULL AND ( -- Pattern: just digits + AM/PM (no colon, missing hour) (alert_time_txt::text ~ '^\\d{1,2}\\s*(AM|PM)$' AND alert_time_txt::text !~ '^\\d{1,2}:\\d{2}') -- Pattern: colon but missing hour OR alert_time_txt::text ~ '^:\\d{1,2}\\s*(AM|PM)$' ) GROUP BY alert_date, alert_time_txt ORDER BY count DESC LIMIT 20; `); console.log('šŸ“Š Malformed alert_time_txt entries:'); if (malformed.length > 0) { console.log(` Found ${malformed.length} unique malformed time patterns`); malformed.forEach(row => { console.log(` - "${row.alert_time_txt}" on ${row.alert_date}: ${row.count} occurrences`); }); } else { console.log(' āœ… No issues found'); } console.log(''); // Check total count const totalMalformed = await rawQuery(` SELECT COUNT(*) as total FROM public.alertstream_monthly WHERE alert_time_txt IS NOT NULL AND ( (alert_time_txt::text ~ '^\\d{1,2}\\s*(AM|PM)$' AND alert_time_txt::text !~ '^\\d{1,2}:\\d{2}') OR alert_time_txt::text ~ '^:\\d{1,2}\\s*(AM|PM)$' ); `); const total = await rawQuery(` SELECT COUNT(*) as total FROM public.alertstream_monthly WHERE alert_time_txt IS NOT NULL; `); const malformedCount = totalMalformed[0]?.total || 0; const totalCount = total[0]?.total || 0; const percentage = totalCount > 0 ? ((malformedCount / totalCount) * 100).toFixed(2) : 0; console.log('šŸ“‹ Summary:'); console.log(` Total entries with alert_time_txt: ${totalCount}`); console.log(` Malformed entries: ${malformedCount} (${percentage}%)`); console.log(` Properly formatted: ${totalCount - malformedCount} (${(100 - parseFloat(percentage)).toFixed(2)}%)`); console.log(''); // Show sample of properly formatted times const properFormat = await rawQuery(` SELECT alert_date, alert_time_txt, COUNT(*) as count FROM public.alertstream_monthly WHERE alert_time_txt IS NOT NULL AND alert_time_txt::text ~ '^\\d{1,2}:\\d{2}' GROUP BY alert_date, alert_time_txt ORDER BY alert_date DESC, count DESC LIMIT 10; `); console.log('āœ… Sample of properly formatted times:'); properFormat.forEach(row => { console.log(` - "${row.alert_time_txt}" on ${row.alert_date}: ${row.count} occurrences`); }); console.log(''); if (malformedCount > 0) { console.log('āš ļø ACTION REQUIRED:'); console.log(' Create a fix script for AlertStream_monthly table'); } else { console.log('āœ… All alert_time_txt entries appear to be properly formatted!'); } } catch (error) { console.error('āŒ Error checking AlertStream times:', error.message); if (error.message.includes('does not exist') || error.message.includes('relation')) { console.log(' ā„¹ļø Table alertstream_monthly may not exist or use different column names'); } console.error(error); } } checkAlertStreamTimes() .then(() => { console.log('\nāœ… Diagnostic complete'); process.exit(0); }) .catch((error) => { console.error('\nāŒ Diagnostic failed:', error); process.exit(1); });