Skip to content

fix: PR #905 レビュー指摘のフォローアップ#908

Merged
otomatty merged 3 commits into
developfrom
fix/pr905-review-followups
May 18, 2026
Merged

fix: PR #905 レビュー指摘のフォローアップ#908
otomatty merged 3 commits into
developfrom
fix/pr905-review-followups

Conversation

@otomatty

@otomatty otomatty commented May 18, 2026

Copy link
Copy Markdown
Owner

概要 / Summary

PR #905(develop → main)に付いた Bot レビュー(CodeRabbit / Codex)のうち、対応推奨だった項目をまとめて修正します。

変更内容(対応したコメントの対応関係)

  • analyze-error ワークフロー: 同一 sentry_issue_id で古い run をキャンセル(cancel-in-progress: true
  • claude-analyze: コールバック本文の workflow command エスケープ、requireEnv の trim、JSON 抽出の頑健化(括弧バランス + ルートっぽいオブジェクトはスキーマエラーを即時化)
  • admin Errors: Select の all / __any__ 整合、ダイアログ閉鎖時の pending リセット、SSE でフィルタ外になった行を一覧から除去、英語 nav の複数形 ARIA、getApiErrorById の URL エンコード検証強化
  • API: installation token リフレッシュの in-flight 合体、scrubSentryEventrequest.url のクエリ除去・パス成分のマスク、SSE テストのタイムアウト、pageAccessService テストのフィクスチャ修正、各種テストコメントの日英併記、sentry webhook テストの fetch stub を try/finally で確実に復元

意図的に見送ったもの(PR #905 のスレッドへインライン返信済みの内容と整合):

  • Sentry webhook の isNew を upsert と原子的にする件 → コード上のトレードオフとして既に文書化済み
  • GET/PATCH /api/admin/errors/:id の成功レスポンスキー error の改名 → admin クライアント契約との同期が必要なため別検討

テスト / Test plan

  • node --test .github/actions/claude-analyze/__tests__/schema.test.mjs
  • server/api: 関連 vitest(sentry、admin errors、webhooks、sentry.test、pageAccess、pages、pageSnapshots、syncPages)
  • admin: admin.test.ts, useApiErrors.test.ts

Related: #905

Made with Cursor

Summary by CodeRabbit

  • New Features

    • Pluralized unread API error badge labels in the admin panel.
  • Bug Fixes

    • Clearing pending status when closing error detail dialog.
    • Aligning status/severity selector values with internal sentinel.
    • Dropping non-matching API error rows from live updates.
    • Improved URL scrubbing for error tracking privacy.
    • Prevent duplicate in-progress analyses for the same issue.
  • Chores

    • Safer workflow error annotations and stricter whitespace env-var validation.
  • Tests

    • Expanded coverage for analysis JSON parsing and related behaviors.

Review Change Stack

Implement CodeRabbit/Codex feedback for admin errors UX, Sentry scrubbing, GitHub Actions analyze-error hardening, Claude JSON parsing, and related tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@otomatty has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 51 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d76803ff-85b5-405b-8d79-1372faf81bd3

📥 Commits

Reviewing files that changed from the base of the PR and between 86e3f5e and d0b0d69.

📒 Files selected for processing (22)
  • .github/actions/claude-analyze/__tests__/schema.test.mjs
  • .github/actions/claude-analyze/action.yml
  • .github/actions/claude-analyze/autoIssueRunner.mjs
  • .github/actions/claude-analyze/escapeGithubAnnotation.mjs
  • .github/actions/claude-analyze/schema.mjs
  • .github/workflows/analyze-error.yml
  • admin/src/api/admin.test.ts
  • admin/src/i18n/locales/en/nav.json
  • admin/src/i18n/locales/ja/nav.json
  • admin/src/pages/errors/ErrorDetailDialog.test.tsx
  • admin/src/pages/errors/ErrorDetailDialog.tsx
  • admin/src/pages/errors/ErrorsContent.tsx
  • admin/src/pages/errors/useApiErrors.ts
  • server/api/src/__tests__/routes/admin/errors.test.ts
  • server/api/src/__tests__/routes/pageSnapshots.test.ts
  • server/api/src/__tests__/routes/pages.test.ts
  • server/api/src/__tests__/routes/syncPages.test.ts
  • server/api/src/__tests__/routes/webhooks/sentry.test.ts
  • server/api/src/__tests__/services/pageAccessService.test.ts
  • server/api/src/lib/githubAppAuth.ts
  • server/api/src/lib/sentry.test.ts
  • server/api/src/lib/sentry.ts
📝 Walkthrough

Walkthrough

This PR strengthens Claude JSON parsing and tests, escapes GitHub Action annotation payloads, trims env values, cancels duplicate analyze workflows, updates admin filter/UI and SSE behavior, coalesces GitHub App token refreshes, scrubs Sentry request URLs, and improves several tests and comments.

Changes

Claude Analysis Workflow Robustness

Layer / File(s) Summary
JSON extraction and validation
.github/actions/claude-analyze/schema.mjs, .github/actions/claude-analyze/__tests__/schema.test.mjs
Adds fence-stripping, balanced {...} candidate extraction, per-candidate JSON parse+schema validation; tests cover plain fences, stray braces, and root-shaped invalid objects.
Error handling and annotation escaping
.github/actions/claude-analyze/escapeGithubAnnotation.mjs, .github/actions/claude-analyze/action.yml, .github/actions/claude-analyze/autoIssueRunner.mjs
Adds CLI to escape text for GitHub annotations; action uses it for 4xx and retry-exhausted callback errors; requireEnv now trims whitespace.
Workflow concurrency management
.github/workflows/analyze-error.yml
Workflow concurrency configured to cancel in-progress runs for the same Sentry issue.

Admin Error List Management and UI

Layer / File(s) Summary
Filter UI and pluralized labels
admin/src/pages/errors/ErrorsContent.tsx, admin/src/i18n/locales/en/nav.json, admin/src/i18n/locales/ja/nav.json
Select controls map "all" to an ANY sentinel; unread badge aria-labels split into singular/plural i18n keys.
SSE-driven row filtering
admin/src/pages/errors/useApiErrors.ts
SSE update now drops rows that no longer match the active filter and decrements cached total safely.
Dialog state cleanup on close
admin/src/pages/errors/ErrorDetailDialog.tsx
Dialog resets pendingFor before closing and on cancel via shared handler.
Error fetch API tests
admin/src/api/admin.test.ts
Tests assert adminFetch path uses encodeURIComponent(id) for IDs with reserved characters.

Security and Infrastructure Improvements

Layer / File(s) Summary
GitHub App token concurrent refresh coalescing
server/api/src/lib/githubAppAuth.ts
Introduces shared in-flight installation-token refresh promise so concurrent callers reuse the same refresh; test helper clears in-flight state.
Sentry request URL scrubbing
server/api/src/lib/sentry.ts, server/api/src/lib/sentry.test.ts
Adds scrubRequestUrl to parse absolute/relative URLs, redact UUID-like/opaque segments, remove sensitive query params; tests added for absolute and relative URLs.

Test Suite Improvements

Layer / File(s) Summary
SSE test timeout handling
server/api/src/__tests__/routes/admin/errors.test.ts
readUntil uses setTimeout-driven timeout with reader.cancel and finally cleanup.
Test documentation and mock chain clarity
server/api/src/__tests__/routes/pageSnapshots.test.ts, server/api/src/__tests__/routes/pages.test.ts, server/api/src/__tests__/routes/syncPages.test.ts
Expanded comments clarify mock DB SELECT chain ordering and expectations.
Test isolation and cross-user scenarios
server/api/src/__tests__/routes/webhooks/sentry.test.ts, server/api/src/__tests__/services/pageAccessService.test.ts
Ensures global mocks are unstubbed in finally; page access test covers page owned by other user.
ErrorDetailDialog UI tests
admin/src/pages/errors/ErrorDetailDialog.test.tsx
New Vitest/RTL tests with mocked UI components verify pending status discard on cancel and state reset on reopen.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • otomatty/zedi#398: Related changes touching page routes and ydoc_state handling in pages endpoints.
  • otomatty/zedi#815: Prior work on Claude analyze schema parsing/tests that this PR extends.
  • otomatty/zedi#814: Related changes to GitHub App auth/token flow that connect to the token caching updates here.

Poem

🐰 A rabbit's note on fixes and tests:
Fences trimmed and braces found with care,
Tokens fetched once when callers share,
SSE rows drop when filters declare,
Sentry URLs hidden from stare,
Tests now close timers—no leaks to spare.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: PR #905 レビュー指摘のフォローアップ' accurately reflects the PR's purpose as a follow-up addressing review comments from PR #905, covering multiple targeted fixes across workflows, CLI tools, admin UI, and backend services.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pr905-review-followups

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

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 332b89e44d

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

* @returns {string}
*/
function stripMarkdownJsonFence(raw) {
const m = raw.match(/```(?:json)?\s*([\s\S]*?)```/im);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restrict fence stripping to JSON code blocks

stripMarkdownJsonFence currently matches the first triple-backtick block regardless of language, because (?:json)? is optional. If Claude returns any non-JSON fenced snippet before the actual payload (for example a ```text block in a preamble), this function discards the real response body and parseAndValidate fails even when valid analysis JSON is present later. This can cause the analyze workflow to reject otherwise valid runs and skip callback/issue processing.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Addressed: stripMarkdownJsonFence now matches only explicit json-labeled fences (opening delimiter plus json label). Unlabeled fences are left untouched so we do not strip arbitrary code blocks. Added regression coverage in schema.test.mjs.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces several improvements across the automation scripts, admin UI, and server-side logic. Key changes include a more robust JSON extraction mechanism for AI responses, escaping for GitHub Action annotations, and the implementation of request coalescing for GitHub App installation tokens to prevent redundant API calls. In the admin interface, error filtering and pluralization support were improved. On the server, Sentry event scrubbing was enhanced to redact UUIDs and opaque path segments. Feedback was provided regarding the Sentry URL scrubbing logic, specifically noting that the use of the URL constructor may fail on relative paths and that the regex for opaque IDs might inadvertently mask long filenames.

Comment thread server/api/src/lib/sentry.ts Outdated
Comment on lines +143 to +156
const u = new URL(url);
u.search = "";
const segments = u.pathname.split("/").map((seg) => {
if (seg.length === 0) return seg;
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(seg)) {
return "[uuid]";
}
if (/^[A-Za-z0-9._~-]{24,}$/.test(seg)) {
return FILTERED;
}
return seg;
});
u.pathname = segments.join("/") || "/";
return u.toString();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

new URL(url) は絶対 URL を期待するため、相対パス(例: /api/pages/...)が渡された場合に TypeError を投げ、結果が一律で [Filtered] になってしまいます。Sentry SDK から送られる URL が常に絶対 URL であるとは限らないため、ベース URL を指定して相対パスも解析できるようにするのが安全です。

また、不透明な ID をマスクする正規表現 /^[A-Za-z0-9._~-]{24,}$/ は、ドットを含む長いファイル名(例: pageAccessService.test.ts)もマスクしてしまう可能性があるため、ドットを除外するか閾値を調整することを検討してください。

    try {
      const isAbsolute = /^https?:\/\//i.test(url);
      const u = new URL(url, "http://n");
      u.search = "";
      u.hash = "";
      const segments = u.pathname.split("/").map((seg) => {
        if (seg.length === 0) return seg;
        if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(seg)) {
          return "[uuid]";
        }
        if (/^[A-Za-z0-9_~-]{24,}$/.test(seg)) {
          return FILTERED;
        }
        return seg;
      });
      u.pathname = segments.join("/") || "/";
      return isAbsolute ? u.toString() : u.pathname;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Addressed: scrubRequestUrl now resolves relative paths against a synthetic origin before pathname scrubbing, so relative SDK URLs are scrubbed instead of collapsing to [Filtered]. Return type is string | undefined to satisfy Sentry typings (fixes API Typecheck). Added sentry.test.ts coverage for a relative URL.

@otomatty otomatty self-assigned this May 18, 2026
Fix API typecheck for scrubRequestUrl, scrub relative request URLs with a synthetic base, and only unwrap json-labeled markdown fences in Claude analyze parsing.

Co-authored-by: Cursor <cursoragent@cursor.com>
@otomatty

Copy link
Copy Markdown
Owner Author

レビューコメントへの対応をコミットしました(0b83c79a)。API Typecheck の TS2322、Sentry の相対 URL スクラブ、Claude analyze の JSON フェンス抽出を修正済みです。最新の変更に対する再レビューをお願いします。

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

@otomatty ご対応ありがとうございます!commit 0b83c79a で修正された内容(TS2322、Sentry 相対 URL スクラブ、Claude analyze の JSON フェンス抽出)を含む最新の変更に対してレビューを実施します。

🐇

✅ Actions performed

Full review triggered.

@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 (1)
admin/src/api/admin.test.ts (1)

316-316: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Update the test assertion to verify encodeURIComponent encoding, consistent with the implementation.

The patchApiErrorStatus implementation correctly uses encodeURIComponent(id) when building the path (line 481). Update the test assertion on line 316 to verify this encoding behavior:

expect(adminFetch).toHaveBeenCalledWith(`/api/admin/errors/${encodeURIComponent(sampleErrorRow.id)}`, {

While sampleErrorRow.id is a plain UUID that yields the same string after encoding, this change documents and verifies the defensive encoding behavior consistent with the implementation and the getApiErrorById test pattern.

🤖 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 `@admin/src/api/admin.test.ts` at line 316, The test assertion in admin.test.ts
should mirror the implementation's defensive encoding: update the expect call
that checks adminFetch to use encodeURIComponent(sampleErrorRow.id) in the URL;
specifically change the assertion that references
`/api/admin/errors/${sampleErrorRow.id}` to
`/api/admin/errors/${encodeURIComponent(sampleErrorRow.id)}` so it matches
patchApiErrorStatus's use of encodeURIComponent(id) and the getApiErrorById test
pattern.
🤖 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 @.github/actions/claude-analyze/schema.mjs:
- Around line 125-129: The root-payload detection in looksLikeAnalysisPayload is
too strict/type-based and can skip early rejection when keys exist but types are
wrong; change the check to detect the shape by key presence (use
Object.prototype.hasOwnProperty.call(o, "severity") &&
Object.prototype.hasOwnProperty.call(o, "ai_summary")) so it returns true only
when those keys exist, and move/keep type validation later where the payload is
consumed to fail fast on malformed types; apply the same key-presence change to
the duplicate detection at the second occurrence (the block around lines
181-183) so both places test for key presence rather than immediate type
matching.

In `@admin/src/pages/errors/ErrorDetailDialog.tsx`:
- Around line 75-79: The pending state reset only runs inside the onOpenChange
handler so clicking the Cancel button (which calls onClose directly) doesn't
clear it; update ErrorDetailDialog to centralize clearing by ensuring onClose
always clears pending state—e.g., create/replace the existing onClose handler
used by the Cancel button with a wrapper that calls setPendingFor(null) then
calls the original onClose (and remove duplicate clearing from onOpenChange or
also call the wrapper there); apply the same change for the other occurrence
around the code referenced at lines 197-199 so every close path (overlay, ESC,
Cancel button) clears pending state.

---

Outside diff comments:
In `@admin/src/api/admin.test.ts`:
- Line 316: The test assertion in admin.test.ts should mirror the
implementation's defensive encoding: update the expect call that checks
adminFetch to use encodeURIComponent(sampleErrorRow.id) in the URL; specifically
change the assertion that references `/api/admin/errors/${sampleErrorRow.id}` to
`/api/admin/errors/${encodeURIComponent(sampleErrorRow.id)}` so it matches
patchApiErrorStatus's use of encodeURIComponent(id) and the getApiErrorById test
pattern.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 63e5c21d-fb7c-4472-8e71-cbeb1367a3ac

📥 Commits

Reviewing files that changed from the base of the PR and between 86e3f5e and 0b83c79.

📒 Files selected for processing (21)
  • .github/actions/claude-analyze/__tests__/schema.test.mjs
  • .github/actions/claude-analyze/action.yml
  • .github/actions/claude-analyze/autoIssueRunner.mjs
  • .github/actions/claude-analyze/escapeGithubAnnotation.mjs
  • .github/actions/claude-analyze/schema.mjs
  • .github/workflows/analyze-error.yml
  • admin/src/api/admin.test.ts
  • admin/src/i18n/locales/en/nav.json
  • admin/src/i18n/locales/ja/nav.json
  • admin/src/pages/errors/ErrorDetailDialog.tsx
  • admin/src/pages/errors/ErrorsContent.tsx
  • admin/src/pages/errors/useApiErrors.ts
  • server/api/src/__tests__/routes/admin/errors.test.ts
  • server/api/src/__tests__/routes/pageSnapshots.test.ts
  • server/api/src/__tests__/routes/pages.test.ts
  • server/api/src/__tests__/routes/syncPages.test.ts
  • server/api/src/__tests__/routes/webhooks/sentry.test.ts
  • server/api/src/__tests__/services/pageAccessService.test.ts
  • server/api/src/lib/githubAppAuth.ts
  • server/api/src/lib/sentry.test.ts
  • server/api/src/lib/sentry.ts

Comment thread .github/actions/claude-analyze/schema.mjs
Comment thread admin/src/pages/errors/ErrorDetailDialog.tsx
Detect analysis root payload by own keys for fast schema failures; reset pending status on Cancel in ErrorDetailDialog.

Co-authored-by: Cursor <cursoragent@cursor.com>
@otomatty

Copy link
Copy Markdown
Owner Author

CodeRabbit の未対応スレッド 2 件を反映しました(d0b0d698)。looksLikeAnalysisPayload のルート判定強化と、ErrorDetailDialog のキャンセル経路での pending リセットです。

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

@otomatty ありがとうございます!commit d0b0d698 で対応された looksLikeAnalysisPayload のルート判定強化と ErrorDetailDialog のキャンセル経路での pending リセットを含む最新の変更に対してレビューを実施します。

🐇

✅ Actions performed

Full review triggered.

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

🧹 Nitpick comments (1)
admin/src/pages/errors/ErrorDetailDialog.test.tsx (1)

108-151: ⚡ Quick win

Well-structured test for cancel-clears-pending-state behavior.

The test correctly verifies that when a user makes a pending status change and clicks Cancel, that draft is discarded when the dialog reopens with the same row. The bilingual comments, explicit typing, and proper use of async user-event interactions align with coding guidelines.

💡 Optional: Consider additional test coverage

The current test suite has one focused test case. You may want to add tests for:

  • Save button click (verify onUpdateStatus is called with new status)
  • Outside-click behavior (the mock includes data-testid="outside-close")
  • Error state handling when saveError is not null
  • Disabled state when saving={true}

These would provide more complete coverage of the dialog's state management, though the current test successfully validates the specific cancel behavior mentioned in the PR objectives.

🤖 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 `@admin/src/pages/errors/ErrorDetailDialog.test.tsx` around lines 108 - 151,
Add complementary tests to cover save, outside-click, error, and disabled-saving
behaviors: (1) add a test that selects a new status via userEvent.selectOptions
on the "status-select" then clicks the save button and asserts onUpdateStatus
was called with the chosen value; (2) add a test that clicks the element with
data-testid "outside-close" and asserts onClose is invoked to cover
outside-click closing; (3) add a test that rerenders ErrorDetailDialog with
saveError set (non-null) and asserts the error message or error UI is rendered
when row and saveError are present; (4) add a test that renders with
saving={true} and asserts controls (status-select and save button) are
disabled/grayed out and that onUpdateStatus is not called when attempting to
save; use the existing test patterns, userEvent interactions, and props (row,
onClose, onUpdateStatus, saving, saveError) and reference the "status-select"
test id and button labels to locate elements.
🤖 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 `@admin/src/pages/errors/ErrorDetailDialog.test.tsx`:
- Around line 108-151: Add complementary tests to cover save, outside-click,
error, and disabled-saving behaviors: (1) add a test that selects a new status
via userEvent.selectOptions on the "status-select" then clicks the save button
and asserts onUpdateStatus was called with the chosen value; (2) add a test that
clicks the element with data-testid "outside-close" and asserts onClose is
invoked to cover outside-click closing; (3) add a test that rerenders
ErrorDetailDialog with saveError set (non-null) and asserts the error message or
error UI is rendered when row and saveError are present; (4) add a test that
renders with saving={true} and asserts controls (status-select and save button)
are disabled/grayed out and that onUpdateStatus is not called when attempting to
save; use the existing test patterns, userEvent interactions, and props (row,
onClose, onUpdateStatus, saving, saveError) and reference the "status-select"
test id and button labels to locate elements.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f89af5fc-3b8d-4e8b-bbbd-a0129344c2bd

📥 Commits

Reviewing files that changed from the base of the PR and between 0b83c79 and d0b0d69.

📒 Files selected for processing (4)
  • .github/actions/claude-analyze/__tests__/schema.test.mjs
  • .github/actions/claude-analyze/schema.mjs
  • admin/src/pages/errors/ErrorDetailDialog.test.tsx
  • admin/src/pages/errors/ErrorDetailDialog.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • admin/src/pages/errors/ErrorDetailDialog.tsx
  • .github/actions/claude-analyze/schema.mjs

@otomatty otomatty merged commit 0d11e14 into develop May 18, 2026
18 checks passed
@otomatty otomatty deleted the fix/pr905-review-followups branch May 18, 2026 15:04
@coderabbitai coderabbitai Bot mentioned this pull request May 18, 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