/** * Price Alerts Controller * Handles price alert endpoints */ import type { Request, Response, NextFunction } from 'express'; import { alertsService, AlertCondition } from '../services/alerts.service'; import type { AuthenticatedRequest } from '../../../core/guards/auth.guard'; // ============================================================================ // CRUD Operations // ============================================================================ export async function createAlert(req: Request, res: Response, next: NextFunction): Promise { try { const authReq = req as AuthenticatedRequest; const { symbol, condition, price, note, notifyEmail, notifyPush, isRecurring } = req.body; if (!symbol || !condition || price === undefined) { res.status(400).json({ success: false, error: 'Symbol, condition, and price are required', }); return; } const validConditions: AlertCondition[] = ['above', 'below', 'crosses_above', 'crosses_below']; if (!validConditions.includes(condition)) { res.status(400).json({ success: false, error: `Invalid condition. Must be one of: ${validConditions.join(', ')}`, }); return; } const alert = await alertsService.createAlert({ userId: authReq.user.id, symbol, condition, price, note, notifyEmail, notifyPush, isRecurring, }); res.status(201).json({ success: true, data: alert }); } catch (error) { next(error); } } export async function getAlerts(req: Request, res: Response, next: NextFunction): Promise { try { const authReq = req as AuthenticatedRequest; const { isActive, symbol, condition } = req.query; const alerts = await alertsService.getUserAlerts(authReq.user.id, { isActive: isActive === 'true' ? true : isActive === 'false' ? false : undefined, symbol: symbol as string, condition: condition as AlertCondition, }); res.json({ success: true, data: alerts }); } catch (error) { next(error); } } export async function getAlertById(req: Request, res: Response, next: NextFunction): Promise { try { const authReq = req as AuthenticatedRequest; const { alertId } = req.params; const alert = await alertsService.getAlertById(alertId); if (!alert) { res.status(404).json({ success: false, error: 'Alert not found' }); return; } if (alert.userId !== authReq.user.id) { res.status(403).json({ success: false, error: 'Unauthorized' }); return; } res.json({ success: true, data: alert }); } catch (error) { next(error); } } export async function updateAlert(req: Request, res: Response, next: NextFunction): Promise { try { const authReq = req as AuthenticatedRequest; const { alertId } = req.params; const { price, note, notifyEmail, notifyPush, isRecurring, isActive } = req.body; const alert = await alertsService.updateAlert(alertId, authReq.user.id, { price, note, notifyEmail, notifyPush, isRecurring, isActive, }); if (!alert) { res.status(404).json({ success: false, error: 'Alert not found or unauthorized' }); return; } res.json({ success: true, data: alert }); } catch (error) { next(error); } } export async function deleteAlert(req: Request, res: Response, next: NextFunction): Promise { try { const authReq = req as AuthenticatedRequest; const { alertId } = req.params; const deleted = await alertsService.deleteAlert(alertId, authReq.user.id); if (!deleted) { res.status(404).json({ success: false, error: 'Alert not found or unauthorized' }); return; } res.json({ success: true, message: 'Alert deleted' }); } catch (error) { next(error); } } // ============================================================================ // Enable/Disable // ============================================================================ export async function enableAlert(req: Request, res: Response, next: NextFunction): Promise { try { const authReq = req as AuthenticatedRequest; const { alertId } = req.params; const alert = await alertsService.enableAlert(alertId, authReq.user.id); if (!alert) { res.status(404).json({ success: false, error: 'Alert not found or unauthorized' }); return; } res.json({ success: true, data: alert }); } catch (error) { next(error); } } export async function disableAlert(req: Request, res: Response, next: NextFunction): Promise { try { const authReq = req as AuthenticatedRequest; const { alertId } = req.params; const alert = await alertsService.disableAlert(alertId, authReq.user.id); if (!alert) { res.status(404).json({ success: false, error: 'Alert not found or unauthorized' }); return; } res.json({ success: true, data: alert }); } catch (error) { next(error); } } // ============================================================================ // Statistics // ============================================================================ export async function getAlertStats(req: Request, res: Response, next: NextFunction): Promise { try { const authReq = req as AuthenticatedRequest; const stats = await alertsService.getUserAlertStats(authReq.user.id); res.json({ success: true, data: stats }); } catch (error) { next(error); } }