Spaces:
Paused
Paused
| from fastapi import APIRouter, Depends | |
| from typing import List | |
| from datetime import datetime, timedelta | |
| from sqlalchemy import func, or_, and_ | |
| from sqlalchemy.orm import Session | |
| from app.schemas.dashboard import InfoWidget | |
| from app.db.session import get_db | |
| from app.db.models.project import Project | |
| from app.core.timing import timer | |
| import logging | |
| router = APIRouter(prefix="/api/v1/dashboard", tags=["dashboard"]) | |
| logger = logging.getLogger(__name__) | |
| def get_info_widgets(db: Session = Depends(get_db)) -> List[InfoWidget]: | |
| """Return live counts for dashboard info widgets. | |
| Definitions: | |
| - Projects Executed: projects with InstallDate within the last 7 days. | |
| - New Projects: projects with CreatedDate within the last 7 days. | |
| - Active Projects: projects where Status = 5 (per StatusInfo mapping). | |
| Deltas compare the last 7 days vs the prior 7-day window for the first two metrics. | |
| """ | |
| logger.debug("Fetching dashboard info widgets") | |
| now = datetime.utcnow() | |
| current_start = now - timedelta(days=7) | |
| prev_start = now - timedelta(days=14) | |
| prev_end = current_start | |
| def pct_change(curr: int, prev: int) -> float: | |
| if prev is None or prev == 0: | |
| return 0.0 | |
| return round(((curr - prev) / prev) * 100.0, 2) | |
| # Projects Executed: InstallDate in last 7 days | |
| with timer("Dashboard: Projects Executed query"): | |
| executed_current = ( | |
| db.query(func.count(Project.project_no)) | |
| .filter(Project.install_date >= current_start, Project.install_date < now) | |
| .scalar() | |
| or 0 | |
| ) | |
| executed_prev = ( | |
| db.query(func.count(Project.project_no)) | |
| .filter(Project.install_date >= prev_start, Project.install_date < prev_end) | |
| .scalar() | |
| or 0 | |
| ) | |
| # New Projects: CreatedDate in last 7 days | |
| with timer("Dashboard: New Projects query"): | |
| new_current = ( | |
| db.query(func.count(Project.project_no)) | |
| .filter(Project.created_date >= current_start, Project.created_date < now) | |
| .scalar() | |
| or 0 | |
| ) | |
| new_prev = ( | |
| db.query(func.count(Project.project_no)) | |
| .filter(Project.created_date >= prev_start, Project.created_date < prev_end) | |
| .scalar() | |
| or 0 | |
| ) | |
| # Active Projects: Status = 5 (from StatusInfo) | |
| ACTIVE_STATUS_ID = 5 | |
| with timer("Dashboard: Active Projects query"): | |
| active_current = ( | |
| db.query(func.count(Project.project_no)) | |
| .filter(Project.status == ACTIVE_STATUS_ID) | |
| .scalar() | |
| or 0 | |
| ) | |
| widgets: List[InfoWidget] = [ | |
| InfoWidget( | |
| label="Projects Executed", | |
| value=int(executed_current), | |
| subtitle="Last 7 days", | |
| delta_percent=pct_change(int(executed_current), int(executed_prev)), | |
| delta_from="from last week", | |
| ), | |
| InfoWidget( | |
| label="New Projects", | |
| value=int(new_current), | |
| subtitle="Last 7 days", | |
| delta_percent=pct_change(int(new_current), int(new_prev)), | |
| delta_from="from last week", | |
| ), | |
| InfoWidget( | |
| label="Active Projects", | |
| value=int(active_current), | |
| subtitle="Currently in progress", | |
| # Without historical snapshots, prior active count is unknown; report 0% change. | |
| delta_percent=0.0, | |
| delta_from="from last week", | |
| ), | |
| ] | |
| return widgets | |