Skip to content

Conversation

@Phaoll
Copy link

@Phaoll Phaoll commented Jan 16, 2026

Fix user search to query entire database instead of current page only

The search on the Admin page was only filtering users visible on the current page. This made it useless for finding users in larger projects.

Changes:

  • Added username query parameter to /users endpoint
  • Search now queries the database instead of filtering client-side

Trade-off: Adds network latency on each search, but actually works for projects with 50+ users.

Note: Had to type useGetUsers to pass the tests.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added username filtering support for user queries.
  • Refactor

    • Migrated user filtering from client-side to server-side API approach.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions github-actions bot added the community Pull Request from an external contributor label Jan 16, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 16, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The pull request implements server-side username filtering for user queries across backend and frontend. The backend endpoint now accepts an optional username parameter and applies LIKE pattern filtering. The frontend updates its API hook with improved type safety and modifies the AdminPage to use API-driven filtering instead of client-side filtering.

Changes

Cohort / File(s) Summary
Backend API filtering
src/backend/base/langflow/api/v1/users.py
Added optional username parameter to read_all_users() function. When provided, applies LIKE-based SQL filter to match usernames containing the search term.
Frontend API hook
src/frontend/src/controllers/API/queries/auth/use-get-users-page.ts
Extended getUsersQueryParams interface to include optional username field. Improved type safety by narrowing useGetUsers return type to Array<Users>. Updated API URL construction to append username as query parameter when provided.
Frontend UI filtering
src/frontend/src/pages/AdminPage/index.tsx
Replaced client-side in-memory user filtering logic with server-side API calls. handleFilterUsers() now always invokes mutateGetUsers() with username parameter and updates display from API response rather than local filtering.
Frontend test formatting
src/frontend/tests/extended/features/userSettings.spec.ts
Reformatted test locator construction to span multiple lines; no behavioral changes.

Sequence Diagram

sequenceDiagram
    participant User
    participant AdminPage
    participant APIHook as Frontend API Hook
    participant Backend

    User->>AdminPage: Types username in filter field
    AdminPage->>AdminPage: handleFilterUsers() triggered
    AdminPage->>APIHook: mutateGetUsers({skip, limit, username})
    APIHook->>APIHook: Construct URL with username param
    APIHook->>Backend: GET /users?skip={skip}&limit={limit}&username={username}
    Backend->>Backend: Filter users with LIKE '%{username}%'
    Backend-->>APIHook: Return filtered Array<Users>
    APIHook-->>AdminPage: onSuccess: users array + total_rows_count
    AdminPage->>AdminPage: Update displayed user list from API response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 3 warnings)
Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error PR introduces username filtering functionality but provides inadequate test coverage; only formatting changes in userSettings.spec.ts with no new tests for backend endpoint or frontend hook. Add backend tests for /users endpoint username parameter filtering and frontend tests for useGetUsers hook and AdminPage filtering behavior to verify server-side filtering works correctly.
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Quality And Coverage ⚠️ Warning The PR introduces server-side username filtering and frontend search functionality without corresponding test coverage for backend filtering logic, error paths, or admin page search behavior. Add pytest tests for read_all_users with username parameter cases and Playwright tests for AdminPage search, using project's async patterns.
Test File Naming And Structure ⚠️ Warning Pull request introduces server-side username filtering but lacks adequate test coverage for the new functionality. Add comprehensive test cases to test_users.py for username filtering, special characters, pagination, and error handling in both backend and frontend.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: implementing server-side user filtering in the admin page to search across all users, not just the current page.
Excessive Mock Usage Warning ✅ Passed Pull request shows minimal test changes with only formatting adjustments to Playwright locators. Uses E2E testing with real page interactions rather than excessive mocks, validating actual UI behavior and API interactions.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ogabrielluiz ogabrielluiz assigned Wallgau and unassigned Wallgau Jan 16, 2026
@ogabrielluiz ogabrielluiz requested a review from Wallgau January 16, 2026 17:20
@ogabrielluiz ogabrielluiz changed the title FEAT: user filtering in admin page now filter on all users feat: user filtering in admin page now filter on all users Jan 16, 2026
@github-actions github-actions bot added the enhancement New feature or request label Jan 16, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/backend/base/langflow/api/v1/users.py (1)

