Skip to content

Conversation

sevenjay
Copy link

@sevenjay sevenjay commented Sep 23, 2025

In Token Management, add Select group to filter token
image

Summary by CodeRabbit

  • New Features

    • Added group-based filtering to token search, enabling users to narrow results by group.
    • Introduced a Group selector in the Tokens page with options populated from available token groups.
    • Searches update immediately when the group selection changes.
    • Group choice is included alongside existing keyword and token filters throughout the search flow.
  • Chores

    • Updated underlying search handling to support the new group filter without changing existing error handling or responses.

Copy link
Contributor

coderabbitai bot commented Sep 23, 2025

Walkthrough

Adds optional “group” filtering for token search across backend and frontend. Controller forwards a new query param to the model. Model adjusts query to filter by group. Frontend fetches group options, exposes them via hook, renders a new select in filters, and includes group in search requests.

Changes

Cohort / File(s) Summary of changes
Backend: controller + model
controller/token.go, model/token.go
Added group parameter to search flow. Controller reads query param group and passes to model. Model function signature updated to SearchUserTokens(..., group string) and adds conditional group filter to DB query.
Frontend Hook: data + API integration
web/src/hooks/tokens/useTokensData.jsx
Introduced groupOptions state, searchGroup form field, and fetchGroups calling /api/group/. Search includes searchGroup in requests and conditions. Exposes groupOptions in return. Added mount effects to populate options.
Frontend Components: filters + page wiring
web/src/components/table/tokens/TokensFilters.jsx, web/src/components/table/tokens/index.jsx
TokensFilters now accepts groupOptions prop and renders a group <Select> that triggers search on change. TokensPage pulls groupOptions from hook and passes it to TokensFilters.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant TF as TokensFilters (UI)
  participant TD as useTokensData (Hook)
  participant API as Backend API
  participant C as Controller (token)
  participant M as Model (token)
  participant DB as Database

  Note over TF,TD: On mount
  TF->>TD: init()
  TD->>API: GET /api/group/
  API-->>TD: 200 OK (group list)
  TD-->>TF: groupOptions

  Note over U,TF: User selects a group
  U->>TF: Change searchGroup
  TF->>TD: searchTokens({ keyword, token, group })

  TD->>API: GET /api/token/search?keyword=&token=&group=
  API->>C: route request
  C->>M: SearchUserTokens(userId, keyword, token, group)
  M->>DB: SELECT ... WHERE user_id=? AND (...name/token...) [+ group=?]
  DB-->>M: rows
  M-->>C: tokens
  C-->>API: JSON(tokens)
  API-->>TD: 200 OK (tokens)
  TD-->>TF: update table
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I twitch my whiskers, sort and group,
A burrow of tokens in tidy loop.
New dropdown blooms, a carrot hue,
I click, I filter—results anew! 🥕
Soft thumps of paws on orderly ground,
In fields of queries, patterns found.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title concisely and accurately describes the primary change — adding a group option to token search in the console/token area — and matches the modifications to controller, model, hook, and UI files that implement group-based filtering. It is specific, readable, and free of noise.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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.

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: 1

🧹 Nitpick comments (3)
controller/token.go (1)

32-34: Forwarding group param looks good; trim whitespace to be safe

Minor robustness: trim any accidental spaces in the query value.

-	group := c.Query("group")
+	group := strings.TrimSpace(c.Query("group"))
web/src/components/table/tokens/TokensFilters.jsx (1)

30-31: Align Select default value with form init; avoid null/string mismatch

Your form initializes searchGroup to '', but the default option uses value null. Align to '' to avoid inconsistent value states after reset/clear.

-  groupOptions = [],
+  groupOptions = [],
...
-              { label: t('选择分组'), value: null },
+              { label: t('选择分组'), value: '' },

Also applies to: 82-100

web/src/hooks/tokens/useTokensData.jsx (1)

207-231: Surface network errors in searchTokens

Currently thrown errors during search are swallowed (only finally runs). Catch and show an error like other API calls do.

   setSearching(true);
