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:
2026-06-16 11:45:00 -04:00
parent 62b04803ad
commit 2e9025fe55
18 changed files with 680 additions and 1 deletions
+47
View File
@@ -0,0 +1,47 @@
"""Admin user-management: search/filter and state-transition helpers.
Each mutation function appends an AuditLog row via services/audit.py but
does not commit — the calling route commits once after invoking it.
"""
from app.extensions import db
from app.models.user import User
from app.models.enums import Role, UserStatus, TrustEventType
from app.services import audit
def search_query(*, role=None, status=None, q=None):
query = User.query
if role:
query = query.filter(User.role == Role(role))
if status:
query = query.filter(User.status == UserStatus(status))
if q:
term = f"%{q.strip()}%"
query = query.filter(db.or_(
User.email.ilike(term),
User.display_name.ilike(term),
))
return query.order_by(User.created_at.desc())
def set_status(user, new_status: UserStatus, *, actor, reason=None):
"""Transition a user's status (active/suspended/banned). Caller commits."""
user.status = new_status
audit.log_action(actor, f"user.{new_status.value}", "user", user.id,
meta={"reason": reason} if reason else None)
def set_tier(user, plan, *, actor):
"""Override a user's plan tier directly. Caller commits."""
old_tier_id = user.tier_id
user.tier_id = plan.id if plan else None
audit.log_action(actor, "user.tier_override", "user", user.id,
meta={"old_tier_id": old_tier_id, "new_tier_id": user.tier_id})
def adjust_trust(user, event_type: TrustEventType, delta: int, *, actor):
"""Manually adjust a user's trust score/tier. Caller commits."""
from app.services import trust as trust_svc
trust_svc.record_event(user, event_type, delta)
audit.log_action(actor, "user.trust_adjust", "user", user.id,
meta={"event_type": event_type.value, "delta": delta})