"""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})