Skip to content

Bug 修复 (Bug fix)#3

Merged
CSCITech merged 6 commits into
mainfrom
cscitech
Jun 28, 2026
Merged

Bug 修复 (Bug fix)#3
CSCITech merged 6 commits into
mainfrom
cscitech

Conversation

@CSCITech

Copy link
Copy Markdown
Contributor

⚠️ 提交说明 / PR Notice

Important

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

📝 变更描述 / Description

修复公告中心在渲染包含链接的 Markdown 内容时崩溃的问题。原因是自定义 marked link renderer 复用了脱离运行时 parser 上下文的默认 renderer,导致点击或打开公告时读取 parseInline 报错。本次改为在当前 renderer 上下文中渲染链接文本,并保留外链安全属性与 DOMPurify 清理流程。

同时恢复公告中心的自动弹出行为:页面加载到公告/通知内容后会自动打开一次,用户点击“今日关闭”后当天不再自动弹出。公告已读与自动弹出去重也改为基于内容版本签名,避免同一后端 id 的公告编辑后仍被视为已读;公告签名会排序,避免服务端返回顺序变化导致重复弹出。

🚀 变更类型 / Type of change

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

🔗 关联任务 / Related Issue

  • 无公开 Issue,来自公告栏点击报错与自动弹出失效的用户反馈。

✅ 提交前检查项 / Checklist

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

📸 运行证明 / Proof of Work

已通过以下本地验证:

bun test src/components/ui/markdown.test.ts
bun test src/hooks/notification-utils.test.ts
bunx eslint src/hooks/notification-utils.ts src/hooks/notification-utils.test.ts src/hooks/use-notifications.ts
bun run typecheck
bun run build
git diff --check -- web/default/src

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 36e079aa-8799-4b9a-8c2c-74a15a7ce06f

📥 Commits

Reviewing files that changed from the base of the PR and between 7606795 and ed92fb9.

📒 Files selected for processing (2)
  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/hooks/notification-utils.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Frontend checks
  • GitHub Check: Backend checks
🧰 Additional context used
📓 Path-based instructions (2)
web/default/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (web/default/AGENTS.md)

web/default/src/**/*.{ts,tsx}: 前端页面文本与组件内文案必须支持 i18n:React 组件中应使用 useTranslation() 取得 t,并通过 t() 渲染用户可见文本;子组件也应自行使用 useTranslation() 保持独立性。
禁止使用两层及以上嵌套三元表达式;复杂逻辑应改用 if-else、提前返回或抽取函数。
控制函数圈复杂度,复杂逻辑应拆成更小的函数;变量与函数命名应有意义并遵循驼峰等常规命名约定。
TypeScript 代码应避免使用 any,优先使用具体类型或 unknown;参数与返回值应显式标注类型;仅类型用途的导入应使用 import type
修改 TypeScript 或 TSX 代码后必须执行类型检查,并修复所有类型错误,不得遗留。
对象非必要不要解构,尤其是组件 props;优先直接使用 props.xxx 以保持代码清晰。
组件应使用函数式组件与 Hooks,遵循单一职责;组件 props 必须有明确类型(接口或类型别名)。
单文件超过约 200 行时应考虑拆分子组件或抽取自定义 Hooks;类型定义可与组件同文件或放在同模块的 types 中。
在 React 中应合理使用 useMemouseCallbackReact.memo,避免在渲染路径中创建新对象或数组;必要时进行代码分割与动态 import
React Query 的数据获取应使用 useQuery、变更应使用 useMutation;每个查询需配置唯一 queryKey,并在成功后对相关查询执行 invalidateQueries;服务端错误应统一交给 handleServerError
Axios 请求应使用项目统一的 api 实例;GET 请求默认去重,特殊请求可显式关闭;认证与通用错误应在拦截器中统一处理。
服务端错误应统一使用 handleServerError,展示层应使用 toast.error 等统一方式;文案需走 i18n;路由级错误应由 errorComponent 承接;表单错误应通过 form.setError 等方式映射到字段。
样式应以 Tailwind 工具类为主,动态类名使用 cn() 合并;非动态场景避免内联样式;响应式采用移动优先与 Tailwind 断点,主题与暗色模式通过 CSS 变量与 dark: 处理。
应使用语义化 HTML、正确关联 label 与输入、保证键盘可操作与合理焦点顺序;必要时添加 ARIA 属性,装饰性图标应使用 aria-hidden="true"
认证与权限应在路由与接口层校验;前后端都应做数据校验(如 Zod);敏感信息不得落前端存储;避免使用 dangerouslySetInnerHTML;跨域与 Cookie 需配合 withCredentials 并按后端要求处理 CSRF。
组件测试应使用 React Testing Library,关注交互与行为,避免测试实现细节;关键流程可补充集成与 E2E 测试。
环境变量应通过 .env 读取,并使用 VITE_ 前缀;代码中不得硬编码密钥。

