为登录后用户补充使用文档入口 [未完成]#1233
Conversation
📝 WalkthroughWalkthrough在用户菜单与我的用量页新增指向 /usage-doc 的文档按钮,补充 5 种语言的 myUsage.json 文案,新增组件与单元测试,并在 usage-doc 布局中启用 getSession({ allowReadOnlyAccess: true })。 变更说明文档链接入口功能
代码审查工作量🎯 2 (Simple) | ⏱️ ~12 分钟 可能相关的PR
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Code Review
This pull request adds a "Usage Docs" link (pointing to /usage-doc) to both the UserMenu and MyUsageHeader components, along with corresponding translations in multiple locales and unit tests. Feedback on the changes highlights two issues: first, in user-menu.tsx, the translation key documentation is called within a namespace that does not contain it, which will result in a missing translation; second, in my-usage-keys.test.ts, accessing data.header directly on a Record<string, unknown> type will cause a TypeScript compilation error, and a type-safe suggestion is provided.
| title={t("documentation")} | ||
| aria-label={t("documentation")} |
There was a problem hiding this comment.
|
|
||
| it("defines a documentation label for the readonly usage header", () => { | ||
| for (const [locale, data] of Object.entries(locales)) { | ||
| const documentation = data.header?.documentation; |
There was a problem hiding this comment.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d1e36b783d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| <div className="flex items-center gap-2"> | ||
| <div className="flex shrink-0 items-center gap-2"> | ||
| <Button asChild variant="outline" size="sm" className="gap-2"> | ||
| <Link href="/usage-doc"> |
There was a problem hiding this comment.
Preserve readonly sessions when opening docs
For readonly users this new entry sends them from /my-usage to /usage-doc, but usage-doc/layout.tsx still calls getSession() without allowReadOnlyAccess, and validateKey returns null for keys with canLoginWebUi === false. In that scenario the destination treats an already-authenticated readonly user as anonymous, showing the login header and hiding logged-in quick links instead of preserving their session context; the docs entry should either make the docs layout accept readonly sessions or route to a page that does.
Useful? React with 👍 / 👎.
|
|
||
| vi.mock("next-intl", () => ({ | ||
| useTranslations: () => (key: string) => | ||
| ({ | ||
| documentation: "Docs", | ||
| logout: "Logout", | ||
| })[key] ?? key, | ||
| })); |
There was a problem hiding this comment.
Namespace-blind
useTranslations mock
The mock returns translations by key only and ignores the namespace argument passed to useTranslations. If UserMenu were ever refactored to use a different namespace (e.g. one that lacks documentation), this test would still pass because the mock always resolves "documentation" → "Docs" regardless. The sibling my-usage-header.test.tsx demonstrates a stronger pattern: it wraps the component in NextIntlClientProvider with real messages, making the test sensitive to the actual namespace the component uses.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/[locale]/dashboard/_components/user-menu.test.tsx
Line: 13-20
Comment:
**Namespace-blind `useTranslations` mock**
The mock returns translations by key only and ignores the namespace argument passed to `useTranslations`. If `UserMenu` were ever refactored to use a different namespace (e.g. one that lacks `documentation`), this test would still pass because the mock always resolves `"documentation"` → `"Docs"` regardless. The sibling `my-usage-header.test.tsx` demonstrates a stronger pattern: it wraps the component in `NextIntlClientProvider` with real messages, making the test sensitive to the actual namespace the component uses.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Code Review Summary
No significant issues identified in this PR. The changes are well-structured, i18n keys are consistently added across all 5 locales, and the new component tests adequately cover the added documentation entry points.
PR Size: S
- Lines changed: 222
- Files changed: 10
Review Coverage
- Logic and correctness - Clean
- Security (OWASP Top 10) - Clean
- Error handling - Clean (no new error paths added)
- Type safety - Clean
- Documentation accuracy - Clean
- Test coverage - Adequate (component tests + i18n key parity test)
- Code clarity - Good
Notes
dashboard.nav.documentationkey verified to exist in all locale files (dashboard.json), matching theUserMenucomponent'suseTranslations("dashboard.nav")usage.myUsage.header.documentationkey added consistently across all 5 locale files.ButtonwithasChildcorrectly delegates to thenext-intlLinkcomponent without leakingvariant/sizeprops to the DOM.
Automated review by Claude AI
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/app/[locale]/dashboard/_components/user-menu.test.tsx (1)
1-62: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win测试文件路径/命名不符合仓库约定
当前文件位于
src/.../*.test.tsx,但规则只允许tests/unit/、tests/integration/,或 source-adjacent 的src/**/*.test.ts。请将该用例迁移到tests/unit/(保留.test.tsx)或按规则调整命名/位置。As per coding guidelines, "Use Vitest for unit testing with tests located in tests/unit/, tests/integration/, or source-adjacent in src/**/*.test.ts".
🤖 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 `@src/app/`[locale]/dashboard/_components/user-menu.test.tsx around lines 1 - 62, The test file for the UserMenu component (user-menu.test.tsx) is placed outside the allowed test locations; move the test into an allowed location (e.g., tests/unit/) or make it source-adjacent by renaming/moving it to src/.../*.test.ts per repository rules, keeping the .test.tsx extension and preserving the test contents (including imports and mocks for UserMenu, useTranslations and useRouter); ensure any import paths to UserMenu still resolve after moving and update test runner config if needed.
🧹 Nitpick comments (1)
src/app/[locale]/my-usage/_components/my-usage-header.test.tsx (1)
10-10: ⚡ Quick win统一为路径别名导入,避免相对路径。
这里建议改成
@/别名导入以保持仓库一致性。建议修改
-import { MyUsageHeader } from "./my-usage-header"; +import { MyUsageHeader } from "`@/app/`[locale]/my-usage/_components/my-usage-header";As per coding guidelines:
**/*.{ts,tsx,js,jsx}: Use path alias@/to map to ./src/ for imports🤖 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 `@src/app/`[locale]/my-usage/_components/my-usage-header.test.tsx at line 10, The test imports MyUsageHeader using a relative path; update the import to use the project's path alias (start with "`@/`") instead of a relative path so the MyUsageHeader import aligns with the repo convention (replace the current import statement for MyUsageHeader with an alias-based import that resolves to the same module).
🤖 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.
Outside diff comments:
In `@src/app/`[locale]/dashboard/_components/user-menu.test.tsx:
- Around line 1-62: The test file for the UserMenu component
(user-menu.test.tsx) is placed outside the allowed test locations; move the test
into an allowed location (e.g., tests/unit/) or make it source-adjacent by
renaming/moving it to src/.../*.test.ts per repository rules, keeping the
.test.tsx extension and preserving the test contents (including imports and
mocks for UserMenu, useTranslations and useRouter); ensure any import paths to
UserMenu still resolve after moving and update test runner config if needed.
---
Nitpick comments:
In `@src/app/`[locale]/my-usage/_components/my-usage-header.test.tsx:
- Line 10: The test imports MyUsageHeader using a relative path; update the
import to use the project's path alias (start with "`@/`") instead of a relative
path so the MyUsageHeader import aligns with the repo convention (replace the
current import statement for MyUsageHeader with an alias-based import that
resolves to the same module).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ef55bbec-12bb-4338-a65c-1c51a1f9b027
📒 Files selected for processing (10)
messages/en/myUsage.jsonmessages/ja/myUsage.jsonmessages/ru/myUsage.jsonmessages/zh-CN/myUsage.jsonmessages/zh-TW/myUsage.jsonsrc/app/[locale]/dashboard/_components/user-menu.test.tsxsrc/app/[locale]/dashboard/_components/user-menu.tsxsrc/app/[locale]/my-usage/_components/my-usage-header.test.tsxsrc/app/[locale]/my-usage/_components/my-usage-header.tsxtests/unit/i18n/my-usage-keys.test.ts
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/app/[locale]/usage-doc/layout.tsx (1)
42-51:⚠️ Potential issue | 🟠 Major补充:只读用户在 usage-doc 会看到完整 Dashboard 导航,但
/dashboard侧会按canLoginWebUi再次拦截
src/app/[locale]/usage-doc/layout.tsx确实会调用getSession({ allowReadOnlyAccess: true }),因此canLoginWebUi=false的“只读会话”在该页会走session ? <DashboardHeader .../>分支,出现完整DashboardHeader。src/app/[locale]/dashboard/_components/dashboard-header.tsx的导航项仅按session.user.role === "admin"过滤adminOnly,未见基于session.key.canLoginWebUi的降级/隐藏;因此/dashboard、/dashboard/logs、/dashboard/leaderboard、/dashboard/users等对只读用户仍会展示。- 同时,代码库里存在针对
canLoginWebUi的服务器端拦截逻辑(例如src/app/[locale]/dashboard/layout.tsx中的session.key.canLoginWebUi检查)。因此如果该拦截是“拒绝/报错页/跳转受限”,就会落入原评论担心的“可点击但实际访问被拒”的体验;若是“重定向到只读入口(如 my-usage)”,则现有导航展示影响会减轻。- 建议:在
DashboardHeader的导航构建处同样基于session.key.canLoginWebUi做隐藏/禁用,或确保/dashboard拦截路径对只读用户是明确的重定向与提示,避免落差体验。🤖 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 `@src/app/`[locale]/usage-doc/layout.tsx around lines 42 - 51, 在 usage-doc 的 layout.tsx 已以 allowReadOnlyAccess 获取只读会话导致 DashboardHeader 在只读用户也会渲染,为避免出现可点却无法访问的菜单,请在 DashboardHeader(组件名 DashboardHeader,或其构建导航的函数/变量)里基于 session.key.canLoginWebUi 对导航项进行过滤或降级(例如把需登录的条目从导航列表中过滤掉或渲染为不可点状态),或者在 DashboardHeader 根处当 session.key.canLoginWebUi 为 false 时改为渲染简化头部;同时保持 getSession({ allowReadOnlyAccess: true }) 行为不变以支持只读会话。
🤖 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.
Outside diff comments:
In `@src/app/`[locale]/usage-doc/layout.tsx:
- Around line 42-51: 在 usage-doc 的 layout.tsx 已以 allowReadOnlyAccess 获取只读会话导致
DashboardHeader 在只读用户也会渲染,为避免出现可点却无法访问的菜单,请在 DashboardHeader(组件名
DashboardHeader,或其构建导航的函数/变量)里基于 session.key.canLoginWebUi
对导航项进行过滤或降级(例如把需登录的条目从导航列表中过滤掉或渲染为不可点状态),或者在 DashboardHeader 根处当
session.key.canLoginWebUi 为 false 时改为渲染简化头部;同时保持 getSession({
allowReadOnlyAccess: true }) 行为不变以支持只读会话。
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 11095ee5-44d8-4c94-881c-cbb5956fb49c
📒 Files selected for processing (4)
src/app/[locale]/dashboard/_components/user-menu.test.tsxsrc/app/[locale]/usage-doc/layout.tsxtests/unit/i18n/my-usage-keys.test.tstests/unit/usage-doc/usage-doc-auth-state.test.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- tests/unit/i18n/my-usage-keys.test.ts
- src/app/[locale]/dashboard/_components/user-menu.test.tsx
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/app/[locale]/dashboard/_components/dashboard-header.tsx (1)
36-39: 💤 Low value只读用户回退导航逻辑正确,可选地复用文档项常量。
逻辑无问题:已登录但无 dashboard 权限时仅保留文档链接,其余情况按
NAV_ITEMS过滤。第 38 行的{ href: "/usage-doc", label: t("documentation") }与第 32 行重复,可抽取为常量减少漂移风险,但非必须。🤖 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 `@src/app/`[locale]/dashboard/_components/dashboard-header.tsx around lines 36 - 39, The conditional that builds items duplicates the documentation link literal; extract a single constant (e.g., DOCUMENTATION_ITEM = { href: "/usage-doc", label: t("documentation") }) and use it in the readonly branch instead of repeating the object, keeping the existing logic that uses session, canUseDashboard, NAV_ITEMS, and isAdmin unchanged.
🤖 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 `@src/app/`[locale]/dashboard/_components/dashboard-header.tsx:
- Around line 36-39: The conditional that builds items duplicates the
documentation link literal; extract a single constant (e.g., DOCUMENTATION_ITEM
= { href: "/usage-doc", label: t("documentation") }) and use it in the readonly
branch instead of repeating the object, keeping the existing logic that uses
session, canUseDashboard, NAV_ITEMS, and isAdmin unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a6dcb8f8-7335-4a51-9b74-7738c0316a61
📒 Files selected for processing (2)
src/app/[locale]/dashboard/_components/dashboard-header.test.tsxsrc/app/[locale]/dashboard/_components/dashboard-header.tsx
|
本轮已完成 #1232 的文档入口改进,并处理了机器人审阅意见。 主要改动:
审阅处理:
验证结果:
|
Summary
为已登录用户在两个关键位置补充使用文档入口(
/usage-doc),解决只读用户登录后难以找到文档的问题。Problem
/usage-doc页面已存在,但缺少从用户界面直接跳转的链接。Related Issues:
Solution
在
/my-usage页头与 Dashboard 用户控制区分别新增文档入口,并为所有 5 种语言补齐 i18n 文案。Changes
Core Changes
src/app/[locale]/my-usage/_components/my-usage-header.tsx— 在页头新增「使用文档」按钮(BookOpen图标),链接至/usage-doc;同时优化响应式布局(移动端flex-col,桌面端flex-row)。src/app/[locale]/dashboard/_components/user-menu.tsx— 在用户控制区新增图标按钮入口,跳转/usage-doc。Supporting Changes
messages/{en,zh-CN,zh-TW,ja,ru}/myUsage.json新增header.documentation键,覆盖 5 种语言。my-usage-header.test.tsx与user-menu.test.tsx,验证文档入口可见性与链接正确性。tests/unit/i18n/my-usage-keys.test.ts,确保所有语言文件键一致且documentation不为空。Breaking Changes
无。本次仅添加 UI 入口与 i18n 键,未修改现有 API、组件签名或数据结构。
Testing
Automated Tests
src/app/[locale]/my-usage/_components/my-usage-header.test.tsxsrc/app/[locale]/dashboard/_components/user-menu.test.tsxtests/unit/i18n/my-usage-keys.test.tsManual Testing
/my-usage页面。/usage-doc。/usage-doc。Verification Commands
Checklist
Description enhanced by Claude AI
Greptile Summary
This PR adds documentation entry points (
/usage-doc) in two locations for logged-in users — a "Usage Docs" button in theMyUsageHeaderand aBookOpenicon inUserMenu— and fixes the root cause by passingallowReadOnlyAccess: truetogetSession()in theusage-doclayout so read-only-key users are no longer redirected away from the page.usage-doc/layout.tsx: switches togetSession({ allowReadOnlyAccess: true }), which is the critical gate that previously blocked read-only users from reaching the page at all.dashboard-header.tsx: introducescanUseDashboardto collapse the nav to only[documentationItem]for read-only sessions, while full-access and admin paths are unchanged.my-usage-header.tsx/user-menu.tsx: each receives a newBookOpenbutton linking to/usage-doc;myUsage.header.documentationis added to all 5 locale files with a parity test to enforce key completeness.Confidence Score: 5/5
Safe to merge — changes are additive UI and i18n additions with no modifications to auth logic, APIs, or data structures.
The most impactful change (
allowReadOnlyAccess: trueinusage-doc/layout.tsx) correctly gates access using existing auth infrastructure. Navigation filtering is straightforward conditional logic. All new i18n keys are covered by a parity test.No files require special attention.
Important Files Changed
allowReadOnlyAccess: truetogetSession()so read-only-key users can reach the usage-doc page instead of being redirected.documentationItem, addscanUseDashboardgate, collapses nav to docs-only for read-only sessions.BookOpenicon button to user-control area linking to/usage-doc.Prompt To Fix All With AI
Reviews (4): Last reviewed commit: "抽取仪表盘文档导航项" | Re-trigger Greptile