trading-platform-backend/src/modules/trading/controllers/alerts.controller.ts

190 lines
5.4 KiB
TypeScript

/**
* 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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
try {
const authReq = req as AuthenticatedRequest;
const stats = await alertsService.getUserAlertStats(authReq.user.id);
res.json({ success: true, data: stats });
} catch (error) {
next(error);
}
}