Files:

  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/hooks/notification-utils.ts
web/default/src/**/*.test.ts

📄 CodeRabbit inference engine (web/default/AGENTS.md)

工具函数与纯逻辑应优先编写单元测试;测试文件应命名为 *.test.ts

Files:

  • web/default/src/hooks/notification-utils.test.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: MAX-API-Next/MAX-API

Timestamp: 2026-06-28T15:36:39.497Z
Learning: Do not modify, delete, replace, or remove protected project identity references related to `max-api` or `max-api-next` anywhere in the repository, including docs, metadata, code, comments, and deployment files.
Learnt from: CR
Repo: MAX-API-Next/MAX-API

Timestamp: 2026-06-28T15:36:39.497Z
Learning: Before working on tiered/dynamic billing (expression-based pricing), read `pkg/billingexpr/expr.md` and follow its documented design, expression language, architecture, normalization rules, quota conversion, and versioning.
Learnt from: CR
Repo: MAX-API-Next/MAX-API

Timestamp: 2026-06-28T15:36:48.958Z
Learning: Project identity and attribution references for `max-api` and `MAX API Next` must not be modified, deleted, replaced, or removed in any project content, including metadata, docs, code, configs, and comments.
Learnt from: CR
Repo: MAX-API-Next/MAX-API

Timestamp: 2026-06-28T15:36:48.958Z
Learning: All non-project process documents (notes, drafts, review outputs, temporary plans, one-off notes, and similar internal working docs) must be created and kept under `.tmp/` and not placed in public project directories.
🔇 Additional comments (2)
web/default/src/hooks/notification-utils.ts (1)

137-139: LGTM!

web/default/src/hooks/notification-utils.test.ts (1)

172-176: LGTM!


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added “Close Today” to the notifications popover.
    • Added quota status filtering to user search.
    • Added enhanced log detail access for individual entries.
  • Bug Fixes

    • Improved notification auto-opening so it opens more reliably and avoids repeatedly reopening the same content; “Close Today” suppresses it until the next day.
    • Strengthened Markdown security: unsafe HTML is removed and unsafe/invalid links are stripped or rendered as text (safe links open in a new tab with safer attributes).
    • Improved AI responses by retrying when completions are empty.

Walkthrough

Adds notification auto-open helpers and a close-for-today action, hardens Markdown rendering and tests, updates quota/redemption transaction handling, and changes OpenAI empty-completion retry behavior. It also adds process-document placement rules and adjusts one log-filter test.

Changes

Notification Close-for-Today & Auto-Open Refactor

