Files
classifieds/app/services/admin_dashboard.py
T
nngo 2e9025fe55 06/16 Phase 6 foundation: admin blueprint, audit log, user management
Adds the admin backend foundation: AuditLog + Setting models/migration,
an admin-only dashboard with KPI cards, and user management (search,
ban/suspend/activate, tier override, trust adjust) with audit logging
on every write action. Smoke suite extended to 64 checks.
2026-06-16 11:45:00 -04:00

45 lines
1.5 KiB
Python

"""Admin dashboard KPI queries. Money returned as integer cents."""
from datetime import datetime, timedelta
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 > datetime.utcnow(),
).count()
def new_users_count(days):
since = datetime.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 = datetime.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():
return Listing.query.filter(Listing.flag_count > 0).count()