from fastapi import APIRouter, Request, Depends from sqlalchemy.orm import Session from datetime import datetime, timedelta from backend.database import get_db from backend.models import ScheduledAction, MonitoringLocation, Project from backend.services.snapshot import emit_status_snapshot from backend.templates_config import templates from backend.utils.timezone import utc_to_local, local_to_utc, get_user_timezone router = APIRouter() @router.get("/dashboard/active") def dashboard_active(request: Request): snapshot = emit_status_snapshot() return templates.TemplateResponse( "partials/active_table.html", {"request": request, "units": snapshot["active"]} ) @router.get("/dashboard/benched") def dashboard_benched(request: Request): snapshot = emit_status_snapshot() return templates.TemplateResponse( "partials/benched_table.html", {"request": request, "units": snapshot["benched"]} ) @router.get("/dashboard/todays-actions") def dashboard_todays_actions(request: Request, db: Session = Depends(get_db)): """ Get today's scheduled actions for the dashboard card. Shows upcoming, completed, and failed actions for today. """ import json from zoneinfo import ZoneInfo # Get today's date range in local timezone tz = ZoneInfo(get_user_timezone()) now_local = datetime.now(tz) today_start_local = now_local.replace(hour=0, minute=0, second=0, microsecond=0) today_end_local = today_start_local + timedelta(days=1) # Convert to UTC for database query today_start_utc = today_start_local.astimezone(ZoneInfo("UTC")).replace(tzinfo=None) today_end_utc = today_end_local.astimezone(ZoneInfo("UTC")).replace(tzinfo=None) # Query today's actions actions = db.query(ScheduledAction).filter( ScheduledAction.scheduled_time >= today_start_utc, ScheduledAction.scheduled_time < today_end_utc, ).order_by(ScheduledAction.scheduled_time.asc()).all() # Enrich with location/project info and parse results enriched_actions = [] for action in actions: location = None project = None if action.location_id: location = db.query(MonitoringLocation).filter_by(id=action.location_id).first() if action.project_id: project = db.query(Project).filter_by(id=action.project_id).first() # Parse module_response for result details result_data = None if action.module_response: try: result_data = json.loads(action.module_response) except json.JSONDecodeError: pass enriched_actions.append({ "action": action, "location": location, "project": project, "result": result_data, }) # Count by status pending_count = sum(1 for a in actions if a.execution_status == "pending") completed_count = sum(1 for a in actions if a.execution_status == "completed") failed_count = sum(1 for a in actions if a.execution_status == "failed") return templates.TemplateResponse( "partials/dashboard/todays_actions.html", { "request": request, "actions": enriched_actions, "pending_count": pending_count, "completed_count": completed_count, "failed_count": failed_count, "total_count": len(actions), } )