Layer / File(s) Summary
Notification utility types and helpers
web/default/src/hooks/notification-utils.ts, web/default/src/hooks/notification-utils.test.ts
Defines notification types and helper functions for announcement keys, content signatures, tab selection, and auto-open decisions, with tests covering the helper behavior.
useNotifications hook refactor with closeForToday
web/default/src/hooks/use-notifications.ts
Refactors the hook to derive loading and auto-open state from the new helpers, tracks the last opened signature, and adds the close-for-today action.
NotificationPopover onCloseForToday prop and UI button
web/default/src/components/notification-popover.tsx, web/default/src/components/layout/components/app-header.tsx, web/default/src/components/layout/components/public-header.tsx
Adds onCloseForToday to the popover props, renders a Close Today button, and passes the callback through both header components.

Markdown Link Hardening

Layer / File(s) Summary
normalizeUrl, sanitizeHtml, and link renderer rewrite
web/default/src/components/ui/markdown.tsx, web/default/src/components/ui/markdown.test.ts, web/default/package.json
Adds sanitizer typing and helpers, rewrites link rendering to build anchors directly with normalized hrefs, exports a test helper, adds security-focused tests, and includes the jsdom dependencies used by the test module.

Quota and Redemption Transaction Fixes

Layer / File(s) Summary
Redemption and top-up state transitions
fix_quota.diff
Switches redemption and top-up completion paths to locked reads, conditional updates, and matched-row checks while preserving completion timestamps and quota validation.
User quota search and transfer updates
fix_quota.diff
Extends user search with quota-status filtering and changes affiliate quota transfer to an atomic conditional update with row-count validation.

OpenAI Empty-Completion Retry Handling

Layer / File(s) Summary
Response retry checks and completion handling
fix_relay.diff
Updates retry selection and non-stream response handling to recognize empty completions and record retry outcomes.
Streaming buffering and visibility tracking
fix_relay.diff
Expands streaming state to buffer pending events, track visible payloads, and delay forwarding until output becomes visible.

Process Document Placement Rule

Layer / File(s) Summary
Process document storage rule
AGENTS.md, CLAUDE.md
Adds the .tmp/ placement rule and the .agents/skills/ exception in both repository guidance files.

Log ID Filter Assertion Update

Layer / File(s) Summary
Retry filter assertion
model/log_test.go
Builds a returned-ID slice, checks the expected IDs, and verifies one ID is not present in the result set.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐇 I hopped through buttons, hooks, and glowing Markdown light,
Quota paths now lock and update in the night.
Empty replies may retry, if nothing’s there to see,
And .tmp/ keeps secret notes tucked safely in a tree.
My whiskers twitch: the changes are quite a stew—
But every carrot’s labeled, neat, and new!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is too generic and does not describe the specific changes in this PR. Use a concise title that names the main fix, such as markdown link rendering crash and notification auto-popup behavior.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description matches the PR’s main fixes for Markdown rendering and notification auto-popup behavior.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cscitech

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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.

Inline comments:
In `@web/default/src/components/ui/markdown.test.ts`:
- Around line 23-39: The markdown link tests in renderMarkdownForTest cover
valid links and invalid href encoding, but they do not protect against dangerous
protocols. Add a regression test in markdown.test.ts that renders a link with a
malicious scheme such as javascript: or data: and asserts the output is
sanitized or falls back to plain text, so protocol-validation regressions are
caught.

In `@web/default/src/components/ui/markdown.tsx`:
- Around line 729-739: The helper currently named renderMarkdownForTest is used
by the production Markdown component, so rename it to a production-appropriate
name and update its call site inside Markdown to match. Also add an explicit
return type annotation to Markdown so it complies with the required typing
guideline; use the Markdown and renderMarkdownForTest symbols to locate the
change.
- Around line 176-198: Update normalizeUrl to reject unsafe URL schemes up front
so javascript: and similar values are never returned, even after
encoding/cleanup; keep the logic in the normalizeUrl helper so callers like the
markdown rendering path continue to use a safe URL. Also change sanitizeHtml to
fail closed: in the DOMPurify resolution fallback path, return an empty string
instead of the raw html when sanitize() can’t be resolved, so the
dangerouslySetInnerHTML usage in markdown.tsx never renders unsanitized markup.

