Files
classifieds/app/services/admin_dashboard.py
T
2026-07-13 16:52:00 -04:00

47 lines
1.6 KiB
Python

"""Admin dashboard KPI queries. Money returned as integer cents."""
from datetime import datetime, timedelta
from app.utils.time import utcnow
from app.extensions import db
from app.models.user import User
from app.models.listing import Listing
from app.models.enums import ListingStatus
from app.models.plan import Plan
from app.models.payments import Subscription, Transaction
_ACTIVE_SUB_STATUSES = ("active", "trialing")
def active_listings_count():
return Listing.query.filter(
Listing.status == ListingStatus.active,
Listing.expires_at > utcnow(),
).count()
def new_users_count(days):
since = utcnow() - timedelta(days=days)
return User.query.filter(User.created_at >= since).count()
def mrr_cents():
"""Sum price_monthly_cents for users with an active/trialing subscription."""
return (db.session.query(db.func.coalesce(db.func.sum(Plan.price_monthly_cents), 0))
.join(Subscription, Subscription.plan_id == Plan.id)
.filter(Subscription.status.in_(_ACTIVE_SUB_STATUSES))
.scalar())
def revenue_30d_cents():
"""Subscription + boost transactions in the last 30 days."""
since = utcnow() - timedelta(days=30)
return (db.session.query(db.func.coalesce(db.func.sum(Transaction.amount_cents), 0))
.filter(Transaction.type.in_(("subscription", "boost")),
Transaction.created_at >= since,
Transaction.status == "succeeded")
.scalar())
def flag_queue_depth():
from app.services.moderation import QUEUE_FILTER
return Listing.query.filter(QUEUE_FILTER).count()