"""Alerts API endpoints.""" from typing import List, Optional from fastapi import APIRouter, HTTPException, Depends from pydantic import BaseModel from datetime import datetime from sqlalchemy import select from src.core.database import Alert, get_database router = APIRouter() def get_alert_manager(): """Get alert manager instance.""" from src.alerts.manager import get_alert_manager as _get_alert_manager return _get_alert_manager() class AlertCreate(BaseModel): """Create alert request.""" name: str alert_type: str # price, indicator, risk, system condition: dict class AlertUpdate(BaseModel): """Update alert request.""" name: Optional[str] = None condition: Optional[dict] = None enabled: Optional[bool] = None class AlertResponse(BaseModel): """Alert response.""" id: int name: str alert_type: str condition: dict enabled: bool triggered: bool triggered_at: Optional[datetime] = None created_at: datetime updated_at: datetime class Config: from_attributes = True @router.get("/", response_model=List[AlertResponse]) async def list_alerts( enabled_only: bool = False, manager=Depends(get_alert_manager) ): """List all alerts.""" try: alerts = await manager.list_alerts(enabled_only=enabled_only) return [AlertResponse.model_validate(alert) for alert in alerts] except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/", response_model=AlertResponse) async def create_alert( alert_data: AlertCreate, manager=Depends(get_alert_manager) ): """Create a new alert.""" try: alert = await manager.create_alert( name=alert_data.name, alert_type=alert_data.alert_type, condition=alert_data.condition ) return AlertResponse.model_validate(alert) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/{alert_id}", response_model=AlertResponse) async def get_alert(alert_id: int): """Get alert by ID.""" try: db = get_database() async with db.get_session() as session: stmt = select(Alert).where(Alert.id == alert_id) result = await session.execute(stmt) alert = result.scalar_one_or_none() if not alert: raise HTTPException(status_code=404, detail="Alert not found") return AlertResponse.model_validate(alert) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.put("/{alert_id}", response_model=AlertResponse) async def update_alert(alert_id: int, alert_data: AlertUpdate): """Update an alert.""" try: db = get_database() async with db.get_session() as session: stmt = select(Alert).where(Alert.id == alert_id) result = await session.execute(stmt) alert = result.scalar_one_or_none() if not alert: raise HTTPException(status_code=404, detail="Alert not found") if alert_data.name is not None: alert.name = alert_data.name if alert_data.condition is not None: alert.condition = alert_data.condition if alert_data.enabled is not None: alert.enabled = alert_data.enabled await session.commit() await session.refresh(alert) return AlertResponse.model_validate(alert) except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.delete("/{alert_id}") async def delete_alert(alert_id: int): """Delete an alert.""" try: db = get_database() async with db.get_session() as session: stmt = select(Alert).where(Alert.id == alert_id) result = await session.execute(stmt) alert = result.scalar_one_or_none() if not alert: raise HTTPException(status_code=404, detail="Alert not found") await session.delete(alert) await session.commit() return {"status": "deleted", "alert_id": alert_id} except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e))