main
py 376 lines 12.1 KB
Raw
1 from typing import List
2
3 from fastapi import APIRouter
4 from fastapi import Depends
5 from fastapi import HTTPException
6 from fastapi import Security
7 from loguru import logger
8 from sqlalchemy.ext.asyncio import AsyncSession
9 from sqlalchemy.future import select
10 from sqlalchemy.orm import joinedload
11
12 from app.auth.routes.auth import AuthHandler
13 from app.db.db_session import get_db
14 from app.integrations.alert_creation_settings.models.alert_creation_settings import (
15 AlertCreationEventConfig,
16 )
17 from app.integrations.alert_creation_settings.models.alert_creation_settings import (
18 AlertCreationSettings,
19 )
20 from app.integrations.alert_creation_settings.models.alert_creation_settings import (
21 EventOrder,
22 )
23 from app.integrations.alert_creation_settings.schema.alert_creation_settings import (
24 AlertCreationEventConfigResponse,
25 )
26 from app.integrations.alert_creation_settings.schema.alert_creation_settings import (
27 AlertCreationSettingsCreate,
28 )
29 from app.integrations.alert_creation_settings.schema.alert_creation_settings import (
30 AlertCreationSettingsResponse,
31 )
32 from app.integrations.alert_creation_settings.schema.alert_creation_settings import (
33 EventOrderCreate,
34 )
35 from app.integrations.alert_creation_settings.schema.alert_creation_settings import (
36 EventOrderResponse,
37 )
38 from app.utils import get_customer_alert_event_configs
39
40 alert_creation_settings_router = APIRouter()
41
42
43 @alert_creation_settings_router.get(
44 "/{customer_code}/event_configs",
45 response_model=List[List[AlertCreationEventConfigResponse]],
46 description="Get all alert event configs for a customer.",
47 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
48 )
49 async def get_customer_event_configs(
50 customer_code: str,
51 session: AsyncSession = Depends(get_db),
52 ):
53 """
54 Retrieve all alert event configurations for a specific customer.
55
56 Args:
57 customer_code (str): The code of the customer.
58 session (AsyncSession, optional): The database session. Defaults to Depends(get_db).
59
60 Returns:
61 List[List[AlertCreationEventConfigResponse]]: A list of alert event configurations.
62
63 Raises:
64 HTTPException: If no event configurations are found for the customer.
65 """
66 event_configs = await get_customer_alert_event_configs(customer_code, session)
67
68 if not event_configs:
69 raise HTTPException(
70 status_code=404,
71 detail="No event configs found for this customer.",
72 )
73
74 return event_configs
75
76
77 @alert_creation_settings_router.post(
78 "/create",
79 response_model=AlertCreationSettings,
80 description="Create a new alert creation setting.",
81 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
82 )
83 async def create_alert_creation_settings(
84 alert_creation_settings: AlertCreationSettingsCreate,
85 session: AsyncSession = Depends(get_db),
86 ):
87 """
88 Create a new alert creation setting.
89
90 Args:
91 alert_creation_settings (AlertCreationSettingsCreate): The data for creating the alert creation setting.
92 session (AsyncSession, optional): The database session. Defaults to Depends(get_db).
93
94 Returns:
95 AlertCreationSettings: The created alert creation setting.
96 """
97 logger.info(f"alert_creation_settings: {alert_creation_settings.model_dump()}")
98
99 result = await session.execute(
100 select(AlertCreationSettings).where(
101 AlertCreationSettings.customer_code == alert_creation_settings.customer_code,
102 ),
103 )
104 settings = result.scalars().first()
105
106 if settings:
107 logger.info(
108 f"Alert creation settings already exist for customer_code: {alert_creation_settings.customer_code}",
109 )
110 raise HTTPException(
111 status_code=200,
112 detail="Alert creation settings already exist.",
113 )
114
115 alert_creation_settings_db = AlertCreationSettings(
116 **alert_creation_settings.model_dump(exclude={"event_orders"}),
117 )
118
119 if alert_creation_settings.event_orders is not None:
120 for event_order in alert_creation_settings.event_orders:
121 event_order_db = EventOrder(
122 order_label=event_order.order_label,
123 alert_creation_settings=alert_creation_settings_db,
124 )
125 session.add(event_order_db)
126 for event_config in event_order.event_configs:
127 event_config_db = AlertCreationEventConfig(
128 **event_config.model_dump(),
129 event_order=event_order_db,
130 )
131 session.add(event_config_db)
132
133 session.add(alert_creation_settings_db)
134 await session.commit()
135 await session.refresh(alert_creation_settings_db)
136
137 return alert_creation_settings_db
138
139
140 @alert_creation_settings_router.get(
141 "/{customer_name}",
142 response_model=AlertCreationSettingsResponse,
143 description="Retrieve alert creation settings by customer name.",
144 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
145 )
146 async def get_alert_creation_settings(
147 customer_name: str,
148 session: AsyncSession = Depends(get_db),
149 ):
150 """
151 Retrieve alert creation settings by customer name.
152
153 Args:
154 customer_name (str): The name of the customer.
155
156 Returns:
157 AlertCreationSettings: The alert creation settings for the specified customer.
158
159 Raises:
160 HTTPException: If the alert creation settings are not found.
161 """
162 result = await session.execute(
163 select(AlertCreationSettings)
164 .options(
165 joinedload(AlertCreationSettings.event_orders).joinedload(
166 EventOrder.event_configs,
167 ),
168 )
169 .where(AlertCreationSettings.customer_name == customer_name),
170 )
171 settings = result.scalars().first()
172
173 if not settings:
174 raise HTTPException(
175 status_code=404,
176 detail="Alert creation settings not found.",
177 )
178
179 return settings
180
181
182 @alert_creation_settings_router.post(
183 "/{customer_name}/event",
184 response_model=EventOrderResponse,
185 description="Add a new event to a customer's alert creation settings.",
186 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
187 )
188 async def add_event_order(
189 customer_name: str,
190 event_order: EventOrderCreate,
191 session: AsyncSession = Depends(get_db),
192 ):
193 """
194 Add a new event to a customer's alert creation settings.
195
196 Args:
197 customer_name (str): The name of the customer.
198 event_order (EventOrderCreate): The event order to be added.
199 session (AsyncSession, optional): The database session. Defaults to Depends(get_db).
200
201 Returns:
202 EventOrder: The newly created event order.
203 """
204 result = await session.execute(
205 select(AlertCreationSettings)
206 .options(
207 joinedload(AlertCreationSettings.event_orders).joinedload(
208 EventOrder.event_configs,
209 ),
210 )
211 .where(AlertCreationSettings.customer_name == customer_name),
212 )
213 settings = result.scalars().first()
214
215 if not settings:
216 raise HTTPException(
217 status_code=404,
218 detail="Alert creation settings not found.",
219 )
220
221 # Create new event order and configs
222 event_order_db = EventOrder(
223 order_label=event_order.order_label,
224 alert_creation_settings=settings,
225 )
226 session.add(event_order_db)
227 for event_config in event_order.event_configs:
228 event_config_db = AlertCreationEventConfig(
229 **event_config.model_dump(),
230 event_order=event_order_db,
231 )
232 session.add(event_config_db)
233
234 await session.commit()
235
236 # Query the EventOrder instance again to ensure event_configs are loaded
237 result = await session.execute(
238 select(EventOrder).options(joinedload(EventOrder.event_configs)).where(EventOrder.id == event_order_db.id),
239 )
240 event_order_db = result.scalars().first()
241
242 return event_order_db
243
244
245 @alert_creation_settings_router.put(
246 "/{customer_name}",
247 response_model=AlertCreationSettingsResponse,
248 description="Update a customer's event orders.",
249 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
250 )
251 async def update_event_orders(
252 customer_name: str,
253 event_orders: List[EventOrderCreate],
254 session: AsyncSession = Depends(get_db),
255 ):
256 """
257 Update a customer's event orders.
258
259 Args:
260 customer_name (str): The name of the customer.
261 event_orders (List[EventOrderCreate]): The list of event orders to update.
262 session (AsyncSession, optional): The database session. Defaults to Depends(get_db).
263
264 Returns:
265 AlertCreationSettings: The updated alert creation settings.
266 """
267 result = await session.execute(
268 select(AlertCreationSettings)
269 .options(
270 joinedload(AlertCreationSettings.event_orders).joinedload(
271 EventOrder.event_configs,
272 ),
273 )
274 .where(AlertCreationSettings.customer_name == customer_name),
275 )
276 settings = result.scalars().first()
277
278 if not settings:
279 raise HTTPException(
280 status_code=404,
281 detail="Alert creation settings not found.",
282 )
283
284 # Create new event orders and configs or add to existing ones
285 for event_order in event_orders:
286 # Check if an EventOrder with the given order_label already exists
287 existing_order = next(
288 (order for order in settings.event_orders if order.order_label == event_order.order_label),
289 None,
290 )
291
292 if existing_order:
293 # If it does, add the new EventConfig instances to it
294 for event_config in event_order.event_configs:
295 event_config_db = AlertCreationEventConfig(
296 **event_config.model_dump(),
297 event_order=existing_order,
298 )
299 session.add(event_config_db)
300 else:
301 # If it doesn't, return a 404
302 raise HTTPException(
303 status_code=404,
304 detail=f"Event order with order_label: {event_order.order_label} not found.",
305 )
306
307 await session.commit()
308 await session.refresh(settings)
309
310 return settings
311
312
313 @alert_creation_settings_router.delete(
314 "/{customer_name}/event/{order_label}",
315 description="Delete an event order by order_label.",
316 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst"))],
317 )
318 async def delete_event_order(
319 customer_name: str,
320 order_label: str,
321 session: AsyncSession = Depends(get_db),
322 ):
323 """
324 Delete an event order by order_label.
325
326 Args:
327 customer_name (str): The name of the customer.
328 order_label (str): The label of the event order.
329 session (AsyncSession, optional): The database session. Defaults to Depends(get_db).
330
331 Returns:
332 dict: A dictionary containing the success message.
333 """
334 result = await session.execute(
335 select(AlertCreationSettings)
336 .options(
337 joinedload(AlertCreationSettings.event_orders).joinedload(
338 EventOrder.event_configs,
339 ),
340 )
341 .where(AlertCreationSettings.customer_name == customer_name),
342 )
343 settings = result.scalars().first()
344
345 if not settings:
346 raise HTTPException(
347 status_code=404,
348 detail="Alert creation settings not found.",
349 )
350
351 # Check if an EventOrder with the given order_label exists
352 existing_order = next(
353 (order for order in settings.event_orders if order.order_label == order_label),
354 None,
355 )
356
357 if existing_order:
358 # If it does, delete its AlertCreationEventConfig instances
359 for config in existing_order.event_configs:
360 await session.delete(config)
361
362 # Then delete the EventOrder itself
363 await session.delete(existing_order)
364 else:
365 # If it doesn't, return a 404
366 raise HTTPException(
367 status_code=404,
368 detail=f"Event order with order_label: {order_label} not found.",
369 )
370
371 await session.commit()
372
373 return {
374 "message": f"Event order with order_label: {order_label} and related alert creation event configs deleted.",
375 "success": True,
376 }