Saltar al contenido principal

Moderación de usuarios

Los administradores y moderadores pueden buscar usuarios, ver su historial de moderación, y tomar acciones — advertencias, suspensiones, baneos y verificación — desde el panel de administración.

Checklist de implementación

Buscar y ver usuarios

  • Buscar y listar usuarios con filtros (adminGetUsers - backend listo, conectado a la página de listado de usuarios)
  • Obtener el perfil de moderación de un usuario (adminGetUserDetails - backend listo, conectado a la página de detalle de usuario)
  • Obtener el historial de acciones de moderación de un usuario (adminGetUserModerationHistory - conectado a la sección "Historial de moderación" de la página de detalle de usuario)
  • Estadísticas de usuarios a nivel de plataforma (adminGetUserStats - conectado a las tarjetas de estadísticas de la página de listado de usuarios)
  • Las queries adminGetSuspendedUsers, adminGetBannedUsers, adminGetUserSuspensions y adminGetUserWarnings han sido eliminadas del esquema (ya no están en admin/user-moderation.type.js ni en admin/user-moderation.resolver.js). La página de listado de usuarios sigue filtrando por estado mediante adminGetUsers en su lugar; los conteos de suspensiones/advertencias por usuario se muestran a través de adminGetUserDetails (warningCount) y el historial a través de adminGetUserModerationHistory. El manager todavía tiene los métodos getSuspendedUsers/getBannedUsers/getUserSuspensions/getUserWarnings en user-moderation.manager.js, pero ahora son código muerto inalcanzable - ningún resolver los llama.

Suspender, advertir y banear

  • Suspender a un usuario (adminSuspendUser - backend listo, conectado a la página de detalle de usuario)
  • Levantar una suspensión (adminUnsuspendUser - backend listo, conectado a la página de detalle de usuario)
  • Emitir una advertencia (adminWarnUser - conectado a la página de detalle de usuario. Corregido en esta sesión: pasaba el ID del administrador emisor como issued_by, pero create() de user-warnings.access-service.js solo lee adminId/admin_id - la columna admin_id de la advertencia persistida siempre quedaba en NULL.)
  • Banear a un usuario (adminBanUser - conectado a la página de detalle de usuario. Corregido en esta sesión: cuando se solicita "también eliminar contenido" llama internamente a removeUserContent, pero lo hacía con solo 3 de sus 5 argumentos, así que context caía en la posición de reason y adminId/context quedaban ambos undefined más abajo - inofensivo por coincidencia ya que removeUserContent tampoco usaba esos parámetros, pero un desajuste de firma real; ahora pasa los 5 en orden.)
  • Revertir un baneo (adminUnbanUser - backend listo, conectado a la página de detalle de usuario)
  • Eliminar el contenido de un usuario (posts/comentarios) (adminRemoveUserContent - conectado a la acción "Eliminar contenido" de la página de detalle de usuario, con un selector de tipo de contenido: ALL/POSTS/COMMENTS. Corregido en esta sesión: la rama POSTS llamaba a postAccessService.findByUser(), un método que no existe (el método real es getByUser) - el error resultante era silenciosamente absorbido por el try/catch que lo rodeaba, lo cual significaba que contentType: 'ALL' omitía silenciosamente POSTS y todo tipo de contenido posterior dentro del mismo bloque try, mientras seguía reportando success: true. El selector antes también ofrecía BLASTS/TALES/ARTICLES; se eliminaron porque nunca tuvieron un modelo de backend real — ver la nota del enum ContentType en la referencia técnica de Moderación de Contenido.)

Moderación masiva

  • Suspender usuarios en lote (solo super_admin) (adminBulkSuspendUsers - conectado a la acción de selección en lote + "Suspender seleccionados" de la página de listado de usuarios)
  • Banear usuarios en lote (solo super_admin) (adminBulkBanUsers(userIds, reason, permanent) - el resolver está protegido por isSuperAdminuserModerationManager.bulkBanUsers, que llama a banUser por cada usuario con deleteContent: false, notifyUser: false. Corregido en esta sesión: su tipo de retorno era ModerationActionResponse (success/message/actionId), que no expone los successCount/failedCount/total/errors que el manager ya calcula por usuario - se amplió a un nuevo tipo UserBulkOperationResponse (adminBulkSuspendUsers se amplió de la misma forma, mismo hueco latente). Conectado a un botón "Banear seleccionados" en la barra de selección múltiple de la página /users, solo super_admin, junto a la acción de suspensión en lote ya existente; un resultado parcialmente fallido ahora muestra un mensaje en línea "N exitosos, M fallidos" en lugar de un éxito ciego.)

Verificación (esquema de administrador)

Estas son independientes del flujo de solicitud de verificación orientado al cliente (getPendingVerificationRequests / grantVerification / removeVerification / rejectVerificationRequest), que vive en el esquema de cliente y está documentado en Verificación. Ambas son implementaciones reales e independientes de una funcionalidad similar, en esquemas distintos con modelos de autenticación distintos.

Referencia técnica

Ver Panel de administración → Gestión de usuarios para la API completa de GraphQL.