-  try {
+  try {
     const res = await API.get('/api/token/search', {
       params: {
         keyword: searchKeyword,
         token: searchToken,
         group: searchGroup,
       },
     });
     const { success, message, data } = res.data;
     if (success) {
       setTokens(data);
       setTokenCount(data.length);
       setActivePage(1);
     } else {
       showError(message);
     }
-  } finally {
+  } catch (error) {
+    showError(error.message || '搜索失败');
+  } finally {
     setSearching(false);
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abe31f2 and 7bc7846.

📒 Files selected for processing (5)
  • controller/token.go (1 hunks)
  • model/token.go (1 hunks)
  • web/src/components/table/tokens/TokensFilters.jsx (2 hunks)
  • web/src/components/table/tokens/index.jsx (2 hunks)
  • web/src/hooks/tokens/useTokensData.jsx (6 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
web/src/components/table/tokens/TokensFilters.jsx (1)
web/src/hooks/tokens/useTokensData.jsx (2)
  • groupOptions (37-37)
  • searchTokens (206-232)
model/token.go (1)
model/main.go (1)
  • DB (63-63)
controller/token.go (1)
model/token.go (1)
  • SearchUserTokens (65-75)
web/src/components/table/tokens/index.jsx (1)
web/src/hooks/tokens/useTokensData.jsx (1)
  • groupOptions (37-37)
web/src/hooks/tokens/useTokensData.jsx (1)
web/src/helpers/utils.jsx (1)
  • showError (118-147)
🔇 Additional comments (2)
web/src/components/table/tokens/index.jsx (1)

348-349: LGTM: groupOptions plumbed through correctly

Prop wiring from hook to Filters is consistent and non-breaking.

Also applies to: 395-396

web/src/hooks/tokens/useTokensData.jsx (1)

187-204: Group options loading is fine — re-fetch after group changes

Consider re-fetching groups after token add/update flows so newly created/renamed groups appear in the selector. I searched the repo for a Go handler for /api/group/ and found no matches; please verify the endpoint exists and is user-scoped (returns only the requesting user's groups) to avoid leaking other users' groups.

Comment on lines +65 to 75
func SearchUserTokens(userId int, keyword string, token string, group string) (tokens []*Token, err error) {
if token != "" {
token = strings.Trim(token, "sk-")
}
err = DB.Where("user_id = ?", userId).Where("name LIKE ?", "%"+keyword+"%").Where(commonKeyCol+" LIKE ?", "%"+token+"%").Find(&tokens).Error
query := DB.Where("user_id = ?", userId).Where("name LIKE ?", "%"+keyword+"%").Where(commonKeyCol+" LIKE ?", "%"+token+"%")
if group != "" && group != "null" {
query = query.Where(commonGroupCol+" = ?", group)
}
err = query.Find(&tokens).Error
return tokens, err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

🧩 Analysis chain

Use TrimPrefix (not Trim) for token; normalize group input

strings.Trim(token, "sk-") removes any leading/trailing 's', 'k', '-' chars, not just the "sk-" prefix. This can corrupt searches. Also trim spaces for group before applying the filter.

 func SearchUserTokens(userId int, keyword string, token string, group string) (tokens []*Token, err error) {
 	if token != "" {
-		token = strings.Trim(token, "sk-")
+		token = strings.TrimPrefix(token, "sk-")
 	}
-	query := DB.Where("user_id = ?", userId).Where("name LIKE ?", "%"+keyword+"%").Where(commonKeyCol+" LIKE ?", "%"+token+"%")
-	if group != "" && group != "null" {
+	group = strings.TrimSpace(group)
+	query := DB.Where("user_id = ?", userId).Where("name LIKE ?", "%"+keyword+"%").Where(commonKeyCol+" LIKE ?", "%"+token+"%")
+	if group != "" && group != "null" {
 		query = query.Where(commonGroupCol+" = ?", group)
 	}
 	err = query.Find(&tokens).Error
 	return tokens, err
 }

Please also verify commonGroupCol is properly quoted/escaped given group is a reserved SQL word in many dialects.


🏁 Script executed:

#!/bin/bash
# Locate commonGroupCol definition and its usages to ensure it's quoted.
rg -n -C3 '\bcommonGroupCol\b'

Length of output: 5965


Use TrimPrefix for token; normalize group input (commonGroupCol already quoted)

strings.Trim(token, "sk-") can remove any leading/trailing 's','k','-' — use strings.TrimPrefix(token, "sk-"); also TrimSpace(group) before filtering. commonGroupCol is already quoted in model/main.go (initCol).

File: model/token.go (around lines 65-75)

 func SearchUserTokens(userId int, keyword string, token string, group string) (tokens []*Token, err error) {
 	if token != "" {
-		token = strings.Trim(token, "sk-")
+		token = strings.TrimPrefix(token, "sk-")
 	}
-	query := DB.Where("user_id = ?", userId).Where("name LIKE ?", "%"+keyword+"%").Where(commonKeyCol+" LIKE ?", "%"+token+"%")
-	if group != "" && group != "null" {
+	group = strings.TrimSpace(group)
+	query := DB.Where("user_id = ?", userId).Where("name LIKE ?", "%"+keyword+"%").Where(commonKeyCol+" LIKE ?", "%"+token+"%")
+	if group != "" && group != "null" {
 		query = query.Where(commonGroupCol+" = ?", group)
 	}
 	err = query.Find(&tokens).Error
 	return tokens, err
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func SearchUserTokens(userId int, keyword string, token string, group string) (tokens []*Token, err error) {
if token != "" {
token = strings.Trim(token, "sk-")
}
err = DB.Where("user_id = ?", userId).Where("name LIKE ?", "%"+keyword+"%").Where(commonKeyCol+" LIKE ?", "%"+token+"%").Find(&tokens).Error
query := DB.Where("user_id = ?", userId).Where("name LIKE ?", "%"+keyword+"%").Where(commonKeyCol+" LIKE ?", "%"+token+"%")
if group != "" && group != "null" {
query = query.Where(commonGroupCol+" = ?", group)
}
err = query.Find(&tokens).Error
return tokens, err
}
func SearchUserTokens(userId int, keyword string, token string, group string) (tokens []*Token, err error) {
if token != "" {
token = strings.TrimPrefix(token, "sk-")
}
group = strings.TrimSpace(group)
query := DB.Where("user_id = ?", userId).Where("name LIKE ?", "%"+keyword+"%").Where(commonKeyCol+" LIKE ?", "%"+token+"%")
if group != "" && group != "null" {
query = query.Where(commonGroupCol+" = ?", group)
}
err = query.Find(&tokens).Error
return tokens, err
}
🤖 Prompt for AI Agents
In model/token.go around lines 65 to 75, replace strings.Trim(token, "sk-") with
strings.TrimPrefix(token, "sk-") to avoid removing any arbitrary
leading/trailing characters, and normalize the group input by applying
strings.TrimSpace(group) before the group filter (keep using commonGroupCol
as-is since it’s already quoted in initCol); update the query construction to
use the trimmed token and trimmed group when applying the WHERE clause.

@seefs001
Copy link
Collaborator

seefs001 commented Oct 6, 2025

看看小兔子提的问题改一下再合吧 @sevenjay

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants