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.
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user