async def _paginated_query(
        self,
        client: httpx.AsyncClient,
        query_template: str,
        process_node_func,
        page_size: int = 50,
        entity_type: str = "items",
    ) -> AsyncGenerator:
        """Execute a paginated GraphQL query against the Linear API.

        Args:
            client: HTTP client to use for requests
            query_template: GraphQL query template with {pagination} placeholder
            process_node_func: Function to process each node from the results
            page_size: Number of items to request per page
            entity_type: Type of entity being queried (for logging)

        Yields:
            Processed entities from the query results
        """
        has_next_page = True
        cursor = None
        items_processed = 0

        while has_next_page:
            # Build pagination parameters
            pagination = f"first: {page_size}"
            if cursor:
                pagination += f', after: "{cursor}"'

            # Insert pagination into query template
            query = query_template.format(pagination=pagination)

            try:
                # Execute the query
                response = await self._post_with_auth(client, query)

                # Extract data - assumes response structure with nodes and pageInfo
                data = response.get("data", {})
                # The first key in data should be the entity collection (issues, teams, etc.)
                collection_key = next(iter(data.keys()), None)

                if not collection_key:
                    logger.error(f"Unexpected response structure: {response}")
                    break

                collection_data = data[collection_key]
                nodes = collection_data.get("nodes", [])

                # Log the batch
                batch_count = len(nodes)
                items_processed += batch_count
                logger.info(
                    f"Processing batch of {batch_count} {entity_type} (total: {items_processed})"
                )

                # Process each node
                for node in nodes:
                    # Use the provided function to process each node
                    async for entity in process_node_func(node):
                        if entity:  # Only yield non-None results
                            yield entity

                # Update pagination info for next iteration
                page_info = collection_data.get("pageInfo", {})
                has_next_page = page_info.get("hasNextPage", False)
                cursor = page_info.get("endCursor")

                # If no more results or empty response, exit
                if not nodes or not has_next_page:
                    break

            except Exception as e:
                logger.error(f"Error processing {entity_type} batch: {str(e)}")
                break
Execute a paginated GraphQL query against the Linear API.

        Args:
            client: HTTP client to use for requests
            query_template: GraphQL query template with {pagination} placeholder
            process_node_func: Function to process each node from the results
            page_size: Number of items to request per page
            entity_type: Type of entity being queried (for logging)

        Yields:
            Processed entities from the query results
        
backend/airweave/platform/sources/linear.py