Revisión de verificación de identidad
Los administradores revisan la cola de verificación de edad/identidad (estilo KYC) — las solicitudes de documento oficial + selfie que se requieren antes de que un creador pueda solicitar un retiro. Este es un sistema independiente de la cola de verificación de notoriedad/insignia en /verification (ver Verificación de Usuario): son operaciones GraphQL distintas, un permiso distinto (MODERATE_CONTENT, no VERIFY_USERS), y esta página tiene un modal de revisión de documento/selfie que la cola de insignias no tiene.
Esta es la contraparte del lado de administración del checkbox "Cola de revisión de admin" de Verificación de edad e identidad (ya marcado como hecho en esa página) — anteriormente no estaba documentada específicamente en el lado de administración. Documento nuevo.
Checklist de implementación
- Listar las solicitudes de verificación de identidad pendientes (
adminPendingIdentityVerifications) - Ver el documento y la foto selfie enviados en un modal de revisión
- Aprobar una solicitud (
adminApproveIdentityVerification) - Rechazar una solicitud con un motivo (
adminRejectIdentityVerification)
Dónde vive esto
Backend
apps/backend/graphql/types/identity-verification.type.js— esquema (el comentario de encabezado lo describe como la "mitad de identidad (estilo KYC)" de Verificación de edad e identidad, distinta del sistema de insignias; la aprobación habilita los retiros de dinero real)apps/backend/graphql/resolvers/identity-verification.resolver.js—adminPendingIdentityVerifications→identityVerificationManager.getPendingRequests;adminApproveIdentityVerification/adminRejectIdentityVerification→identityVerificationManager.approve/.reject. Nota: estos fueron renombrados este ciclo para llevar el prefijoadmin, así que la división de esquema los enruta al esquema de administración (/admin/graphql) — aunque el archivo de resolver siga fuera de la carpetaadmin/. Cada uno además exigecontext.admin+ el permisoMODERATE_CONTENTdentro del resolver.apps/backend/managers/user-managers/identity-verification.manager.js— lógica de negocio de aprobación/rechazo (un archivo separado deverification-badges.manager.js)
Frontend — apps/frontend-admin/src/app/moderation/identity-verifications/page.tsx. La tabla de listado muestra el nombre de usuario, el correo electrónico y identityVerificationRequestedAt; un modal de revisión que se abre por fila renderiza identityDocumentUrl/identitySelfieUrl como imágenes en las que se puede hacer clic, más un textarea para el motivo de rechazo. Protegido por MODERATE_CONTENT, coincidiendo con la verificación del lado del servidor.
Referencia de GraphQL
query PendingIdentityVerifications($limit: Int, $offset: Int) {
adminPendingIdentityVerifications(limit: $limit, offset: $offset) {
id username email firstName lastName profilePicture
identityVerificationStatus identityDocumentUrl
identitySelfieUrl identityVerificationRequestedAt
}
}
mutation ApproveIdentityVerification($userId: ID!) {
adminApproveIdentityVerification(userId: $userId) { identityVerificationStatus }
}
mutation RejectIdentityVerification($userId: ID!, $reason: String!) {
adminRejectIdentityVerification(userId: $userId, reason: $reason) { identityVerificationStatus }
}
Nota: adminPendingIdentityVerifications devuelve una lista simple ([IdentityVerificationRequest!]!), no un wrapper paginado { total, requests } — el frontend pagina mediante limit/offset y deshabilita "siguiente" en cuanto una página vuelve más corta que el tamaño de página. El id de cada elemento es el id del usuario (se usa directamente como userId en las mutaciones); no existe un subobjeto user { id username } separado. Ambas mutaciones devuelven un IdentityVerificationStatusResult (identityVerificationStatus, identityVerificationRequestedAt, identityVerifiedAt, identityRejectionReason), no un payload { success, message }, y reason es obligatorio en adminRejectIdentityVerification.