ab-ms-core / app /controllers /dashboard.py
MukeshKapoor25's picture
feat(dashboard): update new projects query to use CreatedDate instead of BidDate
36d0907
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__)
@router.get("/widgets/info", response_model=List[InfoWidget], summary="Dashboard info widgets")
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