In API response some keys values are not coming as expected

    <?php

namespace AppServicesFeed;

use AppRepositoriesPollPollRepositoryInterface;
use AppRepositoriesPostPostRepositoryInterface;
use IlluminateHttpResourcesJsonAnonymousResourceCollection;
use IlluminatePaginationLengthAwarePaginator;
use IlluminateSupportFacadesLog;

class FeedService implements FeedServiceInterface
{
    public function __construct(
        private PostRepositoryInterface $postRepository,
        private PollRepositoryInterface $pollRepository
    ) {}

    /** Send all feeds
     *
     * @param array $data The filtered data
     * @return array The feed array
     */
    public function getFeeds(array $data): array
    {
        $page = $data['page'] ?? config('data.pagination.default_page', 1);
        $limit = $data['limit'] ?? config('data.pagination.default_limit', 10);

        // Get paginated posts and polls (fetching only required records)
        $posts = $this->postRepository->getPosts($data);
        $polls = $this->pollRepository->getPolls($data);

        // Ensure collections exist and default to empty collections if null
        $postsCollection = isset($posts->collection) ? collect($posts->collection) : collect();
        $pollsCollection = isset($polls->collection) ? collect($polls->collection) : collect();

        // Merge and sort by combined_created_at
        $mergedFeed = $postsCollection->merge($pollsCollection)
            ->sortByDesc('combined_created_at')
            ->values();

        // Paginate the merged feed
        $total = $mergedFeed->count();
        $paginatedItems = $mergedFeed->slice(($page - 1) * $limit, $limit)->values();

        // Apply transformations **only on the paginated items**
        $startIndex = ($page - 1) * $limit; // Start index based on pagination

        $transformedFeed = $paginatedItems->map(function ($item) use (&$startIndex, $data) {
            // Ensure JSON is properly decoded as an **object**
            $item->show_user_details = json_decode($item->show_user_details, false);

            $item->is_shared = (bool) $item->is_shared;

            // Generate unique ID using type, ID, index, page, and limit
            $uniqueKey = "{$item->type}-{$item->id}-{$startIndex}-{$data['page']}-{$data['limit']}";
            $item->unique_id = hash('sha256', $uniqueKey);

            $startIndex++; // Increment index

            return $item; // Ensure transformation is applied
        });

        // Create the paginator
        $paginatedFeed = new LengthAwarePaginator(
            $transformedFeed, // Only transformed paginated items
            $total, // Total items count
            $limit, // Items per page
            $page, // Current page
            ['path' => request()->url(), 'query' => request()->query()] // Maintain query parameters
        );

        return [
            'post' => $paginatedFeed->items(), // Extract items directly
            'pagination' => [
                'total' => $paginatedFeed->total(),
                'per_page' => $paginatedFeed->perPage(),
                'current_page' => $paginatedFeed->currentPage(),
                'last_page' => $paginatedFeed->lastPage(),
                'from' => $paginatedFeed->firstItem(),
                'to' => $paginatedFeed->lastItem(),
            ],
        ];
    }
}

    /**
     * Send all posts
     *
     * @param array $data The filtered data
     * @return AnonymousResourceCollection The post collection
     */
    public function getPosts(array $data): AnonymousResourceCollection
    {
        $this->setPaginationAndOrderBy($data);

        $postableId = $data["postable_id"] ?? null;
        $postableType = $data["postable_type"] ?? null;

        $username = $data['username'] ?? null;

        // Fetch user ID from username
        $userId = null;
        if ($username) {
            $userId = $this->user->where('username', $username)->value('id');
        }

        // Original Posts with Creator's Name
        $originalPosts = $this->post
            ->select(
                'posts.*',
                DB::raw('posts.created_at as combined_created_at'),
                DB::raw("
                CASE 
                    WHEN posts.postable_type LIKE '%User' THEN users.username
                    WHEN posts.postable_type LIKE '%Club' THEN clubs.name
                    ELSE NULL
                END as show_user
            "),
                DB::raw("
                CASE 
                    WHEN posts.postable_type LIKE '%User' THEN CAST(
                        JSON_OBJECT(
                            'id', users.id,
                            'profile_image', users.profile_image,
                            'username', users.username,
                            'email', users.email,
                            'first_name', users.first_name,
                            'last_name', users.last_name,
                            'gender',
                                CASE 
                                    WHEN users.gender = 0 THEN 'Male'
                                    WHEN users.gender = 1 THEN 'Female'
                                    WHEN users.gender = 2 THEN 'Others'
                                    ELSE NULL
                                END
                        ) AS JSON
                    )
                    WHEN posts.postable_type LIKE '%Club' THEN CAST(
                        JSON_OBJECT(
                            'id', clubs.id,
                            'name', clubs.name,
                            'description', clubs.description
                        ) AS JSON
                    )
                    ELSE NULL
                END as show_user_details
            "),
                DB::raw("FALSE as is_shared") // Adding is_shared flag
            )
            ->leftJoin('users', function ($join) {
                $join->on('posts.postable_id', '=', 'users.id')
                    ->where('posts.postable_type', 'App\Models\User');
            })
            ->leftJoin('clubs', function ($join) {
                $join->on('posts.postable_id', '=', 'clubs.id')
                    ->where('posts.postable_type', 'App\Models\Club');
            });

        // Apply filters for `postable_id` and `postable_type`
        if ($postableId && $postableType) {
            $originalPosts->where('posts.postable_id', $postableId)
                ->where('posts.postable_type', $postableType);
        }

        // Apply filter for user posts if username exists
        if ($userId) {
            $originalPosts->where('posts.postable_id', $userId)
                ->where('posts.postable_type', 'App\Models\User');
        }

        // Shared Posts with Sharer's Username
        $sharedPosts = $this->post
            ->select(
                'posts.*',
                DB::raw('post_shares.created_at as combined_created_at'),
                'shared_users.username as show_user',
                DB::raw("
                    CAST(
                        JSON_OBJECT(
                            'id', shared_users.id,
                            'profile_image', shared_users.profile_image,
                            'username', shared_users.username,
                            'email', shared_users.email,
                            'first_name', shared_users.first_name,
                            'last_name', shared_users.last_name,
                            'gender',
                                CASE 
                                    WHEN shared_users.gender = 0 THEN 'Male'
                                    WHEN shared_users.gender = 1 THEN 'Female'
                                    WHEN shared_users.gender = 2 THEN 'Others'
                                    ELSE NULL
                                END
                        ) AS JSON
                    ) as show_user_details
                "),
                DB::raw("TRUE as is_shared") // Adding is_shared flag
            )
            ->join('post_shares', 'posts.id', '=', 'post_shares.post_id')
            ->join('users as shared_users', 'post_shares.user_id', '=', 'shared_users.id');

        // Apply filter for shared posts if username exists
        if ($userId) {
            $sharedPosts->where('post_shares.user_id', $userId);
        }

        // Combine Original Posts + Shared Posts using UNION
        $posts = $originalPosts
            ->unionAll($sharedPosts)
            ->orderByDesc('combined_created_at')
            // ->paginate($this->limit, ['*'], 'page', $this->page);
            ->get();

        // $startIndex = ($data['page'] - 1) * $data['limit']; // Start index based on pagination

        // // Handles JSON decoding
        // $posts->transform(function ($post) use ($startIndex, $data) {
        //     $post->show_user_details = json_decode($post->show_user_details, true);
        //     $post->is_shared = (bool) $post->is_shared; // Ensure boolean type

        //     // Generate unique ID using post ID, index, page, and limit
        //     $uniqueKey = "{$post->type}-{$post->id}-{$startIndex}-{$data['page']}-{$data['limit']}";

        //     // Generate unique ID using hash
        //     $post->unique_id = hash('sha256', $uniqueKey);

        //     $startIndex++; // Increment the index for next post

        //     return $post;
        // });

        // Load default relations
        $posts->load([
            'postMedias',
            'postable',
            'comments.commentable',
            'club'
        ]);

        return PostResource::collection($posts);
    }

    /**
     * Send all polls
     *
     * @param array $data The filtered data
     * @return AnonymousResourceCollection The poll collection
     */
    public function getPolls(array $data): AnonymousResourceCollection
    {
        $this->setPaginationAndOrderBy($data);

        $pollableId = $data['pollable_id'] ?? null;
        $pollableType = $data['pollable_type'] ?? null;

        $username = $data['username'] ?? null;

        // Fetch user ID from username
        $userId = null;
        if ($username) {
            $userId = $this->user->where('username', $username)->value('id');
        }

        // Original Polls with Creator's Name
        $originalPolls = $this->poll
            ->select(
                'polls.*',
                DB::raw('polls.created_at as combined_created_at'),
                DB::raw("
                CASE 
                    WHEN polls.pollable_type LIKE '%User' THEN users.username
                    WHEN polls.pollable_type LIKE '%Admin' THEN admins.name
                    WHEN polls.pollable_type LIKE '%Club' THEN clubs.name
                    ELSE NULL
                END as show_user
            "),
                DB::raw("
                CASE 
                    WHEN polls.pollable_type LIKE '%User' THEN CAST(
                        JSON_OBJECT(
                            'id', users.id,
                            'profile_image', users.profile_image,
                            'username', users.username,
                            'email', users.email,
                            'first_name', users.first_name,
                            'last_name', users.last_name,
                            'gender',
                                CASE 
                                    WHEN users.gender = 0 THEN 'Male'
                                    WHEN users.gender = 1 THEN 'Female'
                                    WHEN users.gender = 2 THEN 'Others'
                                    ELSE NULL
                                END
                        ) AS JSON
                    )
                    WHEN polls.pollable_type LIKE '%Admin' THEN CAST(
                        JSON_OBJECT(
                            'id', admins.id,
                            'name', admins.name,
                            'email', admins.email
                        ) AS JSON
                    )
                    WHEN polls.pollable_type LIKE '%Club' THEN CAST(
                        JSON_OBJECT(
                            'id', clubs.id,
                            'name', clubs.name,
                            'description', clubs.description
                        ) AS JSON
                    )
                    ELSE NULL
                END as show_user_details
            "),
                DB::raw("FALSE as is_shared") // Adding is_shared flag
            )
            ->leftJoin('users', function ($join) {
                $join->on('polls.pollable_id', '=', 'users.id')
                    ->where('polls.pollable_type', 'App\Models\User');
            })
            ->leftJoin('admins', function ($join) {
                $join->on('polls.pollable_id', '=', 'admins.id')
                    ->where('polls.pollable_type', 'App\Models\Admin');
            })
            ->leftJoin('clubs', function ($join) {
                $join->on('polls.pollable_id', '=', 'clubs.id')
                    ->where('polls.pollable_type', 'App\Models\Club');
            });

        // Apply filters for `postable_id` and `postable_type`
        if ($pollableId && $pollableType) {
            $originalPolls->where('polls.pollable_id', $pollableId)
                ->where('polls.pollable_type', $pollableType);
        }

        // Apply filter for user polls if username exists
        if ($userId) {
            $originalPolls->where('polls.pollable_id', $userId)
                ->where('polls.pollable_type', 'App\Models\User');
        }

        // Shared Polls with Sharer's Username
        $sharedPolls = $this->poll
            ->select(
                'polls.*',
                DB::raw('poll_shares.created_at as combined_created_at'),
                'shared_users.username as show_user',
                DB::raw("
                CAST(
                    JSON_OBJECT(
                        'id', shared_users.id,
                        'profile_image', shared_users.profile_image,
                        'username', shared_users.username,
                        'email', shared_users.email,
                        'first_name', shared_users.first_name,
                        'last_name', shared_users.last_name,
                        'gender',
                            CASE 
                                WHEN shared_users.gender = 0 THEN 'Male'
                                WHEN shared_users.gender = 1 THEN 'Female'
                                WHEN shared_users.gender = 2 THEN 'Others'
                                ELSE NULL
                            END
                    ) AS JSON
                ) as show_user_details
                "),
                DB::raw("TRUE as is_shared") // Adding is_shared flag
            )
            ->join('poll_shares', 'polls.id', '=', 'poll_shares.poll_id')
            ->join('users as shared_users', 'poll_shares.user_id', '=', 'shared_users.id');

        // Apply filter for shared polls if username exists
        if ($userId) {
            $sharedPolls->where('poll_shares.user_id', $userId);
        }

        // Combine Original Polls + Shared Polls using UNION
        $polls = $originalPolls
            ->unionAll($sharedPolls)
            ->orderByDesc('combined_created_at')
            //->paginate($this->limit, ['*'], 'page', $this->page);
            ->get();

        // $startIndex = ($data['page'] - 1) * $data['limit']; // Start index based on pagination

        // // Handles JSON decoding
        // $polls->transform(function ($poll) use ($startIndex, $data) {
        //     $poll->show_user_details = json_decode($poll->show_user_details, true);
        //     $poll->is_shared = (bool) $poll->is_shared; // Ensure boolean type

        //     // Generate unique ID using post ID, index, page, and limit
        //     $uniqueKey = "{$poll->type}-{$poll->id}-{$startIndex}-{$data['page']}-{$data['limit']}";

        //     // Generate unique ID using hash
        //     $poll->unique_id = hash('sha256', $uniqueKey);

        //     $startIndex++; // Increment the index for next post

        //     return $poll;
        // });

        // Load default relations
        $polls->load([
            'pollOptions',
            'pollable',
            'comments.commentable',
            'club',
        ]);

        return PollResource::collection($polls);
    }

Here we’ve an API /feeds?page=1&limit=10 and API response will be sent from the getFeeds function and we’re merging the post and poll data and after merging we apply the pagination.
In response of the API show_user_details not decoded properly.Instead of is_shared 0 or 1 in response false or true should come. And unique_id is not present in the response