true, 'data' => $data, 'user' => Auth::user()], JSON_UNESCAPED_UNICODE); exit; } function err(string $msg, int $code = 400): void { http_response_code($code); echo json_encode(['ok' => false, 'error' => $msg], JSON_UNESCAPED_UNICODE); exit; } function body(): array { return json_decode((string) file_get_contents('php://input'), true) ?? []; } $method = $_SERVER['REQUEST_METHOD']; $action = $_GET['action'] ?? ''; $me = Auth::userId(); $pdo = Db::pdo(); try { if ($method === 'GET' && $action === 'list_users') { ok(Lookups::allUsers()); } if ($method === 'POST' && $action === 'create_user') { $b = body(); $email = strtolower(trim((string)($b['email'] ?? ''))); if ($email === '') err('email requerido'); if (!filter_var($email, FILTER_VALIDATE_EMAIL)) err('email inválido'); $name = trim((string)($b['name'] ?? '')); $role = in_array(($b['role'] ?? ''), ROLES, true) ? $b['role'] : 'usuario'; $activo = (int)($b['activo'] ?? 1) === 1 ? 1 : 0; $orden = (int)($b['orden'] ?? 0); $exists = $pdo->prepare('SELECT id FROM users WHERE email = :e'); $exists->execute([':e' => $email]); if ($exists->fetch()) err('Ya existe un usuario con ese email', 409); $ins = $pdo->prepare( 'INSERT INTO users (email, name, role, activo, orden, first_seen_at, last_login_at) VALUES (:email, :name, :role, :activo, :orden, NULL, NULL)' ); $ins->execute([ ':email' => $email, ':name' => $name, ':role' => $role, ':activo' => $activo, ':orden' => $orden, ]); $id = (int)$pdo->lastInsertId(); $sel = $pdo->prepare('SELECT id, email, name, role, activo, orden, first_seen_at, last_login_at FROM users WHERE id = :id'); $sel->execute([':id' => $id]); $row = $sel->fetch(); $row['id'] = (int)$row['id']; $row['activo'] = (int)$row['activo']; $row['orden'] = (int)$row['orden']; ok($row); } if ($method === 'PUT' && $action === 'update_user') { $b = body(); $id = (int)($b['_id'] ?? 0); if (!$id) err('id requerido'); $sel = $pdo->prepare('SELECT id, email, role, activo FROM users WHERE id = :id'); $sel->execute([':id' => $id]); $existing = $sel->fetch(); if (!$existing) err('Usuario no encontrado', 404); $newRole = in_array(($b['role'] ?? $existing['role']), ROLES, true) ? $b['role'] : $existing['role']; $newActivo = isset($b['activo']) ? ((int)$b['activo'] === 1 ? 1 : 0) : (int)$existing['activo']; // Salvaguardas: el socio no puede demoverse ni desactivarse a sí mismo if ((int)$existing['id'] === $me) { if ($newRole !== 'socio') err('No puedes quitarte el rol de Socio a ti mismo', 400); if ($newActivo === 0) err('No puedes desactivarte a ti mismo', 400); } $newEmail = isset($b['email']) ? strtolower(trim((string)$b['email'])) : $existing['email']; if (!filter_var($newEmail, FILTER_VALIDATE_EMAIL)) err('email inválido'); if ($newEmail !== $existing['email']) { $chk = $pdo->prepare('SELECT id FROM users WHERE email = :e AND id != :id'); $chk->execute([':e' => $newEmail, ':id' => $id]); if ($chk->fetch()) err('Otro usuario ya tiene ese email', 409); } $name = trim((string)($b['name'] ?? '')); $orden = (int)($b['orden'] ?? 0); $upd = $pdo->prepare( 'UPDATE users SET email = :email, name = :name, role = :role, activo = :activo, orden = :orden WHERE id = :id' ); $upd->execute([ ':email' => $newEmail, ':name' => $name, ':role' => $newRole, ':activo' => $newActivo, ':orden' => $orden, ':id' => $id, ]); $sel = $pdo->prepare('SELECT id, email, name, role, activo, orden, first_seen_at, last_login_at FROM users WHERE id = :id'); $sel->execute([':id' => $id]); $row = $sel->fetch(); $row['id'] = (int)$row['id']; $row['activo'] = (int)$row['activo']; $row['orden'] = (int)$row['orden']; ok($row); } err('Acción no reconocida', 404); } catch (PDOException $e) { error_log('admin db error: ' . $e->getMessage()); err('Error de base de datos', 500); } catch (Throwable $e) { error_log('admin error: ' . $e->getMessage()); err('Error interno', 500); }