In `@web/default/src/hooks/use-notifications.ts`:
- Line 36: The useNotifications hook currently relies on inferred return shape,
which should be made explicit because it is a shared contract. Extract a
UseNotificationsResult type that captures the hook’s returned object, then
annotate the useNotifications export with that return type so any shape changes
are caught at compile time. Keep the type definition close to useNotifications
and update the hook implementation to satisfy the new explicit contract.
- Around line 162-202: The auto-open effect in use-notifications should remember
the current contentSignature even when popoverOpen is already true, since the
early return leaves lastAutoOpenedSignatureRef unset and causes an immediate
reopen after manual close. Update the useEffect flow around
shouldAutoOpenNotifications and getAutoNotificationTab so the signature is
recorded whenever the current content has effectively been seen/opened, not only
after scheduling handleOpenPopover. Keep the existing timeout behavior for
automatic opening, but ensure lastAutoOpenedSignatureRef.current is set in the
open state path too.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 28934d5d-dffb-49bd-b047-0188634a342e

📥 Commits

Reviewing files that changed from the base of the PR and between ecb2dd4 and 9c15eaa.

📒 Files selected for processing (8)
  • web/default/src/components/layout/components/app-header.tsx
  • web/default/src/components/layout/components/public-header.tsx
  • web/default/src/components/notification-popover.tsx
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/components/ui/markdown.tsx
  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/hooks/notification-utils.ts
  • web/default/src/hooks/use-notifications.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Backend checks
