Skip to content

添加游乐场一键清除功能#4

Merged
CSCITech merged 5 commits into
mainfrom
cscitech
Jun 30, 2026
Merged

添加游乐场一键清除功能#4
CSCITech merged 5 commits into
mainfrom
cscitech

Conversation

@CSCITech

Copy link
Copy Markdown
Contributor

⚠️ 提交说明 / PR Notice

Important

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

📝 变更描述 / Description

本次为游乐场聊天输入区新增“一键清空聊天记录”入口。按钮会在存在历史消息时可用,点击后调用现有的 clearMessages() 状态逻辑,将本地保存的 playground_messages 清空,并同步关闭当前编辑态、显示清空成功提示。

同时补齐了该按钮和提示文案在 en / zh / fr / ja / ru / vi 六种语言下的翻译,避免新增 UI 文案缺失。

🚀 变更类型 / Type of change

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

🔗 关联任务 / Related Issue

  • Closes # (如有)

✅ 提交前检查项 / Checklist

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

📸 运行证明 / Proof of Work

bunx eslint src/features/playground/index.tsx src/features/playground/components/playground-input.tsx
bun run typecheck
bun run i18n:sync
git diff --check

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: ab1b7e6f-4b2f-47a1-a89f-d863bc861b4f

📥 Commits

Reviewing files that changed from the base of the PR and between 1c8e244 and 41d9baa.

📒 Files selected for processing (5)
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/lib/selection-state.test.ts
  • web/default/src/features/playground/lib/selection-state.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Backend checks
🧰 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/features/playground/lib/selection-state.test.ts
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/features/playground/lib/selection-state.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/components/playground-input.tsx
web/default/src/features/**/lib/**/*.ts

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

表单应使用 React Hook Form + Zod:在功能模块的 lib/ 下定义 schema,并用 z.infer 导出表单类型;useForm 应配合 @hookform/resolvers/zod 进行校验。

Files:

  • web/default/src/features/playground/lib/selection-state.test.ts
  • web/default/src/features/playground/lib/selection-state.ts
web/default/src/features/**

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

功能模块应放在 src/features/<feature>/,并按需包含 components/lib/hooks/api.tstypes.tsconstants.ts 等;通用组件应放在 src/components/,通用工具与类型应放在 src/lib/

Files:

  • web/default/src/features/playground/lib/selection-state.test.ts
  • web/default/src/features/playground/lib/selection-state.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/components/playground-input.tsx
web/default/src/**/*.test.ts

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

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

Files:

  • web/default/src/features/playground/lib/selection-state.test.ts
  • web/default/src/components/ui/markdown.test.ts
web/default/**/*

