64 lines
2.5 KiB
Python
64 lines
2.5 KiB
Python
from fastapi import APIRouter, Depends
|
|
from sqlalchemy import func, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.deps import get_current_active_user, get_db
|
|
from app.models.comment import Comment
|
|
from app.models.event import Event, EventRegistration
|
|
from app.models.favorite import Favorite
|
|
from app.models.promotion import Promotion
|
|
from app.models.rating import Rating
|
|
from app.models.shooting import ShootingRequest, ShootingApplication
|
|
from app.models.spot import Spot
|
|
from app.models.user import User
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/overview")
|
|
async def get_stats_overview(
|
|
current_user: User = Depends(get_current_active_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
if current_user.role not in ("admin", "moderator"):
|
|
return {"detail": "Not allowed"}
|
|
|
|
user_count = (await db.execute(select(func.count(User.id)))).scalar() or 0
|
|
spot_count = (await db.execute(select(func.count(Spot.id)))).scalar() or 0
|
|
approved_spot_count = (await db.execute(
|
|
select(func.count(Spot.id)).where(Spot.audit_status == "approved")
|
|
)).scalar() or 0
|
|
pending_spot_count = (await db.execute(
|
|
select(func.count(Spot.id)).where(Spot.audit_status == "pending")
|
|
)).scalar() or 0
|
|
comment_count = (await db.execute(select(func.count(Comment.id)))).scalar() or 0
|
|
rating_count = (await db.execute(select(func.count(Rating.id)))).scalar() or 0
|
|
favorite_count = (await db.execute(select(func.count(Favorite.id)))).scalar() or 0
|
|
shooting_count = (await db.execute(select(func.count(ShootingRequest.id)))).scalar() or 0
|
|
event_count = (await db.execute(select(func.count(Event.id)))).scalar() or 0
|
|
|
|
promo_result = await db.execute(
|
|
select(
|
|
func.coalesce(func.sum(Promotion.impressions), 0),
|
|
func.coalesce(func.sum(Promotion.clicks), 0),
|
|
)
|
|
)
|
|
promo_row = promo_result.one()
|
|
total_impressions = int(promo_row[0])
|
|
total_clicks = int(promo_row[1])
|
|
|
|
return {
|
|
"user_count": user_count,
|
|
"spot_count": spot_count,
|
|
"approved_spot_count": approved_spot_count,
|
|
"pending_spot_count": pending_spot_count,
|
|
"comment_count": comment_count,
|
|
"rating_count": rating_count,
|
|
"favorite_count": favorite_count,
|
|
"shooting_count": shooting_count,
|
|
"event_count": event_count,
|
|
"promo_impressions": total_impressions,
|
|
"promo_clicks": total_clicks,
|
|
"promo_ctr": round(total_clicks / total_impressions * 100, 2) if total_impressions > 0 else 0,
|
|
}
|