🧰 Additional context used
📓 Path-based instructions (3)
web/default/**/*.{js,jsx,ts,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

In web/default/, use Bun for frontend dependency and script commands (bun install, bun run dev, bun run build, bun run i18n:*).

Files:

  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/components/layout/components/app-header.tsx
  • web/default/src/components/layout/components/public-header.tsx
  • web/default/src/hooks/notification-utils.ts
  • web/default/src/components/notification-popover.tsx
  • web/default/src/hooks/use-notifications.ts
  • web/default/src/components/ui/markdown.tsx
web/default/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (web/default/AGENTS.md)

web/default/src/**/*.{ts,tsx}: 前端页面文本与组件内文案必须支持 i18n:React 组件中应使用 useTranslation() 取得 t,并通过 t() 渲染用户可见文本;子组件也应自行使用 useTranslation() 保持独立性。
禁止使用两层及以上嵌套三元表达式;复杂逻辑应改用 if-else、提前返回或抽取函数。
控制函数圈复杂度,复杂逻辑应拆成更小的函数;变量与函数命名应有意义并遵循驼峰等常规命名约定。
TypeScript 代码应避免使用 any,优先使用具体类型或 unknown;参数与返回值应显式标注类型;仅类型用途的导入应使用 import type
修改 TypeScript 或 TSX 代码后必须执行类型检查,并修复所有类型错误,不得遗留。
对象非必要不要解构,尤其是组件 props;优先直接使用 props.xxx 以保持代码清晰。
组件应使用函数式组件与 Hooks,遵循单一职责;组件 props 必须有明确类型(接口或类型别名)。
单文件超过约 200 行时应考虑拆分子组件或抽取自定义 Hooks;类型定义可与组件同文件或放在同模块的 types 中。
在 React 中应合理使用 useMemouseCallbackReact.memo,避免在渲染路径中创建新对象或数组;必要时进行代码分割与动态 import
React Query 的数据获取应使用 useQuery、变更应使用 useMutation;每个查询需配置唯一 queryKey,并在成功后对相关查询执行 invalidateQueries;服务端错误应统一交给 handleServerError
Axios 请求应使用项目统一的 api 实例;GET 请求默认去重,特殊请求可显式关闭;认证与通用错误应在拦截器中统一处理。
服务端错误应统一使用 handleServerError,展示层应使用 toast.error 等统一方式;文案需走 i18n;路由级错误应由 errorComponent 承接;表单错误应通过 form.setError 等方式映射到字段。
样式应以 Tailwind 工具类为主,动态类名使用 cn() 合并;非动态场景避免内联样式;响应式采用移动优先与 Tailwind 断点,主题与暗色模式通过 CSS 变量与 dark: 处理。
应使用语义化 HTML、正确关联 label 与输入、保证键盘可操作与合理焦点顺序;必要时添加 ARIA 属性,装饰性图标应使用 aria-hidden="true"
认证与权限应在路由与接口层校验;前后端都应做数据校验(如 Zod);敏感信息不得落前端存储;避免使用 dangerouslySetInnerHTML;跨域与 Cookie 需配合 withCredentials 并按后端要求处理 CSRF。
组件测试应使用 React Testing Library,关注交互与行为,避免测试实现细节;关键流程可补充集成与 E2E 测试。
环境变量应通过 .env 读取,并使用 VITE_ 前缀;代码中不得硬编码密钥。

Files:

  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/components/layout/components/app-header.tsx
  • web/default/src/components/layout/components/public-header.tsx
  • web/default/src/hooks/notification-utils.ts
  • web/default/src/components/notification-popover.tsx
  • web/default/src/hooks/use-notifications.ts
  • web/default/src/components/ui/markdown.tsx
web/default/src/**/*.test.ts

📄 CodeRabbit inference engine (web/default/AGENTS.md)

工具函数与纯逻辑应优先编写单元测试;测试文件应命名为 *.test.ts

Files:

  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/components/ui/markdown.test.ts
🔇 Additional comments (2)
web/default/src/components/ui/markdown.tsx (1)

132-134: LGTM!

Also applies to: 594-596

web/default/src/hooks/notification-utils.ts (1)

54-62: 🎯 Functional Correctness

No change needed — the fingerprint already covers the rendered announcement fields.

			> Likely an incorrect or invalid review comment.

Comment thread web/default/src/components/ui/markdown.test.ts
Comment thread web/default/src/components/ui/markdown.tsx
Comment on lines +729 to +739
export function renderMarkdownForTest(markdown: string): string {
const markdownParser = createMarkdownParser()
const parsedHtml = markdownParser.parse(markdown, markdownOptions)
return DOMPurify.sanitize(parsedHtml, sanitizeOptions)
return sanitizeHtml(parsedHtml)
}

export function Markdown(props: MarkdownProps) {
const html = useMemo(() => renderMarkdown(props.children), [props.children])
const html = useMemo(
() => renderMarkdownForTest(props.children),
[props.children]
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename the production helper and add the component return type.

renderMarkdownForTest() is now used by production Markdown, so the name is misleading; Markdown also lacks the required explicit return type.

Suggested cleanup
-export function renderMarkdownForTest(markdown: string): string {
+export function renderMarkdownHtml(markdown: string): string {
   const markdownParser = createMarkdownParser()
   const parsedHtml = markdownParser.parse(markdown, markdownOptions)
   return sanitizeHtml(parsedHtml)
 }
+
+export const renderMarkdownForTest = renderMarkdownHtml
 
-export function Markdown(props: MarkdownProps) {
+export function Markdown(props: MarkdownProps): React.JSX.Element {
   const html = useMemo(
-    () => renderMarkdownForTest(props.children),
+    () => renderMarkdownHtml(props.children),
     [props.children]
   )

As per coding guidelines, “变量与函数命名应有意义” and “参数与返回值应显式标注类型.”

📝 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
export function renderMarkdownForTest(markdown: string): string {
const markdownParser = createMarkdownParser()
const parsedHtml = markdownParser.parse(markdown, markdownOptions)
return DOMPurify.sanitize(parsedHtml, sanitizeOptions)
return sanitizeHtml(parsedHtml)
}
export function Markdown(props: MarkdownProps) {
const html = useMemo(() => renderMarkdown(props.children), [props.children])
const html = useMemo(
() => renderMarkdownForTest(props.children),
[props.children]
)
export function renderMarkdownHtml(markdown: string): string {
const markdownParser = createMarkdownParser()
const parsedHtml = markdownParser.parse(markdown, markdownOptions)
return sanitizeHtml(parsedHtml)
}
export const renderMarkdownForTest = renderMarkdownHtml
export function Markdown(props: MarkdownProps): React.JSX.Element {
const html = useMemo(
() => renderMarkdownHtml(props.children),
[props.children]
)
🤖 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 `@web/default/src/components/ui/markdown.tsx` around lines 729 - 739, The
helper currently named renderMarkdownForTest is used by the production Markdown
component, so rename it to a production-appropriate name and update its call
site inside Markdown to match. Also add an explicit return type annotation to
Markdown so it complies with the required typing guideline; use the Markdown and
renderMarkdownForTest symbols to locate the change.

Source: Coding guidelines

Comment thread web/default/src/hooks/use-notifications.ts Outdated
Comment thread web/default/src/hooks/use-notifications.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@web/default/package.json`:
- Line 95: `jsdom` is a test-only package and should not remain in the
production dependencies list. Move the `jsdom` entry in
`web/default/package.json` from `dependencies` to `devDependencies` alongside
`@types/jsdom`, then regenerate the Bun lockfile so the package metadata stays
in sync. Keep the change scoped to the package manifest used by
`markdown.test.ts`.

In `@web/default/src/hooks/notification-utils.ts`:
- Around line 138-190: The notification signature guard currently persists
through window.sessionStorage, which changes the behavior from “once after page
load” to “once per tab session.” Update getLastAutoOpenedNotificationSignature()
and rememberAutoOpenedNotificationSignature() in notification-utils so they rely
on the in-memory memoryLastAutoOpenedSignature only, removing the sessionStorage
read/write path while keeping the existing fallback behavior for repeated hook
remounts within the same page load.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 88ee126d-60ac-4bd8-bc65-12446111a32d

📥 Commits

Reviewing files that changed from the base of the PR and between c244f98 and 7606795.

⛔ Files ignored due to path filters (1)
  • web/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • AGENTS.md
  • CLAUDE.md
  • fix_quota.diff
  • fix_relay.diff
  • model/log_test.go
  • web/default/package.json
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/components/ui/markdown.tsx
  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/hooks/notification-utils.ts
  • web/default/src/hooks/use-notifications.ts
💤 Files with no reviewable changes (2)
  • fix_quota.diff
  • fix_relay.diff
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
web/default/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (web/default/AGENTS.md)

web/default/src/**/*.{ts,tsx}: 前端页面文本与组件内文案必须支持 i18n:React 组件中应使用 useTranslation() 取得 t,并通过 t() 渲染用户可见文本;子组件也应自行使用 useTranslation() 保持独立性。
禁止使用两层及以上嵌套三元表达式;复杂逻辑应改用 if-else、提前返回或抽取函数。
控制函数圈复杂度,复杂逻辑应拆成更小的函数;变量与函数命名应有意义并遵循驼峰等常规命名约定。
TypeScript 代码应避免使用 any,优先使用具体类型或 unknown;参数与返回值应显式标注类型;仅类型用途的导入应使用 import type
修改 TypeScript 或 TSX 代码后必须执行类型检查,并修复所有类型错误,不得遗留。
对象非必要不要解构,尤其是组件 props;优先直接使用 props.xxx 以保持代码清晰。
组件应使用函数式组件与 Hooks,遵循单一职责;组件 props 必须有明确类型(接口或类型别名)。
单文件超过约 200 行时应考虑拆分子组件或抽取自定义 Hooks;类型定义可与组件同文件或放在同模块的 types 中。
在 React 中应合理使用 useMemouseCallbackReact.memo,避免在渲染路径中创建新对象或数组;必要时进行代码分割与动态 import
React Query 的数据获取应使用 useQuery、变更应使用 useMutation;每个查询需配置唯一 queryKey,并在成功后对相关查询执行 invalidateQueries;服务端错误应统一交给 handleServerError
Axios 请求应使用项目统一的 api 实例;GET 请求默认去重,特殊请求可显式关闭;认证与通用错误应在拦截器中统一处理。
服务端错误应统一使用 handleServerError,展示层应使用 toast.error 等统一方式;文案需走 i18n;路由级错误应由 errorComponent 承接;表单错误应通过 form.setError 等方式映射到字段。
样式应以 Tailwind 工具类为主,动态类名使用 cn() 合并;非动态场景避免内联样式;响应式采用移动优先与 Tailwind 断点,主题与暗色模式通过 CSS 变量与 dark: 处理。
应使用语义化 HTML、正确关联 label 与输入、保证键盘可操作与合理焦点顺序;必要时添加 ARIA 属性,装饰性图标应使用 aria-hidden="true"
认证与权限应在路由与接口层校验;前后端都应做数据校验(如 Zod);敏感信息不得落前端存储;避免使用 dangerouslySetInnerHTML;跨域与 Cookie 需配合 withCredentials 并按后端要求处理 CSRF。
组件测试应使用 React Testing Library,关注交互与行为,避免测试实现细节;关键流程可补充集成与 E2E 测试。
环境变量应通过 .env 读取,并使用 VITE_ 前缀;代码中不得硬编码密钥。

Files:

  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/hooks/notification-utils.ts
  • web/default/src/components/ui/markdown.tsx
  • web/default/src/hooks/use-notifications.ts
web/default/src/**/*.test.ts

📄 CodeRabbit inference engine (web/default/AGENTS.md)

工具函数与纯逻辑应优先编写单元测试;测试文件应命名为 *.test.ts

Files:

  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/components/ui/markdown.test.ts
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: All JSON marshal/unmarshal operations in Go business code must use the wrapper functions in common/json.go (common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, common.GetJsonType); do not directly call encoding/json except for type references like json.RawMessage and json.Number.
All database code must remain compatible with SQLite, MySQL 5.7.8+, and PostgreSQL 9.6+; prefer GORM abstractions, avoid backend-specific SQL/features without cross-DB fallback, use the shared quoting/boolean helpers for raw SQL, and ensure migrations work on all three databases.

**/*.go: All JSON marshal/unmarshal operations in Go must use the wrapper functions in common/json.go (common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, common.GetJsonType); do not directly call encoding/json in business code.
All database code in Go must remain compatible with SQLite, MySQL 5.7.8+, and PostgreSQL 9.6+; prefer GORM abstractions, avoid database-specific features without fallback, and ensure migrations work across all three databases.

Files:

  • model/log_test.go
web/default/**/package.json

📄 CodeRabbit inference engine (web/default/AGENTS.md)

脚本与包管理以 package.json 为准;发布前应执行 typecheck、lint、format、生产构建,并检查产物体积与环境变量配置。

Files:

  • web/default/package.json
web/default/{package.json,bun.lockb}

📄 CodeRabbit inference engine (AGENTS.md)

Use Bun as the preferred package manager and script runner for the frontend in web/default/ (bun install, bun run dev, bun run build, and bun run i18n:*).

Files:

  • web/default/package.json
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: MAX-API-Next/MAX-API

Timestamp: 2026-06-28T15:10:54.494Z
Learning: Protected project identity and attribution references related to `max-api` and `max-api-next` must not be modified, deleted, renamed, replaced, or removed anywhere in the repository.
Learnt from: CR
Repo: MAX-API-Next/MAX-API

Timestamp: 2026-06-28T15:10:54.494Z
Learning: All non-project process documents must be created and kept under `.tmp/`; do not place investigation notes, scratch drafts, temporary release-note/PR-copy drafts, one-off deployment notes, or similar internal process documents elsewhere in the repo.
Learnt from: CR
Repo: MAX-API-Next/MAX-API

Timestamp: 2026-06-28T15:11:06.840Z
Learning: Use `bun` as the preferred package manager and script runner for the frontend in `web/default/` (`bun install`, `bun run dev`, `bun run build`, `bun run i18n:*`).
Learnt from: CR
Repo: MAX-API-Next/MAX-API

Timestamp: 2026-06-28T15:11:06.840Z
Learning: Do not modify, delete, replace, or remove any protected project identity references related to `max-api` or `MAX API Next`, including in README files, license headers, package metadata, HTML titles, comments, docs, CI/CD configs, and import or module paths.
Learnt from: CR
Repo: MAX-API-Next/MAX-API

Timestamp: 2026-06-28T15:11:06.840Z
Learning: All non-project process documents (investigation notes, review outputs, scratch plans, temporary drafts, one-off deployment notes, private operation notes, and similar internal work artifacts) must be created and kept under `.tmp/`; project-owned agent workflows and reusable skills under `.agents/skills/` must remain tracked unless retired.
🪛 ast-grep (0.44.0)
web/default/src/components/ui/markdown.test.ts

[warning] 72-72: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(>${label}<)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)

🪛 LanguageTool
CLAUDE.md

[uncategorized] ~144-~144: The official name of this software platform is spelled with a capital “H”.
Context: ... files in the repository root, docs/, .github/, or source directories unless the con...

(GITHUB)

AGENTS.md

[uncategorized] ~144-~144: The official name of this software platform is spelled with a capital “H”.
Context: ... files in the repository root, docs/, .github/, or source directories unless the con...

(GITHUB)

🪛 OpenGrep (1.23.0)
web/default/src/components/ui/markdown.tsx

[ERROR] 185-185: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

🔇 Additional comments (6)
model/log_test.go (1)

50-52: LGTM!

AGENTS.md (1)

138-146: LGTM!

CLAUDE.md (1)

138-146: LGTM!

web/default/src/components/ui/markdown.tsx (2)

758-768: Duplicate: rename the production helper and annotate Markdown’s return type.

renderMarkdownForTest() is still used by production Markdown, and Markdown still lacks the explicit return type required by the TS guidelines.


132-138: LGTM!

Also applies to: 179-227, 645-656

web/default/src/components/ui/markdown.test.ts (1)

21-28: LGTM!

Also applies to: 30-45, 47-52, 54-75, 77-91

Comment thread web/default/package.json
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.6.0",
"jsdom": "^29.1.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move test-only jsdom to devDependencies.

jsdom is only used by markdown.test.ts, so keeping it in production dependencies increases install surface unnecessarily. Move it next to @types/jsdom and regenerate the Bun lockfile afterward.

Proposed package cleanup
+    "jsdom": "^29.1.1",
     "`@types/jsdom`": "^28.0.3",
...
-    "jsdom": "^29.1.1",

As per coding guidelines, “Use Bun as the preferred package manager and script runner for the frontend in web/default/.”

📝 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
"jsdom": "^29.1.1",
🤖 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 `@web/default/package.json` at line 95, `jsdom` is a test-only package and
should not remain in the production dependencies list. Move the `jsdom` entry in
`web/default/package.json` from `dependencies` to `devDependencies` alongside
`@types/jsdom`, then regenerate the Bun lockfile so the package metadata stays
in sync. Keep the change scoped to the package manifest used by
`markdown.test.ts`.

Sources: Coding guidelines, Learnings

Comment thread web/default/src/hooks/notification-utils.ts Outdated
@CSCITech
CSCITech merged commit 85e7f8d into main Jun 28, 2026
3 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jul 17, 2026
11 tasks
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.

1 participant