518 lines
28 KiB
JavaScript
518 lines
28 KiB
JavaScript
import express from 'express';
|
|
import { WebSocketServer } from 'ws';
|
|
import { rawQuery } from '../db.js';
|
|
|
|
const router = express.Router();
|
|
|
|
router.get('/recent', async (req, res) => {
|
|
try {
|
|
const { limit = 50, priority, date, time, hours = 4 } = req.query;
|
|
|
|
// Build datetime string if provided
|
|
let dateTime = null;
|
|
let timeCondition = `NOW() - INTERVAL '${parseInt(hours) || 4} hours'`;
|
|
|
|
if (date) {
|
|
dateTime = time ? `${date} ${time}` : date;
|
|
// If date is provided, calculate the target datetime
|
|
try {
|
|
let targetDateTime;
|
|
if (dateTime.includes('T')) {
|
|
targetDateTime = new Date(dateTime);
|
|
} else if (dateTime.includes(' ')) {
|
|
targetDateTime = new Date(dateTime.replace(' ', 'T'));
|
|
} else {
|
|
targetDateTime = new Date(dateTime + 'T16:00:00');
|
|
}
|
|
|
|
const year = targetDateTime.getFullYear();
|
|
const month = String(targetDateTime.getMonth() + 1).padStart(2, '0');
|
|
const day = String(targetDateTime.getDate()).padStart(2, '0');
|
|
const hours = String(targetDateTime.getHours()).padStart(2, '0');
|
|
const minutes = String(targetDateTime.getMinutes()).padStart(2, '0');
|
|
const seconds = String(targetDateTime.getSeconds()).padStart(2, '0');
|
|
|
|
const hoursBack = parseInt(req.query.hours) || 4;
|
|
timeCondition = `('${year}-${month}-${day} ${hours}:${minutes}:${seconds}'::timestamp AT TIME ZONE 'America/Chicago') - INTERVAL '${hoursBack} hours'`;
|
|
} catch (error) {
|
|
console.error('Error parsing datetime:', error);
|
|
}
|
|
}
|
|
|
|
let query = `
|
|
SELECT
|
|
UPPER(a."Ticker") AS symbol,
|
|
a."Type" AS type,
|
|
a."Message" AS message,
|
|
(
|
|
CASE
|
|
WHEN a."Timestamp"::text ~ '^\d{4}-\d{2}-\d{2}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'YYYY-MM-DD HH12:MI:SS AM')::timestamptz
|
|
WHEN a."Timestamp"::text ~ '^\d{1,2}/\d{1,2}/\d{4}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'MM/DD/YYYY HH12:MI:SS AM')::timestamptz
|
|
WHEN a."date" IS NOT NULL AND a."timestamp" IS NOT NULL
|
|
THEN CASE
|
|
-- Check if timestamp is malformed (just digits + AM/PM without hour)
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}\s*(AM|PM)$' AND btrim(a."timestamp")::text !~ '^\d{1,2}:\d{2}'
|
|
THEN NULL -- Skip malformed entries like "34 AM"
|
|
-- Try 12-hour format with seconds
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
-- Try 12-hour format without seconds
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
-- Try 24-hour format with seconds
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
-- Try 24-hour format without seconds
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
ELSE NULL
|
|
END
|
|
ELSE NULL
|
|
END
|
|
) AS timestamp,
|
|
a."Price" AS price,
|
|
a."Volume" AS volume,
|
|
CASE
|
|
WHEN a."Type" ILIKE '%Halt%' THEN 'HIGH'
|
|
WHEN a."Type" ILIKE '%52W%' OR a."Type" ILIKE '%Spike%' THEN 'MEDIUM'
|
|
ELSE 'LOW'
|
|
END AS priority,
|
|
CASE
|
|
WHEN a."Type" ILIKE '%High%' OR a."Message" ~* 'positive|approval|beat' THEN 'BULLISH'
|
|
WHEN a."Type" ILIKE '%Low%' OR a."Message" ~* 'negative|rejection|miss' THEN 'BEARISH'
|
|
ELSE 'NEUTRAL'
|
|
END AS sentiment
|
|
FROM public."AlertStream_monthly" a
|
|
WHERE (
|
|
CASE
|
|
WHEN a."Timestamp"::text ~ '^\d{4}-\d{2}-\d{2}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'YYYY-MM-DD HH12:MI:SS AM')::timestamptz
|
|
WHEN a."Timestamp"::text ~ '^\d{1,2}/\d{1,2}/\d{4}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'MM/DD/YYYY HH12:MI:SS AM')::timestamptz
|
|
WHEN a."date" IS NOT NULL AND a."timestamp" IS NOT NULL
|
|
THEN CASE
|
|
-- Check if timestamp is malformed (just digits + AM/PM without hour)
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}\s*(AM|PM)$' AND btrim(a."timestamp")::text !~ '^\d{1,2}:\d{2}'
|
|
THEN NULL -- Skip malformed entries like "34 AM"
|
|
-- Try 12-hour format with seconds
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
-- Try 12-hour format without seconds
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
-- Try 24-hour format with seconds
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
-- Try 24-hour format without seconds
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
ELSE NULL
|
|
END
|
|
ELSE NULL
|
|
END
|
|
) >= ${timeCondition}
|
|
AND (
|
|
CASE
|
|
WHEN a."Timestamp"::text ~ '^\d{4}-\d{2}-\d{2}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'YYYY-MM-DD HH12:MI:SS AM')::timestamptz
|
|
WHEN a."Timestamp"::text ~ '^\d{1,2}/\d{1,2}/\d{4}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'MM/DD/YYYY HH12:MI:SS AM')::timestamptz
|
|
WHEN a."date" IS NOT NULL AND a."timestamp" IS NOT NULL
|
|
THEN CASE
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}\s*(AM|PM)$' AND btrim(a."timestamp")::text !~ '^\d{1,2}:\d{2}'
|
|
THEN NULL
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
ELSE NULL
|
|
END
|
|
ELSE NULL
|
|
END
|
|
) IS NOT NULL
|
|
`;
|
|
|
|
const params = [];
|
|
|
|
if (priority) {
|
|
query += ` AND CASE
|
|
WHEN a."Type" ILIKE '%Halt%' THEN 'HIGH'
|
|
WHEN a."Type" ILIKE '%52W%' OR a."Type" ILIKE '%Spike%' THEN 'MEDIUM'
|
|
ELSE 'LOW'
|
|
END = $1`;
|
|
params.push(priority);
|
|
query += ` ORDER BY (
|
|
CASE
|
|
WHEN a."Timestamp"::text ~ '^\d{4}-\d{2}-\d{2}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'YYYY-MM-DD HH12:MI:SS AM')::timestamptz
|
|
WHEN a."Timestamp"::text ~ '^\d{1,2}/\d{1,2}/\d{4}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'MM/DD/YYYY HH12:MI:SS AM')::timestamptz
|
|
WHEN a."date" IS NOT NULL AND a."timestamp" IS NOT NULL
|
|
THEN CASE
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}\s*(AM|PM)$' AND btrim(a."timestamp")::text !~ '^\d{1,2}:\d{2}'
|
|
THEN NULL
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
ELSE NULL
|
|
END
|
|
ELSE NULL
|
|
END
|
|
) DESC LIMIT $2`;
|
|
params.push(parseInt(limit));
|
|
} else {
|
|
query += ` ORDER BY (
|
|
CASE
|
|
WHEN a."Timestamp"::text ~ '^\d{4}-\d{2}-\d{2}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'YYYY-MM-DD HH12:MI:SS AM')::timestamptz
|
|
WHEN a."Timestamp"::text ~ '^\d{1,2}/\d{1,2}/\d{4}'
|
|
THEN to_timestamp(a."Timestamp"::text, 'MM/DD/YYYY HH12:MI:SS AM')::timestamptz
|
|
WHEN a."date" IS NOT NULL AND a."timestamp" IS NOT NULL
|
|
THEN CASE
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}\s*(AM|PM)$' AND btrim(a."timestamp")::text !~ '^\d{1,2}:\d{2}'
|
|
THEN NULL
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim(a."timestamp")::text ~ '^\d{1,2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN a."date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'YYYY-MM-DD HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp(a."date" || ' ' || btrim(a."timestamp"), 'MM/DD/YYYY HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
ELSE NULL
|
|
END
|
|
ELSE NULL
|
|
END
|
|
) DESC LIMIT $1`;
|
|
params.push(parseInt(limit));
|
|
}
|
|
|
|
const data = await rawQuery(query, params);
|
|
|
|
res.json({
|
|
success: true,
|
|
data,
|
|
queryDateTime: dateTime || 'current',
|
|
hoursBack: parseInt(hours) || 4
|
|
});
|
|
} catch (error) {
|
|
console.error('Alerts fetch error:', error);
|
|
res.status(500).json({ success: false, error: error.message });
|
|
}
|
|
});
|
|
|
|
// WebSocket for real-time alerts
|
|
export function setupAlertsWebSocket() {
|
|
const wss = new WebSocketServer({ noServer: true });
|
|
|
|
wss.on('connection', (ws) => {
|
|
console.log('Client connected to alerts feed');
|
|
|
|
// Poll for new alerts every 10 seconds
|
|
const interval = setInterval(async () => {
|
|
try {
|
|
if (ws.readyState !== ws.OPEN) {
|
|
clearInterval(interval);
|
|
return;
|
|
}
|
|
|
|
const newAlerts = await rawQuery(`
|
|
SELECT
|
|
UPPER("Ticker") AS symbol,
|
|
"Type" AS type,
|
|
"Message" AS message,
|
|
(
|
|
CASE
|
|
WHEN "Timestamp"::text ~ '^\d{4}-\d{2}-\d{2}'
|
|
THEN to_timestamp("Timestamp"::text, 'YYYY-MM-DD HH12:MI:SS AM')::timestamptz
|
|
WHEN "Timestamp"::text ~ '^\d{1,2}/\d{1,2}/\d{4}'
|
|
THEN to_timestamp("Timestamp"::text, 'MM/DD/YYYY HH12:MI:SS AM')::timestamptz
|
|
WHEN "date" IS NOT NULL AND "timestamp" IS NOT NULL
|
|
THEN CASE
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}\s*(AM|PM)$' AND btrim("timestamp")::text !~ '^\d{1,2}:\d{2}'
|
|
THEN NULL
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
ELSE NULL
|
|
END
|
|
ELSE NULL
|
|
END
|
|
) AS timestamp,
|
|
"Price" AS price,
|
|
"Volume" AS volume,
|
|
CASE
|
|
WHEN "Type" ILIKE '%Halt%' THEN 'HIGH'
|
|
WHEN "Type" ILIKE '%52W%' OR "Type" ILIKE '%Spike%' THEN 'MEDIUM'
|
|
ELSE 'LOW'
|
|
END AS priority,
|
|
CASE
|
|
WHEN "Type" ILIKE '%High%' OR "Message" ~* 'positive|approval|beat' THEN 'BULLISH'
|
|
WHEN "Type" ILIKE '%Low%' OR "Message" ~* 'negative|rejection|miss' THEN 'BEARISH'
|
|
ELSE 'NEUTRAL'
|
|
END AS sentiment
|
|
FROM public."AlertStream_monthly"
|
|
WHERE (
|
|
CASE
|
|
WHEN "Timestamp"::text ~ '^\d{4}-\d{2}-\d{2}'
|
|
THEN to_timestamp("Timestamp"::text, 'YYYY-MM-DD HH12:MI:SS AM')::timestamptz
|
|
WHEN "Timestamp"::text ~ '^\d{1,2}/\d{1,2}/\d{4}'
|
|
THEN to_timestamp("Timestamp"::text, 'MM/DD/YYYY HH12:MI:SS AM')::timestamptz
|
|
WHEN "date" IS NOT NULL AND "timestamp" IS NOT NULL
|
|
THEN CASE
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}\s*(AM|PM)$' AND btrim("timestamp")::text !~ '^\d{1,2}:\d{2}'
|
|
THEN NULL
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
ELSE NULL
|
|
END
|
|
ELSE NULL
|
|
END
|
|
) >= NOW() - INTERVAL '10 seconds'
|
|
AND (
|
|
CASE
|
|
WHEN "Timestamp"::text ~ '^\d{4}-\d{2}-\d{2}'
|
|
THEN to_timestamp("Timestamp"::text, 'YYYY-MM-DD HH12:MI:SS AM')::timestamptz
|
|
WHEN "Timestamp"::text ~ '^\d{1,2}/\d{1,2}/\d{4}'
|
|
THEN to_timestamp("Timestamp"::text, 'MM/DD/YYYY HH12:MI:SS AM')::timestamptz
|
|
WHEN "date" IS NOT NULL AND "timestamp" IS NOT NULL
|
|
THEN CASE
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}\s*(AM|PM)$' AND btrim("timestamp")::text !~ '^\d{1,2}:\d{2}'
|
|
THEN NULL
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
ELSE NULL
|
|
END
|
|
ELSE NULL
|
|
END
|
|
) IS NOT NULL
|
|
ORDER BY (
|
|
CASE
|
|
WHEN "Timestamp"::text ~ '^\d{4}-\d{2}-\d{2}'
|
|
THEN to_timestamp("Timestamp"::text, 'YYYY-MM-DD HH12:MI:SS AM')::timestamptz
|
|
WHEN "Timestamp"::text ~ '^\d{1,2}/\d{1,2}/\d{4}'
|
|
THEN to_timestamp("Timestamp"::text, 'MM/DD/YYYY HH12:MI:SS AM')::timestamptz
|
|
WHEN "date" IS NOT NULL AND "timestamp" IS NOT NULL
|
|
THEN CASE
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}\s*(AM|PM)$' AND btrim("timestamp")::text !~ '^\d{1,2}:\d{2}'
|
|
THEN NULL
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH12:MI:SS AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}\s*(AM|PM)$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH12:MI AM') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH24:MI:SS') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
WHEN btrim("timestamp")::text ~ '^\d{1,2}:\d{2}$'
|
|
THEN CASE
|
|
WHEN "date"::text ~ '^\d{4}-\d{2}-\d{2}$'
|
|
THEN (to_timestamp("date" || ' ' || btrim("timestamp"), 'YYYY-MM-DD HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
ELSE (to_timestamp("date" || ' ' || btrim("timestamp"), 'MM/DD/YYYY HH24:MI') AT TIME ZONE 'America/Chicago')
|
|
END
|
|
ELSE NULL
|
|
END
|
|
ELSE NULL
|
|
END
|
|
) DESC
|
|
`, []);
|
|
|
|
if (newAlerts && newAlerts.length > 0) {
|
|
newAlerts.forEach(alert => {
|
|
if (ws.readyState === ws.OPEN) {
|
|
ws.send(JSON.stringify({
|
|
type: 'NEW_ALERT',
|
|
data: alert,
|
|
timestamp: new Date().toISOString()
|
|
}));
|
|
}
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('Alert fetch error:', error);
|
|
}
|
|
}, 10000);
|
|
|
|
ws.on('close', () => {
|
|
clearInterval(interval);
|
|
console.log('Client disconnected from alerts');
|
|
});
|
|
|
|
ws.on('error', (error) => {
|
|
console.error('WebSocket error:', error);
|
|
clearInterval(interval);
|
|
});
|
|
});
|
|
|
|
return wss;
|
|
}
|
|
|
|
export default router;
|
|
|