resolveUser($username); $actor = Auth::user(); if ($actor->id === $target->id) { return response()->json(['error' => 'Cannot follow yourself.'], 422); } try { $this->followService->follow((int) $actor->id, (int) $target->id); } catch (\InvalidArgumentException $e) { return response()->json(['error' => $e->getMessage()], 422); } return response()->json([ 'following' => true, 'followers_count' => $this->followService->followersCount((int) $target->id), 'following_count' => $this->followService->followingCount((int) $actor->id), 'context' => $this->followService->relationshipContext((int) $actor->id, (int) $target->id), ]); } // ─── DELETE /api/user/{username}/follow ────────────────────────────────── public function unfollow(Request $request, string $username): JsonResponse { $target = $this->resolveUser($username); $actor = Auth::user(); $this->followService->unfollow((int) $actor->id, (int) $target->id); return response()->json([ 'following' => false, 'followers_count' => $this->followService->followersCount((int) $target->id), 'following_count' => $this->followService->followingCount((int) $actor->id), 'context' => $this->followService->relationshipContext((int) $actor->id, (int) $target->id), ]); } // ─── GET /api/user/{username}/followers ────────────────────────────────── public function followers(Request $request, string $username): JsonResponse { $target = $this->resolveUser($username); $perPage = min((int) $request->query('per_page', 24), 100); $page = max(1, (int) $request->query('page', 1)); $rows = $this->followService ->paginatedFollowers((int) $target->id, $perPage, $page) ->through(fn (array $row) => [ 'id' => $row['id'], 'username' => $row['username'], 'display_name' => $row['display_name'], 'avatar_url' => $row['avatar_url'], 'profile_url' => $row['profile_url'], 'followed_at' => $row['followed_at'], ]); return response()->json($rows); } // ─── GET /api/user/{username}/following ────────────────────────────────── public function following(Request $request, string $username): JsonResponse { $target = $this->resolveUser($username); $perPage = min((int) $request->query('per_page', 24), 100); $page = max(1, (int) $request->query('page', 1)); $rows = $this->followService ->paginatedFollowing((int) $target->id, $perPage, $page) ->through(fn (array $row) => [ 'id' => $row['id'], 'username' => $row['username'], 'display_name' => $row['display_name'], 'avatar_url' => $row['avatar_url'], 'profile_url' => $row['profile_url'], 'followed_at' => $row['followed_at'], ]); return response()->json($rows); } // ─── Private helpers ───────────────────────────────────────────────────── private function resolveUser(string $username): User { $normalized = UsernamePolicy::normalize($username); return User::query() ->whereRaw('LOWER(username) = ?', [$normalized]) ->firstOrFail(); } }