"""Dashboard summary endpoints (reduce frontend API round-trips).""" from datetime import datetime, timedelta from fastapi import APIRouter, Depends from sqlalchemy import select, func, and_ from sqlalchemy.ext.asyncio import AsyncSession from app.api.deps import get_current_user from app.database import get_db from app.models.auction import DomainAuction from app.models.listing import DomainListing, ListingStatus from app.models.user import User # Reuse helpers for consistent formatting from app.api.auctions import _format_time_remaining, _get_affiliate_url from app.api.tld_prices import get_trending_tlds router = APIRouter() @router.get("/summary") async def get_dashboard_summary( current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): """ Return a compact dashboard payload used by `/terminal/radar`. Goal: 1 request instead of multiple heavy round-trips. """ now = datetime.utcnow() # ------------------------- # Market stats + preview # ------------------------- active_auctions_filter = and_(DomainAuction.is_active == True, DomainAuction.end_time > now) total_auctions = (await db.execute(select(func.count(DomainAuction.id)).where(active_auctions_filter))).scalar() or 0 cutoff = now + timedelta(hours=24) ending_soon_filter = and_( DomainAuction.is_active == True, DomainAuction.end_time > now, DomainAuction.end_time <= cutoff, ) ending_soon_count = (await db.execute(select(func.count(DomainAuction.id)).where(ending_soon_filter))).scalar() or 0 ending_soon = ( await db.execute( select(DomainAuction) .where(ending_soon_filter) .order_by(DomainAuction.end_time.asc()) .limit(5) ) ).scalars().all() ending_soon_preview = [ { "domain": a.domain, "current_bid": a.current_bid, "time_remaining": _format_time_remaining(a.end_time, now=now), "platform": a.platform, "affiliate_url": _get_affiliate_url(a.platform, a.domain, a.auction_url), } for a in ending_soon ] # ------------------------- # Listings stats (user) # ------------------------- listing_counts = ( await db.execute( select(DomainListing.status, func.count(DomainListing.id)) .where(DomainListing.user_id == current_user.id) .group_by(DomainListing.status) ) ).all() by_status = {status: int(count) for status, count in listing_counts} listing_stats = { "active": by_status.get(ListingStatus.ACTIVE.value, 0), "sold": by_status.get(ListingStatus.SOLD.value, 0), "draft": by_status.get(ListingStatus.DRAFT.value, 0), "total": sum(by_status.values()), } # ------------------------- # Trending TLDs (public data) # ------------------------- trending = await get_trending_tlds(db) return { "market": { "total_auctions": total_auctions, "ending_soon": ending_soon_count, "ending_soon_preview": ending_soon_preview, }, "listings": listing_stats, "tlds": trending, "timestamp": now.isoformat(), }