68-78: Bug: total_count ignores the username filter.

The count_query on line 73 counts all users in the database, not just the filtered subset. When a username filter is applied, the pagination will display incorrect totals (e.g., "1-10 of 500" when only 3 users match).

🐛 Proposed fix
     query: SelectOfScalar = select(User).offset(skip).limit(limit)
+    count_query = select(func.count()).select_from(User)
     if username is not None:
         query = query.where(User.username.like(f"%{username}%"))
+        count_query = count_query.where(User.username.like(f"%{username}%"))
     users = (await session.exec(query)).fetchall()
 
-    count_query = select(func.count()).select_from(User)
     total_count = (await session.exec(count_query)).first()
src/frontend/src/pages/AdminPage/index.tsx (1)

274-280: Clear button doesn't reset the filter via API.

Clicking the clear button sets filterUserList to userList.current, but userList.current may contain stale data from a previous filtered or paginated request. This should call getUsers() or resetFilter() to fetch fresh unfiltered data.

🔧 Proposed fix
               {inputValue.length > 0 ? (
                 <div
                   className="cursor-pointer"
                   onClick={() => {
                     setInputValue("");
-                    setFilterUserList(userList.current);
+                    resetFilter();
                   }}
                 >
🤖 Fix all issues with AI agents
In `@src/frontend/src/controllers/API/queries/auth/use-get-users-page.ts`:
- Around line 13-16: The return type for useGetUsers is wrong: replace
Array<Users> with UsersResponse wherever useGetUsers is declared/typed (the
useMutationFunctionType generic and any other occurrences in the same file), so
the hook signature and generics (e.g., useGetUsers:
useMutationFunctionType<Array<Users>, getUsersQueryParams>) become
useMutationFunctionType<UsersResponse, getUsersQueryParams> and update any
matching overloads/usages in this file to expect UsersResponse (with total_count
and users fields) instead of a plain Users[].
- Around line 24-27: The URL builder in use-get-users-page.ts is vulnerable to
malformed queries when username contains special characters; update the query
string construction used in the api.get call (the template that currently
injects username) to pass username through encodeURIComponent (e.g., replace the
current `${username ? `&username=${username}` : ""}` fragment) so the username
is safely encoded before appending to the URL; ensure this change is applied
where res is produced in the useGetUsersPage/getUsersPage logic and test that
queries with &, =, % and spaces are handled correctly.
🧹 Nitpick comments (1)
src/frontend/src/pages/AdminPage/index.tsx (1)

113-130: Consider debouncing API calls to reduce server load.

Every keystroke triggers an API request. For rapid typing, this could overwhelm the server and cause UI jank. A debounce (e.g., 300ms) would batch requests while still providing a responsive experience.

♻️ Example using lodash debounce
+import { debounce } from "lodash";
+
+// Inside component, create stable debounced handler
+const debouncedSearch = useRef(
+  debounce((input: string) => {
+    mutateGetUsers(
+      {
+        skip: size * (index - 1),
+        limit: size,
+        username: input,
+      },
+      {
+        onSuccess: (users) => {
+          setTotalRowsCount(users["total_count"]);
+          userList.current = users["users"];
+          setFilterUserList(users["users"]);
+        },
+        onError: () => {},
+      },
+    );
+  }, 300),
+).current;
+
 function handleFilterUsers(input: string) {
   setInputValue(input);
-  mutateGetUsers(
-    {
-      skip: size * (index - 1),
-      limit: size,
-      username: input,
-    },
-    {
-      onSuccess: (users) => {
-        setTotalRowsCount(users["total_count"]);
-        userList.current = users["users"];
-        setFilterUserList(users["users"]);
-      },
-      onError: () => {},
-    },
-  );
+  debouncedSearch(input);
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0689810 and 24c8f1c.

📒 Files selected for processing (4)
  • src/backend/base/langflow/api/v1/users.py
  • src/frontend/src/controllers/API/queries/auth/use-get-users-page.ts
  • src/frontend/src/pages/AdminPage/index.tsx
  • src/frontend/tests/extended/features/userSettings.spec.ts
🧰 Additional context used
📓 Path-based instructions (6)
src/backend/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

src/backend/**/*.py: Use FastAPI async patterns with await for async operations in component execution methods
Use asyncio.create_task() for background tasks and implement proper cleanup with try/except for asyncio.CancelledError
Use queue.put_nowait() for non-blocking queue operations and asyncio.wait_for() with timeouts for controlled get operations

Files:

  • src/backend/base/langflow/api/v1/users.py
src/backend/base/langflow/api/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

Backend API endpoints should be organized by version (v1/, v2/) under src/backend/base/langflow/api/ with specific modules for features (chat.py, flows.py, users.py, etc.)

Files:

  • src/backend/base/langflow/api/v1/users.py
src/frontend/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

src/frontend/src/**/*.{ts,tsx}: Use React 18 with TypeScript for frontend development
Use Zustand for state management

Files:

  • src/frontend/src/controllers/API/queries/auth/use-get-users-page.ts
  • src/frontend/src/pages/AdminPage/index.tsx
src/frontend/**/*.{test,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

src/frontend/**/*.{test,spec}.{ts,tsx,js,jsx}: Use @pytest.mark.asyncio decorator for async frontend tests; structure tests to verify component behavior, state updates, and proper cleanup
Frontend tests should validate component rendering, user interactions, state management, and async operations using appropriate testing libraries (React Testing Library, Vitest, Jest, etc.)
Document each frontend test with a clear docstring/comment explaining its purpose, the scenario being tested, and expected outcomes

Files:

  • src/frontend/tests/extended/features/userSettings.spec.ts
src/frontend/src/**/*.{tsx,jsx,css,scss}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

Use Tailwind CSS for styling

Files:

  • src/frontend/src/pages/AdminPage/index.tsx
src/frontend/src/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

src/frontend/src/**/*.{tsx,jsx}: Implement dark mode support using the useDarkMode hook and dark store
Use Lucide React for icon components in the application

Files:

  • src/frontend/src/pages/AdminPage/index.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-03T18:17:26.561Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2025-12-03T18:17:26.561Z
Learning: Applies to **/*.test.ts?(x) : Frontend test files should follow the naming convention *.test.ts or *.test.tsx using Playwright

Applied to files:

  • src/frontend/tests/extended/features/userSettings.spec.ts
🧬 Code graph analysis (2)
src/backend/base/langflow/api/v1/users.py (2)
src/backend/base/langflow/api/v1/schemas.py (1)
  • UsersResponse (227-229)
src/lfx/src/lfx/services/session.py (1)
  • query (39-40)
src/frontend/src/controllers/API/queries/auth/use-get-users-page.ts (3)
src/frontend/src/types/api/index.ts (2)
  • useMutationFunctionType (291-309)
  • Users (178-192)
src/frontend/src/controllers/API/services/request-processor.ts (1)
  • UseRequestProcessor (14-54)
src/frontend/src/controllers/API/helpers/constants.ts (1)
  • getURL (43-53)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (61)
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 46/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 28/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 47/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 27/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 35/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 45/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 48/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 30/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 49/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 44/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 22/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 41/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 36/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 50/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 43/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 42/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 15/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 39/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 40/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 33/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 38/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 32/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 37/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 24/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 23/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 11/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 14/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 8/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 34/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 29/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 31/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 16/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 1/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 10/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 21/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 26/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 20/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 25/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 9/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 19/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 18/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 7/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 6/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 17/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 13/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 12/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 2/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 3/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 5/50
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 4/50
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Run Backend Tests / LFX Tests - Python 3.10
  • GitHub Check: Run Frontend Unit Tests / Frontend Jest Unit Tests
  • GitHub Check: Test Docker Images / Test docker images
  • GitHub Check: Test Starter Templates
  • GitHub Check: Optimize new Python code in this PR
🔇 Additional comments (1)
src/frontend/tests/extended/features/userSettings.spec.ts (1)

71-73: LGTM!

Purely cosmetic reformatting of the locator construction. The trailing comma and multi-line format improve readability without affecting test behavior.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +13 to +16
export const useGetUsers: useMutationFunctionType<
Array<Users>,
getUsersQueryParams
> = (options?) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Type mismatch: Return type should be UsersResponse, not Array<Users>.

The backend returns { total_count: number, users: Users[] } (see UsersResponse in schemas.py), but the type here declares Array<Users>. The AdminPage correctly accesses users["total_count"] and users["users"], which contradicts this array type.

🔧 Proposed fix
+interface UsersResponse {
+  total_count: number;
+  users: Users[];
+}
+
 export const useGetUsers: useMutationFunctionType<
-  Array<Users>,
+  UsersResponse,
   getUsersQueryParams
 > = (options?) => {
   const { mutate } = UseRequestProcessor();

   async function getUsers({
     skip,
     limit,
     username,
-  }: getUsersQueryParams): Promise<Array<Users>> {
+  }: getUsersQueryParams): Promise<UsersResponse> {
     const res = await api.get(
       `${getURL("USERS")}/?skip=${skip}&limit=${limit}${
         username ? `&username=${username}` : ""
       }`,
     );
     if (res.status === 200) {
       return res.data;
     }
-    return [];
+    return { total_count: 0, users: [] };
   }

   const mutation: UseMutationResult<
-    Array<Users>,
+    UsersResponse,
     Error,
     getUsersQueryParams
   > = mutate(["useGetUsers"], getUsers, options);

Also applies to: 22-23, 35-38

🤖 Prompt for AI Agents
In `@src/frontend/src/controllers/API/queries/auth/use-get-users-page.ts` around
lines 13 - 16, The return type for useGetUsers is wrong: replace Array<Users>
with UsersResponse wherever useGetUsers is declared/typed (the
useMutationFunctionType generic and any other occurrences in the same file), so
the hook signature and generics (e.g., useGetUsers:
useMutationFunctionType<Array<Users>, getUsersQueryParams>) become
useMutationFunctionType<UsersResponse, getUsersQueryParams> and update any
matching overloads/usages in this file to expect UsersResponse (with total_count
and users fields) instead of a plain Users[].

Comment on lines 24 to +27
const res = await api.get(
`${getURL("USERS")}/?skip=${skip}&limit=${limit}`,
`${getURL("USERS")}/?skip=${skip}&limit=${limit}${
username ? `&username=${username}` : ""
}`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Encode the username parameter to handle special characters.

If username contains characters like &, =, or %, the URL will be malformed. Use encodeURIComponent to safely encode the value.

🔧 Proposed fix
     const res = await api.get(
       `${getURL("USERS")}/?skip=${skip}&limit=${limit}${
-        username ? `&username=${username}` : ""
+        username ? `&username=${encodeURIComponent(username)}` : ""
       }`,
     );
🤖 Prompt for AI Agents
In `@src/frontend/src/controllers/API/queries/auth/use-get-users-page.ts` around
lines 24 - 27, The URL builder in use-get-users-page.ts is vulnerable to
malformed queries when username contains special characters; update the query
string construction used in the api.get call (the template that currently
injects username) to pass username through encodeURIComponent (e.g., replace the
current `${username ? `&username=${username}` : ""}` fragment) so the username
is safely encoded before appending to the URL; ensure this change is applied
where res is produced in the useGetUsersPage/getUsersPage logic and test that
queries with &, =, % and spaces are handled correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Pull Request from an external contributor enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants