Skip to content

fix: apply group filter to channel list queries#4885

Merged
Calcium-Ion merged 2 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/channel-group-filter
May 17, 2026
Merged

fix: apply group filter to channel list queries#4885
Calcium-Ion merged 2 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/channel-group-filter

Conversation

@yyhhyyyyyy
Copy link
Copy Markdown
Contributor

@yyhhyyyyyy yyhhyyyyyy commented May 15, 2026

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)
修复渠道页面中,分组筛选不生效

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)
image
image

Summary by CodeRabbit

  • Refactor
    • Improved channel listing and search operations with consolidated filtering logic
    • Enhanced error responses for failed channel queries

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Walkthrough

This PR refactors channel query construction by extracting shared filtering and pagination logic into new helper functions in model/channel.go, then updates GetAllChannels, SearchChannels, and SearchTags across both model and controller layers to use those helpers consistently for group/status/type filtering, reducing ad-hoc query construction and improving error handling.

Changes

Channel Query Refactoring with Shared Helpers

Layer / File(s) Summary
Shared query helper utilities
model/channel.go
Added NormalizeChannelGroupFilter and ApplyChannelGroupFilter for consistent group filtering with dialect-aware SQL escaping, and extracted GetPaginatedChannelTags and CountChannelTags helpers that accept pre-built gorm queries for pagination and tag counting.
GetAllChannels refactoring with query builders
controller/channel.go
Introduced buildChannelListQuery and applyChannelStatusFilter controller-level helpers, imported gorm, normalized group filters early in GetAllChannels, delegated tag and count operations to model helpers in tag mode, counts channel types via grouped query with error handling, and applies consistent Omit("key") and sorting to all retrieval paths.
Search endpoints refactored with group filtering
model/channel.go, controller/channel.go
Refactored model-layer SearchChannels and SearchTags to apply group filtering via ApplyChannelGroupFilter instead of inline SQL, and updated controller-layer SearchChannels tag mode to build queries through buildChannelListQuery with explicit JSON error responses on query failure.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Shared queries now bloom bright,
Group filters dance in SQLite,
No more ad-hoc, just helpers clean—
The channel searches flow, serene! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main fix: applying group filter to channel list queries, which directly addresses the issue.
Linked Issues check ✅ Passed The code changes directly implement the required fix for issue #4878 by adding group filtering utilities and applying them to channel listing queries.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the group filter functionality for channels and refactoring query helpers, with no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown
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.

🧹 Nitpick comments (3)
model/channel.go (3)

155-161: 💤 Low value

Add documentation for exported function.

The exported function ApplyChannelGroupFilter lacks a doc comment explaining its purpose and usage.

📝 Suggested documentation
+// ApplyChannelGroupFilter applies a group membership filter to the query.
+// Filters channels whose comma-delimited Group column contains the specified group.
+// Returns the query unchanged if group is empty, "all", or "null".
 func ApplyChannelGroupFilter(query *gorm.DB, group string) *gorm.DB {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@model/channel.go` around lines 155 - 161, Add a doc comment for the exported
ApplyChannelGroupFilter function describing its purpose and usage: explain that
ApplyChannelGroupFilter normalizes the provided group using
NormalizeChannelGroupFilter, returns the unchanged query when the normalized
group is empty, and otherwise applies a WHERE clause using
channelGroupFilterCondition() with channelGroupFilterPattern(group); mention
expected input format for group (if any) and that it returns a *gorm.DB for
chaining.

131-137: 💤 Low value

Add documentation for exported function.

The exported function NormalizeChannelGroupFilter lacks a doc comment. Consider adding one to explain its purpose and the special handling of "all" and "null" keywords.

📝 Suggested documentation
+// NormalizeChannelGroupFilter sanitizes group filter input.
+// Returns empty string for no filter (empty, "all", or "null" values).
+// Note: literal group name "null" cannot be filtered due to keyword conflict.
 func NormalizeChannelGroupFilter(group string) string {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@model/channel.go` around lines 131 - 137, Add a Go doc comment for the
exported function NormalizeChannelGroupFilter that succinctly explains what the
function does (trims whitespace and normalizes empty/"all"/"null" group values
to an empty string) and documents the special-case handling of case-insensitive
"all" and "null" keywords; place the comment immediately above the
NormalizeChannelGroupFilter declaration so it is picked up by godoc and other
tooling.

139-153: 💤 Low value

Consider adding inline comments for clarity.

The LIKE escape logic in channelGroupFilterPattern and the comma-wrapping technique in channelGroupFilterCondition are subtle. Adding brief inline comments would help future maintainers understand the pattern-matching strategy.

📝 Suggested comments
 func channelGroupFilterCondition() string {
+  // Wrap group column with commas to match groups in comma-delimited lists
+  // e.g., "vip,default" becomes ",vip,default," to match "%,vip,%"
   if common.UsingMySQL {
     return `CONCAT(',', ` + commonGroupCol + `, ',') LIKE ? ESCAPE '!'`
   }
   return `(',' || ` + commonGroupCol + ` || ',') LIKE ? ESCAPE '!'`
 }

 func channelGroupFilterPattern(group string) string {
+  // Escape LIKE wildcards to treat user input as literal string
   group = strings.NewReplacer(
     "!", "!!",
     "%", "!%",
     "_", "!_",
   ).Replace(group)
+  // Match group in comma-delimited list: ",vip,default," LIKE "%,vip,%"
   return "%," + group + ",%"
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@model/channel.go` around lines 139 - 153, Add brief inline comments in
channelGroupFilterCondition and channelGroupFilterPattern explaining the
matching strategy: note that we wrap the stored comma-separated group list with
commas to avoid partial matches (e.g., matching "dev" vs "devops"), explain the
DB-specific concatenation/CONCAT vs '||' choice, and describe the escaping in
channelGroupFilterPattern (replacing '!', '%', '_' and using ESCAPE '!' so
wildcards are treated literally). Place these comments immediately above or
inside the respective functions (channelGroupFilterCondition and
channelGroupFilterPattern) so maintainers can quickly understand why the
comma-wrapping and escape sequence are used.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@model/channel.go`:
- Around line 155-161: Add a doc comment for the exported
ApplyChannelGroupFilter function describing its purpose and usage: explain that
ApplyChannelGroupFilter normalizes the provided group using
NormalizeChannelGroupFilter, returns the unchanged query when the normalized
group is empty, and otherwise applies a WHERE clause using
channelGroupFilterCondition() with channelGroupFilterPattern(group); mention
expected input format for group (if any) and that it returns a *gorm.DB for
chaining.
- Around line 131-137: Add a Go doc comment for the exported function
NormalizeChannelGroupFilter that succinctly explains what the function does
(trims whitespace and normalizes empty/"all"/"null" group values to an empty
string) and documents the special-case handling of case-insensitive "all" and
"null" keywords; place the comment immediately above the
NormalizeChannelGroupFilter declaration so it is picked up by godoc and other
tooling.
- Around line 139-153: Add brief inline comments in channelGroupFilterCondition
and channelGroupFilterPattern explaining the matching strategy: note that we
wrap the stored comma-separated group list with commas to avoid partial matches
(e.g., matching "dev" vs "devops"), explain the DB-specific concatenation/CONCAT
vs '||' choice, and describe the escaping in channelGroupFilterPattern
(replacing '!', '%', '_' and using ESCAPE '!' so wildcards are treated
literally). Place these comments immediately above or inside the respective
functions (channelGroupFilterCondition and channelGroupFilterPattern) so
maintainers can quickly understand why the comma-wrapping and escape sequence
are used.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 02687f45-c011-457b-b9b0-93b6aecb51d1

📥 Commits

Reviewing files that changed from the base of the PR and between 18282e6 and 0f29a10.

📒 Files selected for processing (2)
  • controller/channel.go
  • model/channel.go

@Calcium-Ion Calcium-Ion merged commit 2d968c3 into QuantumNous:main May 17, 2026
1 check passed
chenglu added a commit to chenglu/new-api that referenced this pull request May 17, 2026
Merged 28 commits from QuantumNous/new-api upstream/main, including:

Backend:
- feat: support request_header key source (QuantumNous#4903)
- fix: apply group filter to channel list queries (QuantumNous#4885, QuantumNous#4847)
- fix: enforce header nav access control for public modules (QuantumNous#4889)
- fix: correct usage logs filtering (QuantumNous#4883)
- fix: allow clearing channel remark (QuantumNous#4886)
- feat: track upstream request ID and prevent response header override
- feat: require compliance confirmation for paid features

Frontend:
- fix: 修复新 UI 语言与文案显示问题 (QuantumNous#4876)
- fix(web): handle unlimited API key quota validation (QuantumNous#4881)
- fix(web/default): batch fix new UI issues (QuantumNous#4880, QuantumNous#4893, QuantumNous#4817, QuantumNous#4877, QuantumNous#4898)
- fix: prevent combobox from over-filtering options on focus (QuantumNous#4829)
- fix(default): support DropdownMenuItem onSelect (QuantumNous#4787)
- chore(deps): bump axios to 1.15.2

Conflict resolution:
- Locale JSONs: union merge (design overrides preserved, upstream new keys added)
- router/api-router.go: kept design /public/session route, accepted upstream HeaderNavModuleAuth
- common-logs-filter-bar.tsx: kept design refactor, added upstream upstreamRequestId field
- summary-cards.tsx: kept design layout, adapted to new useSummaryCardsConfig interface
- _reports/*.untranslated.json: design state kept (fr/vi removed, ja/ru ours)
- Other UI conflicts resolved per .gitattributes ours strategy

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

v1.0.0-rc.6 渠道中的分组筛选不起作用

2 participants