📄 CodeRabbit inference engine (CLAUDE.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/src/features/playground/lib/selection-state.test.ts
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/features/playground/lib/selection-state.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/components/playground-input.tsx
🔇 Additional comments (5)
web/default/src/features/playground/components/playground-input.tsx (1)

62-76: LGTM!

Also applies to: 88-125, 199-222, 249-249

web/default/src/features/playground/lib/selection-state.ts (1)

19-45: LGTM!

web/default/src/features/playground/lib/selection-state.test.ts (1)

19-68: LGTM!

web/default/src/features/playground/index.tsx (1)

30-33: LGTM!

Also applies to: 48-48, 63-145, 155-156, 198-224, 252-257

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

20-42: LGTM!


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added Clear chat history to the playground toolbar (with tooltip/accessibility), disabled during generation and when there are no messages.
    • Improved playground submission gating: Send is disabled until trimmed text is non-empty, and suggestion/send actions are blocked when submission is disabled.
  • Bug Fixes

    • Chat history clearing now safely prevents conflicts while generating and closes any active edit, then confirms with a success message.
    • Improved model/group loading error handling and ensured chat regenerate/edit flows respect the send gate.
  • Security / Improvements

    • Unified rich content rendering across Home, About, Legal, and notifications using safer HTML sanitization and constrained iframe embedding.
    • Notification auto-open/remember behavior is now properly scoped per user.
  • Documentation

    • Added localized strings for “Clear chat history” and “chat history cleared.”
  • Tests

    • Added/updated coverage for HTML sanitization and content-rendering behaviors.

Walkthrough

Adds playground chat-history clearing, shared rich-content rendering, user-scoped notification state, retry-log persistence updates, and an upstream sync log tracked via .gitignore.

Changes

Clear Chat History

Layer / File(s) Summary
PlaygroundInput controls
web/default/src/features/playground/components/playground-input.tsx
Extends PlaygroundInput props, adds clear-history disabled state, and renders the tooltip-wrapped clear button.
Playground clear-history flow
web/default/src/features/playground/index.tsx, web/default/src/features/playground/lib/query-state.ts, web/default/src/features/playground/lib/query-state.test.ts, web/default/src/features/playground/lib/selection-state.ts, web/default/src/features/playground/lib/selection-state.test.ts
Updates playground query error handling, adds selection fallback helpers, adds handleClearHistory, and wires the new input props.
Locale strings
web/default/src/i18n/locales/*.json
Adds Chat history cleared and Clear chat history entries across the locale files.

Shared rich-content rendering

Layer / File(s) Summary
HTML sanitization helpers
web/default/src/lib/sanitize-core.ts, web/default/src/lib/html-sanitizer.ts, web/default/src/components/html-content.tsx, web/default/src/components/html-content.test.ts
Adds the sanitizer core, the HTML wrapper component, and tests for sanitized output and fail-closed behavior.
RichContent and Markdown rendering
web/default/src/components/rich-content.tsx, web/default/src/components/ui/markdown.tsx, web/default/src/components/ui/markdown.test.ts
Adds RichContent, updates Markdown sanitization, and switches markdown tests to the new render entry point.
Renderable content pages
web/default/src/features/about/index.tsx, web/default/src/features/home/index.tsx, web/default/src/features/legal/legal-document.tsx, web/default/src/components/notification-popover.tsx, web/default/src/features/dashboard/components/overview/announcement-detail-dialog.tsx, web/default/src/lib/renderable-content.ts, web/default/src/lib/renderable-content.test.ts
Uses renderable-content helpers and RichContent in about, home, legal, and notification views.

Notification scoping

Layer / File(s) Summary
Notification helper API
web/default/src/hooks/notification-utils.ts, web/default/src/hooks/notification-utils.test.ts
Changes notification auto-open identity handling, adds scoped signature helpers, and replaces the remembered-signature helpers.
Notification store and hook wiring
web/default/src/stores/notification-store.ts, web/default/src/stores/notification-store.test.ts, web/default/src/hooks/use-notifications.ts
Moves notification persistence and read state into per-user buckets, updates the hook to pass user scope, and adds scoped store tests.

Retry log persistence

Layer / File(s) Summary
Log retry marker storage
model/log.go, web/default/src/features/usage-logs/lib/utils.ts, web/default/src/features/usage-logs/lib/utils.test.ts, web/default/src/features/usage-logs/types.ts
Adds is_retry to logs, computes it from Other, and filters retry logs by the stored flag.
Retry marker backfill
model/main.go, model/task_cas_test.go
Adds the backfill migration path, completion-key handling, and the supporting schema migration test setup.
Retry marker tests
model/log_test.go
Expands log and migration tests to cover nested markers, backfill behavior, completion scoping, key hashing, and recomputation.

Upstream sync log

Layer / File(s) Summary
Sync log and ignore rules
.agents/upstream-sync/new-api-sync.md, .gitignore
Adds the selective upstream sync log and changes .gitignore to allow .agents/upstream-sync/ to be tracked.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

🐇 I hop through chats, then scrub them clean,
With rich text glow and sanitized sheen.
My whiskers twitch at scoped log trails,
And retry flags dance in tidy rails.
A sync log hums where upstream streams flow,
While my little paws say, “all set to go!” 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.53% 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
Title check ✅ Passed The title clearly summarizes the main change: adding a one-click clear chat history feature in the playground.
Description check ✅ Passed The description matches the changeset and accurately describes the new clear-history action and translations.
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: 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/src/features/playground/components/playground-input.tsx`:
- Around line 207-210: The desktop label in PlaygroundInput uses a missing
translation key, so update the button text to reuse the existing Clear chat
history key instead of t('Clear'); if you keep a separate label, add the Clear
key to all locale files. Use the existing translation calls in
playground-input.tsx to locate the hidden sm:inline and sr-only text and make
both labels consistent.

In `@web/default/src/features/playground/index.tsx`:
- Around line 72-90: The two error-handling effects in the playground page are
bypassing the shared server-error path by calling toast.error directly for
modelsError and groupsError. Update the useEffect handlers in the playground
component to delegate both failures through handleServerError instead of
formatting the toast inline, keeping the existing modelsError/groupsError checks
and using the shared frontend error flow for auth/common failures.
🪄 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: fa7d2d78-a582-40bb-b4ea-13c795ffc726

📥 Commits

Reviewing files that changed from the base of the PR and between 85e7f8d and 477e480.

📒 Files selected for processing (8)
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/index.tsx
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Frontend checks
  • GitHub Check: Backend checks
🧰 Additional context used
📓 Path-based instructions (3)
web/default/**/*

📄 CodeRabbit inference engine (CLAUDE.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/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/zh.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/index.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/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/index.tsx
web/default/src/features/**

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

功能模块应放在 src/features/<feature>/,并按需包含 components/lib/hooks/api.tstypes.tsconstants.ts 等;通用组件应放在 src/components/,通用工具与类型应放在 src/lib/

Files:

  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/index.tsx
🔇 Additional comments (7)
web/default/src/features/playground/index.tsx (1)

194-201: LGTM!

Also applies to: 230-232

web/default/src/i18n/locales/en.json (1)

798-798: LGTM!

Also applies to: 855-855

web/default/src/i18n/locales/fr.json (1)

798-798: LGTM!

Also applies to: 855-855

web/default/src/i18n/locales/ja.json (1)

798-798: LGTM!

Also applies to: 855-855

web/default/src/i18n/locales/ru.json (1)

798-798: LGTM!

Also applies to: 855-855

web/default/src/i18n/locales/vi.json (1)

798-798: LGTM!

Also applies to: 855-855

web/default/src/i18n/locales/zh.json (1)

798-798: LGTM!

Also applies to: 855-855

Comment thread web/default/src/features/playground/components/playground-input.tsx Outdated
Comment thread web/default/src/features/playground/index.tsx Outdated

@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

Caution

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

⚠️ Outside diff range comments (2)
web/default/src/features/playground/components/playground-input.tsx (1)

99-100: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Disable the clear-history button when no callback is wired.

onClearHistory is optional here, but isClearHistoryDisabled ignores that. Any caller that passes hasMessages={true} without the handler gets an enabled button that silently no-ops.

Suggested fix
-  const isClearHistoryDisabled = disabled || isGenerating || !hasMessages
+  const isClearHistoryDisabled =
+    disabled || isGenerating || !hasMessages || !onClearHistory

Also applies to: 108-108, 199-203

🤖 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/features/playground/components/playground-input.tsx` around
lines 99 - 100, The clear-history button state in playground-input.tsx is
missing the optional handler check, so callers can get an enabled button even
when onClearHistory is not provided. Update isClearHistoryDisabled (and any
related button props in PlaygroundInput) to treat the button as disabled
whenever onClearHistory is absent, even if hasMessages is true, so the UI cannot
trigger a no-op. Use the existing onClearHistory, hasMessages, and
isClearHistoryDisabled symbols to locate the logic and keep the disabled
behavior consistent wherever the clear-history action is rendered.
web/default/src/features/home/index.tsx (1)

51-55: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Keep framed popups sandboxed.

This iframe is fed by custom admin content. allow-popups-to-escape-sandbox lets that content open unsandboxed windows; remove it unless the flow explicitly requires escaping.

Proposed fix
-              sandbox='allow-forms allow-popups allow-popups-to-escape-sandbox allow-scripts'
+              sandbox='allow-forms allow-popups allow-scripts'
🤖 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/features/home/index.tsx` around lines 51 - 55, The custom
home page iframe is allowing framed popups to escape the sandbox, which weakens
isolation for admin-provided content. Update the iframe in the home feature
component to remove allow-popups-to-escape-sandbox from the sandbox attribute,
keeping the popup behavior sandboxed unless a specific flow in the Home page
requires otherwise.
🤖 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/html-content.test.ts`:
- Around line 31-38: The current test only checks that dangerous HTML is
removed, but it can still pass when sanitizeHtmlContent() falls back to an empty
string instead of actually sanitizing. Update the html-content test around
sanitizeHtmlContent() to assert that safe HTML is preserved as well, using a
harmless element/attribute that should survive sanitization. This will ensure
the sanitizer is really running and not just returning '' while still keeping
the existing checks for executable content removal.
- Around line 24-28: The module-level JSDOM setup in html-content.test.ts
mutates globalThis.window and can leak into other tests; move the window
assignment into test setup/teardown and restore the original globalThis.window
after the suite finishes. Use the existing JSDOM initialization and
globalThis.window override as the fix point, and ensure the cleanup runs
reliably even if tests fail.

In `@web/default/src/features/about/index.tsx`:
- Around line 147-154: The iframe in the About content flow is currently
allowing popups to escape the sandbox, which weakens isolation for
admin-configured URLs. Update the iframe sandbox configuration in the
contentKind === 'url' branch of the About component to remove the
allow-popups-to-escape-sandbox permission while keeping the other required
sandbox flags intact. Use the existing iframe setup in the About page as the
place to apply this change.

In
`@web/default/src/features/dashboard/components/overview/announcement-detail-dialog.tsx`:
- Line 20: The announcement detail dialog is rendering RichContent without an
explicit mode, so HTML content still falls back to the default Markdown path.
Update the announcement rendering in announcement-detail-dialog to derive the
content mode the same way the page consumers do, and pass that mode when
rendering both announcement.content and announcement.extra. Use the RichContent
component and the announcement data handling in this dialog as the main places
to adjust.

In `@web/default/src/features/home/index.tsx`:
- Around line 59-63: The custom home content path currently sends
iframe-containing HTML through RichContent, which ends up sanitizing away iframe
tags. Update the home rendering logic in index.tsx to detect iframe embeds
before choosing the RichContent branch, and route those cases to the iframe
renderer instead of HtmlContent, or otherwise add a narrow allowlist that
preserves only safe iframe embeds. Use getRenderableContentKind and RichContent
as the main touchpoints when adjusting the selection flow.

---

Outside diff comments:
In `@web/default/src/features/home/index.tsx`:
- Around line 51-55: The custom home page iframe is allowing framed popups to
escape the sandbox, which weakens isolation for admin-provided content. Update
the iframe in the home feature component to remove
allow-popups-to-escape-sandbox from the sandbox attribute, keeping the popup
behavior sandboxed unless a specific flow in the Home page requires otherwise.

In `@web/default/src/features/playground/components/playground-input.tsx`:
- Around line 99-100: The clear-history button state in playground-input.tsx is
missing the optional handler check, so callers can get an enabled button even
when onClearHistory is not provided. Update isClearHistoryDisabled (and any
related button props in PlaygroundInput) to treat the button as disabled
whenever onClearHistory is absent, even if hasMessages is true, so the UI cannot
trigger a no-op. Use the existing onClearHistory, hasMessages, and
isClearHistoryDisabled symbols to locate the logic and keep the disabled
behavior consistent wherever the clear-history action is rendered.
🪄 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: a569766e-ebec-429c-a1fe-fae6dda79b2f

📥 Commits

Reviewing files that changed from the base of the PR and between 477e480 and 3ed3a26.

📒 Files selected for processing (13)
  • .agents/upstream-sync/new-api-sync.md
  • .gitignore
  • web/default/src/components/html-content.test.ts
  • web/default/src/components/html-content.tsx
  • web/default/src/components/notification-popover.tsx
  • web/default/src/components/rich-content.tsx
  • web/default/src/features/about/index.tsx
  • web/default/src/features/dashboard/components/overview/announcement-detail-dialog.tsx
  • web/default/src/features/home/index.tsx
  • web/default/src/features/legal/legal-document.tsx
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/playground/index.tsx
  • web/default/src/lib/html-sanitizer.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Backend checks
🧰 Additional context used
📓 Path-based instructions (4)
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/components/html-content.test.ts
  • web/default/src/components/rich-content.tsx
  • web/default/src/lib/html-sanitizer.ts
  • web/default/src/components/html-content.tsx
  • web/default/src/features/dashboard/components/overview/announcement-detail-dialog.tsx
  • web/default/src/features/home/index.tsx
  • web/default/src/features/playground/index.tsx
  • web/default/src/components/notification-popover.tsx
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/about/index.tsx
  • web/default/src/features/legal/legal-document.tsx
web/default/src/**/*.test.ts

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

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

Files:

  • web/default/src/components/html-content.test.ts
web/default/**/*

📄 CodeRabbit inference engine (CLAUDE.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/src/components/html-content.test.ts
  • web/default/src/components/rich-content.tsx
  • web/default/src/lib/html-sanitizer.ts
  • web/default/src/components/html-content.tsx
  • web/default/src/features/dashboard/components/overview/announcement-detail-dialog.tsx
  • web/default/src/features/home/index.tsx
  • web/default/src/features/playground/index.tsx
  • web/default/src/components/notification-popover.tsx
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/about/index.tsx
  • web/default/src/features/legal/legal-document.tsx
web/default/src/features/**

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

功能模块应放在 src/features/<feature>/,并按需包含 components/lib/hooks/api.tstypes.tsconstants.ts 等;通用组件应放在 src/components/,通用工具与类型应放在 src/lib/

Files:

  • web/default/src/features/dashboard/components/overview/announcement-detail-dialog.tsx
  • web/default/src/features/home/index.tsx
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/components/playground-input.tsx
  • web/default/src/features/about/index.tsx
  • web/default/src/features/legal/legal-document.tsx
🪛 ast-grep (0.44.0)
web/default/src/components/html-content.tsx

[warning] 39-39: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation

(react-unsafe-html-injection)

🪛 Betterleaks (1.5.0)
.agents/upstream-sync/new-api-sync.md

[high] 12-12: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 OpenGrep (1.23.0)
web/default/src/components/html-content.tsx

[WARNING] 34-42: dangerouslySetInnerHTML with dynamic content can lead to XSS. Sanitize the input with a library like DOMPurify before rendering.

(coderabbit.xss.react-dangerously-set-innerhtml)

🔇 Additional comments (8)
.agents/upstream-sync/new-api-sync.md (1)

1-54: LGTM!

.gitignore (1)

27-29: LGTM!

web/default/src/features/playground/index.tsx (1)

23-23: LGTM!

Also applies to: 73-83, 187-225

web/default/src/lib/html-sanitizer.ts (1)

21-60: LGTM!

web/default/src/components/notification-popover.tsx (1)

188-188: 🎯 Functional Correctness

Verify whether notification payloads can be HTML.

These calls omit mode, so RichContent takes the markdown path. If notice, item.content, or item.extra can now carry HTML, pass the content kind through this model; otherwise this change is behaviorally equivalent to the previous Markdown rendering.

Also applies to: 242-247

web/default/src/components/rich-content.tsx (1)

30-36: 📐 Maintainability & Code Quality

No explicit return type needed here. RichContent is a simple typed passthrough component, and the codebase does not require explicit function return annotations for this pattern.

			> Likely an incorrect or invalid review comment.
web/default/src/features/about/index.tsx (1)

22-25: LGTM!

Also applies to: 122-124, 163-167

web/default/src/features/legal/legal-document.tsx (1)

22-27: LGTM!

Also applies to: 52-54, 92-92, 131-135

Comment thread web/default/src/components/html-content.test.ts Outdated
Comment thread web/default/src/components/html-content.test.ts
Comment thread web/default/src/features/about/index.tsx Outdated
Comment thread web/default/src/features/home/index.tsx

@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

Caution

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

⚠️ Outside diff range comments (2)
web/default/src/hooks/use-notifications.ts (1)

109-131: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Read the unread-announcement count from readAnnouncementKeys. isAnnouncementRead is a stable store action, so this memo won’t rerun when markAnnouncementsRead updates the stored keys. The hook rerenders, but useMemo keeps the stale count until another dependency changes. Pull readAnnouncementKeys from getUserState(userScope) and depend on that array directly.

🤖 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/hooks/use-notifications.ts` around lines 109 - 131, The
unread announcement count in use-notifications.ts is derived through the stable
isAnnouncementRead action, so the memo can stay stale after
markAnnouncementsRead updates the store. In useNotifications/useMemo, read
readAnnouncementKeys directly from getUserState(userScope), compute unread
announcements from that array instead of calling isAnnouncementRead, and update
the dependency list to include readAnnouncementKeys so the count refreshes
whenever stored keys change.
web/default/src/features/about/index.tsx (1)

151-162: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider centralizing the embed iframe + sandbox policy in a shared component.

This exact iframe markup (same sandbox='allow-forms allow-popups allow-scripts', same sizing) is duplicated in home/index.tsx and legal/legal-document.tsx (with a cosmetic border-0/border-none drift). A single shared component makes the sandbox policy a single source of truth, so a future flag change can't silently diverge between pages.

♻️ Proposed shared component + usage

New web/default/src/components/content-embed-frame.tsx:

import { cn } from '`@/lib/utils`'

interface ContentEmbedFrameProps {
  src: string
  title: string
  className?: string
}

export function ContentEmbedFrame(props: ContentEmbedFrameProps) {
  return (
    <iframe
      src={props.src}
      title={props.title}
      className={cn('h-[calc(100vh-3.5rem)] w-full border-0', props.className)}
      sandbox='allow-forms allow-popups allow-scripts'
    />
  )
}

Then in About (and similarly in Home/Legal):

-        <iframe
-          src={iframeEmbedSrc}
-          className='h-[calc(100vh-3.5rem)] w-full border-0'
-          title={t('About')}
-          sandbox='allow-forms allow-popups allow-scripts'
-        />
+        <ContentEmbedFrame src={iframeEmbedSrc} title={t('About')} />
🤖 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/features/about/index.tsx` around lines 151 - 162, The iframe
embed markup in About is duplicated with the same sizing and sandbox policy used
in Home and Legal, so centralize it into a shared component (for example, a
content embed frame component) and reuse it here instead of inlining the iframe.
Move the common src/title/className handling and the fixed sandbox='allow-forms
allow-popups allow-scripts' into that shared component, then update the About
page to render it so the sandbox policy stays consistent across pages.
🤖 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 24-28: The file-level JSDOM setup in markdown.test.ts leaves
globalThis.window patched for the rest of the worker, so restore the previous
window descriptor after the suite. Update the markdown.test.ts setup around the
globalThis.window assignment to mirror the safer cleanup used in
html-content.test.ts, using the same test hooks to save and restore the original
global descriptor. Keep the fix scoped to the test suite so later tests do not
inherit browser globals.

In `@web/default/src/features/playground/index.tsx`:
- Around line 95-124: The model/group sync effects in playground/index.tsx leave
stale config.model and config.group values when effectiveModelsData or
effectiveGroupsData fall back to empty arrays. Update the useEffect blocks that
call setModels and setGroups so they also clear or reset the corresponding
config fields when no valid options are available, or otherwise prevent sendChat
from using them until the queries recover. Use the existing updateConfig logic
in the effects to keep config.model and config.group aligned with the available
options.

---

Outside diff comments:
In `@web/default/src/features/about/index.tsx`:
- Around line 151-162: The iframe embed markup in About is duplicated with the
same sizing and sandbox policy used in Home and Legal, so centralize it into a
shared component (for example, a content embed frame component) and reuse it
here instead of inlining the iframe. Move the common src/title/className
handling and the fixed sandbox='allow-forms allow-popups allow-scripts' into
that shared component, then update the About page to render it so the sandbox
policy stays consistent across pages.

In `@web/default/src/hooks/use-notifications.ts`:
- Around line 109-131: The unread announcement count in use-notifications.ts is
derived through the stable isAnnouncementRead action, so the memo can stay stale
after markAnnouncementsRead updates the store. In useNotifications/useMemo, read
readAnnouncementKeys directly from getUserState(userScope), compute unread
announcements from that array instead of calling isAnnouncementRead, and update
the dependency list to include readAnnouncementKeys so the count refreshes
whenever stored keys change.
🪄 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: dc43ac7c-0853-4292-a63b-7f0d9fc5e401

📥 Commits

Reviewing files that changed from the base of the PR and between 9a177be and 1c8e244.

📒 Files selected for processing (25)
  • model/log.go
  • model/log_test.go
  • model/main.go
  • model/task_cas_test.go
  • web/default/src/components/html-content.test.ts
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/components/ui/markdown.tsx
  • web/default/src/features/about/index.tsx
  • web/default/src/features/home/index.tsx
  • web/default/src/features/legal/legal-document.tsx
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/playground/lib/query-state.test.ts
  • web/default/src/features/playground/lib/query-state.ts
  • web/default/src/features/usage-logs/lib/utils.test.ts
  • web/default/src/features/usage-logs/lib/utils.ts
  • web/default/src/features/usage-logs/types.ts
  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/hooks/notification-utils.ts
  • web/default/src/hooks/use-notifications.ts
  • web/default/src/lib/html-sanitizer.ts
  • web/default/src/lib/renderable-content.test.ts
  • web/default/src/lib/renderable-content.ts
  • web/default/src/lib/sanitize-core.ts
  • web/default/src/stores/notification-store.test.ts
  • web/default/src/stores/notification-store.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (7)
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/features/usage-logs/lib/utils.test.ts
  • web/default/src/components/html-content.test.ts
  • web/default/src/features/usage-logs/types.ts
  • web/default/src/features/playground/lib/query-state.ts
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/lib/html-sanitizer.ts
  • web/default/src/lib/sanitize-core.ts
  • web/default/src/lib/renderable-content.test.ts
  • web/default/src/features/usage-logs/lib/utils.ts
  • web/default/src/features/home/index.tsx
  • web/default/src/features/playground/lib/query-state.test.ts
  • web/default/src/lib/renderable-content.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/about/index.tsx
  • web/default/src/stores/notification-store.test.ts
  • web/default/src/features/legal/legal-document.tsx
  • web/default/src/stores/notification-store.ts
  • web/default/src/components/ui/markdown.tsx
  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/hooks/use-notifications.ts
  • web/default/src/hooks/notification-utils.ts
web/default/src/features/**/lib/**/*.ts

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

表单应使用 React Hook Form + Zod:在功能模块的 lib/ 下定义 schema,并用 z.infer 导出表单类型;useForm 应配合 @hookform/resolvers/zod 进行校验。

Files:

  • web/default/src/features/usage-logs/lib/utils.test.ts
  • web/default/src/features/playground/lib/query-state.ts
  • web/default/src/features/usage-logs/lib/utils.ts
  • web/default/src/features/playground/lib/query-state.test.ts
web/default/src/features/**

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

功能模块应放在 src/features/<feature>/,并按需包含 components/lib/hooks/api.tstypes.tsconstants.ts 等;通用组件应放在 src/components/,通用工具与类型应放在 src/lib/

Files:

  • web/default/src/features/usage-logs/lib/utils.test.ts
  • web/default/src/features/usage-logs/types.ts
  • web/default/src/features/playground/lib/query-state.ts
  • web/default/src/features/usage-logs/lib/utils.ts
  • web/default/src/features/home/index.tsx
  • web/default/src/features/playground/lib/query-state.test.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/about/index.tsx
  • web/default/src/features/legal/legal-document.tsx
web/default/src/**/*.test.ts

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

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

Files:

  • web/default/src/features/usage-logs/lib/utils.test.ts
  • web/default/src/components/html-content.test.ts
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/lib/renderable-content.test.ts
  • web/default/src/features/playground/lib/query-state.test.ts
  • web/default/src/stores/notification-store.test.ts
  • web/default/src/hooks/notification-utils.test.ts
web/default/**/*

📄 CodeRabbit inference engine (CLAUDE.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/src/features/usage-logs/lib/utils.test.ts
  • web/default/src/components/html-content.test.ts
  • web/default/src/features/usage-logs/types.ts
  • web/default/src/features/playground/lib/query-state.ts
  • web/default/src/components/ui/markdown.test.ts
  • web/default/src/lib/html-sanitizer.ts
  • web/default/src/lib/sanitize-core.ts
  • web/default/src/lib/renderable-content.test.ts
  • web/default/src/features/usage-logs/lib/utils.ts
  • web/default/src/features/home/index.tsx
  • web/default/src/features/playground/lib/query-state.test.ts
  • web/default/src/lib/renderable-content.ts
  • web/default/src/features/playground/index.tsx
  • web/default/src/features/about/index.tsx
  • web/default/src/stores/notification-store.test.ts
  • web/default/src/features/legal/legal-document.tsx
  • web/default/src/stores/notification-store.ts
  • web/default/src/components/ui/markdown.tsx
  • web/default/src/hooks/notification-utils.test.ts
  • web/default/src/hooks/use-notifications.ts
  • web/default/src/hooks/notification-utils.ts
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.go: All JSON marshal/unmarshal operations in Go business code must use the wrappers in common/json.go (common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, common.GetJsonType) instead of directly calling encoding/json; encoding/json types like json.RawMessage and json.Number may still be used as types.
All database code must be compatible with SQLite, MySQL 5.7.8+, and PostgreSQL 9.6+ simultaneously: prefer GORM methods over raw SQL, avoid direct AUTO_INCREMENT/SERIAL, use cross-DB quoting/boolean helpers when raw SQL is unavoidable, avoid DB-specific functions/operators without fallbacks, and ensure migrations work on all three databases.
For request structs parsed from client JSON and later re-marshaled to upstream providers, especially in relay/convert paths, optional scalar fields must use pointer types with omitempty so explicit zero/false values are preserved and omitted-only fields remain nil.

**/*.go: Use common.Marshal, common.Unmarshal, common.UnmarshalJsonStr, common.DecodeJson, and common.GetJsonType from common/json.go for all JSON marshal/unmarshal operations; do not directly call encoding/json in business code.
Keep all database code fully compatible with SQLite, MySQL >= 5.7.8, and PostgreSQL >= 9.6; prefer GORM abstractions, avoid raw SQL unless cross-DB-safe, and use the provided DB-specific helpers/flags for quoting, booleans, and branching.
For request structs parsed from client JSON and re-marshaled to upstream providers, especially in relay/convert paths, use pointer types with omitempty for optional scalar fields so explicit zero/false values are preserved.

Files:

  • model/task_cas_test.go
  • model/log.go
  • model/main.go
  • model/log_test.go
web/default/src/stores/**/*.ts

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

使用 Zustand 时应通过 create 定义 store,并为 state 与 actions 定义清晰类型;优先使用选择器订阅,避免整 store 订阅导致多余渲染;需持久化状态应在 store 内处理 localStorage 恢复;store 应按功能放在 src/stores/

Files:

  • web/default/src/stores/notification-store.test.ts
  • web/default/src/stores/notification-store.ts
🔇 Additional comments (27)
web/default/src/features/playground/index.tsx (1)

200-206: LGTM!

Also applies to: 228-238

web/default/src/features/playground/lib/query-state.ts (1)

19-28: LGTM!

web/default/src/features/playground/lib/query-state.test.ts (1)

23-38: LGTM!

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

27-39: LGTM!

Also applies to: 73-84, 106-122, 146-165

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

21-60: LGTM!

Also applies to: 90-100, 117-129, 146-169, 171-271

web/default/src/stores/notification-store.ts (2)

22-72: LGTM!

Also applies to: 107-170, 172-178


74-98: 📐 Maintainability & Code Quality

Make migrate return the persisted shape. partialize writes only { byUser: ... }, so this function should return that slice shape instead of Partial<NotificationState>.

web/default/src/hooks/use-notifications.ts (1)

19-32: LGTM!

Also applies to: 64-66, 90-101, 134-204, 215-274, 295-298

web/default/src/stores/notification-store.test.ts (1)

22-97: LGTM!

Also applies to: 99-151

model/log.go (1)

56-75: LGTM!

Also applies to: 99-99, 181-196

web/default/src/features/usage-logs/lib/utils.ts (1)

99-99: LGTM!

Also applies to: 111-113

web/default/src/features/usage-logs/types.ts (1)

41-41: LGTM!

web/default/src/features/usage-logs/lib/utils.test.ts (1)

89-94: LGTM!

model/main.go (1)

4-4: LGTM!

Also applies to: 29-44, 316-321, 402-406, 408-452, 454-468, 470-482

model/task_cas_test.go (1)

42-42: LGTM!

model/log_test.go (1)

4-11: LGTM!

Also applies to: 76-122, 124-161, 163-193, 195-249, 251-267, 269-295, 297-313

web/default/src/lib/sanitize-core.ts (1)

19-68: LGTM!

web/default/src/lib/html-sanitizer.ts (1)

19-27: LGTM!

web/default/src/components/html-content.test.ts (1)

25-25: LGTM!

Also applies to: 45-118

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

23-23: LGTM!

Also applies to: 190-192, 723-730

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

22-22: LGTM!

Also applies to: 30-32, 42-48, 69-85

web/default/src/features/about/index.tsx (2)

25-28: LGTM!

Also applies to: 128-128


167-171: LGTM!

web/default/src/features/home/index.tsx (1)

38-38: LGTM!

Also applies to: 54-69

web/default/src/features/legal/legal-document.tsx (1)

27-30: LGTM!

Also applies to: 55-58, 96-107, 148-152

web/default/src/lib/renderable-content.test.ts (1)

78-83: LGTM!

web/default/src/lib/renderable-content.ts (1)

35-57: LGTM!

Comment thread web/default/src/components/ui/markdown.test.ts
Comment thread web/default/src/features/playground/index.tsx
@CSCITech
CSCITech merged commit b60bbcc into main Jun 30, 2026
3 checks passed
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